Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Classes | Namespaces | Macros | Enumerations | Variables
kernel_binary.h File Reference
#include "platform/unaligned.h"
#include "vm/kernel.h"
#include "vm/object.h"

Go to the source code of this file.

Classes

class  dart::kernel::Reader
 
class  dart::kernel::AlternativeReadingScope
 
class  dart::kernel::AlternativeReadingScopeWithNewData
 
class  dart::kernel::PositionScope
 

Namespaces

namespace  dart
 
namespace  dart::kernel
 

Macros

#define KERNEL_TAG_LIST(V)
 
#define DECLARE(Name, value)   k##Name = value,
 

Enumerations

enum  dart::kernel::Tag
 
enum  dart::kernel::ConstantTag {
  dart::kernel::kNullConstant = 0 , dart::kernel::kBoolConstant = 1 , dart::kernel::kIntConstant = 2 , dart::kernel::kDoubleConstant = 3 ,
  dart::kernel::kStringConstant = 4 , dart::kernel::kSymbolConstant = 5 , dart::kernel::kMapConstant = 6 , dart::kernel::kListConstant = 7 ,
  dart::kernel::kSetConstant = 13 , dart::kernel::kInstanceConstant = 8 , dart::kernel::kInstantiationConstant = 9 , dart::kernel::kStaticTearOffConstant = 10 ,
  dart::kernel::kTypeLiteralConstant = 11 , dart::kernel::kUnevaluatedConstant = 12 , dart::kernel::kTypedefTearOffConstant = 14 , dart::kernel::kConstructorTearOffConstant = 15 ,
  dart::kernel::kRedirectingFactoryTearOffConstant = 16 , dart::kernel::kRecordConstant = 17
}
 
enum class  dart::kernel::KernelNullability : int8_t { dart::kernel::kUndetermined = 0 , dart::kernel::kNullable = 1 , dart::kernel::kNonNullable = 2 , dart::kernel::kLegacy = 3 }
 
enum  dart::kernel::Variance {
  dart::kernel::kUnrelated = 0 , dart::kernel::kCovariant = 1 , dart::kernel::kContravariant = 2 , dart::kernel::kInvariant = 3 ,
  dart::kernel::kLegacyCovariant = 4
}
 
enum  dart::kernel::AsExpressionFlags {
  dart::kernel::kAsExpressionFlagTypeError = 1 << 0 , dart::kernel::kAsExpressionFlagCovarianceCheck = 1 << 1 , dart::kernel::kAsExpressionFlagForDynamic = 1 << 2 , dart::kernel::kAsExpressionFlagForLegacy = 1 << 3 ,
  dart::kernel::kAsExpressionFlagUnchecked = 1 << 4
}
 
enum  dart::kernel::IsExpressionFlags { dart::kernel::kIsExpressionFlagForLegacy = 1 << 0 }
 
enum  dart::kernel::InstanceInvocationFlags { dart::kernel::kInstanceInvocationFlagInvariant = 1 << 0 , dart::kernel::kInstanceInvocationFlagBoundsSafe = 1 << 1 }
 
enum  dart::kernel::DynamicInvocationFlags { dart::kernel::kDynamicInvocationFlagImplicitCall = 1 << 0 }
 
enum  dart::kernel::ThrowFlags { dart::kernel::kThrowForErrorHandling = 1 << 0 }
 
enum  dart::kernel::YieldStatementFlags { dart::kernel::kYieldStatementFlagYieldStar = 1 << 0 }
 
enum class  dart::kernel::NamedTypeFlags : uint8_t { dart::kernel::kIsRequired = 1 << 0 }
 
enum class  dart::kernel::FunctionAccessKind { dart::kernel::kFunction , dart::kernel::kFunctionType , dart::kernel::kInapplicable , dart::kernel::kNullable }
 

Variables

static const uint32_t dart::kernel::kMagicProgramFile = 0x90ABCDEFu
 
static const uint32_t dart::kernel::kSupportedKernelFormatVersion = 117
 
static constexpr intptr_t dart::kernel::kSpecializedTagHighBits = 0xe0
 
static constexpr intptr_t dart::kernel::kSpecializedTagMask = 0xf8
 
static constexpr intptr_t dart::kernel::kSpecializedPayloadMask = 0x7
 
