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
5#ifndef RUNTIME_VM_COMPILER_FRONTEND_KERNEL_TRANSLATION_HELPER_H_
6#define RUNTIME_VM_COMPILER_FRONTEND_KERNEL_TRANSLATION_HELPER_H_
7
8#if defined(DART_PRECOMPILED_RUNTIME)
9#error "AOT runtime should not use compiler sources (including header files)"
10#endif // defined(DART_PRECOMPILED_RUNTIME)
11
12#include "vm/compiler/backend/il.h" // For CompileType.
13#include "vm/kernel.h"
14#include "vm/kernel_binary.h"
15#include "vm/object.h"
16
17namespace dart {
18namespace kernel {
19
20class ConstantReader;
21class KernelReaderHelper;
22class TypeTranslator;
23
24class TranslationHelper {
25 public:
26 explicit TranslationHelper(Thread* thread);
27
28 TranslationHelper(Thread* thread, Heap::Space space);
29
30 virtual ~TranslationHelper() {}
31
32 void Reset();
33
34 void InitFromScript(const Script& script);
35
36 void InitFromKernelProgramInfo(const KernelProgramInfo& info);
37
38 Thread* thread() { return thread_; }
39
40 Zone* zone() { return zone_; }
41
42 Isolate* isolate() { return isolate_; }
43
44 Heap::Space allocation_space() { return allocation_space_; }
45
46 // Access to strings.
47 const TypedData& string_offsets() const { return string_offsets_; }
48 void SetStringOffsets(const TypedData& string_offsets);
49
50 const ExternalTypedData& string_data() const { return string_data_; }
51 void SetStringData(const ExternalTypedData& string_data);
52
53 const TypedData& canonical_names() const { return canonical_names_; }
54 void SetCanonicalNames(const TypedData& canonical_names);
55
56 const ExternalTypedData& metadata_payloads() const {
57 return metadata_payloads_;
58 }
59 void SetMetadataPayloads(const ExternalTypedData& metadata_payloads);
60
61 const ExternalTypedData& metadata_mappings() const {
62 return metadata_mappings_;
63 }
64 void SetMetadataMappings(const ExternalTypedData& metadata_mappings);
65
66 // Access to previously evaluated constants from the constants table.
67 const Array& constants() { return constants_; }
68 void SetConstants(const Array& constants);
69
70 // Access to the raw bytes of the constants table.
71 const ExternalTypedData& constants_table() const { return constants_table_; }
72 void SetConstantsTable(const ExternalTypedData& constants_table);
73
74 KernelProgramInfo& info() { return info_; }
75
76 GrowableObjectArrayPtr EnsurePotentialPragmaFunctions();
77
78 void AddPotentialExtensionLibrary(const Library& library);
79 GrowableObjectArrayPtr GetPotentialExtensionLibraries();
80
81 void SetKernelProgramInfo(const KernelProgramInfo& info);
82 const KernelProgramInfo& GetKernelProgramInfo() const { return info_; }
83
84 intptr_t StringOffset(StringIndex index) const;
85 intptr_t StringSize(StringIndex index) const;
86
87 // The address of the backing store of the string with a given index. If the
88 // backing store is in the VM's heap this address is not safe for GC (call the
89 // function and use the result within a NoSafepointScope).
90 uint8_t* StringBuffer(StringIndex index) const;
91
92 uint8_t CharacterAt(StringIndex string_index, intptr_t index);
93 bool StringEquals(StringIndex string_index, const char* other);
94
95 // Accessors and predicates for canonical names.
96 NameIndex CanonicalNameParent(NameIndex name);
97 StringIndex CanonicalNameString(NameIndex name);
98 bool IsAdministrative(NameIndex name);
99 bool IsPrivate(NameIndex name);
100 bool IsRoot(NameIndex name);
101 bool IsLibrary(NameIndex name);
102 bool IsClass(NameIndex name);
103 bool IsMember(NameIndex name);
104 bool IsField(NameIndex name);
105 bool IsConstructor(NameIndex name);
106 bool IsProcedure(NameIndex name);
107 bool IsMethod(NameIndex name);
108 bool IsGetter(NameIndex name);
109 bool IsSetter(NameIndex name);
110 bool IsFactory(NameIndex name);
111
112 // For a member (field, constructor, or procedure) return the canonical name
113 // of the enclosing class or library.
114 NameIndex EnclosingName(NameIndex name);
115
116 InstancePtr Canonicalize(const Instance& instance);
117
118 const String& DartString(const char* content) {
119 return DartString(content, allocation_space_);
120 }
121 const String& DartString(const char* content, Heap::Space space);
122
123 String& DartString(StringIndex index) {
124 return DartString(index, allocation_space_);
125 }
126 String& DartString(StringIndex string_index, Heap::Space space);
127
128 String& DartString(const uint8_t* utf8_array,
129 intptr_t len,
130 Heap::Space space);
131
132 const String& DartSymbolPlain(const char* content) const;
133 String& DartSymbolPlain(StringIndex string_index) const;
134 const String& DartSymbolObfuscate(const char* content) const;
135 String& DartSymbolObfuscate(StringIndex string_index) const;
136
137 String& DartIdentifier(const Library& lib, StringIndex string_index);
138
139 const String& DartClassName(NameIndex kernel_class);
140
141 const String& DartConstructorName(NameIndex constructor);
142
143 const String& DartProcedureName(NameIndex procedure);
144
145 const String& DartSetterName(NameIndex setter);
146 const String& DartSetterName(NameIndex parent, StringIndex setter);
147
148 const String& DartGetterName(NameIndex getter);
149 const String& DartGetterName(NameIndex parent, StringIndex getter);
150
151 const String& DartFieldName(NameIndex field);
152 const String& DartFieldName(NameIndex parent, StringIndex field);
153
154 const String& DartMethodName(NameIndex method);
155 const String& DartMethodName(NameIndex parent, StringIndex method);
156
157 const String& DartFactoryName(NameIndex factory);
158
159 // A subclass overrides these when reading in the Kernel program in order to
160 // support recursive type expressions (e.g. for "implements X" ...
161 // annotations).
162 virtual LibraryPtr LookupLibraryByKernelLibrary(NameIndex library);
163 virtual ClassPtr LookupClassByKernelClass(NameIndex klass);
164
165 FieldPtr LookupFieldByKernelField(NameIndex field);
166 FunctionPtr LookupStaticMethodByKernelProcedure(NameIndex procedure);
167 FunctionPtr LookupConstructorByKernelConstructor(NameIndex constructor);
168 FunctionPtr LookupConstructorByKernelConstructor(const Class& owner,
169 NameIndex constructor);
170 FunctionPtr LookupConstructorByKernelConstructor(
171 const Class& owner,
172 StringIndex constructor_name);
173 FunctionPtr LookupMethodByMember(NameIndex target, const String& method_name);
174 FunctionPtr LookupDynamicFunction(const Class& klass, const String& name);
175
176 Type& GetDeclarationType(const Class& klass);
177
178 void SetupFieldAccessorFunction(const Class& klass,
179 const Function& function,
180 const AbstractType& field_type);
181
182 void ReportError(const char* format, ...) PRINTF_ATTRIBUTE(2, 3);
183 void ReportError(const Script& script,
184 const TokenPosition position,
185 const char* format,
186 ...) PRINTF_ATTRIBUTE(4, 5);
187 void ReportError(const Error& prev_error, const char* format, ...)
188 PRINTF_ATTRIBUTE(3, 4);
189 void ReportError(const Error& prev_error,
190 const Script& script,
191 const TokenPosition position,
192 const char* format,
193 ...) PRINTF_ATTRIBUTE(5, 6);
194
195 ArrayPtr GetBytecodeComponent() const { return info_.bytecode_component(); }
196 void SetBytecodeComponent(const Array& bytecode_component) {
197 info_.set_bytecode_component(bytecode_component);
198 }
199
200 void SetExpressionEvaluationFunction(const Function& function) {
201 ASSERT(expression_evaluation_function_ == nullptr);
202 expression_evaluation_function_ = &Function::Handle(zone_, function.raw());
203 }
204 const Function& GetExpressionEvaluationFunction() {
205 if (expression_evaluation_function_ == nullptr) {
206 return Function::null_function();
207 }
208 return *expression_evaluation_function_;
209 }
210 void SetExpressionEvaluationRealClass(const Class& real_class) {
211 ASSERT(expression_evaluation_real_class_ == nullptr);
212 ASSERT(!real_class.IsNull());
213 expression_evaluation_real_class_ = &Class::Handle(zone_, real_class.raw());
214 }
215 ClassPtr GetExpressionEvaluationRealClass() {
216 ASSERT(expression_evaluation_real_class_ != nullptr);
217 return expression_evaluation_real_class_->raw();
218 }
219
220 private:
221 // This will mangle [name_to_modify] if necessary and make the result a symbol
222 // if asked. The result will be available in [name_to_modify] and it is also
223 // returned. If the name is private, the canonical name [parent] will be used
224 // to get the import URI of the library where the name is visible.
225 String& ManglePrivateName(NameIndex parent,
226 String* name_to_modify,
227 bool symbolize = true,
228 bool obfuscate = true);
229 String& ManglePrivateName(const Library& library,
230 String* name_to_modify,
231 bool symbolize = true,
232 bool obfuscate = true);
233
234 Thread* thread_;
235 Zone* zone_;
236 Isolate* isolate_;
237 Heap::Space allocation_space_;
238
239 TypedData& string_offsets_;
240 ExternalTypedData& string_data_;
241 TypedData& canonical_names_;
242 ExternalTypedData& metadata_payloads_;
243 ExternalTypedData& metadata_mappings_;
244 Array& constants_;
245 ExternalTypedData& constants_table_;
246 KernelProgramInfo& info_;
247 Smi& name_index_handle_;
248 GrowableObjectArray* potential_extension_libraries_ = nullptr;
249 Function* expression_evaluation_function_ = nullptr;
250 Class* expression_evaluation_real_class_ = nullptr;
251
252 DISALLOW_COPY_AND_ASSIGN(TranslationHelper);
253};
254
255// Helper class that reads a kernel FunctionNode from binary.
256//
257// Use ReadUntilExcluding to read up to but not including a field.
258// One can then for instance read the field from the call-site (and remember to
259// call SetAt to inform this helper class), and then use this to read more.
260// Simple fields are stored (e.g. integers) and can be fetched from this class.
261// If asked to read a compound field (e.g. an expression) it will be skipped.
262class FunctionNodeHelper {
263 public:
264 enum Field {
265 kStart, // tag.
266 kPosition,
267 kEndPosition,
268 kAsyncMarker,
269 kDartAsyncMarker,
270 kTypeParameters,
271 kTotalParameterCount,
272 kRequiredParameterCount,
273 kPositionalParameters,
274 kNamedParameters,
275 kReturnType,
276 kBody,
277 kEnd,
278 };
279
280 enum AsyncMarker : intptr_t {
281 kSync = 0,
282 kSyncStar = 1,
283 kAsync = 2,
284 kAsyncStar = 3,
285 kSyncYielding = 4,
286 };
287
288 explicit FunctionNodeHelper(KernelReaderHelper* helper) {
289 helper_ = helper;
290 next_read_ = kStart;
291 }
292
293 void ReadUntilIncluding(Field field) {
294 ReadUntilExcluding(static_cast<Field>(static_cast<int>(field) + 1));
295 }
296
297 void ReadUntilExcluding(Field field);
298
299 void SetNext(Field field) { next_read_ = field; }
300 void SetJustRead(Field field) { next_read_ = field + 1; }
301
302 TokenPosition position_;
303 TokenPosition end_position_;
304 AsyncMarker async_marker_;
305 AsyncMarker dart_async_marker_;
306 intptr_t total_parameter_count_ = 0;
307 intptr_t required_parameter_count_ = 0;
308
309 private:
310 KernelReaderHelper* helper_;
311 intptr_t next_read_;
312
313 DISALLOW_COPY_AND_ASSIGN(FunctionNodeHelper);
314};
315
316class TypeParameterHelper {
317 public:
318 enum Field {
319 kStart, // tag.
320 kFlags,
321 kAnnotations,
322 kVariance,
323 kName,
324 kBound,
325 kDefaultType,
326 kEnd,
327 };
328
329 enum Flag {
330 kIsGenericCovariantImpl = 1 << 0,
331 };
332
333 explicit TypeParameterHelper(KernelReaderHelper* helper) {
334 helper_ = helper;
335 next_read_ = kStart;
336 }
337
338 void ReadUntilIncluding(Field field) {
339 ReadUntilExcluding(static_cast<Field>(static_cast<int>(field) + 1));
340 }
341
342 void ReadUntilExcluding(Field field);
343
344 void SetNext(Field field) { next_read_ = field; }
345 void SetJustRead(Field field) { next_read_ = field + 1; }
346
347 void ReadUntilExcludingAndSetJustRead(Field field) {
348 ReadUntilExcluding(field);
349 SetJustRead(field);
350 }
351
352 void Finish() { ReadUntilExcluding(kEnd); }
353
354 bool IsGenericCovariantImpl() {
355 return (flags_ & kIsGenericCovariantImpl) != 0;
356 }
357
358 TokenPosition position_;
359 uint8_t flags_ = 0;
360 StringIndex name_index_;
361
362 private:
363 KernelReaderHelper* helper_;
364 intptr_t next_read_;
365
366 DISALLOW_COPY_AND_ASSIGN(TypeParameterHelper);
367};
368
369// Helper class that reads a kernel VariableDeclaration from binary.
370//
371// Use ReadUntilExcluding to read up to but not including a field.
372// One can then for instance read the field from the call-site (and remember to
373// call SetAt to inform this helper class), and then use this to read more.
374// Simple fields are stored (e.g. integers) and can be fetched from this class.
375// If asked to read a compound field (e.g. an expression) it will be skipped.
376class VariableDeclarationHelper {
377 public:
378 enum Field {
379 kPosition,
380 kEqualPosition,
381 kAnnotations,
382 kFlags,
383 kNameIndex,
384 kType,
385 kInitializer,
386 kEnd,
387 };
388
389 enum Flag {
390 kFinal = 1 << 0,
391 kConst = 1 << 1,
392 kCovariant = 1 << 3,
393 kIsGenericCovariantImpl = 1 << 5,
394 kLate = 1 << 6,
395 kRequired = 1 << 7,
396 };
397
398 explicit VariableDeclarationHelper(KernelReaderHelper* helper)
399 : annotation_count_(0), helper_(helper), next_read_(kPosition) {}
400
401 void ReadUntilIncluding(Field field) {
402 ReadUntilExcluding(static_cast<Field>(static_cast<int>(field) + 1));
403 }
404
405 void ReadUntilExcluding(Field field);
406
407 void SetNext(Field field) { next_read_ = field; }
408 void SetJustRead(Field field) { next_read_ = field + 1; }
409
410 bool IsConst() const { return (flags_ & kConst) != 0; }
411 bool IsFinal() const { return (flags_ & kFinal) != 0; }
412 bool IsCovariant() const { return (flags_ & kCovariant) != 0; }
413 bool IsLate() const { return (flags_ & kLate) != 0; }
414 bool IsRequired() const { return (flags_ & kRequired) != 0; }
415
416 bool IsGenericCovariantImpl() const {
417 return (flags_ & kIsGenericCovariantImpl) != 0;
418 }
419
420 TokenPosition position_;
421 TokenPosition equals_position_;
422 uint8_t flags_ = 0;
423 StringIndex name_index_;
424 intptr_t annotation_count_ = 0;
425
426 private:
427 KernelReaderHelper* helper_;
428 intptr_t next_read_;
429
430 DISALLOW_COPY_AND_ASSIGN(VariableDeclarationHelper);
431};
432
433// Helper class that reads a kernel Field from binary.
434//
435// Use ReadUntilExcluding to read up to but not including a field.
436// One can then for instance read the field from the call-site (and remember to
437// call SetAt to inform this helper class), and then use this to read more.
438// Simple fields are stored (e.g. integers) and can be fetched from this class.
439// If asked to read a compound field (e.g. an expression) it will be skipped.
440class FieldHelper {
441 public:
442 enum Field {
443 kStart, // tag.
444 kCanonicalName,
445 kSourceUriIndex,
446 kPosition,
447 kEndPosition,
448 kFlags,
449 kName,
450 kAnnotations,
451 kType,
452 kInitializer,
453 kEnd,
454 };
455
456 enum Flag {
457 kFinal = 1 << 0,
458 kConst = 1 << 1,
459 kStatic = 1 << 2,
460 kIsCovariant = 1 << 5,
461 kIsGenericCovariantImpl = 1 << 6,
462 kIsLate = 1 << 7,
463 kExtensionMember = 1 << 8,
464 };
465
466 explicit FieldHelper(KernelReaderHelper* helper)
467 : helper_(helper), next_read_(kStart) {}
468
469 FieldHelper(KernelReaderHelper* helper, intptr_t offset);
470
471 void ReadUntilIncluding(Field field) {
472 ReadUntilExcluding(static_cast<Field>(static_cast<int>(field) + 1));
473 }
474
475 void ReadUntilExcluding(Field field);
476
477 void SetNext(Field field) { next_read_ = field; }
478 void SetJustRead(Field field) { next_read_ = field + 1; }
479
480 bool IsConst() { return (flags_ & kConst) != 0; }
481 bool IsFinal() { return (flags_ & kFinal) != 0; }
482 bool IsStatic() { return (flags_ & kStatic) != 0; }
483 bool IsCovariant() const { return (flags_ & kIsCovariant) != 0; }
484 bool IsGenericCovariantImpl() {
485 return (flags_ & kIsGenericCovariantImpl) != 0;
486 }
487 bool IsLate() const { return (flags_ & kIsLate) != 0; }
488 bool IsExtensionMember() const { return (flags_ & kExtensionMember) != 0; }
489
490 NameIndex canonical_name_;
491 TokenPosition position_;
492 TokenPosition end_position_;
493 uint32_t flags_ = 0;
494 intptr_t source_uri_index_ = 0;
495 intptr_t annotation_count_ = 0;
496
497 private:
498 KernelReaderHelper* helper_;
499 intptr_t next_read_;
500
501 DISALLOW_COPY_AND_ASSIGN(FieldHelper);
502};
503
504// Helper class that reads a kernel Procedure from binary.
505//
506// Use ReadUntilExcluding to read up to but not including a field.
507// One can then for instance read the field from the call-site (and remember to
508// call SetAt to inform this helper class), and then use this to read more.
509// Simple fields are stored (e.g. integers) and can be fetched from this class.
510// If asked to read a compound field (e.g. an expression) it will be skipped.
511class ProcedureHelper {
512 public:
513 enum Field {
514 kStart, // tag.
515 kCanonicalName,
516 kSourceUriIndex,
517 kStartPosition,
518 kPosition,
519 kEndPosition,
520 kKind,
521 kFlags,
522 kName,
523 kAnnotations,
524 kForwardingStubSuperTarget,
525 kForwardingStubInterfaceTarget,
526 kMemberSignatureTarget,
527 kFunction,
528 kEnd,
529 };
530
531 enum Kind {
532 kMethod,
533 kGetter,
534 kSetter,
535 kOperator,
536 kFactory,
537 };
538
539 enum Flag {
540 kStatic = 1 << 0,
541 kAbstract = 1 << 1,
542 kExternal = 1 << 2,
543 kConst = 1 << 3, // Only for external const factories.
544 kForwardingStub = 1 << 4,
545
546 // TODO(29841): Remove this line after the issue is resolved.
547 kRedirectingFactoryConstructor = 1 << 6,
548 kNoSuchMethodForwarder = 1 << 7,
549 kExtensionMember = 1 << 8,
550 kMemberSignature = 1 << 9,
551 };
552
553 explicit ProcedureHelper(KernelReaderHelper* helper)
554 : helper_(helper), next_read_(kStart) {}
555
556 void ReadUntilIncluding(Field field) {
557 ReadUntilExcluding(static_cast<Field>(static_cast<int>(field) + 1));
558 }
559
560 void ReadUntilExcluding(Field field);
561
562 void SetNext(Field field) { next_read_ = field; }
563 void SetJustRead(Field field) { next_read_ = field + 1; }
564
565 bool IsStatic() const { return (flags_ & kStatic) != 0; }
566 bool IsAbstract() const { return (flags_ & kAbstract) != 0; }
567 bool IsExternal() const { return (flags_ & kExternal) != 0; }
568 bool IsConst() const { return (flags_ & kConst) != 0; }
569 bool IsForwardingStub() const { return (flags_ & kForwardingStub) != 0; }
570 bool IsRedirectingFactoryConstructor() const {
571 return (flags_ & kRedirectingFactoryConstructor) != 0;
572 }
573 bool IsNoSuchMethodForwarder() const {
574 return (flags_ & kNoSuchMethodForwarder) != 0;
575 }
576 bool IsExtensionMember() const { return (flags_ & kExtensionMember) != 0; }
577 bool IsMemberSignature() const { return (flags_ & kMemberSignature) != 0; }
578
579 NameIndex canonical_name_;
580 TokenPosition start_position_;
581 TokenPosition position_;
582 TokenPosition end_position_;
583 Kind kind_;
584 uint32_t flags_ = 0;
585 intptr_t source_uri_index_ = 0;
586 intptr_t annotation_count_ = 0;
587
588 // Only valid if the 'isForwardingStub' flag is set.
589 NameIndex forwarding_stub_super_target_;
590
591 private:
592 KernelReaderHelper* helper_;
593 intptr_t next_read_;
594
595 DISALLOW_COPY_AND_ASSIGN(ProcedureHelper);
596};
597
598// Helper class that reads a kernel Constructor from binary.
599//
600// Use ReadUntilExcluding to read up to but not including a field.
601// One can then for instance read the field from the call-site (and remember to
602// call SetAt to inform this helper class), and then use this to read more.
603// Simple fields are stored (e.g. integers) and can be fetched from this class.
604// If asked to read a compound field (e.g. an expression) it will be skipped.
605class ConstructorHelper {
606 public:
607 enum Field {
608 kStart, // tag.
609 kCanonicalName,
610 kSourceUriIndex,
611 kStartPosition,
612 kPosition,
613 kEndPosition,
614 kFlags,
615 kName,
616 kAnnotations,
617 kFunction,
618 kInitializers,
619 kEnd,
620 };
621
622 enum Flag {
623 kConst = 1 << 0,
624 kExternal = 1 << 1,
625 kSynthetic = 1 << 2,
626 };
627
628 explicit ConstructorHelper(KernelReaderHelper* helper)
629 : helper_(helper), next_read_(kStart) {}
630
631 void ReadUntilIncluding(Field field) {
632 ReadUntilExcluding(static_cast<Field>(static_cast<int>(field) + 1));
633 }
634
635 void ReadUntilExcluding(Field field);
636
637 void SetNext(Field field) { next_read_ = field; }
638 void SetJustRead(Field field) { next_read_ = field + 1; }
639
640 bool IsExternal() { return (flags_ & kExternal) != 0; }
641 bool IsConst() { return (flags_ & kConst) != 0; }
642 bool IsSynthetic() { return (flags_ & kSynthetic) != 0; }
643
644 NameIndex canonical_name_;
645 TokenPosition start_position_;
646 TokenPosition position_;
647 TokenPosition end_position_;
648 uint8_t flags_ = 0;
649 intptr_t source_uri_index_ = 0;
650 intptr_t annotation_count_ = 0;
651
652 private:
653 KernelReaderHelper* helper_;
654 intptr_t next_read_;
655
656 DISALLOW_COPY_AND_ASSIGN(ConstructorHelper);
657};
658
659// Helper class that reads a kernel Class from binary.
660//
661// Use ReadUntilExcluding to read up to but not including a field.
662// One can then for instance read the field from the call-site (and remember to
663// call SetAt to inform this helper class), and then use this to read more.
664// Simple fields are stored (e.g. integers) and can be fetched from this class.
665// If asked to read a compound field (e.g. an expression) it will be skipped.
666class ClassHelper {
667 public:
668 enum Field {
669 kStart, // tag.
670 kCanonicalName,
671 kSourceUriIndex,
672 kStartPosition,
673 kPosition,
674 kEndPosition,
675 kFlags,
676 kNameIndex,
677 kAnnotations,
678 kTypeParameters,
679 kSuperClass,
680 kMixinType,
681 kImplementedClasses,
682 kFields,
683 kConstructors,
684 kProcedures,
685 kClassIndex,
686 kEnd,
687 };
688
689 enum Flag {
690 kIsAbstract = 1 << 2,
691 kIsEnumClass = 1 << 3,
692 kIsAnonymousMixin = 1 << 4,
693 kIsEliminatedMixin = 1 << 5,
694 kFlagMixinDeclaration = 1 << 6,
695 kHasConstConstructor = 1 << 7,
696 };
697
698 explicit ClassHelper(KernelReaderHelper* helper)
699 : helper_(helper), next_read_(kStart) {}
700
701 void ReadUntilIncluding(Field field) {
702 ReadUntilExcluding(static_cast<Field>(static_cast<int>(field) + 1));
703 }
704
705 void ReadUntilExcluding(Field field);
706
707 void SetNext(Field field) { next_read_ = field; }
708 void SetJustRead(Field field) { next_read_ = field + 1; }
709
710 bool is_abstract() const { return (flags_ & Flag::kIsAbstract) != 0; }
711
712 bool is_enum_class() const { return (flags_ & Flag::kIsEnumClass) != 0; }
713
714 bool is_transformed_mixin_application() const {
715 return (flags_ & Flag::kIsEliminatedMixin) != 0;
716 }
717
718 bool has_const_constructor() const {
719 return (flags_ & Flag::kHasConstConstructor) != 0;
720 }
721
722 NameIndex canonical_name_;
723 TokenPosition start_position_;
724 TokenPosition position_;
725 TokenPosition end_position_;
726 StringIndex name_index_;
727 intptr_t source_uri_index_ = 0;
728 intptr_t annotation_count_ = 0;
729 intptr_t procedure_count_ = 0;
730 uint8_t flags_ = 0;
731
732 private:
733 KernelReaderHelper* helper_;
734 intptr_t next_read_;
735
736 DISALLOW_COPY_AND_ASSIGN(ClassHelper);
737};
738
739// Helper class that reads a kernel Library from binary.
740//
741// Use ReadUntilExcluding to read up to but not including a field.
742// One can then for instance read the field from the call-site (and remember to
743// call SetAt to inform this helper class), and then use this to read more.
744// Simple fields are stored (e.g. integers) and can be fetched from this class.
745// If asked to read a compound field (e.g. an expression) it will be skipped.
746class LibraryHelper {
747 public:
748 enum Field {
749 kFlags,
750 kLanguageVersion /* from binary version 27 */,
751 kCanonicalName,
752 kName,
753 kSourceUriIndex,
754 kProblemsAsJson,
755 kAnnotations,
756 kDependencies,
757 // There are other fields in a library:
758 // * kAdditionalExports
759 // * kParts
760 // * kTypedefs
761 // * kClasses
762 // * kToplevelField
763 // * kToplevelProcedures
764 // * kSourceReferences
765 // * kLibraryIndex
766 // but we never read them via this helper and it makes extending the format
767 // harder to keep the code around.
768 };
769
770 enum Flag {
771 kExternal = 1 << 0,
772 kSynthetic = 1 << 1,
773 kIsNonNullableByDefault = 1 << 2,
774 kNonNullableByDefaultCompiledModeBit1Weak = 1 << 3,
775 kNonNullableByDefaultCompiledModeBit2Strong = 1 << 4,
776 };
777
778 explicit LibraryHelper(KernelReaderHelper* helper, uint32_t binary_version)
779 : helper_(helper), binary_version_(binary_version), next_read_(kFlags) {}
780
781 void ReadUntilIncluding(Field field) {
782 ReadUntilExcluding(static_cast<Field>(static_cast<int>(field) + 1));
783 }
784
785 void ReadUntilExcluding(Field field);
786
787 void SetNext(Field field) { next_read_ = field; }
788 void SetJustRead(Field field) { next_read_ = field + 1; }
789
790 bool IsExternal() const { return (flags_ & kExternal) != 0; }
791 bool IsSynthetic() const { return (flags_ & kSynthetic) != 0; }
792 bool IsNonNullableByDefault() const {
793 return (flags_ & kIsNonNullableByDefault) != 0;
794 }
795 NNBDCompiledMode GetNonNullableByDefaultCompiledMode() const {
796 bool weak = (flags_ & kNonNullableByDefaultCompiledModeBit1Weak) != 0;
797 bool strong = (flags_ & kNonNullableByDefaultCompiledModeBit2Strong) != 0;
798 if (weak && strong) return NNBDCompiledMode::kAgnostic;
799 if (strong) return NNBDCompiledMode::kStrong;
800 if (weak) return NNBDCompiledMode::kWeak;
801 return NNBDCompiledMode::kDisabled;
802 }
803
804 uint8_t flags_ = 0;
805 NameIndex canonical_name_;
806 StringIndex name_index_;
807 intptr_t source_uri_index_ = 0;
808
809 private:
810 KernelReaderHelper* helper_;
811 uint32_t binary_version_;
812 intptr_t next_read_;
813
814 DISALLOW_COPY_AND_ASSIGN(LibraryHelper);
815};
816
817class LibraryDependencyHelper {
818 public:
819 enum Field {
820 kFileOffset,
821 kFlags,
822 kAnnotations,
823 kTargetLibrary,
824 kName,
825 kCombinators,
826 kEnd,
827 };
828
829 enum Flag {
830 Export = 1 << 0,
831 Deferred = 1 << 1,
832 };
833
834 enum CombinatorFlag {
835 Show = 1 << 0,
836 };
837
838 explicit LibraryDependencyHelper(KernelReaderHelper* helper)
839 : helper_(helper), next_read_(kFileOffset) {}
840
841 void ReadUntilIncluding(Field field) {
842 ReadUntilExcluding(static_cast<Field>(static_cast<int>(field) + 1));
843 }
844
845 void ReadUntilExcluding(Field field);
846
847 uint8_t flags_ = 0;
848 StringIndex name_index_;
849 NameIndex target_library_canonical_name_;
850 intptr_t annotation_count_ = 0;
851
852 private:
853 KernelReaderHelper* helper_;
854 intptr_t next_read_;
855
856 DISALLOW_COPY_AND_ASSIGN(LibraryDependencyHelper);
857};
858
859// Base class for helpers accessing metadata of a certain kind.
860// Assumes that metadata is accessed in linear order.
861class MetadataHelper {
862 public:
863 MetadataHelper(KernelReaderHelper* helper,
864 const char* tag,
865 bool precompiler_only);
866
867#if defined(DEBUG)
868 static void VerifyMetadataMappings(
869 const ExternalTypedData& metadata_mappings);
870#endif
871
872 protected:
873 // Look for metadata mapping with node offset greater or equal than the given.
874 intptr_t FindMetadataMapping(intptr_t node_offset);
875
876 // Return offset of the metadata payload corresponding to the given node,
877 // or -1 if there is no metadata.
878 // Assumes metadata is accesses for nodes in linear order most of the time.
879 intptr_t GetNextMetadataPayloadOffset(intptr_t node_offset);
880
881 // Returns metadata associated with component.
882 intptr_t GetComponentMetadataPayloadOffset();
883
884 KernelReaderHelper* helper_;
885 TranslationHelper& translation_helper_;
886
887 private:
888 MetadataHelper();
889
890 void SetMetadataMappings(intptr_t mappings_offset, intptr_t mappings_num);
891 void ScanMetadataMappings();
892
893 const char* tag_;
894 bool mappings_scanned_;
895 bool precompiler_only_;
896 intptr_t mappings_offset_;
897 intptr_t mappings_num_;
898 intptr_t last_node_offset_;
899 intptr_t last_mapping_index_;
900
901 DISALLOW_COPY_AND_ASSIGN(MetadataHelper);
902};
903
904struct DirectCallMetadata {
905 DirectCallMetadata(const Function& target, bool check_receiver_for_null)
906 : target_(target), check_receiver_for_null_(check_receiver_for_null) {}
907
908 const Function& target_;
909 const bool check_receiver_for_null_;
910};
911
912// Helper class which provides access to direct call metadata.
913class DirectCallMetadataHelper : public MetadataHelper {
914 public:
915 static const char* tag() { return "vm.direct-call.metadata"; }
916
917 explicit DirectCallMetadataHelper(KernelReaderHelper* helper);
918
919 DirectCallMetadata GetDirectTargetForPropertyGet(intptr_t node_offset);
920 DirectCallMetadata GetDirectTargetForPropertySet(intptr_t node_offset);
921 DirectCallMetadata GetDirectTargetForMethodInvocation(intptr_t node_offset);
922
923 private:
924 bool ReadMetadata(intptr_t node_offset,
925 NameIndex* target_name,
926 bool* check_receiver_for_null);
927
928 DISALLOW_COPY_AND_ASSIGN(DirectCallMetadataHelper);
929};
930
931struct InferredTypeMetadata {
932 enum Flag {
933 kFlagNullable = 1 << 0,
934 kFlagInt = 1 << 1,
935 kFlagSkipCheck = 1 << 2,
936 kFlagConstant = 1 << 3,
937 kFlagReceiverNotInt = 1 << 4,
938 };
939
940 InferredTypeMetadata(intptr_t cid_,
941 uint8_t flags_,
942 const Object& constant_value_ = Object::null_object())
943 : cid(cid_), flags(flags_), constant_value(constant_value_) {}
944
945 const intptr_t cid;
946 const uint8_t flags;
947 const Object& constant_value;
948
949 bool IsTrivial() const {
950 return (cid == kDynamicCid) && (flags == kFlagNullable);
951 }
952 bool IsNullable() const { return (flags & kFlagNullable) != 0; }
953 bool IsInt() const {
954 return (flags & kFlagInt) != 0 || cid == kMintCid || cid == kSmiCid;
955 }
956 bool IsSkipCheck() const { return (flags & kFlagSkipCheck) != 0; }
957 bool IsConstant() const { return (flags & kFlagConstant) != 0; }
958 bool ReceiverNotInt() const { return (flags & kFlagReceiverNotInt) != 0; }
959
960 CompileType ToCompileType(Zone* zone) const {
961 if (IsInt() && cid == kDynamicCid) {
962 return CompileType::FromAbstractType(
963 Type::ZoneHandle(
964 zone, (IsNullable() ? Type::NullableIntType() : Type::IntType())),
965 IsNullable());
966 } else {
967 return CompileType::CreateNullable(IsNullable(), cid);
968 }
969 }
970};
971
972// Helper class which provides access to inferred type metadata.
973class InferredTypeMetadataHelper : public MetadataHelper {
974 public:
975 static const char* tag() { return "vm.inferred-type.metadata"; }
976
977 explicit InferredTypeMetadataHelper(KernelReaderHelper* helper,
978 ConstantReader* constant_reader);
979
980 InferredTypeMetadata GetInferredType(intptr_t node_offset,
981 bool read_constant = true);
982
983 private:
984 ConstantReader* constant_reader_;
985
986 DISALLOW_COPY_AND_ASSIGN(InferredTypeMetadataHelper);
987};
988
989struct ProcedureAttributesMetadata {
990 static const int32_t kInvalidSelectorId = 0;
991
992 bool method_or_setter_called_dynamically = true;
993 bool getter_called_dynamically = true;
994 bool has_this_uses = true;
995 bool has_non_this_uses = true;
996 bool has_tearoff_uses = true;
997 int32_t method_or_setter_selector_id = kInvalidSelectorId;
998 int32_t getter_selector_id = kInvalidSelectorId;
999
1000 void InitializeFromFlags(uint8_t flags);
1001};
1002
1003// Helper class which provides access to direct call metadata.
1004class ProcedureAttributesMetadataHelper : public MetadataHelper {
1005 public:
1006 static const char* tag() { return "vm.procedure-attributes.metadata"; }
1007
1008 explicit ProcedureAttributesMetadataHelper(KernelReaderHelper* helper);
1009
1010 ProcedureAttributesMetadata GetProcedureAttributes(intptr_t node_offset);
1011
1012 private:
1013 bool ReadMetadata(intptr_t node_offset,
1014 ProcedureAttributesMetadata* metadata);
1015
1016 DISALLOW_COPY_AND_ASSIGN(ProcedureAttributesMetadataHelper);
1017};
1018
1019class ObfuscationProhibitionsMetadataHelper : public MetadataHelper {
1020 public:
1021 static const char* tag() { return "vm.obfuscation-prohibitions.metadata"; }
1022
1023 explicit ObfuscationProhibitionsMetadataHelper(KernelReaderHelper* helper);
1024
1025 void ReadProhibitions() { ReadMetadata(0); }
1026
1027 private:
1028 void ReadMetadata(intptr_t node_offset);
1029
1030 DISALLOW_COPY_AND_ASSIGN(ObfuscationProhibitionsMetadataHelper);
1031};
1032
1033class LoadingUnitsMetadataHelper : public MetadataHelper {
1034 public:
1035 static const char* tag() { return "vm.loading-units.metadata"; }
1036
1037 explicit LoadingUnitsMetadataHelper(KernelReaderHelper* helper);
1038
1039 void ReadLoadingUnits() { ReadMetadata(0); }
1040
1041 private:
1042 void ReadMetadata(intptr_t node_offset);
1043
1044 DISALLOW_COPY_AND_ASSIGN(LoadingUnitsMetadataHelper);
1045};
1046
1047struct CallSiteAttributesMetadata {
1048 const AbstractType* receiver_type = nullptr;
1049};
1050
1051// Helper class which provides access to direct call metadata.
1052class CallSiteAttributesMetadataHelper : public MetadataHelper {
1053 public:
1054 static const char* tag() { return "vm.call-site-attributes.metadata"; }
1055
1056 CallSiteAttributesMetadataHelper(KernelReaderHelper* helper,
1057 TypeTranslator* type_translator);
1058
1059 CallSiteAttributesMetadata GetCallSiteAttributes(intptr_t node_offset);
1060
1061 private:
1062 bool ReadMetadata(intptr_t node_offset, CallSiteAttributesMetadata* metadata);
1063
1064 TypeTranslator& type_translator_;
1065
1066 DISALLOW_COPY_AND_ASSIGN(CallSiteAttributesMetadataHelper);
1067};
1068
1069// Information about a table selector computed by the TFA.
1070struct TableSelectorInfo {
1071 int call_count = 0;
1072 bool called_on_null = true;
1073 bool torn_off = true;
1074};
1075
1076// Collection of table selector information for all selectors in the program.
1077class TableSelectorMetadata : public ZoneAllocated {
1078 public:
1079 explicit TableSelectorMetadata(intptr_t num_selectors)
1080 : selectors(num_selectors) {
1081 selectors.FillWith(TableSelectorInfo(), 0, num_selectors);
1082 }
1083
1084 GrowableArray<TableSelectorInfo> selectors;
1085
1086 DISALLOW_COPY_AND_ASSIGN(TableSelectorMetadata);
1087};
1088
1089// Helper class which provides access to table selector metadata.
1090class TableSelectorMetadataHelper : public MetadataHelper {
1091 public:
1092 static const char* tag() { return "vm.table-selector.metadata"; }
1093
1094 explicit TableSelectorMetadataHelper(KernelReaderHelper* helper);
1095
1096 TableSelectorMetadata* GetTableSelectorMetadata(Zone* zone);
1097
1098 private:
1099 static const uint8_t kCalledOnNullBit = 1 << 0;
1100 static const uint8_t kTornOffBit = 1 << 1;
1101
1102 void ReadTableSelectorInfo(TableSelectorInfo* info);
1103
1104 DISALLOW_COPY_AND_ASSIGN(TableSelectorMetadataHelper);
1105};
1106
1107// Information about a function regarding unboxed parameters and return value.
1108class UnboxingInfoMetadata : public ZoneAllocated {
1109 public:
1110 enum UnboxingInfoTag {
1111 kBoxed = 0,
1112 kUnboxedIntCandidate = 1 << 0,
1113 kUnboxedDoubleCandidate = 1 << 1,
1114 kUnboxingCandidate = kUnboxedIntCandidate | kUnboxedDoubleCandidate,
1115 };
1116
1117 UnboxingInfoMetadata() : unboxed_args_info(0) { return_info = kBoxed; }
1118
1119 void SetArgsCount(intptr_t num_args) {
1120 ASSERT(unboxed_args_info.is_empty());
1121 unboxed_args_info.SetLength(num_args);
1122 unboxed_args_info.FillWith(kBoxed, 0, num_args);
1123 }
1124
1125 GrowableArray<UnboxingInfoTag> unboxed_args_info;
1126 UnboxingInfoTag return_info;
1127
1128 DISALLOW_COPY_AND_ASSIGN(UnboxingInfoMetadata);
1129};
1130
1131// Helper class which provides access to unboxing information metadata.
1132class UnboxingInfoMetadataHelper : public MetadataHelper {
1133 public:
1134 static const char* tag() { return "vm.unboxing-info.metadata"; }
1135
1136 explicit UnboxingInfoMetadataHelper(KernelReaderHelper* helper);
1137
1138 UnboxingInfoMetadata* GetUnboxingInfoMetadata(intptr_t node_offset);
1139
1140 DISALLOW_COPY_AND_ASSIGN(UnboxingInfoMetadataHelper);
1141};
1142
1143class KernelReaderHelper {
1144 public:
1145 KernelReaderHelper(Zone* zone,
1146 TranslationHelper* translation_helper,
1147 const Script& script,
1148 const ExternalTypedData& data,
1149 intptr_t data_program_offset)
1150 : zone_(zone),
1151 translation_helper_(*translation_helper),
1152 reader_(data),
1153 script_(script),
1154 data_program_offset_(data_program_offset) {}
1155
1156 KernelReaderHelper(Zone* zone,
1157 TranslationHelper* translation_helper,
1158 const uint8_t* data_buffer,
1159 intptr_t buffer_length,
1160 intptr_t data_program_offset)
1161 : zone_(zone),
1162 translation_helper_(*translation_helper),
1163 reader_(data_buffer, buffer_length),
1164 script_(Script::Handle(zone_)),
1165 data_program_offset_(data_program_offset) {}
1166
1167 virtual ~KernelReaderHelper() = default;
1168
1169 void SetOffset(intptr_t offset);
1170
1171 intptr_t ReadListLength();
1172 virtual void ReportUnexpectedTag(const char* variant, Tag tag);
1173
1174 void ReadUntilFunctionNode();
1175
1176 Tag PeekTag(uint8_t* payload = NULL);
1177
1178 protected:
1179 const Script& script() const { return script_; }
1180
1181 virtual void set_current_script_id(intptr_t id) {
1182 // Do nothing by default.
1183 // This is overridden in KernelTokenPositionCollector.
1184 USE(id);
1185 }
1186
1187 virtual void RecordTokenPosition(TokenPosition position) {
1188 // Do nothing by default.
1189 // This is overridden in KernelTokenPositionCollector.
1190 USE(position);
1191 }
1192
1193 intptr_t ReaderOffset() const;
1194 void SkipBytes(intptr_t skip);
1195 bool ReadBool();
1196 uint8_t ReadByte();
1197 uint32_t ReadUInt();
1198 uint32_t ReadUInt32();
1199 uint32_t PeekUInt();
1200 double ReadDouble();
1201 uint32_t PeekListLength();
1202 StringIndex ReadStringReference();
1203 NameIndex ReadCanonicalNameReference();
1204 NameIndex ReadInterfaceMemberNameReference();
1205 StringIndex ReadNameAsStringIndex();
1206 const String& ReadNameAsMethodName();
1207 const String& ReadNameAsGetterName();
1208 const String& ReadNameAsSetterName();
1209 const String& ReadNameAsFieldName();
1210 void SkipFlags();
1211 void SkipStringReference();
1212 void SkipConstantReference();
1213 void SkipCanonicalNameReference();
1214 void SkipInterfaceMemberNameReference();
1215 void SkipDartType();
1216 void SkipOptionalDartType();
1217 void SkipInterfaceType(bool simple);
1218 void SkipFunctionType(bool simple);
1219 void SkipStatementList();
1220 void SkipListOfExpressions();
1221 void SkipListOfDartTypes();
1222 void SkipListOfStrings();
1223 void SkipListOfVariableDeclarations();
1224 void SkipTypeParametersList();
1225 void SkipInitializer();
1226 void SkipExpression();
1227 void SkipStatement();
1228 void SkipFunctionNode();
1229 void SkipName();
1230 void SkipArguments();
1231 void SkipVariableDeclaration();
1232 void SkipLibraryCombinator();
1233 void SkipLibraryDependency();
1234 void SkipLibraryPart();
1235 void SkipLibraryTypedef();
1236 TokenPosition ReadPosition();
1237 Tag ReadTag(uint8_t* payload = NULL);
1238 uint8_t ReadFlags() { return reader_.ReadFlags(); }
1239 Nullability ReadNullability();
1240 Variance ReadVariance();
1241
1242 intptr_t SourceTableFieldCountFromFirstLibraryOffset();
1243 intptr_t SourceTableSize();
1244 intptr_t GetOffsetForSourceInfo(intptr_t index);
1245 String& SourceTableUriFor(intptr_t index);
1246 const String& GetSourceFor(intptr_t index);
1247 TypedDataPtr GetLineStartsFor(intptr_t index);
1248 String& SourceTableImportUriFor(intptr_t index, uint32_t binaryVersion);
1249
1250 Zone* zone_;
1251 TranslationHelper& translation_helper_;
1252 Reader reader_;
1253 const Script& script_;
1254 // Some items like variables are specified in the kernel binary as
1255 // absolute offsets (as in, offsets within the whole kernel program)
1256 // of their declaration nodes. Hence, to cache and/or access them
1257 // uniquely from within a function's kernel data, we need to
1258 // add/subtract the offset of the kernel data in the over all
1259 // kernel program.
1260 intptr_t data_program_offset_;
1261
1262 friend class BytecodeMetadataHelper;
1263 friend class BytecodeReaderHelper;
1264 friend class ClassHelper;
1265 friend class CallSiteAttributesMetadataHelper;
1266 friend class ConstantReader;
1267 friend class ConstantHelper;
1268 friend class ConstructorHelper;
1269 friend class DirectCallMetadataHelper;
1270 friend class FieldHelper;
1271 friend class FunctionNodeHelper;
1272 friend class InferredTypeMetadataHelper;
1273 friend class KernelLoader;
1274 friend class LibraryDependencyHelper;
1275 friend class LibraryHelper;
1276 friend class MetadataHelper;
1277 friend class ProcedureAttributesMetadataHelper;
1278 friend class ProcedureHelper;
1279 friend class SimpleExpressionConverter;
1280 friend class ScopeBuilder;
1281 friend class TableSelectorMetadataHelper;
1282 friend class TypeParameterHelper;
1283 friend class TypeTranslator;
1284 friend class UnboxingInfoMetadataHelper;
1285 friend class VariableDeclarationHelper;
1286 friend class ObfuscationProhibitionsMetadataHelper;
1287 friend class LoadingUnitsMetadataHelper;
1288 friend bool NeedsDynamicInvocationForwarder(const Function& function);
1289
1290 private:
1291 DISALLOW_COPY_AND_ASSIGN(KernelReaderHelper);
1292};
1293
1294class ActiveClass {
1295 public:
1296 ActiveClass()
1297 : klass(NULL),
1298 member(NULL),
1299 enclosing(NULL),
1300 local_type_parameters(NULL) {}
1301
1302 bool HasMember() { return member != NULL; }
1303
1304 bool MemberIsProcedure() {
1305 ASSERT(member != NULL);
1306 FunctionLayout::Kind function_kind = member->kind();
1307 return function_kind == FunctionLayout::kRegularFunction ||
1308 function_kind == FunctionLayout::kGetterFunction ||
1309 function_kind == FunctionLayout::kSetterFunction ||
1310 function_kind == FunctionLayout::kMethodExtractor ||
1311 function_kind == FunctionLayout::kDynamicInvocationForwarder ||
1312 member->IsFactory();
1313 }
1314
1315 bool MemberIsFactoryProcedure() {
1316 ASSERT(member != NULL);
1317 return member->IsFactory();
1318 }
1319
1320 bool RequireLegacyErasure(bool null_safety) const {
1321 return klass != nullptr && !null_safety &&
1322 Library::Handle(klass->library()).nnbd_compiled_mode() ==
1323 NNBDCompiledMode::kAgnostic;
1324 }
1325
1326 intptr_t MemberTypeParameterCount(Zone* zone);
1327
1328 intptr_t ClassNumTypeArguments() {
1329 ASSERT(klass != NULL);
1330 return klass->NumTypeArguments();
1331 }
1332
1333 void RecordDerivedTypeParameter(Zone* zone,
1334 const TypeParameter& original,
1335 const TypeParameter& derived) {
1336 if (original.raw() != derived.raw() &&
1337 original.bound() == AbstractType::null()) {
1338 if (derived_type_parameters == nullptr) {
1339 derived_type_parameters = &GrowableObjectArray::Handle(
1340 zone, GrowableObjectArray::New(Heap::kOld));
1341 }
1342 derived_type_parameters->Add(derived);
1343 }
1344 }
1345
1346 const char* ToCString() {
1347 return member != NULL ? member->ToCString() : klass->ToCString();
1348 }
1349
1350 // The current enclosing class (or the library top-level class).
1351 const Class* klass;
1352
1353 const Function* member;
1354
1355 // The innermost enclosing function. This is used for building types, as a
1356 // parent for function types.
1357 const Function* enclosing;
1358
1359 const TypeArguments* local_type_parameters;
1360
1361 GrowableObjectArray* derived_type_parameters = nullptr;
1362};
1363
1364class ActiveClassScope {
1365 public:
1366 ActiveClassScope(ActiveClass* active_class, const Class* klass)
1367 : active_class_(active_class), saved_(*active_class) {
1368 active_class_->klass = klass;
1369 }
1370
1371 ~ActiveClassScope() { *active_class_ = saved_; }
1372
1373 private:
1374 ActiveClass* active_class_;
1375 ActiveClass saved_;
1376
1377 DISALLOW_COPY_AND_ASSIGN(ActiveClassScope);
1378};
1379
1380class ActiveMemberScope {
1381 public:
1382 ActiveMemberScope(ActiveClass* active_class, const Function* member)
1383 : active_class_(active_class), saved_(*active_class) {
1384 // The class is inherited.
1385 active_class_->member = member;
1386 }
1387
1388 ~ActiveMemberScope() { *active_class_ = saved_; }
1389
1390 private:
1391 ActiveClass* active_class_;
1392 ActiveClass saved_;
1393
1394 DISALLOW_COPY_AND_ASSIGN(ActiveMemberScope);
1395};
1396
1397class ActiveEnclosingFunctionScope {
1398 public:
1399 ActiveEnclosingFunctionScope(ActiveClass* active_class,
1400 const Function* enclosing)
1401 : active_class_(active_class), saved_(*active_class) {
1402 active_class_->enclosing = enclosing;
1403 }
1404
1405 ~ActiveEnclosingFunctionScope() { *active_class_ = saved_; }
1406
1407 private:
1408 ActiveClass* active_class_;
1409 ActiveClass saved_;
1410
1411 DISALLOW_COPY_AND_ASSIGN(ActiveEnclosingFunctionScope);
1412};
1413
1414class ActiveTypeParametersScope {
1415 public:
1416 // Set the local type parameters of the ActiveClass to be exactly all type
1417 // parameters defined by 'innermost' and any enclosing *closures* (but not
1418 // enclosing methods/top-level functions/classes).
1419 //
1420 // Also, the enclosing function is set to 'innermost'.
1421 ActiveTypeParametersScope(ActiveClass* active_class,
1422 const Function& innermost,
1423 Zone* Z);
1424
1425 // Append the list of the local type parameters to the list in ActiveClass.
1426 //
1427 // Also, the enclosing function is set to 'function'.
1428 ActiveTypeParametersScope(ActiveClass* active_class,
1429 const Function* function,
1430 const TypeArguments& new_params,
1431 Zone* Z);
1432
1433 ~ActiveTypeParametersScope() { *active_class_ = saved_; }
1434
1435 private:
1436 ActiveClass* active_class_;
1437 ActiveClass saved_;
1438
1439 DISALLOW_COPY_AND_ASSIGN(ActiveTypeParametersScope);
1440};
1441
1442class TypeTranslator {
1443 public:
1444 TypeTranslator(KernelReaderHelper* helper,
1445 ConstantReader* constant_reader,
1446 ActiveClass* active_class,
1447 bool finalize = false,
1448 bool apply_legacy_erasure = false);
1449
1450 AbstractType& BuildType();
1451 AbstractType& BuildTypeWithoutFinalization();
1452
1453 const TypeArguments& BuildTypeArguments(intptr_t length);
1454
1455 const TypeArguments& BuildInstantiatedTypeArguments(
1456 const Class& receiver_class,
1457 intptr_t length);
1458
1459 void LoadAndSetupTypeParameters(ActiveClass* active_class,
1460 const Object& set_on,
1461 intptr_t type_parameter_count,
1462 const Function& parameterized_function);
1463
1464 const Type& ReceiverType(const Class& klass);
1465
1466 void SetupFunctionParameters(const Class& klass,
1467 const Function& function,
1468 bool is_method,
1469 bool is_closure,
1470 FunctionNodeHelper* function_node_helper);
1471
1472 private:
1473 void SetupUnboxingInfoMetadata(const Function& function,
1474 intptr_t library_kernel_offset);
1475 void SetupUnboxingInfoMetadataForFieldAccessors(
1476 const Function& field_accessor,
1477 intptr_t library_kernel_offset);
1478
1479 void BuildTypeInternal();
1480 void BuildInterfaceType(bool simple);
1481 void BuildFunctionType(bool simple);
1482 void BuildTypeParameterType();
1483
1484 class TypeParameterScope {
1485 public:
1486 TypeParameterScope(TypeTranslator* translator, intptr_t parameter_count)
1487 : parameter_count_(parameter_count),
1488 outer_(translator->type_parameter_scope_),
1489 translator_(translator) {
1490 outer_parameter_count_ = 0;
1491 if (outer_ != NULL) {
1492 outer_parameter_count_ =
1493 outer_->outer_parameter_count_ + outer_->parameter_count_;
1494 }
1495 translator_->type_parameter_scope_ = this;
1496 }
1497 ~TypeParameterScope() { translator_->type_parameter_scope_ = outer_; }
1498
1499 TypeParameterScope* outer() const { return outer_; }
1500 intptr_t parameter_count() const { return parameter_count_; }
1501 intptr_t outer_parameter_count() const { return outer_parameter_count_; }
1502
1503 private:
1504 intptr_t parameter_count_;
1505 intptr_t outer_parameter_count_;
1506 TypeParameterScope* outer_;
1507 TypeTranslator* translator_;
1508 };
1509
1510 KernelReaderHelper* helper_;
1511 ConstantReader* constant_reader_;
1512 TranslationHelper& translation_helper_;
1513 ActiveClass* const active_class_;
1514 TypeParameterScope* type_parameter_scope_;
1515 InferredTypeMetadataHelper inferred_type_metadata_helper_;
1516 UnboxingInfoMetadataHelper unboxing_info_metadata_helper_;
1517 Zone* zone_;
1518 AbstractType& result_;
1519 bool finalize_;
1520 const bool apply_legacy_erasure_;
1521
1522 friend class ScopeBuilder;
1523 friend class KernelLoader;
1524
1525 DISALLOW_COPY_AND_ASSIGN(TypeTranslator);
1526};
1527
1528} // namespace kernel
1529} // namespace dart
1530
1531#endif // RUNTIME_VM_COMPILER_FRONTEND_KERNEL_TRANSLATION_HELPER_H_
1532