Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
kernel_translation_helper.cc
Go to the documentation of this file.
1// Copyright (c) 2018, 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
6
12#include "vm/flags.h"
13#include "vm/log.h"
14#include "vm/object_store.h"
15#include "vm/parser.h" // for ParsedFunction
16#include "vm/symbols.h"
17
18#define Z (zone_)
19#define H (translation_helper_)
20#define T (type_translator_)
21#define I Isolate::Current()
22#define IG IsolateGroup::Current()
23
24namespace dart {
25namespace kernel {
26
28 : thread_(thread),
29 zone_(thread->zone()),
30 isolate_group_(thread->isolate_group()),
31 allocation_space_(Heap::kNew),
32 string_offsets_(TypedData::Handle(Z)),
33 string_data_(TypedDataView::Handle(Z)),
34 canonical_names_(TypedData::Handle(Z)),
35 metadata_payloads_(TypedDataView::Handle(Z)),
36 metadata_mappings_(TypedDataView::Handle(Z)),
37 constants_(Array::Handle(Z)),
38 constants_table_(TypedDataView::Handle(Z)),
39 info_(KernelProgramInfo::Handle(Z)),
40 name_index_handle_(Smi::Handle(Z)) {}
41
43 : thread_(thread),
44 zone_(thread->zone()),
45 isolate_group_(thread->isolate_group()),
46 allocation_space_(space),
47 string_offsets_(TypedData::Handle(Z)),
48 string_data_(TypedDataView::Handle(Z)),
49 canonical_names_(TypedData::Handle(Z)),
50 metadata_payloads_(TypedDataView::Handle(Z)),
51 metadata_mappings_(TypedDataView::Handle(Z)),
52 constants_(Array::Handle(Z)),
53 constants_table_(TypedDataView::Handle(Z)),
54 info_(KernelProgramInfo::Handle(Z)),
55 name_index_handle_(Smi::Handle(Z)) {}
56
58 string_offsets_ = TypedData::null();
59 string_data_ = TypedDataView::null();
60 canonical_names_ = TypedData::null();
61 metadata_payloads_ = TypedDataView::null();
62 metadata_mappings_ = TypedDataView::null();
63 constants_ = Array::null();
64}
65
67 const KernelProgramInfo& info) {
68 if (info.IsNull()) {
69 // If there is no kernel data available then do not bother initializing!
70 // This can happen with few special functions like
71 // NoSuchMethodDispatcher and InvokeFieldDispatcher.
72 return;
73 }
74 SetStringOffsets(TypedData::Handle(Z, info.string_offsets()));
76 SetCanonicalNames(TypedData::Handle(Z, info.canonical_names()));
77 SetMetadataPayloads(TypedDataView::Handle(Z, info.metadata_payloads()));
78 SetMetadataMappings(TypedDataView::Handle(Z, info.metadata_mappings()));
79 SetConstants(Array::Handle(Z, info.constants()));
80 SetConstantsTable(TypedDataView::Handle(Z, info.constants_table()));
82}
83
85 ASSERT(string_offsets_.IsNull());
86 string_offsets_ = string_offsets.ptr();
87}
88
90 ASSERT(string_data_.IsNull());
91 string_data_ = string_data.ptr();
92}
93
94void TranslationHelper::SetCanonicalNames(const TypedData& canonical_names) {
95 ASSERT(canonical_names_.IsNull());
96 canonical_names_ = canonical_names.ptr();
97}
98
100 const TypedDataView& metadata_payloads) {
101 ASSERT(metadata_payloads_.IsNull());
103 metadata_payloads_ = metadata_payloads.ptr();
104}
105
107 const TypedDataView& metadata_mappings) {
108 ASSERT(metadata_mappings_.IsNull());
109 metadata_mappings_ = metadata_mappings.ptr();
110}
111
113 ASSERT(constants_.IsNull() ||
114 (constants.IsNull() || constants.Length() == 0));
115 constants_ = constants.ptr();
116}
117
119 const TypedDataView& constants_table) {
120 ASSERT(constants_table_.IsNull());
121 constants_table_ = constants_table.ptr();
122}
123
127
128intptr_t TranslationHelper::StringOffset(StringIndex index) const {
129 return string_offsets_.GetUint32(index << 2);
130}
131
132intptr_t TranslationHelper::StringSize(StringIndex index) const {
133 return StringOffset(StringIndex(index + 1)) - StringOffset(index);
134}
135
136uint8_t TranslationHelper::CharacterAt(StringIndex string_index,
137 intptr_t index) {
138 ASSERT(index < StringSize(string_index));
139 return string_data_.GetUint8(StringOffset(string_index) + index);
140}
141
142uint8_t* TranslationHelper::StringBuffer(StringIndex string_index) const {
143 // Though this implementation appears like it could be replaced by
144 // string_data_.DataAddr(StringOffset(string_index)), it can't quite. If the
145 // last string in the string table is a zero length string, then the latter
146 // expression will try to return the address that is one past the backing
147 // store of the string_data_ table. Though this is safe in C++ as long as the
148 // address is not dereferenced, it will trigger the assert in
149 // ExternalTypedData::DataAddr.
150 ASSERT(Thread::Current()->no_safepoint_scope_depth() > 0);
151 return reinterpret_cast<uint8_t*>(string_data_.DataAddr(0)) +
152 StringOffset(string_index);
153}
154
155bool TranslationHelper::StringEquals(StringIndex string_index,
156 const char* other) {
157 intptr_t length = strlen(other);
158 if (length != StringSize(string_index)) return false;
159
160 NoSafepointScope no_safepoint;
161 return memcmp(StringBuffer(string_index), other, length) == 0;
162}
163
165 // Canonical names are pairs of 4-byte parent and string indexes, so the size
166 // of an entry is 8 bytes. The parent is biased: 0 represents the root name
167 // and N+1 represents the name with index N.
168 return NameIndex(static_cast<intptr_t>(canonical_names_.GetUint32(8 * name)) -
169 1);
170}
171
173 return StringIndex(canonical_names_.GetUint32((8 * name) + 4));
174}
175
177 // Administrative names start with '@'.
178 StringIndex name_string = CanonicalNameString(name);
179 return (StringSize(name_string) > 0) && (CharacterAt(name_string, 0) == '@');
180}
181
183 // Private names start with '_'.
184 StringIndex name_string = CanonicalNameString(name);
185 return (StringSize(name_string) > 0) && (CharacterAt(name_string, 0) == '_');
186}
187
189 return name == -1;
190}
191
193 // Libraries are the only canonical names with the root as their parent.
195}
196
198 // Classes have the library as their parent and are not an administrative
199 // name starting with @.
200 return !IsAdministrative(name) && !IsRoot(name) &&
202}
203
207
209 // Constructors with private names have the import URI of the library where
210 // they are visible as the parent and the string "@constructors" as the
211 // parent's parent. Constructors with non-private names have the string
212 // "@constructors" as the parent.
213 if (IsRoot(name)) {
214 return false;
215 }
217 if (IsPrivate(name)) {
218 kind = CanonicalNameParent(kind);
219 }
220 return StringEquals(CanonicalNameString(kind), "@constructors");
221}
222
226
228 // Methods with private names have the import URI of the library where they
229 // are visible as the parent and the string "@methods" as the parent's parent.
230 // Methods with non-private names have the string "@methods" as the parent.
231 if (IsRoot(name)) {
232 return false;
233 }
235 if (IsPrivate(name)) {
236 kind = CanonicalNameParent(kind);
237 }
238 return StringEquals(CanonicalNameString(kind), "@methods");
239}
240
242 // Getters with private names have the import URI of the library where they
243 // are visible as the parent and the string "@getters" as the parent's parent.
244 // Getters with non-private names have the string "@getters" as the parent.
245 if (IsRoot(name)) {
246 return false;
247 }
249 if (IsPrivate(name)) {
250 kind = CanonicalNameParent(kind);
251 }
252 return StringEquals(CanonicalNameString(kind), "@getters");
253}
254
256 // Setters with private names have the import URI of the library where they
257 // are visible as the parent and the string "@setters" as the parent's parent.
258 // Setters with non-private names have the string "@setters" as the parent.
259 if (IsRoot(name)) {
260 return false;
261 }
263 if (IsPrivate(name)) {
264 kind = CanonicalNameParent(kind);
265 }
266 return StringEquals(CanonicalNameString(kind), "@setters");
267}
268
270 // Factories with private names have the import URI of the library where they
271 // are visible as the parent and the string "@factories" as the parent's
272 // parent. Factories with non-private names have the string "@factories" as
273 // the parent.
274 if (IsRoot(name)) {
275 return false;
276 }
278 if (IsPrivate(name)) {
279 kind = CanonicalNameParent(kind);
280 }
281 return StringEquals(CanonicalNameString(kind), "@factories");
282}
283
285 // Fields with private names have the import URI of the library where they
286 // are visible as the parent and the string "@fields" as the parent's parent.
287 // Fields with non-private names have the string "@fields" as the parent.
288 if (IsRoot(name)) {
289 return false;
290 }
292 if (IsPrivate(name)) {
293 kind = CanonicalNameParent(kind);
294 }
295 return StringEquals(CanonicalNameString(kind), "@fields");
296}
297
301 if (IsPrivate(name)) {
302 enclosing = CanonicalNameParent(enclosing);
303 }
304 ASSERT(IsLibrary(enclosing) || IsClass(enclosing));
305 return enclosing;
306}
307
309 if (instance.IsNull()) return instance.ptr();
310
311 return instance.Canonicalize(thread());
312}
313
315 Heap::Space space) {
316 return String::ZoneHandle(Z, String::New(content, space));
317}
318
319String& TranslationHelper::DartString(StringIndex string_index,
320 Heap::Space space) {
321 intptr_t length = StringSize(string_index);
322 uint8_t* buffer = Z->Alloc<uint8_t>(length);
323 {
324 NoSafepointScope no_safepoint;
325 memmove(buffer, StringBuffer(string_index), length);
326 }
328}
329
330String& TranslationHelper::DartString(const uint8_t* utf8_array,
331 intptr_t len,
332 Heap::Space space) {
333 return String::ZoneHandle(Z, String::FromUTF8(utf8_array, len, space));
334}
335
340
342 return String::ZoneHandle(Z, Symbols::New(thread_, content));
343}
344
345String& TranslationHelper::DartSymbolPlain(StringIndex string_index) const {
346 intptr_t length = StringSize(string_index);
347 uint8_t* buffer = Z->Alloc<uint8_t>(length);
348 {
349 NoSafepointScope no_safepoint;
350 memmove(buffer, StringBuffer(string_index), length);
351 }
352 String& result =
354 return result;
355}
356
358 const char* content) const {
360 if (IG->obfuscate()) {
361 Obfuscator obfuscator(thread_, String::Handle(Z));
362 result = obfuscator.Rename(result, true);
363 }
364 return result;
365}
366
367String& TranslationHelper::DartSymbolObfuscate(StringIndex string_index) const {
368 intptr_t length = StringSize(string_index);
369 uint8_t* buffer = Z->Alloc<uint8_t>(length);
370 {
371 NoSafepointScope no_safepoint;
372 memmove(buffer, StringBuffer(string_index), length);
373 }
374 String& result =
376 if (IG->obfuscate()) {
377 Obfuscator obfuscator(thread_, String::Handle(Z));
378 result = obfuscator.Rename(result, true);
379 }
380 return result;
381}
382
384 StringIndex string_index) {
385 String& name = DartString(string_index);
386 ManglePrivateName(lib, &name);
387 return name;
388}
389
391 ASSERT(IsClass(kernel_class));
392 String& name = DartString(CanonicalNameString(kernel_class));
393 return ManglePrivateName(CanonicalNameParent(kernel_class), &name);
394}
395
397 ASSERT(IsConstructor(constructor));
398 return DartFactoryName(constructor);
399}
400
402 ASSERT(IsProcedure(procedure) || IsConstructor(procedure));
403 if (IsSetter(procedure)) {
404 return DartSetterName(procedure);
405 } else if (IsGetter(procedure)) {
406 return DartGetterName(procedure);
407 } else if (IsFactory(procedure)) {
408 return DartFactoryName(procedure);
409 } else if (IsMethod(procedure)) {
410 return DartMethodName(procedure);
411 } else {
412 ASSERT(IsConstructor(procedure));
413 return DartConstructorName(procedure);
414 }
415}
416
421
423 StringIndex setter) {
424 // The names flowing into [setter] are coming from the Kernel file:
425 // * user-defined setters: `fieldname=`
426 // * property-set expressions: `fieldname`
427 //
428 // The VM uses `get:fieldname` and `set:fieldname`.
429 //
430 // => In order to be consistent, we remove the `=` always and adopt the VM
431 // conventions.
432 intptr_t size = StringSize(setter);
433 ASSERT(size > 0);
434 if (CharacterAt(setter, size - 1) == '=') {
435 --size;
436 }
437 uint8_t* buffer = Z->Alloc<uint8_t>(size);
438 {
439 NoSafepointScope no_safepoint;
440 memmove(buffer, StringBuffer(setter), size);
441 }
442 String& name =
443 String::ZoneHandle(Z, String::FromUTF8(buffer, size, allocation_space_));
444 ManglePrivateName(parent, &name);
446 return name;
447}
448
453
455 StringIndex getter) {
456 String& name = DartString(getter);
457 ManglePrivateName(parent, &name);
459 return name;
460}
461
465
467 StringIndex field) {
468 String& name = DartString(field);
469 return ManglePrivateName(parent, &name);
470}
471
476
478 StringIndex method) {
479 String& name = DartString(method);
480 return ManglePrivateName(parent, &name);
481}
482
484 ASSERT(IsConstructor(factory) || IsFactory(factory));
486 pieces.Add(DartClassName(EnclosingName(factory)));
487 pieces.Add(Symbols::Dot());
488 // [DartMethodName] will mangle the name.
489 pieces.Add(DartMethodName(factory));
490 return String::ZoneHandle(Z, Symbols::FromConcatAll(thread_, pieces));
491}
492
504
510
512 NameIndex kernel_library,
513 bool required) {
514 // We only use the string and don't rely on having any particular parent.
515 // This ASSERT is just a sanity check.
516 ASSERT(IsLibrary(kernel_library) ||
517 IsAdministrative(CanonicalNameParent(kernel_library)));
518 {
519 name_index_handle_ = Smi::New(kernel_library);
520 LibraryPtr raw_lib = info_.LookupLibrary(thread_, name_index_handle_);
521 NoSafepointScope no_safepoint_scope(thread_);
522 if (raw_lib != Library::null()) {
523 return raw_lib;
524 }
525 }
526
527 const String& library_name =
528 DartSymbolPlain(CanonicalNameString(kernel_library));
529 ASSERT(!library_name.IsNull());
530 const Library& library =
531 Library::Handle(Z, Library::LookupLibrary(thread_, library_name));
532 if (library.IsNull()) {
533 if (required) {
534 LookupFailed(kernel_library);
535 }
536 return Library::null();
537 }
538 name_index_handle_ = Smi::New(kernel_library);
539 return info_.InsertLibrary(thread_, name_index_handle_, library);
540}
541
543 bool required) {
544 ASSERT(IsClass(kernel_class));
545 {
546 name_index_handle_ = Smi::New(kernel_class);
547 ClassPtr raw_class = info_.LookupClass(thread_, name_index_handle_);
548 NoSafepointScope no_safepoint_scope(thread_);
549 if (raw_class != Class::null()) {
550 return raw_class;
551 }
552 }
553
554 const String& class_name = DartClassName(kernel_class);
555 NameIndex kernel_library = CanonicalNameParent(kernel_class);
556 Library& library = Library::Handle(
557 Z, LookupLibraryByKernelLibrary(kernel_library, /*required=*/false));
558 if (library.IsNull()) {
559 if (required) {
560 LookupFailed(kernel_class);
561 }
562 return Class::null();
563 }
564 const Class& klass =
566 if (klass.IsNull()) {
567 if (required) {
568 LookupFailed(kernel_class);
569 }
570 return Class::null();
571 }
572 name_index_handle_ = Smi::New(kernel_class);
573 return info_.InsertClass(thread_, name_index_handle_, klass);
574}
575
577 NameIndex kernel_name,
578 bool required) {
579 if (IsLibrary(kernel_name)) {
580 const auto& library =
581 Library::Handle(Z, LookupLibraryByKernelLibrary(kernel_name, required));
582 if (library.IsNull()) {
583 return Class::null();
584 }
585 return library.toplevel_class();
586 } else {
587 ASSERT(IsClass(kernel_name));
588 return LookupClassByKernelClass(kernel_name, required);
589 }
590}
591
593 bool required) {
594 ASSERT(IsField(kernel_field));
595 NameIndex enclosing = EnclosingName(kernel_field);
596
597 const Class& klass = Class::Handle(
598 Z, LookupClassByKernelClassOrLibrary(enclosing, /*required=*/false));
599 if (klass.IsNull()) {
600 if (required) {
601 LookupFailed(kernel_field);
602 }
603 return Field::null();
604 }
605 Field& field = Field::Handle(
608 if (field.IsNull() && required) {
609 LookupFailed(kernel_field);
610 }
611 return field.ptr();
612}
613
615 NameIndex kernel_field,
616 bool required) {
617 ASSERT(IsGetter(kernel_field) || IsSetter(kernel_field));
618 NameIndex enclosing = EnclosingName(kernel_field);
619
620 const Class& klass = Class::Handle(
621 Z, LookupClassByKernelClassOrLibrary(enclosing, /*required=*/false));
622 if (klass.IsNull()) {
623 if (required) {
624 LookupFailed(kernel_field);
625 }
626 return Field::null();
627 }
628 const Field& field = Field::Handle(
631 if (field.IsNull() && required) {
632 LookupFailed(kernel_field);
633 }
634 return field.ptr();
635}
636
638 NameIndex procedure,
639 bool required) {
640 const String& procedure_name = DartProcedureName(procedure);
641
642 // The parent is either a library or a class (in which case the procedure is a
643 // static method).
644 NameIndex enclosing = EnclosingName(procedure);
645 const Class& klass = Class::Handle(
646 Z, LookupClassByKernelClassOrLibrary(enclosing, /*required=*/false));
647 if (klass.IsNull()) {
648 if (required) {
649 LookupFailed(procedure);
650 }
651 return Function::null();
652 }
653
654 const auto& error = klass.EnsureIsFinalized(thread_);
657 Function::Handle(Z, klass.LookupFunctionAllowPrivate(procedure_name));
658 if (function.IsNull() && required) {
659 LookupFailed(procedure);
660 }
661 return function.ptr();
662}
663
665 NameIndex constructor,
666 bool required) {
667 ASSERT(IsConstructor(constructor));
668 Class& klass = Class::Handle(
669 Z,
670 LookupClassByKernelClass(EnclosingName(constructor), /*required=*/false));
672 if (!klass.IsNull()) {
674 /*required=*/false);
675 }
676 if (function.IsNull() && required) {
677 LookupFailed(constructor);
678 }
679 return function.ptr();
680}
681
683 const Class& owner,
684 NameIndex constructor,
685 bool required) {
686 ASSERT(IsConstructor(constructor));
687 const auto& error = owner.EnsureIsFinalized(thread_);
691 if (function.IsNull() && required) {
692 LookupFailed(constructor);
693 }
694 return function.ptr();
695}
696
698 const Class& owner,
699 StringIndex constructor_name,
700 bool required) {
702 pieces.Add(String::Handle(Z, owner.Name()));
703 pieces.Add(Symbols::Dot());
704 String& name = DartSymbolPlain(constructor_name);
705 pieces.Add(ManglePrivateName(Library::Handle(owner.library()), &name));
706
707 String& new_name =
709 const auto& error = owner.EnsureIsFinalized(thread_);
711 FunctionPtr function = owner.LookupConstructorAllowPrivate(new_name);
712 if (function == Object::null() && required) {
713 LookupFailed(constructor_name);
714 }
715 return function;
716}
717
719 const String& method_name,
720 bool required) {
721 NameIndex kernel_class = EnclosingName(target);
722 Class& klass = Class::Handle(
723 Z, LookupClassByKernelClass(kernel_class, /*required=*/false));
725 if (!klass.IsNull() && klass.EnsureIsFinalized(thread_) == Error::null()) {
726 function = klass.LookupFunctionAllowPrivate(method_name);
727 }
728 if (function.IsNull() && required) {
730 }
731 return function.ptr();
732}
733
735 bool required) {
736 // The parent is either a library or a class.
737 NameIndex enclosing = EnclosingName(kernel_name);
738 const Class& klass = Class::Handle(
739 Z, LookupClassByKernelClassOrLibrary(enclosing, /*required=*/false));
740 if (klass.IsNull()) {
741 if (required) {
742 LookupFailed(kernel_name);
743 }
744 return Object::null();
745 }
746
747 Object& member = Object::Handle(Z);
748 if (IsField(kernel_name)) {
749 member = klass.LookupFieldAllowPrivate(
751 } else {
752 const String& procedure_name = DartProcedureName(kernel_name);
753
754 const auto& error = klass.EnsureIsFinalized(thread_);
756 member = klass.LookupFunctionAllowPrivate(procedure_name);
757 }
758 if (member.IsNull() && required) {
759 LookupFailed(kernel_name);
760 }
761 return member.ptr();
762}
763
765 const String& name) {
766 // Search the superclass chain for the selector.
767 Class& iterate_klass = Class::Handle(Z, klass.ptr());
768 while (!iterate_klass.IsNull()) {
769 FunctionPtr function =
771 if (function != Object::null()) {
772 return function;
773 }
774 iterate_klass = iterate_klass.SuperClass();
775 }
776 return Function::null();
777}
778
780 ASSERT(!klass.IsNull());
781 // Forward expression evaluation class to a real class when
782 // creating types.
783 if (GetExpressionEvaluationClass().ptr() == klass.ptr()) {
784 ASSERT(GetExpressionEvaluationRealClass().ptr() != klass.ptr());
786 }
787 ASSERT(klass.id() != kIllegalCid);
788 // Note that if cls is _Closure, the returned type will be _Closure,
789 // and not the signature type.
791 if (klass.is_type_finalized()) {
792 type = klass.DeclarationType();
793 } else {
794 // Note that the type argument vector is not yet extended.
796 const intptr_t num_type_params = klass.NumTypeParameters();
797 if (num_type_params > 0) {
798 type_args = TypeArguments::New(num_type_params);
799 TypeParameter& type_param = TypeParameter::Handle();
800 for (intptr_t i = 0; i < num_type_params; i++) {
801 type_param = klass.TypeParameterAt(i);
802 type_args.SetTypeAt(i, type_param);
803 }
804 }
805 type = Type::New(klass, type_args, Nullability::kNonNullable);
806 }
807 return type;
808}
809
811 const Class& klass,
812 const Function& function,
813 const AbstractType& field_type) {
814 bool is_setter = function.IsImplicitSetterFunction();
815 bool is_method = !function.IsStaticFunction();
816 intptr_t parameter_count = (is_method ? 1 : 0) + (is_setter ? 1 : 0);
817
818 const FunctionType& signature = FunctionType::Handle(Z, function.signature());
819 signature.SetNumOptionalParameters(0, false);
820 signature.set_num_fixed_parameters(parameter_count);
821 if (parameter_count > 0) {
822 signature.set_parameter_types(
823 Array::Handle(Z, Array::New(parameter_count, Heap::kOld)));
824 }
825 function.CreateNameArray();
826
827 intptr_t pos = 0;
828 if (is_method) {
829 signature.SetParameterTypeAt(pos, GetDeclarationType(klass));
830 function.SetParameterNameAt(pos, Symbols::This());
831 pos++;
832 }
833 if (is_setter) {
834 signature.SetParameterTypeAt(pos, field_type);
835 function.SetParameterNameAt(pos, Symbols::Value());
836 pos++;
837 }
838}
839
841 const Script& null_script = Script::Handle(Z);
842
843 va_list args;
844 va_start(args, format);
845 Report::MessageV(Report::kError, null_script, TokenPosition::kNoSource,
847 va_end(args);
848 UNREACHABLE();
849}
850
852 const TokenPosition position,
853 const char* format,
854 ...) {
855 va_list args;
856 va_start(args, format);
858 args);
859 va_end(args);
860 UNREACHABLE();
861}
862
864 const char* format,
865 ...) {
866 const Script& null_script = Script::Handle(Z);
867
868 va_list args;
869 va_start(args, format);
870 Report::LongJumpV(prev_error, null_script, TokenPosition::kNoSource, format,
871 args);
872 va_end(args);
873 UNREACHABLE();
874}
875
877 const Script& script,
878 const TokenPosition position,
879 const char* format,
880 ...) {
881 va_list args;
882 va_start(args, format);
883 Report::LongJumpV(prev_error, script, position, format, args);
884 va_end(args);
885 UNREACHABLE();
886}
887
888String& TranslationHelper::ManglePrivateName(NameIndex parent,
889 String* name_to_modify,
890 bool symbolize,
891 bool obfuscate) {
892 if (name_to_modify->Length() >= 1 && name_to_modify->CharAt(0) == '_') {
893 const Library& library =
895 *name_to_modify = library.PrivateName(*name_to_modify);
896 if (obfuscate && IG->obfuscate()) {
897 const String& library_key = String::Handle(library.private_key());
898 Obfuscator obfuscator(thread_, library_key);
899 *name_to_modify = obfuscator.Rename(*name_to_modify);
900 }
901 } else if (symbolize) {
902 *name_to_modify = Symbols::New(thread_, *name_to_modify);
903 if (obfuscate && IG->obfuscate()) {
904 const String& library_key = String::Handle();
905 Obfuscator obfuscator(thread_, library_key);
906 *name_to_modify = obfuscator.Rename(*name_to_modify);
907 }
908 }
909 return *name_to_modify;
910}
911
912String& TranslationHelper::ManglePrivateName(const Library& library,
913 String* name_to_modify,
914 bool symbolize,
915 bool obfuscate) {
916 if (name_to_modify->Length() >= 1 && name_to_modify->CharAt(0) == '_' &&
917 !library.IsNull()) {
918 *name_to_modify = library.PrivateName(*name_to_modify);
919 if (obfuscate && IG->obfuscate()) {
920 const String& library_key = String::Handle(library.private_key());
921 Obfuscator obfuscator(thread_, library_key);
922 *name_to_modify = obfuscator.Rename(*name_to_modify);
923 }
924 } else if (symbolize) {
925 *name_to_modify = Symbols::New(thread_, *name_to_modify);
926 if (obfuscate && IG->obfuscate()) {
927 const String& library_key = String::Handle();
928 Obfuscator obfuscator(thread_, library_key);
929 *name_to_modify = obfuscator.Rename(*name_to_modify);
930 }
931 }
932 return *name_to_modify;
933}
934
936 if (field <= next_read_) return;
937
938 // Ordered with fall-through.
939 switch (next_read_) {
940 case kStart: {
941 Tag tag = helper_->ReadTag(); // read tag.
942 ASSERT(tag == kFunctionNode);
943 if (++next_read_ == field) return;
944 }
946 case kPosition:
947 position_ = helper_->ReadPosition(); // read position.
948 if (++next_read_ == field) return;
950 case kEndPosition:
951 end_position_ = helper_->ReadPosition(); // read end position.
952 if (++next_read_ == field) return;
954 case kAsyncMarker:
955 async_marker_ = static_cast<AsyncMarker>(helper_->ReadByte());
956 if (++next_read_ == field) return;
958 case kDartAsyncMarker:
959 dart_async_marker_ = static_cast<AsyncMarker>(
960 helper_->ReadByte()); // read dart async marker.
961 if (++next_read_ == field) return;
963 case kTypeParameters:
964 helper_->SkipTypeParametersList(); // read type parameters.
965 if (++next_read_ == field) return;
969 helper_->ReadUInt(); // read total parameter count.
970 if (++next_read_ == field) return;
974 helper_->ReadUInt(); // read required parameter count.
975 if (++next_read_ == field) return;
978 helper_->SkipListOfVariableDeclarations(); // read positionals.
979 if (++next_read_ == field) return;
981 case kNamedParameters:
982 helper_->SkipListOfVariableDeclarations(); // read named.
983 if (++next_read_ == field) return;
985 case kReturnType:
986 helper_->SkipDartType(); // read return type.
987 if (++next_read_ == field) return;
990 helper_->SkipOptionalDartType(); // read emitted value type.
991 if (++next_read_ == field) return;
994 Tag tag = helper_->ReadTag(); // read tag.
995 if (tag == kSomething) {
996 helper_->ReadCanonicalNameReference(); // read target.
997 tag = helper_->ReadTag();
998 if (tag == kSomething) {
999 helper_->SkipListOfDartTypes(); // read type arguments.
1000 } else {
1001 ASSERT(tag == kNothing);
1002 }
1003 tag = helper_->ReadTag();
1004 if (tag == kSomething) {
1005 helper_->ReadStringReference(); // read error message.
1006 } else {
1007 ASSERT(tag == kNothing);
1008 }
1009 } else {
1010 ASSERT(tag == kNothing);
1011 }
1012 if (++next_read_ == field) return;
1013 }
1015 case kBody:
1016 if (helper_->ReadTag() == kSomething)
1017 helper_->SkipStatement(); // read body.
1018 if (++next_read_ == field) return;
1020 case kEnd:
1021 return;
1022 }
1023}
1024
1026 for (; next_read_ < field; ++next_read_) {
1027 switch (next_read_) {
1028 case kFlags:
1029 flags_ = helper_->ReadFlags();
1030 break;
1031 case kAnnotations:
1032 helper_->SkipListOfExpressions(); // read annotations.
1033 break;
1034 case kVariance:
1035 helper_->ReadVariance();
1036 break;
1037 case kName:
1038 name_index_ = helper_->ReadStringReference(); // read name index.
1039 break;
1040 case kBound:
1041 helper_->SkipDartType();
1042 break;
1043 case kDefaultType:
1044 helper_->SkipDartType();
1045 break;
1046 case kEnd:
1047 return;
1048 }
1049 }
1050}
1051
1053 if (field <= next_read_) return;
1054
1055 // Ordered with fall-through.
1056 switch (next_read_) {
1057 case kPosition:
1058 position_ = helper_->ReadPosition(); // read position.
1059 if (++next_read_ == field) return;
1061 case kEqualPosition:
1062 equals_position_ = helper_->ReadPosition(); // read equals position.
1063 if (++next_read_ == field) return;
1065 case kAnnotations:
1066 annotation_count_ = helper_->ReadListLength(); // read list length.
1067 for (intptr_t i = 0; i < annotation_count_; ++i) {
1068 helper_->SkipExpression(); // read ith expression.
1069 }
1070 if (++next_read_ == field) return;
1072 case kFlags:
1073 flags_ = helper_->ReadUInt();
1074 if (++next_read_ == field) return;
1076 case kNameIndex:
1077 name_index_ = helper_->ReadStringReference(); // read name index.
1078 if (++next_read_ == field) return;
1080 case kType:
1081 helper_->SkipDartType(); // read type.
1082 if (++next_read_ == field) return;
1084 case kInitializer:
1085 if (helper_->ReadTag() == kSomething)
1086 helper_->SkipExpression(); // read initializer.
1087 if (++next_read_ == field) return;
1089 case kEnd:
1090 return;
1091 }
1092}
1093
1095 : helper_(helper), next_read_(kStart) {
1096 helper_->SetOffset(offset);
1097}
1098
1100 if (field <= next_read_) return;
1101
1102 // Ordered with fall-through.
1103 switch (next_read_) {
1104 case kStart: {
1105 Tag tag = helper_->ReadTag(); // read tag.
1106 ASSERT(tag == kField);
1107 if (++next_read_ == field) return;
1108 }
1112 helper_->ReadCanonicalNameReference(); // read canonical_name_field.
1113 if (++next_read_ == field) return;
1117 helper_->ReadCanonicalNameReference(); // read canonical_name_getter.
1118 if (++next_read_ == field) return;
1122 helper_->ReadCanonicalNameReference(); // read canonical_name_setter.
1123 if (++next_read_ == field) return;
1125 case kSourceUriIndex:
1126 source_uri_index_ = helper_->ReadUInt(); // read source_uri_index.
1128 if (++next_read_ == field) return;
1130 case kPosition:
1131 position_ = helper_->ReadPosition(); // read position.
1132 if (++next_read_ == field) return;
1134 case kEndPosition:
1135 end_position_ = helper_->ReadPosition(); // read end position.
1136 if (++next_read_ == field) return;
1138 case kFlags:
1139 flags_ = helper_->ReadUInt();
1140 if (++next_read_ == field) return;
1142 case kName:
1143 helper_->SkipName(); // read name.
1144 if (++next_read_ == field) return;
1146 case kAnnotations: {
1147 annotation_count_ = helper_->ReadListLength(); // read list length.
1148 for (intptr_t i = 0; i < annotation_count_; ++i) {
1149 helper_->SkipExpression(); // read ith expression.
1150 }
1151 if (++next_read_ == field) return;
1152 }
1154 case kType:
1155 helper_->SkipDartType(); // read type.
1156 if (++next_read_ == field) return;
1158 case kInitializer:
1159 if (helper_->ReadTag() == kSomething) {
1160 helper_->SkipExpression(); // read initializer.
1161 }
1162 if (++next_read_ == field) return;
1164 case kEnd:
1165 return;
1166 }
1167}
1168
1170 if (field <= next_read_) return;
1171
1172 // Ordered with fall-through.
1173 switch (next_read_) {
1174 case kStart: {
1175 Tag tag = helper_->ReadTag(); // read tag.
1176 ASSERT(tag == kProcedure);
1177 if (++next_read_ == field) return;
1178 }
1180 case kCanonicalName:
1182 helper_->ReadCanonicalNameReference(); // read canonical_name.
1183 if (++next_read_ == field) return;
1185 case kSourceUriIndex:
1186 source_uri_index_ = helper_->ReadUInt(); // read source_uri_index.
1188 if (++next_read_ == field) return;
1190 case kStartPosition:
1191 start_position_ = helper_->ReadPosition(); // read position.
1192 if (++next_read_ == field) return;
1194 case kPosition:
1195 position_ = helper_->ReadPosition(); // read position.
1196 if (++next_read_ == field) return;
1198 case kEndPosition:
1199 end_position_ = helper_->ReadPosition(); // read end position.
1200 if (++next_read_ == field) return;
1202 case kKind:
1203 kind_ = static_cast<Kind>(helper_->ReadByte());
1204 if (++next_read_ == field) return;
1206 case kStubKind:
1207 stub_kind_ = static_cast<StubKind>(helper_->ReadByte());
1208 if (++next_read_ == field) return;
1210 case kFlags:
1211 flags_ = helper_->ReadUInt();
1212 if (++next_read_ == field) return;
1214 case kName:
1215 helper_->SkipName(); // read name.
1216 if (++next_read_ == field) return;
1218 case kAnnotations: {
1219 annotation_count_ = helper_->ReadListLength(); // read list length.
1220 for (intptr_t i = 0; i < annotation_count_; ++i) {
1221 helper_->SkipExpression(); // read ith expression.
1222 }
1223 if (++next_read_ == field) return;
1224 }
1226 case kStubTarget:
1229 helper_->ReadCanonicalNameReference();
1230 } else {
1231 helper_->ReadCanonicalNameReference();
1232 }
1233 if (++next_read_ == field) return;
1235 case kSignatureType:
1236 helper_->SkipOptionalDartType(); // read signature type.
1237 if (++next_read_ == field) return;
1239 case kFunction:
1240 helper_->SkipFunctionNode(); // read function node.
1241 if (++next_read_ == field) return;
1243 case kEnd:
1244 return;
1245 }
1246}
1247
1249 if (field <= next_read_) return;
1250
1251 // Ordered with fall-through.
1252 switch (next_read_) {
1253 case kStart: {
1254 Tag tag = helper_->ReadTag(); // read tag.
1255 ASSERT(tag == kConstructor);
1256 if (++next_read_ == field) return;
1257 }
1259 case kCanonicalName:
1261 helper_->ReadCanonicalNameReference(); // read canonical_name.
1262 if (++next_read_ == field) return;
1264 case kSourceUriIndex:
1265 source_uri_index_ = helper_->ReadUInt(); // read source_uri_index.
1267 if (++next_read_ == field) return;
1269 case kStartPosition:
1270 start_position_ = helper_->ReadPosition(); // read position.
1271 if (++next_read_ == field) return;
1273 case kPosition:
1274 position_ = helper_->ReadPosition(); // read position.
1275 if (++next_read_ == field) return;
1277 case kEndPosition:
1278 end_position_ = helper_->ReadPosition(); // read end position.
1279 if (++next_read_ == field) return;
1281 case kFlags:
1282 flags_ = helper_->ReadFlags();
1283 if (++next_read_ == field) return;
1285 case kName:
1286 helper_->SkipName(); // read name.
1287 if (++next_read_ == field) return;
1289 case kAnnotations: {
1290 annotation_count_ = helper_->ReadListLength(); // read list length.
1291 for (intptr_t i = 0; i < annotation_count_; ++i) {
1292 helper_->SkipExpression(); // read ith expression.
1293 }
1294 if (++next_read_ == field) return;
1295 }
1297 case kFunction:
1298 helper_->SkipFunctionNode(); // read function.
1299 if (++next_read_ == field) return;
1301 case kInitializers: {
1302 intptr_t list_length =
1303 helper_->ReadListLength(); // read initializers list length.
1304 for (intptr_t i = 0; i < list_length; i++) {
1305 helper_->SkipInitializer();
1306 }
1307 if (++next_read_ == field) return;
1308 }
1310 case kEnd:
1311 return;
1312 }
1313}
1314
1316 if (field <= next_read_) return;
1317
1318 // Ordered with fall-through.
1319 switch (next_read_) {
1320 case kStart: {
1321 Tag tag = helper_->ReadTag(); // read tag.
1322 ASSERT(tag == kClass);
1323 if (++next_read_ == field) return;
1324 }
1326 case kCanonicalName:
1328 helper_->ReadCanonicalNameReference(); // read canonical_name.
1329 if (++next_read_ == field) return;
1331 case kSourceUriIndex:
1332 source_uri_index_ = helper_->ReadUInt(); // read source_uri_index.
1334 if (++next_read_ == field) return;
1336 case kStartPosition:
1337 start_position_ = helper_->ReadPosition(); // read position.
1338 if (++next_read_ == field) return;
1340 case kPosition:
1341 position_ = helper_->ReadPosition(); // read position.
1342 if (++next_read_ == field) return;
1344 case kEndPosition:
1345 end_position_ = helper_->ReadPosition(); // read end position.
1346 if (++next_read_ == field) return;
1348 case kFlags:
1349 flags_ = helper_->ReadUInt(); // read flags.
1350 if (++next_read_ == field) return;
1352 case kNameIndex:
1353 name_index_ = helper_->ReadStringReference(); // read name index.
1354 if (++next_read_ == field) return;
1356 case kAnnotations: {
1357 annotation_count_ = helper_->ReadListLength(); // read list length.
1358 for (intptr_t i = 0; i < annotation_count_; ++i) {
1359 helper_->SkipExpression(); // read ith expression.
1360 }
1361 if (++next_read_ == field) return;
1362 }
1364 case kTypeParameters:
1365 helper_->SkipTypeParametersList(); // read type parameters.
1366 if (++next_read_ == field) return;
1368 case kSuperClass: {
1369 Tag type_tag = helper_->ReadTag(); // read super class type (part 1).
1370 if (type_tag == kSomething) {
1371 helper_->SkipDartType(); // read super class type (part 2).
1372 }
1373 if (++next_read_ == field) return;
1374 }
1376 case kMixinType: {
1377 Tag type_tag = helper_->ReadTag(); // read mixin type (part 1).
1378 if (type_tag == kSomething) {
1379 helper_->SkipDartType(); // read mixin type (part 2).
1380 }
1381 if (++next_read_ == field) return;
1382 }
1385 helper_->SkipListOfDartTypes(); // read implemented_classes.
1386 if (++next_read_ == field) return;
1388 case kFields: {
1389 intptr_t list_length =
1390 helper_->ReadListLength(); // read fields list length.
1391 for (intptr_t i = 0; i < list_length; i++) {
1392 FieldHelper field_helper(helper_);
1393 field_helper.ReadUntilExcluding(FieldHelper::kEnd); // read field.
1394 }
1395 if (++next_read_ == field) return;
1396 }
1398 case kConstructors: {
1399 intptr_t list_length =
1400 helper_->ReadListLength(); // read constructors list length.
1401 for (intptr_t i = 0; i < list_length; i++) {
1402 ConstructorHelper constructor_helper(helper_);
1403 constructor_helper.ReadUntilExcluding(
1404 ConstructorHelper::kEnd); // read constructor.
1405 }
1406 if (++next_read_ == field) return;
1407 }
1409 case kProcedures: {
1410 procedure_count_ = helper_->ReadListLength(); // read procedures #.
1411 for (intptr_t i = 0; i < procedure_count_; i++) {
1412 ProcedureHelper procedure_helper(helper_);
1413 procedure_helper.ReadUntilExcluding(
1414 ProcedureHelper::kEnd); // read procedure.
1415 }
1416 if (++next_read_ == field) return;
1417 }
1419 case kClassIndex:
1420 // Read class index.
1421 for (intptr_t i = 0; i < procedure_count_; ++i) {
1422 helper_->reader_.ReadUInt32();
1423 }
1424 helper_->reader_.ReadUInt32();
1425 helper_->reader_.ReadUInt32();
1426 if (++next_read_ == field) return;
1428 case kEnd:
1429 return;
1430 }
1431}
1432
1434 if (field <= next_read_) return;
1435
1436 // Ordered with fall-through.
1437 switch (next_read_) {
1438 // Note that this (up to canonical name) needs to be kept in sync with
1439 // "library_canonical_name" (currently in "kernel_loader.h").
1440 case kFlags: {
1441 flags_ = helper_->ReadFlags();
1442 if (++next_read_ == field) return;
1444 }
1445 case kLanguageVersion: {
1446 helper_->ReadUInt(); // Read major language version.
1447 helper_->ReadUInt(); // Read minor language version.
1448 if (++next_read_ == field) return;
1450 }
1451 case kCanonicalName:
1453 helper_->ReadCanonicalNameReference(); // read canonical_name.
1454 if (++next_read_ == field) return;
1456 case kName:
1457 name_index_ = helper_->ReadStringReference(); // read name index.
1458 if (++next_read_ == field) return;
1460 case kSourceUriIndex:
1461 source_uri_index_ = helper_->ReadUInt(); // read source_uri_index.
1463 if (++next_read_ == field) return;
1465 case kProblemsAsJson: {
1466 intptr_t length = helper_->ReadUInt(); // read length of table.
1467 for (intptr_t i = 0; i < length; ++i) {
1468 helper_->SkipBytes(helper_->ReadUInt()); // read strings.
1469 }
1470 if (++next_read_ == field) return;
1471 }
1473 case kAnnotations:
1474 helper_->SkipListOfExpressions(); // read annotations.
1475 if (++next_read_ == field) return;
1477 case kDependencies: {
1478 intptr_t dependency_count = helper_->ReadUInt(); // read list length.
1479 for (intptr_t i = 0; i < dependency_count; ++i) {
1480 helper_->SkipLibraryDependency();
1481 }
1482 if (++next_read_ == field) return;
1483 }
1484 return;
1485 }
1486}
1487
1489 if (field <= next_read_) return;
1490
1491 // Ordered with fall-through.
1492 switch (next_read_) {
1493 case kFileOffset: {
1494 helper_->ReadPosition();
1495 if (++next_read_ == field) return;
1497 }
1498 case kFlags: {
1499 flags_ = helper_->ReadFlags();
1500 if (++next_read_ == field) return;
1502 }
1503 case kAnnotations: {
1504 annotation_count_ = helper_->ReadListLength();
1505 for (intptr_t i = 0; i < annotation_count_; ++i) {
1506 helper_->SkipExpression(); // read ith expression.
1507 }
1508 if (++next_read_ == field) return;
1509 }
1511 case kTargetLibrary: {
1513 if (++next_read_ == field) return;
1514 }
1516 case kName: {
1517 name_index_ = helper_->ReadStringReference();
1518 if (++next_read_ == field) return;
1519 }
1521 case kCombinators: {
1522 intptr_t count = helper_->ReadListLength();
1523 for (intptr_t i = 0; i < count; ++i) {
1524 // Skip flags
1525 helper_->SkipBytes(1);
1526 // Skip list of names.
1527 helper_->SkipListOfStrings();
1528 }
1529 if (++next_read_ == field) return;
1530 }
1532 case kEnd:
1533 return;
1534 }
1535}
1536
1537#if defined(DEBUG)
1538
1539void MetadataHelper::VerifyMetadataMappings(
1540 const TypedDataView& metadata_mappings) {
1541 const intptr_t kUInt32Size = 4;
1542 Reader reader(metadata_mappings);
1543 if (reader.size() == 0) {
1544 return;
1545 }
1546
1547 // Scan through metadata mappings in reverse direction.
1548
1549 // Read metadataMappings length.
1550 intptr_t offset = reader.size() - kUInt32Size;
1551 const intptr_t metadata_num = reader.ReadUInt32At(offset);
1552
1553 if (metadata_num == 0) {
1554 ASSERT(metadata_mappings.LengthInBytes() == kUInt32Size);
1555 return;
1556 }
1557
1558 // Read metadataMappings elements.
1559 for (intptr_t i = 0; i < metadata_num; ++i) {
1560 // Read nodeOffsetToMetadataOffset length.
1562 const intptr_t mappings_num = reader.ReadUInt32At(offset);
1563
1564 // Skip nodeOffsetToMetadataOffset.
1565 offset -= mappings_num * 2 * kUInt32Size;
1566
1567 // Verify that node offsets are sorted.
1568 intptr_t prev_node_offset = -1;
1569 reader.set_offset(offset);
1570 for (intptr_t j = 0; j < mappings_num; ++j) {
1571 const intptr_t node_offset = reader.ReadUInt32();
1572 const intptr_t md_offset = reader.ReadUInt32();
1573
1574 ASSERT(node_offset >= 0 && md_offset >= 0);
1575 ASSERT(node_offset > prev_node_offset);
1576 prev_node_offset = node_offset;
1577 }
1578
1579 // Skip tag.
1581 }
1582}
1583
1584#endif // defined(DEBUG)
1585
1586MetadataHelper::MetadataHelper(KernelReaderHelper* helper,
1587 const char* tag,
1588 bool precompiler_only)
1589 : helper_(helper),
1590 translation_helper_(helper->translation_helper_),
1591 tag_(tag),
1592 mappings_scanned_(false),
1593 precompiler_only_(precompiler_only),
1594 mappings_offset_(0),
1595 mappings_num_(0),
1596 last_node_offset_(0),
1597 last_mapping_index_(0) {}
1598
1599void MetadataHelper::SetMetadataMappings(intptr_t mappings_offset,
1600 intptr_t mappings_num) {
1601 ASSERT((mappings_offset_ == 0) && (mappings_num_ == 0));
1602 ASSERT((mappings_offset != 0) && (mappings_num != 0));
1603 mappings_offset_ = mappings_offset;
1604 mappings_num_ = mappings_num;
1605 last_node_offset_ = kIntptrMax;
1606 last_mapping_index_ = 0;
1607}
1608
1609void MetadataHelper::ScanMetadataMappings() {
1610 const intptr_t kUInt32Size = 4;
1611 Reader reader(H.metadata_mappings());
1612 if (reader.size() == 0) {
1613 return;
1614 }
1615
1616 // Scan through metadata mappings in reverse direction.
1617
1618 // Read metadataMappings length.
1619 intptr_t offset = reader.size() - kUInt32Size;
1620 uint32_t metadata_num = reader.ReadUInt32At(offset);
1621
1622 if (metadata_num == 0) {
1623 ASSERT(H.metadata_mappings().LengthInBytes() == kUInt32Size);
1624 return;
1625 }
1626
1627 // Read metadataMappings elements.
1628 for (uint32_t i = 0; i < metadata_num; ++i) {
1629 // Read nodeOffsetToMetadataOffset length.
1631 uint32_t mappings_num = reader.ReadUInt32At(offset);
1632
1633 // Skip nodeOffsetToMetadataOffset and read tag.
1634 offset -= mappings_num * 2 * kUInt32Size + kUInt32Size;
1635 StringIndex tag = StringIndex(reader.ReadUInt32At(offset));
1636
1637 if (mappings_num == 0) {
1638 continue;
1639 }
1640
1641 if (H.StringEquals(tag, tag_)) {
1642 if ((!FLAG_precompiled_mode) && precompiler_only_) {
1643 FATAL("%s metadata is allowed in precompiled mode only", tag_);
1644 }
1645 SetMetadataMappings(offset + kUInt32Size, mappings_num);
1646 return;
1647 }
1648 }
1649}
1650
1651intptr_t MetadataHelper::FindMetadataMapping(intptr_t node_offset) {
1652 const intptr_t kUInt32Size = 4;
1653 ASSERT(mappings_num_ > 0);
1654
1655 Reader reader(H.metadata_mappings());
1656
1657 intptr_t left = 0;
1658 intptr_t right = mappings_num_ - 1;
1659 while (left < right) {
1660 intptr_t mid = ((right - left) / 2) + left;
1661 intptr_t mid_node_offset =
1662 reader.ReadUInt32At(mappings_offset_ + mid * 2 * kUInt32Size);
1663
1664 if (node_offset < mid_node_offset) {
1665 right = mid - 1;
1666 } else if (node_offset > mid_node_offset) {
1667 left = mid + 1;
1668 } else {
1669 return mid; // Exact match found.
1670 }
1671 }
1672 ASSERT((0 <= left) && (left <= mappings_num_));
1673
1674 // Approximate match is found. Make sure it has an offset greater or equal
1675 // to the given node offset.
1676 if (left < mappings_num_) {
1677 intptr_t found_node_offset =
1678 reader.ReadUInt32At(mappings_offset_ + left * 2 * kUInt32Size);
1679
1680 if (found_node_offset < node_offset) {
1681 ++left;
1682 }
1683 }
1684 ASSERT((left == mappings_num_) ||
1685 static_cast<intptr_t>(reader.ReadUInt32At(
1686 mappings_offset_ + left * 2 * kUInt32Size)) >= node_offset);
1687
1688 return left;
1689}
1690
1691intptr_t MetadataHelper::GetNextMetadataPayloadOffset(intptr_t node_offset) {
1692 if (!mappings_scanned_) {
1693 ScanMetadataMappings();
1694 mappings_scanned_ = true;
1695 }
1696
1697 if (mappings_num_ == 0) {
1698 return -1; // No metadata.
1699 }
1700
1701 node_offset += helper_->data_program_offset_;
1702
1703 // Nodes are parsed in linear order most of the time, so do the search
1704 // only if looking back.
1705 if (node_offset < last_node_offset_) {
1706 last_mapping_index_ = FindMetadataMapping(node_offset);
1707 }
1708
1709 intptr_t index = last_mapping_index_;
1710 intptr_t mapping_node_offset = 0;
1711 intptr_t mapping_md_offset = -1;
1712
1713 Reader reader(H.metadata_mappings());
1714 const intptr_t kUInt32Size = 4;
1715 reader.set_offset(mappings_offset_ + index * 2 * kUInt32Size);
1716
1717 for (; index < mappings_num_; ++index) {
1718 mapping_node_offset = reader.ReadUInt32();
1719 mapping_md_offset = reader.ReadUInt32();
1720
1721 if (mapping_node_offset >= node_offset) {
1722 break;
1723 }
1724 }
1725
1726 last_mapping_index_ = index;
1727 last_node_offset_ = node_offset;
1728
1729 if ((index < mappings_num_) && (mapping_node_offset == node_offset)) {
1730 ASSERT(mapping_md_offset >= 0);
1731 return mapping_md_offset;
1732 } else {
1733 return -1;
1734 }
1735}
1736
1738 const intptr_t kComponentNodeOffset = 0;
1739 return GetNextMetadataPayloadOffset(kComponentNodeOffset -
1741}
1742
1744 : MetadataHelper(helper, tag(), /* precompiler_only = */ true) {}
1745
1746bool DirectCallMetadataHelper::ReadMetadata(intptr_t node_offset,
1747 NameIndex* target_name,
1748 bool* check_receiver_for_null,
1749 intptr_t* closure_id) {
1750 intptr_t md_offset = GetNextMetadataPayloadOffset(node_offset);
1751 if (md_offset < 0) {
1752 return false;
1753 }
1754
1755 AlternativeReadingScopeWithNewData alt(&helper_->reader_,
1756 &H.metadata_payloads(), md_offset);
1757
1758 *target_name = helper_->ReadCanonicalNameReference();
1759 const intptr_t flags = helper_->ReadByte();
1760 *check_receiver_for_null =
1763 const intptr_t id = helper_->ReadUInt();
1764 if (closure_id != nullptr) {
1765 *closure_id = id;
1766 }
1767 }
1768 return true;
1769}
1770
1772 intptr_t node_offset) {
1773 NameIndex kernel_name;
1774 bool check_receiver_for_null = false;
1775 if (!ReadMetadata(node_offset, &kernel_name, &check_receiver_for_null)) {
1776 return DirectCallMetadata(Function::null_function(), false);
1777 }
1778
1779 if (H.IsProcedure(kernel_name) && !H.IsGetter(kernel_name)) {
1780 // Tear-off. Use method extractor as direct call target.
1781 const String& method_name = H.DartMethodName(kernel_name);
1782 const Function& target_method = Function::ZoneHandle(
1783 helper_->zone_, H.LookupMethodByMember(kernel_name, method_name));
1784 const String& getter_name = H.DartGetterName(kernel_name);
1785 return DirectCallMetadata(
1787 target_method.GetMethodExtractor(getter_name)),
1788 check_receiver_for_null);
1789 } else {
1790 const String& getter_name = H.DartGetterName(kernel_name);
1792 helper_->zone_, H.LookupMethodByMember(kernel_name, getter_name));
1793 ASSERT(target.IsGetterFunction() || target.IsImplicitGetterFunction());
1794 return DirectCallMetadata(target, check_receiver_for_null);
1795 }
1796}
1797
1799 intptr_t node_offset) {
1800 NameIndex kernel_name;
1801 bool check_receiver_for_null = false;
1802 if (!ReadMetadata(node_offset, &kernel_name, &check_receiver_for_null)) {
1803 return DirectCallMetadata(Function::null_function(), false);
1804 }
1805
1806 const String& method_name = H.DartSetterName(kernel_name);
1808 helper_->zone_, H.LookupMethodByMember(kernel_name, method_name));
1809 ASSERT(target.IsSetterFunction() || target.IsImplicitSetterFunction());
1810
1811 return DirectCallMetadata(target, check_receiver_for_null);
1812}
1813
1815 intptr_t node_offset) {
1816 NameIndex kernel_name;
1817 bool check_receiver_for_null = false;
1818 if (!ReadMetadata(node_offset, &kernel_name, &check_receiver_for_null)) {
1819 return DirectCallMetadata(Function::null_function(), false);
1820 }
1821
1822 const String& method_name = H.DartProcedureName(kernel_name);
1824 helper_->zone_, H.LookupMethodByMember(kernel_name, method_name));
1825
1826 return DirectCallMetadata(target, check_receiver_for_null);
1827}
1828
1831 intptr_t node_offset) {
1832 NameIndex kernel_name;
1833 bool check_receiver_for_null = false;
1834 intptr_t closure_id = -1;
1835 if (!ReadMetadata(node_offset, &kernel_name, &check_receiver_for_null,
1836 &closure_id)) {
1837 return DirectCallMetadata(Function::null_function(), false);
1838 }
1839
1840 const auto& member =
1841 Object::Handle(helper_->zone_, H.LookupMemberByMember(kernel_name));
1843 if (member.IsField()) {
1844 const auto& field = Field::Cast(member);
1845 // Non-trivial initializers of instance non-late fields should be
1846 // inlined into constructors on kernel AST
1847 // during MoveFieldInitializers transformation.
1848 ASSERT(field.is_static() || field.is_late());
1849 ASSERT(field.has_nontrivial_initializer());
1850 function = field.EnsureInitializerFunction();
1851 } else {
1852 function = Function::Cast(member).ptr();
1853 }
1854
1855 ASSERT(closure_id >= 0);
1856 if (closure_id == 0) {
1857 // Tear-off
1858 ASSERT(!member.IsField());
1859 function = function.ImplicitClosureFunction();
1860 ASSERT(!function.IsNull());
1861 return DirectCallMetadata(function, check_receiver_for_null);
1862 }
1863
1864 // TODO(alexmarkov): support devirtualization of arbitrary closure calls.
1865 return DirectCallMetadata(Function::null_function(), false);
1866}
1867
1869 KernelReaderHelper* helper,
1870 ConstantReader* constant_reader,
1872 : MetadataHelper(helper, tag(kind), /* precompiler_only = */ true),
1873 constant_reader_(constant_reader) {}
1874
1876 intptr_t node_offset,
1877 bool read_constant) {
1878 const intptr_t md_offset = GetNextMetadataPayloadOffset(node_offset);
1879 if (md_offset < 0) {
1882 }
1883
1885 &H.metadata_payloads(), md_offset);
1886
1887 const NameIndex kernel_name = helper_->ReadCanonicalNameReference();
1888 const uint8_t flags = helper_->ReadByte();
1889
1890 const Object* constant_value = &Object::null_object();
1892 const intptr_t constant_index = helper_->ReadUInt();
1893 if (read_constant) {
1894 constant_value = &Object::ZoneHandle(
1895 H.zone(), constant_reader_->ReadConstant(constant_index));
1896 }
1897 }
1898
1899 if (H.IsRoot(kernel_name)) {
1902 }
1903
1904 const Class& klass =
1905 Class::Handle(helper_->zone_, H.LookupClassByKernelClass(kernel_name));
1906 ASSERT(!klass.IsNull());
1907
1908 intptr_t cid = klass.id();
1909 if (cid == kClosureCid) {
1910 // VM uses more specific function types and doesn't expect instances of
1911 // _Closure class, so inferred _Closure class doesn't make sense for the VM.
1912 cid = kDynamicCid;
1913 }
1914
1915 return InferredTypeMetadata(cid, flags, *constant_value);
1916}
1917
1919 const int kMethodOrSetterCalledDynamicallyBit = 1 << 0;
1920 const int kNonThisUsesBit = 1 << 1;
1921 const int kTearOffUsesBit = 1 << 2;
1922 const int kThisUsesBit = 1 << 3;
1923 const int kGetterCalledDynamicallyBit = 1 << 4;
1924
1926 (flags & kMethodOrSetterCalledDynamicallyBit) != 0;
1927 getter_called_dynamically = (flags & kGetterCalledDynamicallyBit) != 0;
1928 has_this_uses = (flags & kThisUsesBit) != 0;
1929 has_non_this_uses = (flags & kNonThisUsesBit) != 0;
1930 has_tearoff_uses = (flags & kTearOffUsesBit) != 0;
1931}
1932
1936
1937bool ProcedureAttributesMetadataHelper::ReadMetadata(
1938 intptr_t node_offset,
1939 ProcedureAttributesMetadata* metadata) {
1940 intptr_t md_offset = GetNextMetadataPayloadOffset(node_offset);
1941 if (md_offset < 0) {
1942 return false;
1943 }
1944
1945 AlternativeReadingScopeWithNewData alt(&helper_->reader_,
1946 &H.metadata_payloads(), md_offset);
1947
1948 const uint8_t flags = helper_->ReadByte();
1949 metadata->InitializeFromFlags(flags);
1951 metadata->getter_selector_id = helper_->ReadUInt();
1952 return true;
1953}
1954
1955ProcedureAttributesMetadata
1957 intptr_t node_offset) {
1959 ReadMetadata(node_offset, &metadata);
1960 return metadata;
1961}
1962
1966
1967void ObfuscationProhibitionsMetadataHelper::ReadMetadata(intptr_t node_offset) {
1968 intptr_t md_offset = GetNextMetadataPayloadOffset(node_offset);
1969 if (md_offset < 0) {
1970 return;
1971 }
1972
1973 AlternativeReadingScopeWithNewData alt(&helper_->reader_,
1974 &H.metadata_payloads(), md_offset);
1976
1977 intptr_t len = helper_->ReadUInt32();
1978 for (int i = 0; i < len; ++i) {
1979 StringIndex name = helper_->ReadStringReference();
1980 O.PreventRenaming(translation_helper_.DartSymbolPlain(name));
1981 }
1982 return;
1983}
1984
1986 KernelReaderHelper* helper)
1987 : MetadataHelper(helper, tag(), /* precompiler_only = */ true) {}
1988
1989void LoadingUnitsMetadataHelper::ReadMetadata(intptr_t node_offset) {
1990 intptr_t md_offset = GetNextMetadataPayloadOffset(node_offset);
1991 if (md_offset < 0) {
1992 return;
1993 }
1994
1995 AlternativeReadingScopeWithNewData alt(&helper_->reader_,
1996 &H.metadata_payloads(), md_offset);
1997
1998 Thread* thread = Thread::Current();
1999 Zone* zone = thread->zone();
2000 intptr_t unit_count = helper_->ReadUInt();
2001 Array& loading_units = Array::Handle(zone, Array::New(unit_count + 1));
2002 Array& loading_unit_uris = Array::Handle(zone, Array::New(unit_count + 1));
2003 LoadingUnit& unit = LoadingUnit::Handle(zone);
2004 LoadingUnit& parent = LoadingUnit::Handle(zone);
2005 Library& lib = Library::Handle(zone);
2006 Array& uris = Array::Handle(zone);
2007
2008 for (int i = 0; i < unit_count; i++) {
2009 intptr_t id = helper_->ReadUInt();
2010
2011 intptr_t parent_id = helper_->ReadUInt();
2012 RELEASE_ASSERT(parent_id < id);
2013 parent ^= loading_units.At(parent_id);
2014 RELEASE_ASSERT(parent.IsNull() == (parent_id == 0));
2015
2016 unit = LoadingUnit::New(id, parent);
2017
2018 intptr_t library_count = helper_->ReadUInt();
2019 uris = Array::New(library_count);
2020 for (intptr_t j = 0; j < library_count; j++) {
2021 const String& uri =
2023 lib = Library::LookupLibrary(thread, uri);
2024 if (lib.IsNull()) {
2025 FATAL("Missing library: %s\n", uri.ToCString());
2026 }
2027 lib.set_loading_unit(unit);
2028 uris.SetAt(j, uri);
2029 }
2030
2031 loading_units.SetAt(id, unit);
2032 loading_unit_uris.SetAt(id, uris);
2033 }
2034
2035 ObjectStore* object_store = IG->object_store();
2036 ASSERT(object_store->loading_units() == Array::null());
2037 object_store->set_loading_units(loading_units);
2038 ASSERT(object_store->loading_unit_uris() == Array::null());
2039 object_store->set_loading_unit_uris(loading_unit_uris);
2040}
2041
2043 KernelReaderHelper* helper,
2044 TypeTranslator* type_translator)
2045 : MetadataHelper(helper, tag(), /* precompiler_only = */ false),
2046 type_translator_(*type_translator) {}
2047
2048bool CallSiteAttributesMetadataHelper::ReadMetadata(
2049 intptr_t node_offset,
2050 CallSiteAttributesMetadata* metadata) {
2051 intptr_t md_offset = GetNextMetadataPayloadOffset(node_offset);
2052 if (md_offset < 0) {
2053 return false;
2054 }
2055
2056 AlternativeReadingScopeWithNewData alt(&helper_->reader_,
2057 &H.metadata_payloads(), md_offset);
2058
2059 metadata->receiver_type = &type_translator_.BuildType();
2060 return true;
2061}
2062
2063CallSiteAttributesMetadata
2066 ReadMetadata(node_offset, &metadata);
2067 return metadata;
2068}
2069
2071 KernelReaderHelper* helper)
2072 : MetadataHelper(helper, tag(), /* precompiler_only = */ true) {}
2073
2075 Zone* zone) {
2076 const intptr_t node_offset = GetComponentMetadataPayloadOffset();
2077 const intptr_t md_offset = GetNextMetadataPayloadOffset(node_offset);
2078 if (md_offset < 0) {
2079 return nullptr;
2080 }
2081
2083 &H.metadata_payloads(), md_offset);
2084
2085 const intptr_t num_selectors = helper_->ReadUInt();
2086 TableSelectorMetadata* metadata =
2087 new (zone) TableSelectorMetadata(num_selectors);
2088 for (intptr_t i = 0; i < num_selectors; i++) {
2089 ReadTableSelectorInfo(&metadata->selectors[i]);
2090 }
2091 return metadata;
2092}
2093
2094void TableSelectorMetadataHelper::ReadTableSelectorInfo(
2096 info->call_count = helper_->ReadUInt();
2097 uint8_t flags = helper_->ReadByte();
2098 info->called_on_null = (flags & kCalledOnNullBit) != 0;
2099 info->torn_off = (flags & kTornOffBit) != 0;
2100}
2101
2103 KernelReaderHelper* helper)
2104 : MetadataHelper(helper, tag(), /* precompiler_only = */ true) {}
2105
2107 intptr_t node_offset) {
2108 const intptr_t md_offset = GetNextMetadataPayloadOffset(node_offset);
2109
2110 if (md_offset < 0) {
2111 return nullptr;
2112 }
2113
2115 &H.metadata_payloads(), md_offset);
2116
2117 const intptr_t num_args = helper_->ReadUInt();
2118 const auto info = new (helper_->zone_) UnboxingInfoMetadata();
2119 info->SetArgsCount(num_args);
2120 const int8_t flags = helper_->ReadByte();
2121 info->must_use_stack_calling_convention =
2123 info->has_overrides_with_less_direct_parameters =
2124 (flags &
2127 0) {
2128 for (intptr_t i = 0; i < num_args; i++) {
2129 info->unboxed_args_info[i] = ReadUnboxingType();
2130 }
2131 info->return_info = ReadUnboxingType();
2132 }
2133 return info;
2134}
2135
2137UnboxingInfoMetadataHelper::ReadUnboxingType() const {
2138 const auto kind =
2142 if (kind == UnboxingInfoMetadata::kRecord) {
2143 // Read and register record shape.
2144 const intptr_t num_positional = helper_->ReadUInt();
2145 const intptr_t num_named = helper_->ReadUInt();
2146 const Array* field_names = &Array::empty_array();
2147 if (num_named > 0) {
2148 auto& names = Array::Handle(helper_->zone_, Array::New(num_named));
2149 for (intptr_t i = 0; i < num_named; ++i) {
2152 names.SetAt(i, name);
2153 }
2154 names.MakeImmutable();
2155 field_names = &names;
2156 }
2157 const intptr_t num_fields = num_positional + num_named;
2158 const RecordShape shape = RecordShape::Register(
2159 helper_->translation_helper_.thread(), num_fields, *field_names);
2160 return {kind, shape};
2161 }
2162 return {kind, RecordShape::ForUnnamed(0)};
2163}
2164
2166 return reader_.offset();
2167}
2168
2170 return reader_.size();
2171}
2172
2176
2177void KernelReaderHelper::SkipBytes(intptr_t bytes) {
2178 reader_.set_offset(ReaderOffset() + bytes);
2179}
2180
2182 return reader_.ReadBool();
2183}
2184
2186 return reader_.ReadByte();
2187}
2188
2190 return reader_.ReadUInt();
2191}
2192
2194 return reader_.ReadUInt32();
2195}
2196
2201
2203 return reader_.ReadDouble();
2204}
2205
2210
2214
2216 return StringIndex(ReadUInt());
2217}
2218
2222
2225 NameIndex origin_name_index = reader_.ReadCanonicalNameReference();
2226 if (!FLAG_precompiled_mode && origin_name_index != NameIndex::kInvalidName) {
2227 // Reference to a skipped member signature target, return the origin target.
2228 return origin_name_index;
2229 }
2230 return name_index;
2231}
2232
2234 StringIndex name_index = ReadStringReference(); // read name index.
2235 if ((H.StringSize(name_index) >= 1) && H.CharacterAt(name_index, 0) == '_') {
2236 ReadUInt(); // read library index.
2237 }
2238 return name_index;
2239}
2240
2242 StringIndex name_index = ReadStringReference(); // read name index.
2243 if ((H.StringSize(name_index) >= 1) && H.CharacterAt(name_index, 0) == '_') {
2244 NameIndex library_reference =
2245 ReadCanonicalNameReference(); // read library index.
2246 return H.DartMethodName(library_reference, name_index);
2247 } else {
2248 return H.DartMethodName(NameIndex(), name_index);
2249 }
2250}
2251
2253 StringIndex name_index = ReadStringReference(); // read name index.
2254 if ((H.StringSize(name_index) >= 1) && H.CharacterAt(name_index, 0) == '_') {
2255 NameIndex library_reference =
2256 ReadCanonicalNameReference(); // read library index.
2257 return H.DartSetterName(library_reference, name_index);
2258 } else {
2259 return H.DartSetterName(NameIndex(), name_index);
2260 }
2261}
2262
2264 StringIndex name_index = ReadStringReference(); // read name index.
2265 if ((H.StringSize(name_index) >= 1) && H.CharacterAt(name_index, 0) == '_') {
2266 NameIndex library_reference =
2267 ReadCanonicalNameReference(); // read library index.
2268 return H.DartGetterName(library_reference, name_index);
2269 } else {
2270 return H.DartGetterName(NameIndex(), name_index);
2271 }
2272}
2273
2275 StringIndex name_index = ReadStringReference(); // read name index.
2276 if ((H.StringSize(name_index) >= 1) && H.CharacterAt(name_index, 0) == '_') {
2277 NameIndex library_reference =
2278 ReadCanonicalNameReference(); // read library index.
2279 return H.DartFieldName(library_reference, name_index);
2280 } else {
2281 return H.DartFieldName(NameIndex(), name_index);
2282 }
2283}
2284
2288
2292
2296
2300
2305
2306void KernelReaderHelper::ReportUnexpectedTag(const char* variant, Tag tag) {
2307 FATAL("Unexpected tag %d (%s) in ?, expected %s", tag, Reader::TagName(tag),
2308 variant);
2309}
2310
2312 const Tag tag = PeekTag();
2313 switch (tag) {
2314 case kProcedure: {
2315 ProcedureHelper procedure_helper(this);
2317 // Now at start of FunctionNode.
2318 break;
2319 }
2320 case kConstructor: {
2321 ConstructorHelper constructor_helper(this);
2323 // Now at start of FunctionNode.
2324 // Notice that we also have a list of initializers after that!
2325 break;
2326 }
2327 case kFunctionDeclaration:
2328 ReadTag();
2329 ReadPosition();
2331 break;
2332 case kFunctionExpression:
2333 ReadTag();
2334 ReadPosition();
2335 break;
2336 case kFunctionNode:
2337 // Already at start of FunctionNode.
2338 break;
2339 default:
2341 "a procedure, a constructor, a local function or a function node",
2342 tag);
2343 UNREACHABLE();
2344 }
2345 ASSERT(PeekTag() == kFunctionNode);
2346}
2347
2349 Tag tag = ReadTag();
2350 switch (tag) {
2351 case kInvalidType:
2352 case kDynamicType:
2353 case kVoidType:
2354 case kNullType:
2355 // those contain nothing.
2356 return;
2357 case kNeverType:
2359 return;
2360 case kInterfaceType:
2361 SkipInterfaceType(false);
2362 return;
2363 case kSimpleInterfaceType:
2364 SkipInterfaceType(true);
2365 return;
2366 case kFunctionType:
2367 SkipFunctionType(false);
2368 return;
2369 case kSimpleFunctionType:
2370 SkipFunctionType(true);
2371 return;
2372 case kRecordType: {
2375 const intptr_t named_count = ReadListLength();
2376 for (intptr_t i = 0; i < named_count; ++i) {
2378 SkipDartType();
2379 ReadFlags();
2380 }
2381 return;
2382 }
2383 case kExtensionType: {
2385 SkipCanonicalNameReference(); // read index for canonical name.
2386 SkipListOfDartTypes(); // read type arguments
2387 SkipDartType(); // read type erasure.
2388 break;
2389 }
2390 case kTypedefType:
2391 ReadNullability(); // read nullability.
2392 ReadUInt(); // read index for canonical name.
2393 SkipListOfDartTypes(); // read list of types.
2394 return;
2395 case kTypeParameterType:
2396 ReadNullability(); // read nullability.
2397 ReadUInt(); // read index for parameter.
2398 return;
2399 case kIntersectionType:
2400 SkipDartType(); // read left.
2401 SkipDartType(); // read right.
2402 return;
2403 case kFutureOrType:
2405 SkipDartType(); // read type argument.
2406 break;
2407 default:
2408 ReportUnexpectedTag("type", tag);
2409 UNREACHABLE();
2410 }
2411}
2412
2414 Tag tag = ReadTag(); // read tag.
2415 if (tag == kNothing) {
2416 return;
2417 }
2418 ASSERT(tag == kSomething);
2419
2420 SkipDartType(); // read type.
2421}
2422
2424 ReadNullability(); // read nullability.
2425 ReadUInt(); // read klass_name.
2426 if (!simple) {
2427 SkipListOfDartTypes(); // read list of types.
2428 }
2429}
2430
2432 ReadNullability(); // read nullability.
2433
2434 if (!simple) {
2435 SkipTypeParametersList(); // read type_parameters.
2436 ReadUInt(); // read required parameter count.
2437 ReadUInt(); // read total parameter count.
2438 }
2439
2440 SkipListOfDartTypes(); // read positional_parameters types.
2441
2442 if (!simple) {
2443 const intptr_t named_count =
2444 ReadListLength(); // read named_parameters list length.
2445 for (intptr_t i = 0; i < named_count; ++i) {
2446 // read string reference (i.e. named_parameters[i].name).
2448 SkipDartType(); // read named_parameters[i].type.
2449 SkipBytes(1); // read flags
2450 }
2451 }
2452
2453 SkipDartType(); // read return type.
2454}
2455
2457 intptr_t list_length = ReadListLength(); // read list length.
2458 for (intptr_t i = 0; i < list_length; ++i) {
2459 SkipStatement(); // read ith expression.
2460 }
2461}
2462
2464 intptr_t list_length = ReadListLength(); // read list length.
2465 for (intptr_t i = 0; i < list_length; ++i) {
2466 SkipExpression(); // read ith expression.
2467 }
2468}
2469
2471 const intptr_t list_length = ReadListLength(); // read list length.
2472 for (intptr_t i = 0; i < list_length; ++i) {
2473 SkipStringReference(); // read ith name index.
2474 SkipExpression(); // read ith expression.
2475 }
2476}
2477
2479 intptr_t list_length = ReadListLength(); // read list length.
2480 for (intptr_t i = 0; i < list_length; ++i) {
2481 SkipDartType(); // read ith type.
2482 }
2483}
2484
2486 intptr_t list_length = ReadListLength(); // read list length.
2487 for (intptr_t i = 0; i < list_length; ++i) {
2488 SkipStringReference(); // read ith string index.
2489 }
2490}
2491
2493 intptr_t list_length = ReadListLength(); // read list length.
2494 for (intptr_t i = 0; i < list_length; ++i) {
2495 SkipVariableDeclaration(); // read ith variable declaration.
2496 }
2497}
2498
2500 intptr_t list_length = ReadListLength(); // read list length.
2501 for (intptr_t i = 0; i < list_length; ++i) {
2503 }
2504}
2505
2507 intptr_t list_length = ReadListLength(); // read list length.
2508 for (intptr_t i = 0; i < list_length; ++i) {
2509 TypeParameterHelper helper(this);
2510 helper.Finish();
2511 }
2512}
2513
2515 Tag tag = ReadTag();
2516 ReadByte(); // read isSynthetic flag.
2517 switch (tag) {
2518 case kInvalidInitializer:
2519 return;
2520 case kFieldInitializer:
2521 ReadPosition(); // read position.
2522 SkipCanonicalNameReference(); // read field_reference.
2523 SkipExpression(); // read value.
2524 return;
2525 case kSuperInitializer:
2526 ReadPosition(); // read position.
2527 SkipCanonicalNameReference(); // read target_reference.
2528 SkipArguments(); // read arguments.
2529 return;
2530 case kRedirectingInitializer:
2531 ReadPosition(); // read position.
2532 SkipCanonicalNameReference(); // read target_reference.
2533 SkipArguments(); // read arguments.
2534 return;
2535 case kLocalInitializer:
2536 SkipVariableDeclaration(); // read variable.
2537 return;
2538 case kAssertInitializer:
2539 SkipStatement();
2540 return;
2541 default:
2542 ReportUnexpectedTag("initializer", tag);
2543 UNREACHABLE();
2544 }
2545}
2546
2548 uint8_t payload = 0;
2549 Tag tag = ReadTag(&payload);
2550 switch (tag) {
2551 case kInvalidExpression:
2552 ReadPosition();
2554 if (ReadTag() == kSomething) {
2555 SkipExpression(); // read expression.
2556 }
2557 return;
2558 case kVariableGet:
2559 ReadPosition(); // read position.
2560 ReadUInt(); // read kernel position.
2561 ReadUInt(); // read relative variable index.
2562 SkipOptionalDartType(); // read promoted type.
2563 return;
2564 case kSpecializedVariableGet:
2565 ReadPosition(); // read position.
2566 ReadUInt(); // read kernel position.
2567 return;
2568 case kVariableSet:
2569 ReadPosition(); // read position.
2570 ReadUInt(); // read kernel position.
2571 ReadUInt(); // read relative variable index.
2572 SkipExpression(); // read expression.
2573 return;
2574 case kSpecializedVariableSet:
2575 ReadPosition(); // read position.
2576 ReadUInt(); // read kernel position.
2577 SkipExpression(); // read expression.
2578 return;
2579 case kInstanceGet:
2580 ReadByte(); // read kind.
2581 ReadPosition(); // read position.
2582 SkipExpression(); // read receiver.
2583 SkipName(); // read name.
2584 SkipDartType(); // read result_type.
2585 SkipInterfaceMemberNameReference(); // read interface_target_reference.
2586 return;
2587 case kDynamicGet:
2588 ReadByte(); // read kind.
2589 ReadPosition(); // read position.
2590 SkipExpression(); // read receiver.
2591 SkipName(); // read name.
2592 return;
2593 case kInstanceTearOff:
2594 ReadByte(); // read kind.
2595 ReadPosition(); // read position.
2596 SkipExpression(); // read receiver.
2597 SkipName(); // read name.
2598 SkipDartType(); // read result_type.
2599 SkipInterfaceMemberNameReference(); // read interface_target_reference.
2600 return;
2601 case kFunctionTearOff:
2602 // Removed by lowering kernel transformation.
2603 UNREACHABLE();
2604 break;
2605 case kInstanceSet:
2606 ReadByte(); // read kind.
2607 ReadPosition(); // read position.
2608 SkipExpression(); // read receiver.
2609 SkipName(); // read name.
2610 SkipExpression(); // read value.
2611 SkipInterfaceMemberNameReference(); // read interface_target_reference.
2612 return;
2613 case kDynamicSet:
2614 ReadByte(); // read kind.
2615 ReadPosition(); // read position.
2616 SkipExpression(); // read receiver.
2617 SkipName(); // read name.
2618 SkipExpression(); // read value.
2619 return;
2620 case kAbstractSuperPropertyGet:
2621 // Abstract super property getters must be converted into super property
2622 // getters during mixin transformation.
2623 UNREACHABLE();
2624 break;
2625 case kAbstractSuperPropertySet:
2626 // Abstract super property setters must be converted into super property
2627 // setters during mixin transformation.
2628 UNREACHABLE();
2629 break;
2630 case kSuperPropertyGet:
2631 ReadPosition(); // read position.
2632 SkipName(); // read name.
2633 SkipInterfaceMemberNameReference(); // read interface_target_reference.
2634 return;
2635 case kSuperPropertySet:
2636 ReadPosition(); // read position.
2637 SkipName(); // read name.
2638 SkipExpression(); // read value.
2639 SkipInterfaceMemberNameReference(); // read interface_target_reference.
2640 return;
2641 case kStaticGet:
2642 ReadPosition(); // read position.
2643 SkipCanonicalNameReference(); // read target_reference.
2644 return;
2645 case kStaticSet:
2646 ReadPosition(); // read position.
2647 SkipCanonicalNameReference(); // read target_reference.
2648 SkipExpression(); // read expression.
2649 return;
2650 case kInstanceInvocation:
2651 ReadByte(); // read kind.
2652 ReadFlags(); // read flags.
2653 ReadPosition(); // read position.
2654 SkipExpression(); // read receiver.
2655 SkipName(); // read name.
2656 SkipArguments(); // read arguments.
2657 SkipDartType(); // read function_type.
2658 SkipInterfaceMemberNameReference(); // read interface_target_reference.
2659 return;
2660 case kDynamicInvocation:
2661 ReadByte(); // read kind.
2662 ReadByte(); // read flags.
2663 ReadPosition(); // read position.
2664 SkipExpression(); // read receiver.
2665 SkipName(); // read name.
2666 SkipArguments(); // read arguments.
2667 return;
2668 case kLocalFunctionInvocation:
2669 ReadPosition(); // read position.
2670 ReadUInt(); // read variable kernel position.
2671 ReadUInt(); // read relative variable index.
2672 SkipArguments(); // read arguments.
2673 SkipDartType(); // read function_type.
2674 return;
2675 case kFunctionInvocation:
2676 ReadByte(); // read kind.
2677 ReadPosition(); // read position.
2678 SkipExpression(); // read receiver.
2679 SkipArguments(); // read arguments.
2680 SkipDartType(); // read function_type.
2681 return;
2682 case kEqualsCall:
2683 ReadPosition(); // read position.
2684 SkipExpression(); // read left.
2685 SkipExpression(); // read right.
2686 SkipDartType(); // read function_type.
2687 SkipInterfaceMemberNameReference(); // read interface_target_reference.
2688 return;
2689 case kEqualsNull:
2690 ReadPosition(); // read position.
2691 SkipExpression(); // read expression.
2692 return;
2693 case kAbstractSuperMethodInvocation:
2694 // Abstract super method invocations must be converted into super
2695 // method invocations during mixin transformation.
2696 UNREACHABLE();
2697 break;
2698 case kSuperMethodInvocation:
2699 ReadPosition(); // read position.
2700 SkipName(); // read name.
2701 SkipArguments(); // read arguments.
2702 SkipInterfaceMemberNameReference(); // read interface_target_reference.
2703 return;
2704 case kStaticInvocation:
2705 ReadPosition(); // read position.
2706 SkipCanonicalNameReference(); // read procedure_reference.
2707 SkipArguments(); // read arguments.
2708 return;
2709 case kConstructorInvocation:
2710 ReadPosition(); // read position.
2711 SkipCanonicalNameReference(); // read target_reference.
2712 SkipArguments(); // read arguments.
2713 return;
2714 case kNot:
2715 ReadPosition(); // read position.
2716 SkipExpression(); // read expression.
2717 return;
2718 case kNullCheck:
2719 ReadPosition(); // read position.
2720 SkipExpression(); // read expression.
2721 return;
2722 case kLogicalExpression:
2723 ReadPosition(); // read position.
2724 SkipExpression(); // read left.
2725 SkipBytes(1); // read operator.
2726 SkipExpression(); // read right.
2727 return;
2728 case kConditionalExpression:
2729 ReadPosition(); // read position.
2730 SkipExpression(); // read condition.
2731 SkipExpression(); // read then.
2732 SkipExpression(); // read otherwise.
2733 SkipOptionalDartType(); // read unused static type.
2734 return;
2735 case kStringConcatenation:
2736 ReadPosition(); // read position.
2737 SkipListOfExpressions(); // read list of expressions.
2738 return;
2739 case kIsExpression:
2740 ReadPosition(); // read position.
2741 SkipFlags(); // read flags.
2742 SkipExpression(); // read operand.
2743 SkipDartType(); // read type.
2744 return;
2745 case kAsExpression:
2746 ReadPosition(); // read position.
2747 SkipFlags(); // read flags.
2748 SkipExpression(); // read operand.
2749 SkipDartType(); // read type.
2750 return;
2751 case kTypeLiteral:
2752 ReadPosition(); // read position.
2753 SkipDartType(); // read type.
2754 return;
2755 case kThisExpression:
2756 ReadPosition(); // read position.
2757 return;
2758 case kRethrow:
2759 ReadPosition(); // read position.
2760 return;
2761 case kThrow:
2762 ReadPosition(); // read position.
2763 SkipFlags(); // read flags.
2764 SkipExpression(); // read expression.
2765 return;
2766 case kListLiteral:
2767 ReadPosition(); // read position.
2768 SkipDartType(); // read type.
2769 SkipListOfExpressions(); // read list of expressions.
2770 return;
2771 case kSetLiteral:
2772 // Set literals are currently desugared in the frontend and will not
2773 // reach the VM. See http://dartbug.com/35124 for discussion.
2774 UNREACHABLE();
2775 return;
2776 case kMapLiteral: {
2777 ReadPosition(); // read position.
2778 SkipDartType(); // read key type.
2779 SkipDartType(); // read value type.
2780 intptr_t list_length = ReadListLength(); // read list length.
2781 for (intptr_t i = 0; i < list_length; ++i) {
2782 SkipExpression(); // read ith key.
2783 SkipExpression(); // read ith value.
2784 }
2785 return;
2786 }
2787 case kRecordLiteral:
2788 ReadPosition(); // read position.
2789 SkipListOfExpressions(); // read positionals.
2790 SkipListOfNamedExpressions(); // read named.
2791 SkipDartType(); // read recordType.
2792 return;
2793 case kRecordIndexGet:
2794 ReadPosition(); // read position.
2795 SkipExpression(); // read receiver.
2796 SkipDartType(); // read recordType.
2797 ReadUInt(); // read index.
2798 return;
2799 case kRecordNameGet:
2800 ReadPosition(); // read position.
2801 SkipExpression(); // read receiver.
2802 SkipDartType(); // read recordType.
2803 SkipStringReference(); // read name.
2804 return;
2805 case kFunctionExpression:
2806 ReadPosition(); // read position.
2807 SkipFunctionNode(); // read function node.
2808 return;
2809 case kLet:
2810 ReadPosition(); // read position.
2811 SkipVariableDeclaration(); // read variable declaration.
2812 SkipExpression(); // read expression.
2813 return;
2814 case kBlockExpression:
2815 ReadPosition(); // read position.
2817 SkipExpression(); // read expression.
2818 return;
2819 case kInstantiation:
2820 ReadPosition(); // read position.
2821 SkipExpression(); // read expression.
2822 SkipListOfDartTypes(); // read type arguments.
2823 return;
2824 case kBigIntLiteral:
2825 ReadPosition(); // read position.
2826 SkipStringReference(); // read string reference.
2827 return;
2828 case kStringLiteral:
2829 ReadPosition(); // read position.
2830 SkipStringReference(); // read string reference.
2831 return;
2832 case kSpecializedIntLiteral:
2833 ReadPosition(); // read position.
2834 return;
2835 case kNegativeIntLiteral:
2836 ReadPosition(); // read position.
2837 ReadUInt(); // read value.
2838 return;
2839 case kPositiveIntLiteral:
2840 ReadPosition(); // read position.
2841 ReadUInt(); // read value.
2842 return;
2843 case kDoubleLiteral:
2844 ReadPosition(); // read position.
2845 ReadDouble(); // read value.
2846 return;
2847 case kTrueLiteral:
2848 ReadPosition(); // read position.
2849 return;
2850 case kFalseLiteral:
2851 ReadPosition(); // read position.
2852 return;
2853 case kNullLiteral:
2854 ReadPosition(); // read position.
2855 return;
2856 case kConstantExpression:
2857 ReadPosition(); // read position.
2858 SkipDartType(); // read type.
2860 return;
2861 case kFileUriConstantExpression:
2862 ReadPosition(); // read position.
2863 ReadUInt(); // skip uri
2864 SkipDartType(); // read type.
2866 return;
2867 case kLoadLibrary:
2868 case kCheckLibraryIsLoaded:
2869 ReadPosition(); // read file offset.
2870 ReadUInt(); // skip library index
2871 return;
2872 case kAwaitExpression:
2873 ReadPosition(); // read position.
2874 SkipExpression(); // read operand.
2875 if (ReadTag() == kSomething) {
2876 SkipDartType(); // read runtime check type.
2877 }
2878 return;
2879 case kFileUriExpression:
2880 ReadUInt(); // skip uri
2881 ReadPosition(); // read position
2882 SkipExpression(); // read expression
2883 return;
2884 case kConstStaticInvocation:
2885 case kConstConstructorInvocation:
2886 case kConstListLiteral:
2887 case kConstSetLiteral:
2888 case kConstMapLiteral:
2889 case kSymbolLiteral:
2890 case kListConcatenation:
2891 case kSetConcatenation:
2892 case kMapConcatenation:
2893 case kInstanceCreation:
2894 case kStaticTearOff:
2895 case kSwitchExpression:
2896 case kPatternAssignment:
2897 // These nodes are internal to the front end and
2898 // removed by the constant evaluator.
2899 default:
2900 ReportUnexpectedTag("expression", tag);
2901 UNREACHABLE();
2902 }
2903}
2904
2906 Tag tag = ReadTag(); // read tag.
2907 switch (tag) {
2908 case kExpressionStatement:
2909 SkipExpression(); // read expression.
2910 return;
2911 case kBlock:
2912 ReadPosition(); // read file offset.
2913 ReadPosition(); // read file end offset.
2915 return;
2916 case kEmptyStatement:
2917 return;
2918 case kAssertBlock:
2920 return;
2921 case kAssertStatement:
2922 SkipExpression(); // Read condition.
2923 ReadPosition(); // read condition start offset.
2924 ReadPosition(); // read condition end offset.
2925 if (ReadTag() == kSomething) {
2926 SkipExpression(); // read (rest of) message.
2927 }
2928 return;
2929 case kLabeledStatement:
2930 ReadPosition(); // read position.
2931 SkipStatement(); // read body.
2932 return;
2933 case kBreakStatement:
2934 ReadPosition(); // read position.
2935 ReadUInt(); // read target_index.
2936 return;
2937 case kWhileStatement:
2938 ReadPosition(); // read position.
2939 SkipExpression(); // read condition.
2940 SkipStatement(); // read body.
2941 return;
2942 case kDoStatement:
2943 ReadPosition(); // read position.
2944 SkipStatement(); // read body.
2945 SkipExpression(); // read condition.
2946 return;
2947 case kForStatement: {
2948 ReadPosition(); // read position.
2949 SkipListOfVariableDeclarations(); // read variables.
2950 Tag tag = ReadTag(); // Read first part of condition.
2951 if (tag == kSomething) {
2952 SkipExpression(); // read rest of condition.
2953 }
2954 SkipListOfExpressions(); // read updates.
2955 SkipStatement(); // read body.
2956 return;
2957 }
2958 case kSwitchStatement: {
2959 ReadPosition(); // read position.
2960 ReadBool(); // read exhaustive flag.
2961 SkipExpression(); // read condition.
2962 SkipOptionalDartType(); // read expression type
2963 int case_count = ReadListLength(); // read number of cases.
2964 for (intptr_t i = 0; i < case_count; ++i) {
2965 ReadPosition(); // read file offset.
2966 int expression_count = ReadListLength(); // read number of expressions.
2967 for (intptr_t j = 0; j < expression_count; ++j) {
2968 ReadPosition(); // read jth position.
2969 SkipExpression(); // read jth expression.
2970 }
2971 ReadBool(); // read is_default.
2972 SkipStatement(); // read body.
2973 }
2974 return;
2975 }
2976 case kContinueSwitchStatement:
2977 ReadPosition(); // read position.
2978 ReadUInt(); // read target_index.
2979 return;
2980 case kIfStatement:
2981 ReadPosition(); // read position.
2982 SkipExpression(); // read condition.
2983 SkipStatement(); // read then.
2984 SkipStatement(); // read otherwise.
2985 return;
2986 case kReturnStatement: {
2987 ReadPosition(); // read position
2988 Tag tag = ReadTag(); // read (first part of) expression.
2989 if (tag == kSomething) {
2990 SkipExpression(); // read (rest of) expression.
2991 }
2992 return;
2993 }
2994 case kTryCatch: {
2995 ReadPosition(); // read position
2996 SkipStatement(); // read body.
2997 ReadByte(); // read flags
2998 intptr_t catch_count = ReadListLength(); // read number of catches.
2999 for (intptr_t i = 0; i < catch_count; ++i) {
3000 ReadPosition(); // read position.
3001 SkipDartType(); // read guard.
3002 tag = ReadTag(); // read first part of exception.
3003 if (tag == kSomething) {
3004 SkipVariableDeclaration(); // read exception.
3005 }
3006 tag = ReadTag(); // read first part of stack trace.
3007 if (tag == kSomething) {
3008 SkipVariableDeclaration(); // read stack trace.
3009 }
3010 SkipStatement(); // read body.
3011 }
3012 return;
3013 }
3014 case kTryFinally:
3015 ReadPosition(); // read position
3016 SkipStatement(); // read body.
3017 SkipStatement(); // read finalizer.
3018 return;
3019 case kYieldStatement: {
3020 ReadPosition(); // read position.
3021 ReadByte(); // read flags.
3022 SkipExpression(); // read expression.
3023 return;
3024 }
3025 case kVariableDeclaration:
3026 SkipVariableDeclaration(); // read variable declaration.
3027 return;
3028 case kFunctionDeclaration:
3029 ReadPosition(); // read position.
3030 SkipVariableDeclaration(); // read variable.
3031 SkipFunctionNode(); // read function node.
3032 return;
3033 case kForInStatement:
3034 case kAsyncForInStatement:
3035 case kIfCaseStatement:
3036 case kPatternSwitchStatement:
3037 case kPatternVariableDeclaration:
3038 // These nodes are internal to the front end and
3039 // removed by the constant evaluator.
3040 default:
3041 ReportUnexpectedTag("statement", tag);
3042 UNREACHABLE();
3043 }
3044}
3045
3047 FunctionNodeHelper function_node_helper(this);
3048 function_node_helper.ReadUntilExcluding(FunctionNodeHelper::kEnd);
3049}
3050
3052 StringIndex name_index = ReadStringReference(); // read name index.
3053 if ((H.StringSize(name_index) >= 1) && H.CharacterAt(name_index, 0) == '_') {
3054 SkipCanonicalNameReference(); // read library index.
3055 }
3056}
3057
3059 ReadUInt(); // read argument count.
3060
3061 SkipListOfDartTypes(); // read list of types.
3062 SkipListOfExpressions(); // read positional.
3063 SkipListOfNamedExpressions(); // read named.
3064}
3065
3070
3072 ReadBool(); // read is_show.
3073 intptr_t name_count = ReadUInt(); // read list length.
3074 for (intptr_t j = 0; j < name_count; ++j) {
3075 ReadUInt(); // read ith entry of name_indices.
3076 }
3077}
3078
3080 ReadPosition(); // read file offset.
3081 ReadFlags();
3082 SkipListOfExpressions(); // Annotations.
3084 ReadStringReference(); // Name.
3085 intptr_t combinator_count = ReadListLength();
3086 for (intptr_t i = 0; i < combinator_count; ++i) {
3088 }
3089}
3090
3092 TokenPosition position = reader_.ReadPosition();
3093 RecordTokenPosition(position);
3094 return position;
3095}
3096
3099 intptr_t library_count = reader_.ReadFromIndexNoReset(
3101
3102 const intptr_t count_from_first_library_offset =
3104
3105 intptr_t source_table_offset = reader_.ReadFromIndexNoReset(
3106 reader_.size(),
3107 LibraryCountFieldCountFromEnd + 1 + library_count + 1 +
3108 count_from_first_library_offset,
3109 1, 0);
3110 SetOffset(source_table_offset); // read source table offset.
3111 return reader_.ReadUInt32(); // read source table size.
3112}
3113
3116 intptr_t library_count = reader_.ReadFromIndexNoReset(
3118
3119 const intptr_t count_from_first_library_offset =
3121
3122 intptr_t source_table_offset = reader_.ReadFromIndexNoReset(
3123 reader_.size(),
3124 LibraryCountFieldCountFromEnd + 1 + library_count + 1 +
3125 count_from_first_library_offset,
3126 1, 0);
3127 intptr_t next_field_offset = reader_.ReadUInt32();
3128 SetOffset(source_table_offset);
3129 intptr_t size = reader_.ReadUInt32(); // read source table size.
3130
3131 return reader_.ReadFromIndexNoReset(next_field_offset, 0, size, index);
3132}
3133
3137 intptr_t size = ReadUInt(); // read uri List<byte> size.
3138 return H.DartString(reader_.BufferAt(ReaderOffset()), size, Heap::kOld);
3139}
3140
3144 SkipBytes(ReadUInt()); // skip uri.
3145 intptr_t size = ReadUInt(); // read source List<byte> size.
3146 ASSERT(size >= 0);
3147 if (size == 0) {
3148 return Symbols::Empty();
3149 } else {
3150 return H.DartString(reader_.BufferAt(ReaderOffset()), size, Heap::kOld);
3151 }
3152}
3153
3154TypedDataPtr KernelReaderHelper::GetLineStartsFor(intptr_t index) {
3155 // Line starts are delta encoded. So get the max delta first so that we
3156 // can store them as tightly as possible.
3159 SkipBytes(ReadUInt()); // skip uri.
3160 SkipBytes(ReadUInt()); // skip source.
3161 const intptr_t line_start_count = ReadUInt();
3162 return reader_.ReadLineStartsData(line_start_count);
3163}
3164
3168 SkipBytes(ReadUInt()); // skip uri.
3169 SkipBytes(ReadUInt()); // skip source.
3170 const intptr_t line_start_count = ReadUInt(); // read number of line start
3171 // entries.
3172 for (intptr_t i = 0; i < line_start_count; ++i) {
3173 ReadUInt();
3174 }
3175
3176 intptr_t size = ReadUInt(); // read import uri List<byte> size.
3177 return H.DartString(reader_.BufferAt(ReaderOffset()), size, Heap::kOld);
3178}
3179
3180TypedDataViewPtr KernelReaderHelper::GetConstantCoverageFor(intptr_t index) {
3183 SkipBytes(ReadUInt()); // skip uri.
3184 SkipBytes(ReadUInt()); // skip source.
3185 const intptr_t line_start_count = ReadUInt(); // read number of line start
3186 // entries.
3187 for (intptr_t i = 0; i < line_start_count; ++i) {
3188 ReadUInt();
3189 }
3190
3191 SkipBytes(ReadUInt()); // skip import uri.
3192
3193 intptr_t start_offset = ReaderOffset();
3194
3195 // Read past "constant coverage constructors".
3196 const intptr_t constant_coverage_constructors = ReadUInt();
3197 for (intptr_t i = 0; i < constant_coverage_constructors; ++i) {
3198 ReadUInt();
3199 }
3200
3201 intptr_t end_offset = ReaderOffset();
3202
3203 return reader_.ViewFromTo(start_offset, end_offset);
3204}
3205
3207 ASSERT(member != nullptr);
3208 if (member->IsFactory()) {
3209 return klass->NumTypeParameters();
3210 } else if (member->IsMethodExtractor()) {
3211 Function& extracted =
3213 return extracted.NumTypeParameters();
3214 } else {
3215 return member->NumTypeParameters();
3216 }
3217}
3218
3220 ActiveClass* active_class,
3221 const Function& innermost,
3222 const FunctionType* innermost_signature,
3223 Zone* Z)
3224 : active_class_(active_class), saved_(*active_class), zone_(Z) {
3225 active_class_->enclosing = innermost_signature;
3226
3227 intptr_t num_params = 0;
3228
3230 for (f = innermost.ptr(); f.parent_function() != Object::null();
3231 f = f.parent_function()) {
3232 num_params += f.NumTypeParameters();
3233 }
3234 if (num_params == 0) return;
3235
3238
3239 intptr_t index = num_params;
3240 for (f = innermost.ptr(); f.parent_function() != Object::null();
3241 f = f.parent_function()) {
3242 for (intptr_t j = f.NumTypeParameters() - 1; j >= 0; --j) {
3243 const auto& type_param = TypeParameter::Handle(Z, f.TypeParameterAt(j));
3244 params.SetTypeAt(--index, type_param);
3245 }
3246 }
3247
3248 active_class_->local_type_parameters = &params;
3249}
3250
3252 ActiveClass* active_class,
3253 const FunctionType* innermost_signature,
3254 Zone* Z)
3255 : active_class_(active_class), saved_(*active_class), zone_(Z) {
3256 active_class_->enclosing = innermost_signature;
3257
3258 const intptr_t num_new_params =
3259 innermost_signature == nullptr ? active_class->klass->NumTypeParameters()
3260 : innermost_signature->NumTypeParameters();
3261 if (num_new_params == 0) return;
3262
3263 const TypeArguments* old_params = active_class->local_type_parameters;
3264 const intptr_t old_param_count =
3265 old_params == nullptr ? 0 : old_params->Length();
3266 const TypeArguments& extended_params = TypeArguments::Handle(
3267 Z, TypeArguments::New(old_param_count + num_new_params));
3268
3269 intptr_t index = 0;
3270 for (intptr_t i = 0; i < old_param_count; ++i) {
3271 extended_params.SetTypeAt(index++,
3272 AbstractType::Handle(Z, old_params->TypeAt(i)));
3273 }
3274 for (intptr_t i = 0; i < num_new_params; ++i) {
3275 const auto& type_param =
3276 TypeParameter::Handle(Z, innermost_signature == nullptr
3277 ? active_class->klass->TypeParameterAt(i)
3278 : innermost_signature->TypeParameterAt(i));
3279 extended_params.SetTypeAt(index++, type_param);
3280 }
3281
3282 active_class_->local_type_parameters = &extended_params;
3283}
3284
3286 *active_class_ = saved_;
3287}
3288
3290 ConstantReader* constant_reader,
3291 ActiveClass* active_class,
3292 bool finalize,
3293 bool in_constant_context)
3294 : helper_(helper),
3295 constant_reader_(constant_reader),
3296 translation_helper_(helper->translation_helper_),
3297 active_class_(active_class),
3298 type_parameter_scope_(nullptr),
3299 inferred_type_metadata_helper_(helper_, constant_reader_),
3300 unboxing_info_metadata_helper_(helper_),
3301 zone_(translation_helper_.zone()),
3302 result_(AbstractType::Handle(translation_helper_.zone())),
3303 finalize_(finalize),
3304 in_constant_context_(in_constant_context) {}
3305
3307 BuildTypeInternal();
3308
3309 // We return a new `ZoneHandle` here on purpose: The intermediate language
3310 // instructions do not make a copy of the handle, so we do it.
3311 return AbstractType::ZoneHandle(Z, result_.ptr());
3312}
3313
3315 bool saved_finalize = finalize_;
3316 finalize_ = false;
3317 BuildTypeInternal();
3318 finalize_ = saved_finalize;
3319
3320 // We return a new `ZoneHandle` here on purpose: The intermediate language
3321 // instructions do not make a copy of the handle, so we do it.
3322 return AbstractType::ZoneHandle(Z, result_.ptr());
3323}
3324
3325void TypeTranslator::BuildTypeInternal() {
3326 Tag tag = helper_->ReadTag();
3327 switch (tag) {
3328 case kInvalidType:
3329 case kDynamicType:
3330 result_ = Object::dynamic_type().ptr();
3331 break;
3332 case kVoidType:
3333 result_ = Object::void_type().ptr();
3334 break;
3335 case kNeverType: {
3336 Nullability nullability = helper_->ReadNullability();
3337 result_ = Type::Handle(Z, IG->object_store()->never_type())
3338 .ToNullability(nullability, Heap::kOld);
3339 break;
3340 }
3341 case kNullType:
3342 result_ = IG->object_store()->null_type();
3343 break;
3344 case kInterfaceType:
3345 BuildInterfaceType(false);
3346 break;
3347 case kSimpleInterfaceType:
3348 BuildInterfaceType(true);
3349 break;
3350 case kFunctionType:
3351 BuildFunctionType(false);
3352 break;
3353 case kSimpleFunctionType:
3354 BuildFunctionType(true);
3355 break;
3356 case kRecordType:
3357 BuildRecordType();
3358 break;
3359 case kTypeParameterType:
3360 BuildTypeParameterType();
3361 break;
3362 case kIntersectionType:
3363 BuildIntersectionType();
3364 break;
3365 case kExtensionType:
3366 BuildExtensionType();
3367 break;
3368 case kFutureOrType:
3369 BuildFutureOrType();
3370 break;
3371 default:
3372 helper_->ReportUnexpectedTag("type", tag);
3373 UNREACHABLE();
3374 }
3375}
3376
3377void TypeTranslator::BuildInterfaceType(bool simple) {
3378 // NOTE: That an interface type like `T<A, B>` is considered to be
3379 // malformed iff `T` is malformed.
3380 // => We therefore ignore errors in `A` or `B`.
3381
3382 Nullability nullability = helper_->ReadNullability();
3383 NameIndex klass_name =
3384 helper_->ReadCanonicalNameReference(); // read klass_name.
3385
3386 const Class& klass = Class::Handle(Z, H.LookupClassByKernelClass(klass_name));
3387 ASSERT(!klass.IsNull());
3388 if (simple) {
3389 if (finalize_ || klass.is_type_finalized()) {
3390 // Fast path for non-generic types: retrieve or populate the class's only
3391 // canonical type (as long as only one nullability variant is used), which
3392 // is its declaration type.
3393 result_ = klass.DeclarationType();
3394 result_ = Type::Cast(result_).ToNullability(nullability, Heap::kOld);
3395 } else {
3396 // Note that the type argument vector is not yet extended.
3397 result_ = Type::New(klass, Object::null_type_arguments(), nullability);
3398 }
3399 return;
3400 }
3401
3402 intptr_t length =
3403 helper_->ReadListLength(); // read type_arguments list length.
3404 const TypeArguments& type_arguments =
3405 BuildTypeArguments(length); // read type arguments.
3406 result_ = Type::New(klass, type_arguments, nullability);
3407 result_ = result_.NormalizeFutureOrType(Heap::kOld);
3408 if (finalize_) {
3409 result_ = ClassFinalizer::FinalizeType(result_);
3410 }
3411}
3412
3413void TypeTranslator::BuildFutureOrType() {
3414 Nullability nullability = helper_->ReadNullability();
3415
3416 const TypeArguments& type_arguments =
3418 BuildTypeInternal(); // read type argument.
3419 type_arguments.SetTypeAt(0, result_);
3420
3421 const Class& klass = Class::Handle(Z, IG->object_store()->future_or_class());
3422 ASSERT(!klass.IsNull());
3423
3424 result_ = Type::New(klass, type_arguments, nullability);
3425 result_ = result_.NormalizeFutureOrType(Heap::kOld);
3426 if (finalize_) {
3427 result_ = ClassFinalizer::FinalizeType(result_);
3428 }
3429}
3430
3431void TypeTranslator::BuildFunctionType(bool simple) {
3432 const intptr_t num_enclosing_type_arguments =
3433 active_class_->enclosing != nullptr
3434 ? active_class_->enclosing->NumTypeArguments()
3435 : 0;
3436 Nullability nullability = helper_->ReadNullability();
3437 FunctionType& signature = FunctionType::ZoneHandle(
3438 Z, FunctionType::New(num_enclosing_type_arguments, nullability));
3439
3440 // Suspend finalization of types inside this one. They will be finalized after
3441 // the whole function type is constructed.
3442 bool finalize = finalize_;
3443 finalize_ = false;
3444 intptr_t type_parameter_count = 0;
3445
3446 if (!simple) {
3447 type_parameter_count = helper_->ReadListLength();
3448 LoadAndSetupTypeParameters(active_class_, Object::null_function(),
3449 Object::null_class(), signature,
3450 type_parameter_count);
3451 }
3452
3453 ActiveTypeParametersScope scope(active_class_, &signature, Z);
3454
3455 if (!simple) {
3456 LoadAndSetupBounds(active_class_, Object::null_function(),
3457 Object::null_class(), signature, type_parameter_count);
3458 }
3459
3460 intptr_t required_count;
3461 intptr_t all_count;
3462 intptr_t positional_count;
3463 if (!simple) {
3464 required_count = helper_->ReadUInt(); // read required parameter count.
3465 all_count = helper_->ReadUInt(); // read total parameter count.
3466 positional_count =
3467 helper_->ReadListLength(); // read positional_parameters list length.
3468 } else {
3469 positional_count =
3470 helper_->ReadListLength(); // read positional_parameters list length.
3471 required_count = positional_count;
3472 all_count = positional_count;
3473 }
3474
3475 // The additional first parameter is the receiver (type set to dynamic).
3476 const intptr_t kImplicitClosureParam = 1;
3477 signature.set_num_implicit_parameters(kImplicitClosureParam);
3478 signature.set_num_fixed_parameters(kImplicitClosureParam + required_count);
3479 signature.SetNumOptionalParameters(all_count - required_count,
3480 positional_count > required_count);
3481
3482 signature.set_parameter_types(Array::Handle(
3483 Z, Array::New(kImplicitClosureParam + all_count, Heap::kOld)));
3484 signature.CreateNameArrayIncludingFlags();
3485
3486 intptr_t pos = 0;
3487 signature.SetParameterTypeAt(pos, AbstractType::dynamic_type());
3488 ++pos;
3489 for (intptr_t i = 0; i < positional_count; ++i, ++pos) {
3490 BuildTypeInternal(); // read ith positional parameter.
3491 signature.SetParameterTypeAt(pos, result_);
3492 }
3493
3494 if (!simple) {
3495 const intptr_t named_count =
3496 helper_->ReadListLength(); // read named_parameters list length.
3497 for (intptr_t i = 0; i < named_count; ++i, ++pos) {
3498 // read string reference (i.e. named_parameters[i].name).
3499 String& name = H.DartSymbolObfuscate(helper_->ReadStringReference());
3500 BuildTypeInternal(); // read named_parameters[i].type.
3501 const uint8_t flags = helper_->ReadFlags(); // read flags
3502 signature.SetParameterTypeAt(pos, result_);
3503 signature.SetParameterNameAt(pos, name);
3504 if ((flags & static_cast<uint8_t>(NamedTypeFlags::kIsRequired)) != 0) {
3505 signature.SetIsRequiredAt(pos);
3506 }
3507 }
3508 }
3509 signature.FinalizeNameArray();
3510
3511 BuildTypeInternal(); // read return type.
3512 signature.set_result_type(result_);
3513
3514 finalize_ = finalize;
3515
3516 if (finalize_) {
3517 signature ^= ClassFinalizer::FinalizeType(signature);
3518 }
3519
3520 result_ = signature.ptr();
3521}
3522
3523void TypeTranslator::BuildRecordType() {
3524 Nullability nullability = helper_->ReadNullability();
3525 const intptr_t positional_count = helper_->ReadListLength();
3526 intptr_t named_count = 0;
3527 {
3528 AlternativeReadingScope alt(&helper_->reader_);
3529 for (intptr_t i = 0; i < positional_count; ++i) {
3530 helper_->SkipDartType();
3531 }
3532 named_count = helper_->ReadListLength();
3533 }
3534
3535 const intptr_t num_fields = positional_count + named_count;
3536 const Array& field_types =
3537 Array::Handle(Z, Array::New(num_fields, Heap::kOld));
3538 const Array& field_names =
3539 (named_count == 0)
3540 ? Object::empty_array()
3541 : Array::Handle(Z, Array::New(named_count, Heap::kOld));
3542
3543 // Suspend finalization of types inside this one. They will be finalized after
3544 // the whole record type is constructed.
3545 bool finalize = finalize_;
3546 finalize_ = false;
3547
3548 intptr_t pos = 0;
3549 for (intptr_t i = 0; i < positional_count; ++i) {
3550 BuildTypeInternal(); // read ith positional field.
3551 field_types.SetAt(pos++, result_);
3552 }
3553
3554 helper_->ReadListLength();
3555 for (intptr_t i = 0; i < named_count; ++i) {
3556 String& name = H.DartSymbolObfuscate(helper_->ReadStringReference());
3557 field_names.SetAt(i, name);
3558 BuildTypeInternal();
3559 field_types.SetAt(pos++, result_);
3560 helper_->ReadFlags();
3561 }
3562 if (named_count != 0) {
3563 field_names.MakeImmutable();
3564 }
3565 const RecordShape shape =
3566 RecordShape::Register(H.thread(), num_fields, field_names);
3567
3568 finalize_ = finalize;
3569
3570 RecordType& rec =
3571 RecordType::Handle(Z, RecordType::New(shape, field_types, nullability));
3572
3573 if (finalize_) {
3574 rec ^= ClassFinalizer::FinalizeType(rec);
3575 }
3576
3577 result_ = rec.ptr();
3578}
3579
3580void TypeTranslator::BuildTypeParameterType() {
3581 Nullability nullability = helper_->ReadNullability();
3582 intptr_t parameter_index = helper_->ReadUInt(); // read parameter index.
3583
3584 // If the type is from a constant, the parameter index isn't offset by the
3585 // enclosing context.
3586 if (!in_constant_context_) {
3587 const intptr_t class_type_parameter_count =
3588 active_class_->klass->NumTypeParameters();
3589 if (class_type_parameter_count > parameter_index) {
3590 result_ =
3591 active_class_->klass->TypeParameterAt(parameter_index, nullability);
3592 return;
3593 }
3594 parameter_index -= class_type_parameter_count;
3595
3596 if (active_class_->HasMember()) {
3597 if (active_class_->MemberIsFactoryProcedure()) {
3598 //
3599 // WARNING: This is a little hackish:
3600 //
3601 // We have a static factory constructor. The kernel IR gives the factory
3602 // constructor function its own type parameters (which are equal in name
3603 // and number to the ones of the enclosing class). I.e.,
3604 //
3605 // class A<T> {
3606 // factory A.x() { return new B<T>(); }
3607 // }
3608 //
3609 // is basically translated to this:
3610 //
3611 // class A<T> {
3612 // static A.x<T'>() { return new B<T'>(); }
3613 // }
3614 //
3615 if (class_type_parameter_count > parameter_index) {
3616 result_ = active_class_->klass->TypeParameterAt(parameter_index,
3617 nullability);
3618 return;
3619 }
3620 parameter_index -= class_type_parameter_count;
3621 }
3622 // Factory function should not be considered as procedure.
3623 const intptr_t procedure_type_parameter_count =
3624 (active_class_->MemberIsProcedure() &&
3625 !active_class_->MemberIsFactoryProcedure())
3626 ? active_class_->MemberTypeParameterCount(Z)
3627 : 0;
3628 if (procedure_type_parameter_count > 0) {
3629 if (procedure_type_parameter_count > parameter_index) {
3630 result_ = active_class_->member->TypeParameterAt(parameter_index,
3631 nullability);
3632 if (finalize_) {
3633 result_ = ClassFinalizer::FinalizeType(result_);
3634 }
3635 return;
3636 }
3637 parameter_index -= procedure_type_parameter_count;
3638 }
3639 }
3640 }
3641 if (active_class_->local_type_parameters != nullptr) {
3642 if (parameter_index < active_class_->local_type_parameters->Length()) {
3643 const auto& type_param = TypeParameter::CheckedHandle(
3644 Z, active_class_->local_type_parameters->TypeAt(parameter_index));
3645 result_ = type_param.ToNullability(nullability, Heap::kOld);
3646 if (finalize_) {
3647 result_ = ClassFinalizer::FinalizeType(result_);
3648 }
3649 return;
3650 }
3651 parameter_index -= active_class_->local_type_parameters->Length();
3652 }
3653
3654 if (type_parameter_scope_ != nullptr &&
3655 parameter_index < type_parameter_scope_->outer_parameter_count() +
3656 type_parameter_scope_->parameter_count()) {
3657 result_ = Type::DynamicType();
3658 return;
3659 }
3660
3661 const auto& script = Script::Handle(Z, Script());
3662 H.ReportError(
3663 script, TokenPosition::kNoSource,
3664 "Unbound type parameter found in %s. Please report this at dartbug.com.",
3665 active_class_->ToCString());
3666}
3667
3668void TypeTranslator::BuildIntersectionType() {
3669 BuildTypeInternal(); // read left.
3670 helper_->SkipDartType(); // read right.
3671}
3672
3673void TypeTranslator::BuildExtensionType() {
3674 // We skip the extension type and only use the type erasure.
3675 helper_->ReadNullability();
3676 helper_->SkipCanonicalNameReference(); // read index for canonical name.
3677 helper_->SkipListOfDartTypes(); // read type arguments
3678 BuildTypeInternal(); // read type erasure.
3679}
3680
3682 bool only_dynamic = true;
3683 intptr_t offset = helper_->ReaderOffset();
3684 for (intptr_t i = 0; i < length; ++i) {
3685 if (helper_->ReadTag() != kDynamicType) { // Read the ith types tag.
3686 only_dynamic = false;
3687 helper_->SetOffset(offset);
3688 break;
3689 }
3690 }
3691 TypeArguments& type_arguments = TypeArguments::ZoneHandle(Z);
3692 if (!only_dynamic) {
3693 type_arguments = TypeArguments::New(length);
3694 for (intptr_t i = 0; i < length; ++i) {
3695 BuildTypeInternal(); // read ith type.
3696 type_arguments.SetTypeAt(i, result_);
3697 }
3698
3699 if (finalize_) {
3700 type_arguments = type_arguments.Canonicalize(Thread::Current());
3701 }
3702 }
3703 return type_arguments;
3704}
3705
3707 const Class& receiver_class,
3708 intptr_t length) {
3709 const TypeArguments& type_arguments = BuildTypeArguments(length);
3710
3711 // If type_arguments is null all arguments are dynamic.
3712 // If, however, this class doesn't specify all the type arguments directly we
3713 // still need to finalize the type below in order to get any non-dynamic types
3714 // from any super. See http://www.dartbug.com/29537.
3715 if (type_arguments.IsNull() && receiver_class.NumTypeArguments() == length) {
3716 return type_arguments;
3717 }
3718
3719 const TypeArguments& instantiated_type_arguments = TypeArguments::ZoneHandle(
3720 Z, receiver_class.GetInstanceTypeArguments(H.thread(), type_arguments));
3721 return instantiated_type_arguments;
3722}
3723
3725 ActiveClass* active_class,
3726 const Function& function,
3727 const Class& parameterized_class,
3728 const FunctionType& parameterized_signature,
3729 intptr_t type_parameter_count) {
3730 ASSERT(parameterized_class.IsNull() != parameterized_signature.IsNull());
3731 ASSERT(type_parameter_count >= 0);
3732 if (type_parameter_count == 0) {
3733 ASSERT(parameterized_class.IsNull() ||
3734 parameterized_class.type_parameters() == TypeParameters::null());
3735 ASSERT(parameterized_signature.IsNull() ||
3736 parameterized_signature.type_parameters() == TypeParameters::null());
3737 return;
3738 }
3739
3740 // The finalized index of a type parameter can only be determined if the
3741 // length of the flattened type argument vector is known, which in turn can
3742 // only be determined after the super type and its class have been loaded.
3743 // Due to the added complexity of loading classes out of order from the kernel
3744 // file, class type parameter indices are not finalized during class loading.
3745 // However, function type parameter indices can be immediately finalized.
3746
3747 // First setup the type parameters, so if any of the following code uses it
3748 // (in a recursive way) we're fine.
3749
3750 // - Create a [ TypeParameters ] object.
3751 const TypeParameters& type_parameters =
3752 TypeParameters::Handle(Z, TypeParameters::New(type_parameter_count));
3753 const Type& null_bound = Type::Handle(Z);
3754
3755 if (!parameterized_class.IsNull()) {
3756 ASSERT(parameterized_class.type_parameters() == TypeParameters::null());
3757 parameterized_class.set_type_parameters(type_parameters);
3758 } else {
3759 ASSERT(parameterized_signature.type_parameters() == TypeParameters::null());
3760 parameterized_signature.SetTypeParameters(type_parameters);
3761 }
3762
3763 const Library& lib = Library::Handle(Z, active_class->klass->library());
3764 {
3765 AlternativeReadingScope alt(&helper_->reader_);
3766 for (intptr_t i = 0; i < type_parameter_count; i++) {
3767 TypeParameterHelper helper(helper_);
3768 helper.Finish();
3769 type_parameters.SetNameAt(i, H.DartIdentifier(lib, helper.name_index_));
3770 type_parameters.SetIsGenericCovariantImplAt(
3771 i, helper.IsGenericCovariantImpl());
3772 // Bounds are filled later in LoadAndSetupBounds as bound types may
3773 // reference type parameters which are not created yet.
3774 type_parameters.SetBoundAt(i, null_bound);
3775 }
3776 }
3777}
3778
3780 ActiveClass* active_class,
3781 const Function& function,
3782 const Class& parameterized_class,
3783 const FunctionType& parameterized_signature,
3784 intptr_t type_parameter_count) {
3785 ASSERT(parameterized_class.IsNull() != parameterized_signature.IsNull());
3786 ASSERT(type_parameter_count >= 0);
3787 if (type_parameter_count == 0) {
3788 return;
3789 }
3790
3791 const TypeParameters& type_parameters = TypeParameters::Handle(
3792 Z, !parameterized_class.IsNull()
3793 ? parameterized_class.type_parameters()
3794 : parameterized_signature.type_parameters());
3795
3796 // Fill in the bounds and default arguments of all [TypeParameter]s.
3797 for (intptr_t i = 0; i < type_parameter_count; i++) {
3798 TypeParameterHelper helper(helper_);
3800
3801 AbstractType& bound = BuildTypeWithoutFinalization(); // read ith bound.
3802 ASSERT(!bound.IsNull());
3803 type_parameters.SetBoundAt(i, bound);
3806 ASSERT(!default_arg.IsNull());
3807 type_parameters.SetDefaultAt(i, default_arg);
3808 helper.Finish();
3809 }
3810}
3811
3813 ASSERT(!klass.IsNull());
3814 // Forward expression evaluation class to a real class when
3815 // creating types.
3816 if (translation_helper_.GetExpressionEvaluationClass().ptr() == klass.ptr()) {
3817 ASSERT(translation_helper_.GetExpressionEvaluationRealClass().ptr() !=
3818 klass.ptr());
3819 return ReceiverType(translation_helper_.GetExpressionEvaluationRealClass());
3820 }
3821 ASSERT(klass.id() != kIllegalCid);
3822 // Note that if klass is _Closure, the returned type will be _Closure,
3823 // and not the signature type.
3825 if (finalize_ || klass.is_type_finalized()) {
3826 type = klass.DeclarationType();
3827 } else {
3829 const intptr_t num_type_params = klass.NumTypeParameters();
3830 if (num_type_params > 0) {
3831 type_args = TypeArguments::New(num_type_params);
3832 TypeParameter& type_param = TypeParameter::Handle();
3833 for (intptr_t i = 0; i < num_type_params; i++) {
3834 type_param = klass.TypeParameterAt(i);
3835 type_args.SetTypeAt(i, type_param);
3836 }
3837 }
3838 type = Type::New(klass, type_args, Nullability::kNonNullable);
3839 }
3840 return type;
3841}
3842
3844 intptr_t param_index,
3845 const UnboxingInfoMetadata* metadata) {
3846 const intptr_t param_pos =
3847 param_index + (function.HasThisParameter() ? 1 : 0);
3848
3849 if (param_pos < function.maximum_unboxed_parameter_count()) {
3850 switch (metadata->unboxed_args_info[param_index].kind) {
3852 function.set_unboxed_integer_parameter_at(param_pos);
3853 break;
3856 function.set_unboxed_double_parameter_at(param_pos);
3857 }
3858 break;
3860 UNREACHABLE();
3861 break;
3863 UNREACHABLE();
3864 break;
3866 break;
3867 }
3868 }
3869}
3870
3872 const Function& function,
3873 const UnboxingInfoMetadata* metadata) {
3874 switch (metadata->return_info.kind) {
3876 function.set_unboxed_integer_return();
3877 break;
3880 function.set_unboxed_double_return();
3881 }
3882 break;
3884 function.set_unboxed_record_return();
3885 break;
3887 UNREACHABLE();
3888 break;
3890 break;
3891 }
3892}
3893
3894void TypeTranslator::SetupUnboxingInfoMetadata(const Function& function,
3895 intptr_t library_kernel_offset) {
3896 const intptr_t kernel_offset =
3897 function.kernel_offset() + library_kernel_offset;
3898 const auto unboxing_info =
3899 unboxing_info_metadata_helper_.GetUnboxingInfoMetadata(kernel_offset);
3900
3901 if (FLAG_precompiled_mode && unboxing_info != nullptr) {
3902 for (intptr_t i = 0; i < unboxing_info->unboxed_args_info.length(); i++) {
3903 SetupUnboxingInfoOfParameter(function, i, unboxing_info);
3904 }
3906 }
3907}
3908
3909void TypeTranslator::SetupUnboxingInfoMetadataForFieldAccessors(
3910 const Function& field_accessor,
3911 intptr_t library_kernel_offset) {
3912 const intptr_t kernel_offset =
3913 field_accessor.kernel_offset() + library_kernel_offset;
3914 const auto unboxing_info =
3915 unboxing_info_metadata_helper_.GetUnboxingInfoMetadata(kernel_offset);
3916
3917 if (FLAG_precompiled_mode && unboxing_info != nullptr) {
3918 if (field_accessor.IsImplicitSetterFunction()) {
3919 for (intptr_t i = 0; i < unboxing_info->unboxed_args_info.length(); i++) {
3920 SetupUnboxingInfoOfParameter(field_accessor, i, unboxing_info);
3921 }
3922 } else {
3923 ASSERT(field_accessor.IsImplicitGetterFunction() ||
3924 field_accessor.IsImplicitStaticGetterFunction());
3925 SetupUnboxingInfoOfReturnValue(field_accessor, unboxing_info);
3926 }
3927 }
3928}
3929
3931 const Class& klass,
3932 const Function& function,
3933 bool is_method,
3934 bool is_closure,
3935 FunctionNodeHelper* function_node_helper) {
3936 ASSERT(!(is_method && is_closure));
3937 bool is_factory = function.IsFactory();
3938 intptr_t extra_parameters = (is_method || is_closure || is_factory) ? 1 : 0;
3939
3940 const FunctionType& signature = FunctionType::Handle(Z, function.signature());
3941 ASSERT(!signature.IsNull());
3942 intptr_t type_parameter_count = 0;
3943 if (!is_factory) {
3944 type_parameter_count = helper_->ReadListLength();
3946 signature, type_parameter_count);
3947 function_node_helper->SetJustRead(FunctionNodeHelper::kTypeParameters);
3948 }
3949
3950 ActiveTypeParametersScope scope(active_class_, function, &signature, Z);
3951
3952 if (!is_factory) {
3953 LoadAndSetupBounds(active_class_, function, Class::Handle(Z), signature,
3954 type_parameter_count);
3955 function_node_helper->SetJustRead(FunctionNodeHelper::kTypeParameters);
3956 }
3957
3958 function_node_helper->ReadUntilExcluding(
3960
3961 intptr_t required_parameter_count =
3962 function_node_helper->required_parameter_count_;
3963 intptr_t total_parameter_count = function_node_helper->total_parameter_count_;
3964
3965 intptr_t positional_parameter_count =
3966 helper_->ReadListLength(); // read list length.
3967
3968 intptr_t named_parameter_count =
3969 total_parameter_count - positional_parameter_count;
3970
3971 signature.set_num_fixed_parameters(extra_parameters +
3972 required_parameter_count);
3973 if (named_parameter_count > 0) {
3974 signature.SetNumOptionalParameters(named_parameter_count, false);
3975 } else {
3976 signature.SetNumOptionalParameters(
3977 positional_parameter_count - required_parameter_count, true);
3978 }
3979 intptr_t parameter_count = extra_parameters + total_parameter_count;
3980
3981 intptr_t pos = 0;
3982 if (parameter_count > 0) {
3983 signature.set_parameter_types(
3984 Array::Handle(Z, Array::New(parameter_count, Heap::kOld)));
3985 function.CreateNameArray();
3987 if (is_method) {
3988 ASSERT(!klass.IsNull());
3989 signature.SetParameterTypeAt(pos, H.GetDeclarationType(klass));
3990 function.SetParameterNameAt(pos, Symbols::This());
3991 pos++;
3992 } else if (is_closure) {
3993 signature.SetParameterTypeAt(pos, AbstractType::dynamic_type());
3994 function.SetParameterNameAt(pos, Symbols::ClosureParameter());
3995 pos++;
3996 } else if (is_factory) {
3997 signature.SetParameterTypeAt(pos, AbstractType::dynamic_type());
3998 function.SetParameterNameAt(pos, Symbols::TypeArgumentsParameter());
3999 pos++;
4000 }
4001 } else {
4002 ASSERT(!is_method && !is_closure && !is_factory);
4003 }
4004
4005 const Library& lib = Library::Handle(Z, active_class_->klass->library());
4006 for (intptr_t i = 0; i < positional_parameter_count; ++i, ++pos) {
4007 // Read ith variable declaration.
4008 VariableDeclarationHelper helper(helper_);
4010 // The required flag should only be set on named parameters.
4011 ASSERT(!helper.IsRequired());
4012 const AbstractType& type = BuildTypeWithoutFinalization(); // read type.
4013 Tag tag = helper_->ReadTag(); // read (first part of) initializer.
4014 if (tag == kSomething) {
4015 helper_->SkipExpression(); // read (actual) initializer.
4016 }
4017
4018 signature.SetParameterTypeAt(pos, type);
4019 function.SetParameterNameAt(pos, H.DartIdentifier(lib, helper.name_index_));
4020 }
4021
4022 intptr_t named_parameter_count_check =
4023 helper_->ReadListLength(); // read list length.
4024 ASSERT(named_parameter_count_check == named_parameter_count);
4025 for (intptr_t i = 0; i < named_parameter_count; ++i, ++pos) {
4026 // Read ith variable declaration.
4027 VariableDeclarationHelper helper(helper_);
4029 const AbstractType& type = BuildTypeWithoutFinalization(); // read type.
4030 Tag tag = helper_->ReadTag(); // read (first part of) initializer.
4031 if (tag == kSomething) {
4032 helper_->SkipExpression(); // read (actual) initializer.
4033 }
4034
4035 signature.SetParameterTypeAt(pos, type);
4036 signature.SetParameterNameAt(pos,
4037 H.DartIdentifier(lib, helper.name_index_));
4038 if (helper.IsRequired()) {
4039 signature.SetIsRequiredAt(pos);
4040 }
4041 }
4042 signature.FinalizeNameArray();
4043
4045
4046 // The result type for generative constructors has already been set.
4047 if (!function.IsGenerativeConstructor()) {
4048 const AbstractType& return_type =
4049 BuildTypeWithoutFinalization(); // read return type.
4050 signature.set_result_type(return_type);
4051 function_node_helper->SetJustRead(FunctionNodeHelper::kReturnType);
4052 }
4053}
4054
4055} // namespace kernel
4056} // namespace dart
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition DM.cpp:213
int count
SkPoint pos
static int const kUInt32Size
static bool left(const SkPoint &p0, const SkPoint &p1)
static bool right(const SkPoint &p0, const SkPoint &p1)
#define IG
#define UNREACHABLE()
Definition assert.h:248
#define RELEASE_ASSERT(cond)
Definition assert.h:327
#define Z
virtual AbstractTypePtr NormalizeFutureOrType(Heap::Space space) const
Definition object.cc:21161
static ArrayPtr New(intptr_t len, Heap::Space space=Heap::kNew)
Definition object.h:10933
ObjectPtr At(intptr_t index) const
Definition object.h:10854
intptr_t Length() const
Definition object.h:10808
void SetAt(intptr_t index, const Object &value) const
Definition object.h:10858
static AbstractTypePtr FinalizeType(const AbstractType &type, FinalizationKind finalization=kCanonicalize)
FunctionPtr LookupFunctionAllowPrivate(const String &name) const
Definition object.cc:6222
FunctionPtr LookupDynamicFunctionAllowPrivate(const String &name) const
Definition object.cc:6188
LibraryPtr library() const
Definition object.h:1335
FunctionPtr LookupConstructorAllowPrivate(const String &name) const
Definition object.cc:6208
intptr_t id() const
Definition object.h:1235
intptr_t NumTypeArguments() const
Definition object.cc:3690
bool is_type_finalized() const
Definition object.h:1711
StringPtr Name() const
Definition object.cc:3038
TypePtr DeclarationType() const
Definition object.cc:5882
ErrorPtr EnsureIsFinalized(Thread *thread) const
Definition object.cc:4979
ClassPtr SuperClass(ClassTable *class_table=nullptr) const
Definition object.cc:3715
TypeParametersPtr type_parameters() const
Definition object.h:1340
TypeParameterPtr TypeParameterAt(intptr_t index, Nullability nullability=Nullability::kNonNullable) const
Definition object.cc:3739
void set_type_parameters(const TypeParameters &value) const
Definition object.cc:3492
FieldPtr LookupFieldAllowPrivate(const String &name, bool instance_only=false) const
Definition object.cc:6458
intptr_t NumTypeParameters(Thread *thread) const
Definition object.cc:3605
TypeArgumentsPtr GetInstanceTypeArguments(Thread *thread, const TypeArguments &type_arguments, bool canonicalize=true) const
Definition object.cc:3574
static StringPtr GetterSymbol(const String &field_name)
Definition object.cc:11847
static StringPtr SetterSymbol(const String &field_name)
Definition object.cc:11859
static bool SupportsUnboxedDoubles()
TypeParametersPtr type_parameters() const
Definition object.h:9707
void SetIsRequiredAt(intptr_t index) const
Definition object.cc:8829
void set_result_type(const AbstractType &value) const
Definition object.cc:8633
void SetParameterTypeAt(intptr_t index, const AbstractType &value) const
Definition object.cc:8648
TypeParameterPtr TypeParameterAt(intptr_t index, Nullability nullability=Nullability::kNonNullable) const
Definition object.cc:8618
void set_num_fixed_parameters(intptr_t value) const
Definition object.cc:11659
void SetParameterNameAt(intptr_t index, const String &value) const
Definition object.cc:8714
void CreateNameArrayIncludingFlags(Heap::Space space=Heap::kOld) const
Definition object.cc:8750
void set_parameter_types(const Array &value) const
Definition object.cc:8655
intptr_t NumTypeArguments() const
Definition object.h:9563
void FinalizeNameArray() const
Definition object.cc:8844
void SetNumOptionalParameters(intptr_t num_optional_parameters, bool are_optional_positional) const
Definition object.cc:11668
intptr_t NumTypeParameters() const
Definition object.h:9558
void SetTypeParameters(const TypeParameters &value) const
Definition object.cc:8884
static FunctionTypePtr New(intptr_t num_parent_type_arguments=0, Nullability nullability=Nullability::kLegacy, Heap::Space space=Heap::kOld)
Definition object.cc:11682
intptr_t NumTypeParameters() const
Definition object.cc:8905
bool IsMethodExtractor() const
Definition object.h:3264
bool IsFactory() const
Definition object.h:3347
FunctionPtr extracted_method_closure() const
Definition object.cc:8178
FunctionPtr GetMethodExtractor(const String &getter_name) const
Definition object.cc:4063
TypeParameterPtr TypeParameterAt(intptr_t index, Nullability nullability=Nullability::kNonNullable) const
Definition object.cc:8939
@ kOld
Definition heap.h:39
LibraryPtr LookupLibrary(Thread *thread, const Smi &name_index) const
Definition object.cc:15181
ClassPtr LookupClass(Thread *thread, const Smi &name_index) const
Definition object.cc:15230
LibraryPtr InsertLibrary(Thread *thread, const Smi &name_index, const Library &lib) const
Definition object.cc:15203
ClassPtr InsertClass(Thread *thread, const Smi &name_index, const Class &klass) const
Definition object.cc:15252
StringPtr PrivateName(const String &name) const
Definition object.cc:14751
ClassPtr LookupClassAllowPrivate(const String &name) const
Definition object.cc:14160
void set_loading_unit(const LoadingUnit &value) const
Definition object.cc:13659
static LibraryPtr LookupLibrary(Thread *thread, const String &url)
Definition object.cc:14646
StringPtr private_key() const
Definition object.h:5070
static LoadingUnitPtr New(intptr_t id, const LoadingUnit &parent)
Definition object.cc:19738
StringPtr Rename(const String &name, bool atomic=false)
static ObjectPtr null()
Definition object.h:433
ObjectPtr ptr() const
Definition object.h:332
bool IsNull() const
Definition object.h:363
static Object & Handle()
Definition object.h:407
static Object & ZoneHandle()
Definition object.h:419
static RecordShape ForUnnamed(intptr_t num_fields)
Definition object.h:11282
static RecordShape Register(Thread *thread, intptr_t num_fields, const Array &field_names)
Definition object.cc:27980
static RecordTypePtr New(RecordShape shape, const Array &field_types, Nullability nullability=Nullability::kLegacy, Heap::Space space=Heap::kOld)
Definition object.cc:27541
static void static void MessageV(Kind kind, const Script &script, TokenPosition token_pos, bool report_after_token, const char *format, va_list args)
Definition report.cc:135
static DART_NORETURN void LongJump(const Error &error)
Definition report.cc:86
static DART_NORETURN void static DART_NORETURN void LongJumpV(const Error &prev_error, const Script &script, TokenPosition token_pos, const char *format, va_list args)
Definition report.cc:103
static constexpr bool AtLocation
Definition report.h:29
static SmiPtr New(intptr_t value)
Definition object.h:9985
intptr_t Length() const
Definition object.h:10189
static StringPtr New(const char *cstr, Heap::Space space=Heap::kNew)
Definition object.cc:23777
uint16_t CharAt(intptr_t index) const
Definition object.h:10238
static StringPtr Concat(const String &str1, const String &str2, Heap::Space space=Heap::kNew)
Definition object.cc:24116
static const char * ToCString(Thread *thread, StringPtr ptr)
Definition object.cc:24205
static StringPtr FromUTF8(const uint8_t *utf8_array, intptr_t array_len, Heap::Space space=Heap::kNew)
Definition object.cc:23784
static StringPtr FromConcatAll(Thread *thread, const GrowableHandlePtrArray< const String > &strs)
Definition symbols.cc:262
static const String & This()
Definition symbols.h:691
static const String & Empty()
Definition symbols.h:687
static StringPtr FromUTF8(Thread *thread, const uint8_t *utf8_array, intptr_t len)
Definition symbols.cc:196
static StringPtr New(Thread *thread, const char *cstr)
Definition symbols.h:722
static const String & Dot()
Definition symbols.h:612
Zone * zone() const
static Thread * Current()
Definition thread.h:361
intptr_t Length() const
Definition object.cc:7352
void SetTypeAt(intptr_t index, const AbstractType &value) const
Definition object.cc:7381
TypeArgumentsPtr Canonicalize(Thread *thread) const
Definition object.cc:7761
static TypeArgumentsPtr New(intptr_t len, Heap::Space space=Heap::kOld)
Definition object.cc:7733
AbstractTypePtr TypeAt(intptr_t index) const
Definition object.cc:7366
void SetNameAt(intptr_t index, const String &value) const
Definition object.cc:6634
void SetBoundAt(intptr_t index, const AbstractType &value) const
Definition object.cc:6654
static TypeParametersPtr New(Heap::Space space=Heap::kOld)
Definition object.cc:6778
void SetDefaultAt(intptr_t index, const AbstractType &value) const
Definition object.cc:6675
void SetIsGenericCovariantImplAt(intptr_t index, bool value) const
Definition object.cc:6714
static TypePtr New(const Class &clazz, const TypeArguments &arguments, Nullability nullability=Nullability::kLegacy, Heap::Space space=Heap::kOld)
Definition object.cc:22492
static TypePtr DynamicType()
Definition object.cc:21866
intptr_t LengthInBytes() const
Definition object.h:11497
void * DataAddr(intptr_t byte_offset) const
Definition object.h:11545
static constexpr bool IsAligned(T x, uintptr_t alignment, uintptr_t offset=0)
Definition utils.h:77
const TypeArguments * local_type_parameters
intptr_t MemberTypeParameterCount(Zone *zone)
ActiveTypeParametersScope(ActiveClass *active_class, const Function &innermost, const FunctionType *innermost_signature, Zone *Z)
CallSiteAttributesMetadataHelper(KernelReaderHelper *helper, TypeTranslator *type_translator)
CallSiteAttributesMetadata GetCallSiteAttributes(intptr_t node_offset)
InstancePtr ReadConstant(intptr_t constant_index)
DirectCallMetadata GetDirectTargetForPropertyGet(intptr_t node_offset)
DirectCallMetadata GetDirectTargetForFunctionInvocation(intptr_t node_offset)
DirectCallMetadata GetDirectTargetForMethodInvocation(intptr_t node_offset)
DirectCallMetadata GetDirectTargetForPropertySet(intptr_t node_offset)
FieldHelper(KernelReaderHelper *helper)
InferredTypeMetadataHelper(KernelReaderHelper *helper, ConstantReader *constant_reader, Kind kind=Kind::Type)
InferredTypeMetadata GetInferredType(intptr_t node_offset, bool read_constant=true)
const String & GetSourceFor(intptr_t index)
Tag ReadTag(uint8_t *payload=nullptr)
virtual void set_current_script_id(intptr_t id)
virtual void ReportUnexpectedTag(const char *variant, Tag tag)
Tag PeekTag(uint8_t *payload=nullptr)
virtual void RecordTokenPosition(TokenPosition position)
TypedDataViewPtr GetConstantCoverageFor(intptr_t index)
TypedDataPtr GetLineStartsFor(intptr_t index)
intptr_t FindMetadataMapping(intptr_t node_offset)
intptr_t GetNextMetadataPayloadOffset(intptr_t node_offset)
static constexpr int kInvalidName
Definition kernel.h:21
ProcedureAttributesMetadata GetProcedureAttributes(intptr_t node_offset)
TokenPosition ReadPosition()
uint32_t ReadFromIndexNoReset(intptr_t end_offset, intptr_t fields_before, intptr_t list_size, intptr_t list_index)
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
TypedDataPtr ReadLineStartsData(intptr_t line_start_count)
static const char * TagName(Tag tag)
NameIndex ReadCanonicalNameReference()
const uint8_t * BufferAt(intptr_t offset)
TableSelectorMetadata * GetTableSelectorMetadata(Zone *zone)
GrowableArray< TableSelectorInfo > selectors
const String & DartProcedureName(NameIndex procedure)
Type & GetDeclarationType(const Class &klass)
void SetConstantsTable(const TypedDataView &constants_table)
InstancePtr Canonicalize(const Instance &instance)
FunctionPtr LookupStaticMethodByKernelProcedure(NameIndex procedure, bool required=true)
const TypedDataView & string_data() const
FunctionPtr LookupDynamicFunction(const Class &klass, const String &name)
const TypedDataView & metadata_mappings() const
const String & DartSetterName(NameIndex setter)
FieldPtr LookupFieldByKernelGetterOrSetter(NameIndex field, bool required=true)
intptr_t StringSize(StringIndex index) const
void SetCanonicalNames(const TypedData &canonical_names)
const TypedDataView & constants_table() const
intptr_t StringOffset(StringIndex index) const
void ReportError(const char *format,...) PRINTF_ATTRIBUTE(2
const String & DartClassName(NameIndex kernel_class)
uint8_t * StringBuffer(StringIndex index) const
const String & DartString(const char *content)
FunctionPtr LookupMethodByMember(NameIndex target, const String &method_name, bool required=true)
const String & DartConstructorName(NameIndex constructor)
NameIndex CanonicalNameParent(NameIndex name)
FieldPtr LookupFieldByKernelField(NameIndex field, bool required=true)
void SetMetadataMappings(const TypedDataView &metadata_mappings)
void SetKernelProgramInfo(const KernelProgramInfo &info)
void InitFromKernelProgramInfo(const KernelProgramInfo &info)
ClassPtr LookupClassByKernelClassOrLibrary(NameIndex kernel_name, bool required=true)
uint8_t CharacterAt(StringIndex string_index, intptr_t index)
String & DartIdentifier(const Library &lib, StringIndex string_index)
const TypedData & canonical_names() const
const String & DartFactoryName(NameIndex factory)
const String & DartMethodName(NameIndex method)
const TypedDataView & metadata_payloads() const
const String & DartSymbolPlain(const char *content) const
DART_NORETURN void LookupFailed(NameIndex name)
virtual LibraryPtr LookupLibraryByKernelLibrary(NameIndex library, bool required=true)
FunctionPtr LookupConstructorByKernelConstructor(NameIndex constructor, bool required=true)
const String & DartGetterName(NameIndex getter)
void SetupFieldAccessorFunction(const Class &klass, const Function &function, const AbstractType &field_type)
const String & DartSymbolObfuscate(const char *content) const
bool StringEquals(StringIndex string_index, const char *other)
StringIndex CanonicalNameString(NameIndex name)
void SetStringOffsets(const TypedData &string_offsets)
const String & DartFieldName(NameIndex field)
void SetConstants(const Array &constants)
void SetStringData(const TypedDataView &string_data)
ObjectPtr LookupMemberByMember(NameIndex kernel_name, bool required=true)
void SetMetadataPayloads(const TypedDataView &metadata_payloads)
virtual ClassPtr LookupClassByKernelClass(NameIndex klass, bool required=true)
TypeTranslator(KernelReaderHelper *helper, ConstantReader *constant_reader, ActiveClass *active_class, bool finalize=false, bool in_constant_context=false)
const TypeArguments & BuildTypeArguments(intptr_t length)
void SetupFunctionParameters(const Class &klass, const Function &function, bool is_method, bool is_closure, FunctionNodeHelper *function_node_helper)
const Type & ReceiverType(const Class &klass)
void LoadAndSetupTypeParameters(ActiveClass *active_class, const Function &function, const Class &parameterized_class, const FunctionType &parameterized_signature, intptr_t type_parameter_count)
const TypeArguments & BuildInstantiatedTypeArguments(const Class &receiver_class, intptr_t length)
void LoadAndSetupBounds(ActiveClass *active_class, const Function &function, const Class &parameterized_class, const FunctionType &parameterized_signature, intptr_t type_parameter_count)
UnboxingInfoMetadata * GetUnboxingInfoMetadata(intptr_t node_offset)
static constexpr uint8_t kMustUseStackCallingConventionFlag
static constexpr uint8_t kHasUnboxedParameterOrReturnValueFlag
static constexpr uint8_t kHasOverridesWithLessDirectParametersFlag
GrowableArray< UnboxingType > unboxed_args_info
const EmbeddedViewParams * params
#define ASSERT(E)
VkInstance instance
Definition main.cc:48
#define FATAL(error)
FlutterSemanticsFlag flags
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
static const uint8_t buffer[]
const uint8_t uint32_t uint32_t GError ** error
GAsyncResult * result
uint32_t uint32_t * format
uint32_t * target
Dart_NativeFunction function
Definition fuchsia.cc:51
size_t length
union flutter::testing::@2838::KeyboardChange::@76 content
Win32Message message
static void SetupUnboxingInfoOfParameter(const Function &function, intptr_t param_index, const UnboxingInfoMetadata *metadata)
static constexpr int SourceTableFieldCountFromFirstLibraryOffset
static constexpr int LibraryCountFieldCountFromEnd
static void SetupUnboxingInfoOfReturnValue(const Function &function, const UnboxingInfoMetadata *metadata)
static const char *const names[]
Definition symbols.cc:24
const char *const name
Nullability
Definition object.h:1112
const char *const class_name
@ kIllegalCid
Definition class_id.h:214
@ kDynamicCid
Definition class_id.h:253
const intptr_t cid
constexpr intptr_t kWordSize
Definition globals.h:509
constexpr intptr_t kIntptrMax
Definition globals.h:557
#define FALL_THROUGH
Definition globals.h:15
Point offset
Definition SkMD5.cpp:130
const uintptr_t id