static constexpr int dart::kernel::SpecializedIntLiteralBias = 3
 
static constexpr int dart::kernel::LibraryCountFieldCountFromEnd = 1
 
static constexpr int dart::kernel::KernelFormatVersionOffset = 4
 
static constexpr int dart::kernel::SourceTableFieldCountFromFirstLibraryOffset = 9
 
static constexpr int dart::kernel::HeaderSize = 8
 

Macro Definition Documentation

◆ DECLARE

#define DECLARE (   Name,
  value 
)    k##Name = value,

Definition at line 185 of file kernel_binary.h.

◆ KERNEL_TAG_LIST

#define KERNEL_TAG_LIST (   V)

Definition at line 24 of file kernel_binary.h.

183 {
184#define DECLARE(Name, value) k##Name = value,
186#undef DECLARE
187};
188
189// Keep in sync with package:kernel/lib/binary/tag.dart
190enum ConstantTag {
191 kNullConstant = 0,
192 kBoolConstant = 1,
193 kIntConstant = 2,
194 kDoubleConstant = 3,
195 kStringConstant = 4,
196 kSymbolConstant = 5,
197 kMapConstant = 6,
198 kListConstant = 7,
199 kSetConstant = 13,
204 // These constants are not expected to be seen by the VM, because all
205 // constants are fully evaluated.
210 kRecordConstant = 17,
211};
212
213// Keep in sync with package:kernel/lib/ast.dart
214enum class KernelNullability : int8_t {
215 kUndetermined = 0,
216 kNullable = 1,
217 kNonNullable = 2,
218 kLegacy = 3,
219};
220
221// Keep in sync with package:kernel/lib/ast.dart
222enum Variance {
223 kUnrelated = 0,
224 kCovariant = 1,
225 kContravariant = 2,
226 kInvariant = 3,
228};
229
230// Keep in sync with package:kernel/lib/ast.dart
237};
238
239// Keep in sync with package:kernel/lib/ast.dart
242};
243
244// Keep in sync with package:kernel/lib/ast.dart
248};
249
250// Keep in sync with package:kernel/lib/ast.dart
253};
254
255// Keep in sync with package:kernel/lib/ast.dart
256enum ThrowFlags {
257 kThrowForErrorHandling = 1 << 0,
258};
259
260// Keep in sync with package:kernel/lib/ast.dart
263};
264
265// Keep in sync with package:kernel/lib/ast.dart
266enum class NamedTypeFlags : uint8_t {
267 kIsRequired = 1 << 0,
268};
269
270// Keep in sync with package:kernel/lib/ast.dart
271enum class FunctionAccessKind {
272 kFunction,
275 kNullable,
276};
277
278static constexpr int SpecializedIntLiteralBias = 3;
279static constexpr int LibraryCountFieldCountFromEnd = 1;
280static constexpr int KernelFormatVersionOffset = 4;
281static constexpr int SourceTableFieldCountFromFirstLibraryOffset = 9;
282
283static constexpr int HeaderSize = 8; // 'magic', 'formatVersion'.
284
285class Reader : public ValueObject {
286 public:
287 explicit Reader(const TypedDataBase& typed_data)
288 : thread_(Thread::Current()), typed_data_(&typed_data) {
289 Init();
290 }
291
292 uint32_t ReadFromIndex(intptr_t end_offset,
293 intptr_t fields_before,
294 intptr_t list_size,
295 intptr_t list_index) {
296 intptr_t org_offset = offset();
297 uint32_t result =
298 ReadFromIndexNoReset(end_offset, fields_before, list_size, list_index);
299 offset_ = org_offset;
300 return result;
301 }
302
303 uint32_t ReadUInt32At(intptr_t offset) const {
304 ASSERT((size_ >= 4) && (offset >= 0) && (offset <= size_ - 4));
305 uint32_t value =
306 LoadUnaligned(reinterpret_cast<const uint32_t*>(raw_buffer_ + offset));
307 return Utils::BigEndianToHost32(value);
308 }
309
310 uint32_t ReadFromIndexNoReset(intptr_t end_offset,
311 intptr_t fields_before,
312 intptr_t list_size,
313 intptr_t list_index) {
314 offset_ = end_offset - (fields_before + list_size - list_index) * 4;
315 return ReadUInt32();
316 }
317
318 uint32_t ReadUInt32() {
319 uint32_t value = ReadUInt32At(offset_);
320 offset_ += 4;
321 return value;
322 }
323
324 double ReadDouble() {
325 ASSERT((size_ >= 8) && (offset_ >= 0) && (offset_ <= size_ - 8));
326 double value =
327 LoadUnaligned(reinterpret_cast<const double*>(&raw_buffer_[offset_]));
328 offset_ += 8;
329 return value;
330 }
331
332 uint32_t ReadUInt() {
333 ASSERT((size_ >= 1) && (offset_ >= 0) && (offset_ <= size_ - 1));
334
335 const uint8_t* buffer = raw_buffer_;
336 uword byte0 = buffer[offset_];
337 if ((byte0 & 0x80) == 0) {
338 // 0...
339 offset_++;
340 return byte0;
341 } else if ((byte0 & 0xc0) == 0x80) {
342 // 10...
343 ASSERT((size_ >= 2) && (offset_ >= 0) && (offset_ <= size_ - 2));
344 uint32_t value =
345 ((byte0 & ~static_cast<uword>(0x80)) << 8) | (buffer[offset_ + 1]);
346 offset_ += 2;
347 return value;
348 } else {
349 // 11...
350 ASSERT((size_ >= 4) && (offset_ >= 0) && (offset_ <= size_ - 4));
351 uint32_t value = ((byte0 & ~static_cast<uword>(0xc0)) << 24) |
352 (buffer[offset_ + 1] << 16) |
353 (buffer[offset_ + 2] << 8) | (buffer[offset_ + 3] << 0);
354 offset_ += 4;
355 return value;
356 }
357 }
358
359 intptr_t ReadSLEB128() {
360 ReadStream stream(raw_buffer_, size_, offset_);
361 const intptr_t result = stream.ReadSLEB128();
362 offset_ = stream.Position();
363 return result;
364 }
365
366 int64_t ReadSLEB128AsInt64() {
367 ReadStream stream(raw_buffer_, size_, offset_);
368 const int64_t result = stream.ReadSLEB128<int64_t>();
369 offset_ = stream.Position();
370 return result;
371 }
372
373 /**
374 * Read and return a TokenPosition from this reader.
375 */
376 TokenPosition ReadPosition() {
377 // Position is saved as unsigned,
378 // but actually ranges from -1 and up (thus the -1)
379 intptr_t value = ReadUInt() - 1;
380 TokenPosition result = TokenPosition::Deserialize(value);
381 max_position_ = TokenPosition::Max(max_position_, result);
382 min_position_ = TokenPosition::Min(min_position_, result);
383 return result;
384 }
385
386 intptr_t ReadListLength() { return ReadUInt(); }
387
388 uint8_t ReadByte() { return raw_buffer_[offset_++]; }
389
390 uint8_t PeekByte() { return raw_buffer_[offset_]; }
391
392 void ReadBytes(uint8_t* buffer, uint8_t size) {
393 for (int i = 0; i < size; i++) {
394 buffer[i] = ReadByte();
395 }
396 }
397
398 bool ReadBool() { return (ReadByte() & 1) == 1; }
399
400 uint8_t ReadFlags() { return ReadByte(); }
401
402 static const char* TagName(Tag tag);
403
404 Tag ReadTag(uint8_t* payload = nullptr) {
405 uint8_t byte = ReadByte();
406 bool has_payload =
407 (byte & kSpecializedTagHighBits) == kSpecializedTagHighBits;
408 if (has_payload) {
409 if (payload != nullptr) {
410 *payload = byte & kSpecializedPayloadMask;
411 }
412 return static_cast<Tag>(byte & kSpecializedTagMask);
413 } else {
414 return static_cast<Tag>(byte);
415 }
416 }
417
418 Tag PeekTag(uint8_t* payload = nullptr) {
419 uint8_t byte = PeekByte();
420 bool has_payload =
421 (byte & kSpecializedTagHighBits) == kSpecializedTagHighBits;
422 if (has_payload) {
423 if (payload != nullptr) {
424 *payload = byte & kSpecializedPayloadMask;
425 }
426 return static_cast<Tag>(byte & kSpecializedTagMask);
427 } else {
428 return static_cast<Tag>(byte);
429 }
430 }
431
432 static Nullability ConvertNullability(KernelNullability kernel_nullability) {
433 switch (kernel_nullability) {
434 case KernelNullability::kNullable:
435 return Nullability::kNullable;
436 case KernelNullability::kLegacy:
437 return Nullability::kLegacy;
438 case KernelNullability::kNonNullable:
439 case KernelNullability::kUndetermined:
440 return Nullability::kNonNullable;
441 }
442 UNREACHABLE();
443 }
444
445 Nullability ReadNullability() {
446 const uint8_t byte = ReadByte();
447 return ConvertNullability(static_cast<KernelNullability>(byte));
448 }
449
450 Variance ReadVariance() {
451 uint8_t byte = ReadByte();
452 return static_cast<Variance>(byte);
453 }
454
455 void EnsureEnd() {
456 if (offset_ != size_) {
457 FATAL(
458 "Reading Kernel file: Expected to be at EOF "
459 "(offset: %" Pd ", size: %" Pd ")",
460 offset_, size_);
461 }
462 }
463
464 // The largest position read yet (since last reset).
465 // This is automatically updated when calling ReadPosition,
466 // but can be overwritten (e.g. via the PositionScope class).
467 TokenPosition max_position() { return max_position_; }
468 // The smallest position read yet (since last reset).
469 // This is automatically updated when calling ReadPosition,
470 // but can be overwritten (e.g. via the PositionScope class).
471 TokenPosition min_position() { return min_position_; }
472
473 // A canonical name reference of -1 indicates none (for optional names), not
474 // the root name as in the canonical name table.
475 NameIndex ReadCanonicalNameReference() { return NameIndex(ReadUInt() - 1); }
476
477 const TypedDataBase* typed_data() { return typed_data_; }
478
479 intptr_t offset() const { return offset_; }
480 void set_offset(intptr_t offset) {
481 ASSERT(offset < size_);
482 offset_ = offset;
483 }
484 intptr_t size() const { return size_; }
485
486 TypedDataViewPtr ViewFromTo(intptr_t start, intptr_t end) {
487 return typed_data_->ViewFromTo(start, end, Heap::kOld);
488 }
489
490 const uint8_t* BufferAt(intptr_t offset) {
491 ASSERT((offset >= 0) && (offset < size_));
492 return &raw_buffer_[offset];
493 }
494
495 TypedDataPtr ReadLineStartsData(intptr_t line_start_count);
496
497 private:
498 friend class Program;
499 friend class AlternativeReadingScopeWithNewData;
500 friend class AlternativeReadingScope;
501
502 Reader(const uint8_t* buffer, intptr_t size)
503 : thread_(nullptr), raw_buffer_(buffer), size_(size) {}
504
505 void Init() {
506 ASSERT(typed_data_->IsExternalOrExternalView());
507 raw_buffer_ = reinterpret_cast<uint8_t*>(typed_data_->DataAddr(0));
508 size_ = typed_data_->LengthInBytes();
509 offset_ = 0;
510 }
511
512 Thread* thread_ = nullptr;
513
514 // A external typed data or a view on an external typed data.
515 const TypedDataBase* typed_data_ = nullptr;
516
517 // The raw data size/length of [typed_data_].
518 const uint8_t* raw_buffer_ = nullptr;
519 intptr_t size_ = 0;
520
521 intptr_t offset_ = 0;
522 TokenPosition max_position_ = TokenPosition::kNoSource;
523 TokenPosition min_position_ = TokenPosition::kNoSource;
524 intptr_t current_script_id_ = -1;
525
526 friend class PositionScope;
527 friend class Program;
528};
529
530// A helper class that saves the current reader position, goes to another reader
531// position, and upon destruction, resets to the original reader position.
532class AlternativeReadingScope {
533 public:
534 AlternativeReadingScope(Reader* reader, intptr_t new_position)
535 : reader_(reader), saved_offset_(reader_->offset_) {
536 reader_->offset_ = new_position;
537 }
538
539 explicit AlternativeReadingScope(Reader* reader)
540 : reader_(reader), saved_offset_(reader_->offset_) {}
541
542 ~AlternativeReadingScope() { reader_->offset_ = saved_offset_; }
543
544 intptr_t saved_offset() { return saved_offset_; }
545
546 private:
547 Reader* const reader_;
548 const intptr_t saved_offset_;
549
550 DISALLOW_COPY_AND_ASSIGN(AlternativeReadingScope);
551};
552
553// Similar to AlternativeReadingScope, but also switches reading to another
554// typed data array.
555class AlternativeReadingScopeWithNewData {
556 public:
557 AlternativeReadingScopeWithNewData(Reader* reader,
558 const TypedDataBase* new_typed_data,
559 intptr_t new_position)
560 : reader_(reader),
561 saved_size_(reader_->size_),
562 saved_raw_buffer_(reader_->raw_buffer_),
563 saved_typed_data_(reader_->typed_data_),
564 saved_offset_(reader_->offset_) {
565 reader_->typed_data_ = new_typed_data;
566 reader_->Init();
567 reader_->offset_ = new_position;
568 }
569
570 ~AlternativeReadingScopeWithNewData() {
571 reader_->raw_buffer_ = saved_raw_buffer_;
572 reader_->typed_data_ = saved_typed_data_;
573 reader_->size_ = saved_size_;
574 reader_->offset_ = saved_offset_;
575 }
576
577 intptr_t saved_offset() { return saved_offset_; }
578
579 private:
580 Reader* reader_;
581 intptr_t saved_size_;
582 const uint8_t* saved_raw_buffer_;
583 const TypedDataBase* saved_typed_data_;
584 intptr_t saved_offset_;
585
586 DISALLOW_COPY_AND_ASSIGN(AlternativeReadingScopeWithNewData);
587};
588
589// A helper class that resets the readers min and max positions both upon
590// initialization and upon destruction, i.e. when created the min an max
591// positions will be reset to "noSource", when destructing the min and max will
592// be reset to have they value they would have had, if they hadn't been reset in
593// the first place.
594class PositionScope {
595 public:
596 explicit PositionScope(Reader* reader)
597 : reader_(reader),
598 min_(reader->min_position_),
599 max_(reader->max_position_) {
600 reader->min_position_ = reader->max_position_ = TokenPosition::kNoSource;
601 }
602
603 ~PositionScope() {
604 reader_->min_position_ = TokenPosition::Min(reader_->min_position_, min_);
605 reader_->max_position_ = TokenPosition::Max(reader_->max_position_, max_);
606 }
607
608 private:
609 Reader* reader_;
610 TokenPosition min_;
611 TokenPosition max_;
612
613 DISALLOW_COPY_AND_ASSIGN(PositionScope);
614};
615
616} // namespace kernel
617} // namespace dart
618
619#endif // !defined(DART_PRECOMPILED_RUNTIME)
620#endif // RUNTIME_VM_KERNEL_BINARY_H_
static uint8_t PeekByte(unsigned long location, CFDataRef data)
SI F min_(F x, F y)
SI F max_(F x, F y)
#define UNREACHABLE()
Definition assert.h:248
#define ASSERT(E)
#define FATAL(error)
glong glong end
static const uint8_t buffer[]
uint8_t value
GAsyncResult * result
void Init()
#define DECLARE(Name, value)
#define KERNEL_TAG_LIST(V)
@ kConstructorTearOffConstant
@ kRedirectingFactoryTearOffConstant
static constexpr int SpecializedIntLiteralBias
@ kYieldStatementFlagYieldStar
static constexpr int SourceTableFieldCountFromFirstLibraryOffset
static constexpr int LibraryCountFieldCountFromEnd
static constexpr intptr_t kSpecializedPayloadMask
static constexpr intptr_t kSpecializedTagHighBits
@ kDynamicInvocationFlagImplicitCall
static constexpr intptr_t kSpecializedTagMask
@ kInstanceInvocationFlagBoundsSafe
@ kInstanceInvocationFlagInvariant
static constexpr int HeaderSize
@ kAsExpressionFlagCovarianceCheck
@ kAsExpressionFlagForDynamic
static constexpr int KernelFormatVersionOffset
Nullability
Definition object.h:1112
uintptr_t uword
Definition globals.h:501
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition switches.h:259
#define Pd
Definition globals.h:408
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition globals.h:581
Point offset