| Index: runtime/vm/kernel_binary.cc
|
| diff --git a/runtime/vm/kernel_binary.cc b/runtime/vm/kernel_binary.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..407e1a651821001c4bae4670c841a120f5348a8f
|
| --- /dev/null
|
| +++ b/runtime/vm/kernel_binary.cc
|
| @@ -0,0 +1,2902 @@
|
| +// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
|
| +// for details. All rights reserved. Use of this source code is governed by a
|
| +// BSD-style license that can be found in the LICENSE file.
|
| +
|
| +#include <map>
|
| +#include <vector>
|
| +
|
| +#include "vm/flags.h"
|
| +#include "vm/kernel.h"
|
| +#include "vm/os.h"
|
| +
|
| +#if defined(DEBUG)
|
| +#define TRACE_READ_OFFSET() do { \
|
| + if (FLAG_trace_kernel_binary) \
|
| + reader->DumpOffset(__PRETTY_FUNCTION__); \
|
| + } while (0)
|
| +#define TRACE_WRITE_OFFSET() do { \
|
| + if (FLAG_trace_kernel_binary) \
|
| + writer->DumpOffset(__PRETTY_FUNCTION__); \
|
| + } while (0)
|
| +#else
|
| +#define TRACE_READ_OFFSET()
|
| +#define TRACE_WRITE_OFFSET()
|
| +#endif
|
| +
|
| +namespace dart {
|
| +
|
| +
|
| +ByteWriter::~ByteWriter() {}
|
| +
|
| +
|
| +namespace kernel {
|
| +
|
| +
|
| +static const uint32_t kMagicProgramFile = 0x90ABCDEFu;
|
| +
|
| +
|
| +// Keep in sync with package:dynamo/lib/binary/tag.dart
|
| +enum Tag {
|
| + kNothing = 0,
|
| + kSomething = 1,
|
| +
|
| + kNormalClass = 2,
|
| + kMixinClass = 3,
|
| +
|
| + kField = 4,
|
| + kConstructor = 5,
|
| + kProcedure = 6,
|
| +
|
| + kInvalidInitializer = 7,
|
| + kFieldInitializer = 8,
|
| + kSuperInitializer = 9,
|
| + kRedirectingInitializer = 10,
|
| + kLocalInitializer = 11,
|
| +
|
| + kDirectPropertyGet = 15,
|
| + kDirectPropertySet = 16,
|
| + kDirectMethodInvocation = 17,
|
| + kConstStaticInvocation = 18,
|
| + kInvalidExpression = 19,
|
| + kVariableGet = 20,
|
| + kVariableSet = 21,
|
| + kPropertyGet = 22,
|
| + kPropertySet = 23,
|
| + kSuperPropertyGet = 24,
|
| + kSuperPropertySet = 25,
|
| + kStaticGet = 26,
|
| + kStaticSet = 27,
|
| + kMethodInvocation = 28,
|
| + kSuperMethodInvocation = 29,
|
| + kStaticInvocation = 30,
|
| + kConstructorInvocation = 31,
|
| + kConstConstructorInvocation = 32,
|
| + kNot = 33,
|
| + kLogicalExpression = 34,
|
| + kConditionalExpression = 35,
|
| + kStringConcatenation = 36,
|
| + kIsExpression = 37,
|
| + kAsExpression = 38,
|
| + kStringLiteral = 39,
|
| + kDoubleLiteral = 40,
|
| + kTrueLiteral = 41,
|
| + kFalseLiteral = 42,
|
| + kNullLiteral = 43,
|
| + kSymbolLiteral = 44,
|
| + kTypeLiteral = 45,
|
| + kThisExpression = 46,
|
| + kRethrow = 47,
|
| + kThrow = 48,
|
| + kListLiteral = 49,
|
| + kMapLiteral = 50,
|
| + kAwaitExpression = 51,
|
| + kFunctionExpression = 52,
|
| + kLet = 53,
|
| + kBlockExpression = 54,
|
| +
|
| + kPositiveIntLiteral = 55,
|
| + kNegativeIntLiteral = 56,
|
| + kBigIntLiteral = 57,
|
| + kConstListLiteral = 58,
|
| + kConstMapLiteral = 59,
|
| +
|
| + kInvalidStatement = 60,
|
| + kExpressionStatement = 61,
|
| + kBlock = 62,
|
| + kEmptyStatement = 63,
|
| + kAssertStatement = 64,
|
| + kLabeledStatement = 65,
|
| + kBreakStatement = 66,
|
| + kWhileStatement = 67,
|
| + kDoStatement = 68,
|
| + kForStatement = 69,
|
| + kForInStatement = 70,
|
| + kSwitchStatement = 71,
|
| + kContinueSwitchStatement = 72,
|
| + kIfStatement = 73,
|
| + kReturnStatement = 74,
|
| + kTryCatch = 75,
|
| + kTryFinally = 76,
|
| + kYieldStatement = 77,
|
| + kVariableDeclaration = 78,
|
| + kFunctionDeclaration = 79,
|
| + kAsyncForInStatement = 80,
|
| +
|
| + kInvalidType = 90,
|
| + kDynamicType = 91,
|
| + kVoidType = 92,
|
| + kInterfaceType = 93,
|
| + kFunctionType = 94,
|
| + kTypeParameterType = 95,
|
| + kSimpleInterfaceType = 96,
|
| + kSimpleFunctionType = 97,
|
| +
|
| + kNullReference = 99,
|
| + kNormalClassReference = 100,
|
| + kMixinClassReference = 101,
|
| +
|
| + kLibraryFieldReference = 102,
|
| + kClassFieldReference = 103,
|
| + kClassConstructorReference = 104,
|
| + kLibraryProcedureReference = 105,
|
| + kClassProcedureReference = 106,
|
| +
|
| + kSpecializedTagHighBit = 0x80, // 10000000
|
| + kSpecializedTagMask = 0xF8, // 11111000
|
| + kSpecializedPayloadMask = 0x7, // 00000111
|
| +
|
| + kSpecializedVariableGet = 128,
|
| + kSpecializedVariableSet = 136,
|
| + kSpecialIntLiteral = 144,
|
| +};
|
| +
|
| +
|
| +static const int SpecializedIntLiteralBias = 3;
|
| +
|
| +
|
| +template <typename T>
|
| +class BlockStack {
|
| + public:
|
| + BlockStack() : current_count_(0) {}
|
| +
|
| + void EnterScope() {
|
| + variable_count_.push_back(current_count_);
|
| + current_count_ = 0;
|
| + }
|
| +
|
| + void LeaveScope() {
|
| + variables_.resize(variables_.size() - current_count_);
|
| + current_count_ = variable_count_[variable_count_.size() - 1];
|
| + variable_count_.pop_back();
|
| + }
|
| +
|
| + T* Lookup(int index) {
|
| + ASSERT(static_cast<unsigned>(index) < variables_.size());
|
| + return variables_[index];
|
| + }
|
| +
|
| + void Push(T* v) {
|
| + variables_.push_back(v);
|
| + current_count_++;
|
| + }
|
| +
|
| + void Push(List<T>* decl) {
|
| + for (int i = 0; i < decl->length(); i++) {
|
| + variables_.push_back(decl[i]);
|
| + current_count_++;
|
| + }
|
| + }
|
| +
|
| + void Pop(T* decl) {
|
| + variables_.resize(variables_.size() - 1);
|
| + current_count_--;
|
| + }
|
| +
|
| + void Pop(List<T>* decl) {
|
| + variables_.resize(variables_.size() - decl->length());
|
| + current_count_ -= decl->length();
|
| + }
|
| +
|
| + private:
|
| + int current_count_;
|
| + std::vector<T*> variables_;
|
| + std::vector<int> variable_count_;
|
| +};
|
| +
|
| +
|
| +template <typename T>
|
| +class BlockMap {
|
| + public:
|
| + BlockMap() : current_count_(0), stack_height_(0) {}
|
| +
|
| + void EnterScope() {
|
| + variable_count_.push_back(current_count_);
|
| + current_count_ = 0;
|
| + }
|
| +
|
| + void LeaveScope() {
|
| + stack_height_ -= current_count_;
|
| + current_count_ = variable_count_[variable_count_.size() - 1];
|
| + variable_count_.pop_back();
|
| + }
|
| +
|
| + int Lookup(T* object) {
|
| + ASSERT(variables_.find(object) != variables_.end());
|
| + if (variables_.find(object) == variables_.end()) FATAL("lookup failure");
|
| + return variables_[object];
|
| + }
|
| +
|
| + void Push(T* v) {
|
| + int index = stack_height_++;
|
| + variables_[v] = index;
|
| + current_count_++;
|
| + }
|
| +
|
| + void Set(T* v, int index) { variables_[v] = index; }
|
| +
|
| + void Push(List<T>* decl) {
|
| + for (int i = 0; i < decl->length(); i++) {
|
| + Push(decl[i]);
|
| + }
|
| + }
|
| +
|
| + void Pop(T* v) {
|
| + current_count_--;
|
| + stack_height_--;
|
| + }
|
| +
|
| + private:
|
| + int current_count_;
|
| + int stack_height_;
|
| + std::map<T*, int> variables_;
|
| + std::vector<int> variable_count_;
|
| +};
|
| +
|
| +
|
| +template <typename T>
|
| +class VariableScope {
|
| + public:
|
| + explicit VariableScope(T* builder) : builder_(builder) {
|
| + builder_->variables().EnterScope();
|
| + }
|
| + ~VariableScope() { builder_->variables().LeaveScope(); }
|
| +
|
| + private:
|
| + T* builder_;
|
| +};
|
| +
|
| +
|
| +template <typename T>
|
| +class TypeParameterScope {
|
| + public:
|
| + explicit TypeParameterScope(T* builder) : builder_(builder) {
|
| + builder_->type_parameters().EnterScope();
|
| + }
|
| + ~TypeParameterScope() { builder_->type_parameters().LeaveScope(); }
|
| +
|
| + private:
|
| + T* builder_;
|
| +};
|
| +
|
| +
|
| +template <typename T>
|
| +class SwitchCaseScope {
|
| + public:
|
| + explicit SwitchCaseScope(T* builder) : builder_(builder) {
|
| + builder_->switch_cases().EnterScope();
|
| + }
|
| + ~SwitchCaseScope() { builder_->switch_cases().LeaveScope(); }
|
| +
|
| + private:
|
| + T* builder_;
|
| +};
|
| +
|
| +
|
| +class ReaderHelper {
|
| + public:
|
| + ReaderHelper() : program_(NULL) {}
|
| + ~ReaderHelper() {}
|
| +
|
| + Program* program() { return program_; }
|
| + void set_program(Program* program) { program_ = program; }
|
| +
|
| + BlockStack<VariableDeclaration>& variables() { return scope_; }
|
| + BlockStack<TypeParameter>& type_parameters() { return type_parameters_; }
|
| + BlockStack<LabeledStatement>& lables() { return labels_; }
|
| + BlockStack<SwitchCase>& switch_cases() { return switch_cases_; }
|
| +
|
| + private:
|
| + Program* program_;
|
| + BlockStack<VariableDeclaration> scope_;
|
| + BlockStack<TypeParameter> type_parameters_;
|
| + BlockStack<LabeledStatement> labels_;
|
| + BlockStack<SwitchCase> switch_cases_;
|
| +};
|
| +
|
| +
|
| +class Reader {
|
| + public:
|
| + Reader(const uint8_t* buffer, int64_t size)
|
| + : buffer_(buffer), size_(size), offset_(0) {}
|
| +
|
| + uint32_t ReadUInt32() {
|
| + ASSERT(offset_ + 4 <= size_);
|
| +
|
| + uint32_t value = (buffer_[offset_ + 0] << 24) |
|
| + (buffer_[offset_ + 1] << 16) |
|
| + (buffer_[offset_ + 2] << 8) | (buffer_[offset_ + 3] << 0);
|
| + offset_ += 4;
|
| + return value;
|
| + }
|
| +
|
| + uint32_t ReadUInt() {
|
| + ASSERT(offset_ + 1 <= size_);
|
| + uint8_t byte0 = buffer_[offset_];
|
| + if ((byte0 & 0x80) == 0) {
|
| + // 0...
|
| + offset_++;
|
| + return byte0;
|
| + } else if ((byte0 & 0xc0) == 0x80) {
|
| + // 10...
|
| + ASSERT(offset_ + 2 <= size_);
|
| + uint32_t value = ((byte0 & ~0x80) << 8) | (buffer_[offset_ + 1]);
|
| + offset_ += 2;
|
| + return value;
|
| + } else {
|
| + // 11...
|
| + ASSERT(offset_ + 4 <= size_);
|
| + uint32_t value = ((byte0 & ~0xc0) << 24) | (buffer_[offset_ + 1] << 16) |
|
| + (buffer_[offset_ + 2] << 8) |
|
| + (buffer_[offset_ + 3] << 0);
|
| + offset_ += 4;
|
| + return value;
|
| + }
|
| + }
|
| +
|
| + intptr_t ReadListLength() { return ReadUInt(); }
|
| +
|
| + uint8_t ReadByte() { return buffer_[offset_++]; }
|
| +
|
| + bool ReadBool() { return (ReadByte() & 1) == 1; }
|
| +
|
| + word ReadFlags() { return ReadByte(); }
|
| +
|
| + Tag ReadTag(uint8_t* payload = NULL) {
|
| + uint8_t byte = ReadByte();
|
| + bool has_payload = (byte & kSpecializedTagHighBit) != 0;
|
| + if (has_payload) {
|
| + if (payload != NULL) {
|
| + *payload = byte & kSpecializedPayloadMask;
|
| + }
|
| + return static_cast<Tag>(byte & kSpecializedTagMask);
|
| + } else {
|
| + return static_cast<Tag>(byte);
|
| + }
|
| + }
|
| +
|
| + const uint8_t* Consume(int count) {
|
| + ASSERT(offset_ + count <= size_);
|
| + const uint8_t* old = buffer_ + offset_;
|
| + offset_ += count;
|
| + return old;
|
| + }
|
| +
|
| + void EnsureEnd() {
|
| + if (offset_ != size_) {
|
| + FATAL2(
|
| + "Reading Kernel file: Expected to be at EOF "
|
| + "(offset: %" Pd64 ", size: %" Pd64 ")",
|
| + offset_, size_);
|
| + }
|
| + }
|
| +
|
| + void DumpOffset(const char* str) {
|
| + OS::PrintErr("@%" Pd64 " %s\n", offset_, str);
|
| + }
|
| +
|
| + template <typename T, typename RT>
|
| + T* ReadOptional() {
|
| + Tag tag = ReadTag();
|
| + if (tag == kNothing) {
|
| + return NULL;
|
| + }
|
| + ASSERT(tag == kSomething);
|
| + return RT::ReadFrom(this);
|
| + }
|
| +
|
| + template <typename T>
|
| + T* ReadOptional() {
|
| + return ReadOptional<T, T>();
|
| + }
|
| +
|
| + ReaderHelper* helper() { return &builder_; }
|
| +
|
| + private:
|
| + const uint8_t* buffer_;
|
| + int64_t size_;
|
| + int64_t offset_;
|
| + ReaderHelper builder_;
|
| +};
|
| +
|
| +
|
| +class WriterHelper {
|
| + public:
|
| + void SetProgram(Program* program) {
|
| + program_ = program;
|
| + for (int i = 0; i < program->libraries().length(); i++) {
|
| + Library* lib = program->libraries()[i];
|
| + libraries_.Set(lib, i);
|
| +
|
| + for (int j = 0; j < lib->classes().length(); j++) {
|
| + Class* klass = lib->classes()[j];
|
| + classes_.Set(klass, j);
|
| +
|
| + for (int k = 0; k < klass->fields().length(); k++) {
|
| + Field* field = klass->fields()[k];
|
| + fields_.Set(field, k);
|
| + }
|
| + for (int k = 0; k < klass->constructors().length(); k++) {
|
| + Constructor* constructor = klass->constructors()[k];
|
| + constructors_.Set(constructor, k);
|
| + }
|
| + for (int k = 0; k < klass->procedures().length(); k++) {
|
| + Procedure* procedure = klass->procedures()[k];
|
| + procedures_.Set(procedure, k);
|
| + }
|
| + }
|
| +
|
| + for (int k = 0; k < lib->fields().length(); k++) {
|
| + Field* field = lib->fields()[k];
|
| + fields_.Set(field, k);
|
| + }
|
| +
|
| + for (int k = 0; k < lib->procedures().length(); k++) {
|
| + Procedure* procedure = lib->procedures()[k];
|
| + procedures_.Set(procedure, k);
|
| + }
|
| + }
|
| + }
|
| +
|
| + Program* program() { return program_; }
|
| +
|
| + BlockMap<String>& strings() { return strings_; }
|
| + BlockMap<Library>& libraries() { return libraries_; }
|
| + BlockMap<Class>& classes() { return classes_; }
|
| + BlockMap<Field>& fields() { return fields_; }
|
| + BlockMap<Procedure>& procedures() { return procedures_; }
|
| + BlockMap<Constructor>& constructors() { return constructors_; }
|
| +
|
| + BlockMap<VariableDeclaration>& variables() { return scope_; }
|
| + BlockMap<TypeParameter>& type_parameters() { return type_parameters_; }
|
| + BlockMap<LabeledStatement>& lables() { return labels_; }
|
| + BlockMap<SwitchCase>& switch_cases() { return switch_cases_; }
|
| +
|
| + private:
|
| + Program* program_;
|
| +
|
| + BlockMap<String> strings_;
|
| + BlockMap<Library> libraries_;
|
| + BlockMap<Class> classes_;
|
| + BlockMap<Field> fields_;
|
| + BlockMap<Procedure> procedures_;
|
| + BlockMap<Constructor> constructors_;
|
| +
|
| + BlockMap<VariableDeclaration> scope_;
|
| + BlockMap<TypeParameter> type_parameters_;
|
| + BlockMap<LabeledStatement> labels_;
|
| + BlockMap<SwitchCase> switch_cases_;
|
| +};
|
| +
|
| +
|
| +class Writer {
|
| + public:
|
| + explicit Writer(ByteWriter* writer) : out_(writer), offset_(0) {}
|
| +
|
| + void WriteUInt32(uint32_t value) {
|
| + uint8_t buffer[4] = {
|
| + static_cast<uint8_t>((value >> 24) & 0xff),
|
| + static_cast<uint8_t>((value >> 16) & 0xff),
|
| + static_cast<uint8_t>((value >> 8) & 0xff),
|
| + static_cast<uint8_t>((value >> 0) & 0xff),
|
| + };
|
| + WriteBytes(buffer, 4);
|
| + }
|
| +
|
| + void WriteUInt(uint32_t value) {
|
| + if (value < 0x80) {
|
| + // 0...
|
| + WriteByte(static_cast<uint8_t>(value));
|
| + } else if (value < 0x4000) {
|
| + // 10...
|
| + WriteByte(static_cast<uint8_t>(((value >> 8) & 0x3f) | 0x80));
|
| + WriteByte(static_cast<uint8_t>(value & 0xff));
|
| + } else {
|
| + // 11...
|
| + // Ensure the highest 2 bits is not used for anything (we use it to for
|
| + // encoding).
|
| + ASSERT(static_cast<uint8_t>((value >> 24) & 0xc0) == 0);
|
| + uint8_t buffer[4] = {
|
| + static_cast<uint8_t>(((value >> 24) & 0x7f) | 0xc0),
|
| + static_cast<uint8_t>((value >> 16) & 0xff),
|
| + static_cast<uint8_t>((value >> 8) & 0xff),
|
| + static_cast<uint8_t>((value >> 0) & 0xff),
|
| + };
|
| + WriteBytes(buffer, 4);
|
| + }
|
| + }
|
| +
|
| + void WriteListLength(intptr_t value) { return WriteUInt(value); }
|
| +
|
| + void WriteByte(uint8_t value) {
|
| + out_->WriteByte(value);
|
| + offset_++;
|
| + }
|
| +
|
| + void WriteBool(bool value) { WriteByte(value ? 1 : 0); }
|
| +
|
| + void WriteFlags(uint8_t value) { WriteByte(value); }
|
| +
|
| + void WriteTag(Tag tag) { WriteByte(static_cast<uint8_t>(tag)); }
|
| +
|
| + void WriteTag(Tag tag, uint8_t payload) {
|
| + ASSERT((payload & ~kSpecializedPayloadMask) == 0);
|
| + WriteByte(kSpecializedTagHighBit | static_cast<uint8_t>(tag) | payload);
|
| + }
|
| +
|
| + void WriteBytes(uint8_t* bytes, int length) {
|
| + out_->WriteBytes(bytes, length);
|
| + offset_ += length;
|
| + }
|
| +
|
| + template <typename T>
|
| + void WriteOptional(T* object) {
|
| + if (object == NULL) {
|
| + WriteTag(kNothing);
|
| + } else {
|
| + WriteTag(kSomething);
|
| + object->WriteTo(this);
|
| + }
|
| + }
|
| +
|
| + template <typename T, typename WT>
|
| + void WriteOptionalStatic(T* object) {
|
| + if (object == NULL) {
|
| + WriteTag(kNothing);
|
| + } else {
|
| + WriteTag(kSomething);
|
| + WT::WriteTo(this, object);
|
| + }
|
| + }
|
| +
|
| + template <typename T>
|
| + void WriteOptionalStatic(T* object) {
|
| + return WriteOptionalStatic<T, T>(object);
|
| + }
|
| +
|
| + void DumpOffset(const char* str) {
|
| + OS::PrintErr("@%" Pd64 " %s\n", offset_, str);
|
| + }
|
| +
|
| + WriterHelper* helper() { return &helper_; }
|
| +
|
| + private:
|
| + ByteWriter* out_;
|
| + WriterHelper helper_;
|
| + int64_t offset_;
|
| +};
|
| +
|
| +
|
| +template <typename T>
|
| +template <typename IT>
|
| +void List<T>::ReadFrom(Reader* reader, TreeNode* parent) {
|
| + TRACE_READ_OFFSET();
|
| + ASSERT(parent != NULL);
|
| + int length = reader->ReadListLength();
|
| + EnsureInitialized(length);
|
| +
|
| + for (int i = 0; i < length_; i++) {
|
| + IT* object = GetOrCreate<IT>(i, parent);
|
| + object->ReadFrom(reader);
|
| + }
|
| +}
|
| +
|
| +
|
| +template <typename T>
|
| +template <typename IT>
|
| +void List<T>::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + int length = reader->ReadListLength();
|
| + EnsureInitialized(length);
|
| +
|
| + for (int i = 0; i < length_; i++) {
|
| + GetOrCreate<IT>(i)->ReadFrom(reader);
|
| + }
|
| +}
|
| +
|
| +
|
| +template <typename T>
|
| +template <typename IT>
|
| +void List<T>::ReadFromStatic(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + int length = reader->ReadListLength();
|
| + EnsureInitialized(length);
|
| +
|
| + for (int i = 0; i < length_; i++) {
|
| + ASSERT(array_[i] == NULL);
|
| + array_[i] = IT::ReadFrom(reader);
|
| + }
|
| +}
|
| +
|
| +
|
| +template <typename T>
|
| +void List<T>::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| +
|
| + // NOTE: We only support dense lists.
|
| + writer->WriteListLength(length_);
|
| + for (int i = 0; i < length_; i++) {
|
| + T* object = array_[i];
|
| + ASSERT(object != NULL);
|
| + object->WriteTo(writer);
|
| + }
|
| +}
|
| +
|
| +
|
| +template <typename T>
|
| +template <typename IT>
|
| +void List<T>::WriteToStatic(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| +
|
| + // NOTE: We only support dense lists.
|
| + writer->WriteListLength(length_);
|
| + for (int i = 0; i < length_; i++) {
|
| + T* object = array_[i];
|
| + ASSERT(object != NULL);
|
| + IT::WriteTo(writer, object);
|
| + }
|
| +}
|
| +
|
| +
|
| +void TypeParameterList::ReadFrom(Reader* reader) {
|
| + // It is possible for the bound of the first type parameter to refer to
|
| + // the second type parameter. This means we need to create [TypeParameter]
|
| + // objects before reading the bounds.
|
| + int length = reader->ReadListLength();
|
| + EnsureInitialized(length);
|
| +
|
| + // Make all [TypeParameter]s available in scope.
|
| + for (int i = 0; i < length; i++) {
|
| + TypeParameter* parameter = (*this)[i] = new TypeParameter();
|
| + reader->helper()->type_parameters().Push(parameter);
|
| + }
|
| +
|
| + // Read all [TypeParameter]s and their bounds.
|
| + for (int i = 0; i < length; i++) {
|
| + (*this)[i]->ReadFrom(reader);
|
| + }
|
| +}
|
| +
|
| +
|
| +void TypeParameterList::WriteTo(Writer* writer) {
|
| + writer->WriteListLength(length());
|
| +
|
| + // Make all [TypeParameter]s available in scope.
|
| + for (int i = 0; i < length(); i++) {
|
| + TypeParameter* parameter = (*this)[i];
|
| + writer->helper()->type_parameters().Push(parameter);
|
| + }
|
| +
|
| + // Write all [TypeParameter]s and their bounds.
|
| + for (int i = 0; i < length(); i++) {
|
| + TypeParameter* parameter = (*this)[i];
|
| + parameter->WriteTo(writer);
|
| + }
|
| +}
|
| +
|
| +
|
| +template <typename A, typename B>
|
| +Tuple<A, B>* Tuple<A, B>::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + A* first = A::ReadFrom(reader);
|
| + B* second = B::ReadFrom(reader);
|
| + return new Tuple<A, B>(first, second);
|
| +}
|
| +
|
| +
|
| +template <typename A, typename B>
|
| +void Tuple<A, B>::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + first_->WriteTo(writer);
|
| + second_->WriteTo(writer);
|
| +}
|
| +
|
| +
|
| +template <typename B, typename S>
|
| +class DowncastReader {
|
| + public:
|
| + static S* ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + return S::Cast(B::ReadFrom(reader));
|
| + }
|
| +};
|
| +
|
| +
|
| +class StringImpl {
|
| + public:
|
| + static String* ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + return String::ReadFromImpl(reader);
|
| + }
|
| +
|
| + static void WriteTo(Writer* writer, String* string) {
|
| + TRACE_WRITE_OFFSET();
|
| + string->WriteToImpl(writer);
|
| + }
|
| +};
|
| +
|
| +
|
| +class VariableDeclarationImpl {
|
| + public:
|
| + static VariableDeclaration* ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + return VariableDeclaration::ReadFromImpl(reader);
|
| + }
|
| +
|
| + static void WriteTo(Writer* writer, VariableDeclaration* d) {
|
| + TRACE_WRITE_OFFSET();
|
| + d->WriteToImpl(writer);
|
| + }
|
| +};
|
| +
|
| +
|
| +String* String::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + return Reference::ReadStringFrom(reader);
|
| +}
|
| +
|
| +
|
| +String* String::ReadFromImpl(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + uint32_t bytes = reader->ReadUInt();
|
| + String* string = new String(reader->Consume(bytes), bytes);
|
| + return string;
|
| +}
|
| +
|
| +
|
| +void String::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + Reference::WriteStringTo(writer, this);
|
| +}
|
| +
|
| +
|
| +void String::WriteToImpl(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + writer->WriteUInt(size_);
|
| + writer->WriteBytes(buffer_, size_);
|
| +}
|
| +
|
| +
|
| +void StringTable::ReadFrom(Reader* reader) {
|
| + strings_.ReadFromStatic<StringImpl>(reader);
|
| +}
|
| +
|
| +
|
| +void StringTable::WriteTo(Writer* writer) {
|
| + strings_.WriteToStatic<StringImpl>(writer);
|
| +
|
| + // Build up the "String* -> index" table.
|
| + WriterHelper* helper = writer->helper();
|
| + for (int i = 0; i < strings_.length(); i++) {
|
| + helper->strings().Push(strings_[i]);
|
| + }
|
| +}
|
| +
|
| +
|
| +void LineStartingTable::ReadFrom(Reader* reader, intptr_t length) {
|
| + size_ = length;
|
| + values_ = new intptr_t*[size_];
|
| + for (intptr_t i = 0; i < size_; ++i) {
|
| + intptr_t line_count = reader->ReadUInt();
|
| + intptr_t* line_starts = new intptr_t[line_count + 1];
|
| + line_starts[0] = line_count;
|
| + intptr_t previous_line_start = 0;
|
| + for (intptr_t j = 0; j < line_count; ++j) {
|
| + intptr_t lineStart = reader->ReadUInt() + previous_line_start;
|
| + line_starts[j + 1] = lineStart;
|
| + previous_line_start = lineStart;
|
| + }
|
| + values_[i] = line_starts;
|
| + }
|
| +}
|
| +
|
| +
|
| +void LineStartingTable::WriteTo(Writer* writer) {
|
| + for (intptr_t i = 0; i < size_; ++i) {
|
| + intptr_t* line_starts = values_[i];
|
| + intptr_t line_count = line_starts[0];
|
| + writer->WriteUInt(line_count);
|
| +
|
| + intptr_t previous_line_start = 0;
|
| + for (intptr_t j = 0; j < line_count; ++j) {
|
| + intptr_t line_start = line_starts[j + 1];
|
| + writer->WriteUInt(line_start - previous_line_start);
|
| + previous_line_start = line_start;
|
| + }
|
| + }
|
| +}
|
| +
|
| +
|
| +Library* Library::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + int flags = reader->ReadFlags();
|
| + ASSERT(flags == 0); // external libraries not supported
|
| + name_ = Reference::ReadStringFrom(reader);
|
| + import_uri_ = Reference::ReadStringFrom(reader);
|
| + reader->ReadUInt();
|
| +
|
| + int num_classes = reader->ReadUInt();
|
| + classes().EnsureInitialized(num_classes);
|
| + for (int i = 0; i < num_classes; i++) {
|
| + Tag tag = reader->ReadTag();
|
| + if (tag == kNormalClass) {
|
| + NormalClass* klass = classes().GetOrCreate<NormalClass>(i, this);
|
| + klass->ReadFrom(reader);
|
| + } else {
|
| + ASSERT(tag == kMixinClass);
|
| + MixinClass* klass = classes().GetOrCreate<MixinClass>(i, this);
|
| + klass->ReadFrom(reader);
|
| + }
|
| + }
|
| +
|
| + fields().ReadFrom<Field>(reader, this);
|
| + procedures().ReadFrom<Procedure>(reader, this);
|
| + return this;
|
| +}
|
| +
|
| +
|
| +void Library::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + name_->WriteTo(writer);
|
| + import_uri_->WriteTo(writer);
|
| + writer->WriteUInt(0);
|
| +
|
| + writer->WriteUInt(classes_.length());
|
| + for (int i = 0; i < classes_.length(); i++) {
|
| + Class* klass = classes_[i];
|
| + if (klass->IsNormalClass()) {
|
| + writer->WriteTag(kNormalClass);
|
| + NormalClass::Cast(klass)->WriteTo(writer);
|
| + } else {
|
| + writer->WriteTag(kMixinClass);
|
| + MixinClass::Cast(klass)->WriteTo(writer);
|
| + }
|
| + }
|
| + fields().WriteTo(writer);
|
| + procedures().WriteTo(writer);
|
| +}
|
| +
|
| +
|
| +Class* Class::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| +
|
| + is_abstract_ = reader->ReadBool();
|
| + name_ = Reference::ReadStringFrom(reader);
|
| + reader->ReadUInt();
|
| + annotations_.ReadFromStatic<Expression>(reader);
|
| +
|
| + return this;
|
| +}
|
| +
|
| +
|
| +void Class::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + writer->WriteBool(is_abstract_);
|
| + name_->WriteTo(writer);
|
| + writer->WriteUInt(0);
|
| + annotations_.WriteTo(writer);
|
| +}
|
| +
|
| +
|
| +NormalClass* NormalClass::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + Class::ReadFrom(reader);
|
| + TypeParameterScope<ReaderHelper> scope(reader->helper());
|
| +
|
| + type_parameters_.ReadFrom(reader);
|
| + DartType* type = reader->ReadOptional<DartType>();
|
| +
|
| + super_class_ = InterfaceType::Cast(type);
|
| + implemented_classes_.ReadFromStatic<DowncastReader<DartType, InterfaceType> >(
|
| + reader);
|
| + fields_.ReadFrom<Field>(reader, this);
|
| + constructors_.ReadFrom<Constructor>(reader, this);
|
| + procedures_.ReadFrom<Procedure>(reader, this);
|
| +
|
| + return this;
|
| +}
|
| +
|
| +
|
| +void NormalClass::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + Class::WriteTo(writer);
|
| + TypeParameterScope<WriterHelper> scope(writer->helper());
|
| +
|
| + type_parameters().WriteTo(writer);
|
| + writer->WriteOptional<DartType>(super_class_);
|
| + implemented_classes().WriteTo(writer);
|
| + fields_.WriteTo(writer);
|
| + constructors_.WriteTo(writer);
|
| + procedures_.WriteTo(writer);
|
| +}
|
| +
|
| +
|
| +MixinClass* MixinClass::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + TypeParameterScope<ReaderHelper> scope(reader->helper());
|
| +
|
| + Class::ReadFrom(reader);
|
| + type_parameters_.ReadFrom(reader);
|
| + first_ = InterfaceType::Cast(DartType::ReadFrom(reader));
|
| + second_ = InterfaceType::Cast(DartType::ReadFrom(reader));
|
| + implemented_classes_.ReadFromStatic<DowncastReader<DartType, InterfaceType> >(
|
| + reader);
|
| + constructors_.ReadFrom<Constructor>(reader, this);
|
| + return this;
|
| +}
|
| +
|
| +
|
| +void MixinClass::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + TypeParameterScope<WriterHelper> scope(writer->helper());
|
| +
|
| + Class::WriteTo(writer);
|
| + type_parameters_.WriteTo(writer);
|
| + first_->WriteTo(writer);
|
| + second_->WriteTo(writer);
|
| + implemented_classes_.WriteTo(writer);
|
| + constructors_.WriteTo(writer);
|
| +}
|
| +
|
| +
|
| +Member* Reference::ReadMemberFrom(Reader* reader, bool allow_null) {
|
| + TRACE_READ_OFFSET();
|
| +
|
| + Program* program = reader->helper()->program();
|
| + Tag tag = reader->ReadTag();
|
| + switch (tag) {
|
| + case kLibraryFieldReference: {
|
| + int library_idx = reader->ReadUInt();
|
| + int field_idx = reader->ReadUInt();
|
| + Library* library = program->libraries().GetOrCreate<Library>(library_idx);
|
| + return library->fields().GetOrCreate<Field>(field_idx, library);
|
| + }
|
| + case kLibraryProcedureReference: {
|
| + int library_idx = reader->ReadUInt();
|
| + int procedure_idx = reader->ReadUInt();
|
| + Library* library = program->libraries().GetOrCreate<Library>(library_idx);
|
| + return library->procedures().GetOrCreate<Procedure>(procedure_idx,
|
| + library);
|
| + }
|
| + case kClassFieldReference:
|
| + case kClassConstructorReference:
|
| + case kClassProcedureReference: {
|
| + Class* klass = Reference::ReadClassFrom(reader);
|
| + if (tag == kClassFieldReference) {
|
| + int field_idx = reader->ReadUInt();
|
| + return klass->fields().GetOrCreate<Field>(field_idx, klass);
|
| + } else if (tag == kClassConstructorReference) {
|
| + int constructor_idx = reader->ReadUInt();
|
| + return klass->constructors().GetOrCreate<Constructor>(constructor_idx,
|
| + klass);
|
| + } else {
|
| + ASSERT(tag == kClassProcedureReference);
|
| + int procedure_idx = reader->ReadUInt();
|
| + return klass->procedures().GetOrCreate<Procedure>(procedure_idx, klass);
|
| + }
|
| + }
|
| + case kNullReference:
|
| + if (allow_null) {
|
| + return NULL;
|
| + } else {
|
| + FATAL("Expected a valid member reference, but got `null`");
|
| + }
|
| + default:
|
| + UNREACHABLE();
|
| + break;
|
| + }
|
| +
|
| + UNREACHABLE();
|
| + return NULL;
|
| +}
|
| +
|
| +
|
| +void Reference::WriteMemberTo(Writer* writer, Member* member, bool allow_null) {
|
| + TRACE_WRITE_OFFSET();
|
| + if (member == NULL) {
|
| + if (allow_null) {
|
| + writer->WriteTag(kNullReference);
|
| + return;
|
| + } else {
|
| + FATAL("Expected a valid member reference but got `null`");
|
| + }
|
| + }
|
| + TreeNode* node = member->parent();
|
| +
|
| + WriterHelper* helper = writer->helper();
|
| +
|
| + if (node->IsLibrary()) {
|
| + Library* library = Library::Cast(node);
|
| + if (member->IsField()) {
|
| + Field* field = Field::Cast(member);
|
| + writer->WriteTag(kLibraryFieldReference);
|
| + writer->WriteUInt(helper->libraries().Lookup(library));
|
| + writer->WriteUInt(helper->fields().Lookup(field));
|
| + } else {
|
| + Procedure* procedure = Procedure::Cast(member);
|
| + writer->WriteTag(kLibraryProcedureReference);
|
| + writer->WriteUInt(helper->libraries().Lookup(library));
|
| + writer->WriteUInt(helper->procedures().Lookup(procedure));
|
| + }
|
| + } else {
|
| + Class* klass = Class::Cast(node);
|
| +
|
| + if (member->IsField()) {
|
| + Field* field = Field::Cast(member);
|
| + writer->WriteTag(kClassFieldReference);
|
| + Reference::WriteClassTo(writer, klass);
|
| + writer->WriteUInt(helper->fields().Lookup(field));
|
| + } else if (member->IsConstructor()) {
|
| + Constructor* constructor = Constructor::Cast(member);
|
| + writer->WriteTag(kClassConstructorReference);
|
| + Reference::WriteClassTo(writer, klass);
|
| + writer->WriteUInt(helper->constructors().Lookup(constructor));
|
| + } else {
|
| + Procedure* procedure = Procedure::Cast(member);
|
| + writer->WriteTag(kClassProcedureReference);
|
| + Reference::WriteClassTo(writer, klass);
|
| + writer->WriteUInt(helper->procedures().Lookup(procedure));
|
| + }
|
| + }
|
| +}
|
| +
|
| +
|
| +Class* Reference::ReadClassFrom(Reader* reader, bool allow_null) {
|
| + TRACE_READ_OFFSET();
|
| + Program* program = reader->helper()->program();
|
| +
|
| + Tag klass_member_tag = reader->ReadTag();
|
| + if (klass_member_tag == kNullReference) {
|
| + if (allow_null) {
|
| + return NULL;
|
| + } else {
|
| + FATAL("Expected a valid class reference but got `null`.");
|
| + }
|
| + }
|
| + int library_idx = reader->ReadUInt();
|
| + int class_idx = reader->ReadUInt();
|
| +
|
| + Library* library = program->libraries().GetOrCreate<Library>(library_idx);
|
| + Class* klass;
|
| + if (klass_member_tag == kNormalClassReference) {
|
| + klass = library->classes().GetOrCreate<NormalClass>(class_idx, library);
|
| + } else {
|
| + ASSERT(klass_member_tag == kMixinClassReference);
|
| + klass = library->classes().GetOrCreate<MixinClass>(class_idx, library);
|
| + }
|
| + return klass;
|
| +}
|
| +
|
| +
|
| +void Reference::WriteClassTo(Writer* writer, Class* klass, bool allow_null) {
|
| + TRACE_WRITE_OFFSET();
|
| + if (klass == NULL) {
|
| + if (allow_null) {
|
| + writer->WriteTag(kNullReference);
|
| + return;
|
| + } else {
|
| + FATAL("Expected a valid class reference but got `null`.");
|
| + }
|
| + }
|
| + if (klass->IsNormalClass()) {
|
| + writer->WriteTag(kNormalClassReference);
|
| + } else {
|
| + ASSERT(klass->IsMixinClass());
|
| + writer->WriteTag(kMixinClassReference);
|
| + }
|
| +
|
| + writer->WriteUInt(writer->helper()->libraries().Lookup(klass->parent()));
|
| + writer->WriteUInt(writer->helper()->classes().Lookup(klass));
|
| +}
|
| +
|
| +
|
| +String* Reference::ReadStringFrom(Reader* reader) {
|
| + int index = reader->ReadUInt();
|
| + return reader->helper()->program()->string_table().strings()[index];
|
| +}
|
| +
|
| +
|
| +void Reference::WriteStringTo(Writer* writer, String* string) {
|
| + int index = writer->helper()->strings().Lookup(string);
|
| + writer->WriteUInt(index);
|
| +}
|
| +
|
| +
|
| +Field* Field::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + Tag tag = reader->ReadTag();
|
| + ASSERT(tag == kField);
|
| +
|
| + reader->ReadUInt();
|
| + flags_ = reader->ReadFlags();
|
| + name_ = Name::ReadFrom(reader);
|
| + reader->ReadUInt();
|
| + annotations_.ReadFromStatic<Expression>(reader);
|
| + type_ = DartType::ReadFrom(reader);
|
| + inferred_value_ = reader->ReadOptional<InferredValue>();
|
| + initializer_ = reader->ReadOptional<Expression>();
|
| + return this;
|
| +}
|
| +
|
| +
|
| +void Field::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + writer->WriteTag(kField);
|
| + writer->WriteUInt(0);
|
| + writer->WriteFlags(flags_);
|
| + name_->WriteTo(writer);
|
| + writer->WriteUInt(0);
|
| + annotations_.WriteTo(writer);
|
| + type_->WriteTo(writer);
|
| + writer->WriteOptional<InferredValue>(inferred_value_);
|
| + writer->WriteOptional<Expression>(initializer_);
|
| +}
|
| +
|
| +
|
| +Constructor* Constructor::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + Tag tag = reader->ReadTag();
|
| + ASSERT(tag == kConstructor);
|
| +
|
| + VariableScope<ReaderHelper> parameters(reader->helper());
|
| + flags_ = reader->ReadFlags();
|
| + name_ = Name::ReadFrom(reader);
|
| + annotations_.ReadFromStatic<Expression>(reader);
|
| + function_ = FunctionNode::ReadFrom(reader);
|
| + initializers_.ReadFromStatic<Initializer>(reader);
|
| + return this;
|
| +}
|
| +
|
| +
|
| +void Constructor::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + writer->WriteTag(kConstructor);
|
| +
|
| + VariableScope<WriterHelper> parameters(writer->helper());
|
| + writer->WriteFlags(flags_);
|
| + name_->WriteTo(writer);
|
| + annotations_.WriteTo(writer);
|
| + function_->WriteTo(writer);
|
| + initializers_.WriteTo(writer);
|
| +}
|
| +
|
| +
|
| +Procedure* Procedure::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + Tag tag = reader->ReadTag();
|
| + ASSERT(tag == kProcedure);
|
| +
|
| + VariableScope<ReaderHelper> parameters(reader->helper());
|
| + kind_ = static_cast<ProcedureKind>(reader->ReadByte());
|
| + flags_ = reader->ReadFlags();
|
| + name_ = Name::ReadFrom(reader);
|
| + reader->ReadUInt();
|
| + annotations_.ReadFromStatic<Expression>(reader);
|
| + function_ = reader->ReadOptional<FunctionNode>();
|
| + return this;
|
| +}
|
| +
|
| +
|
| +void Procedure::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + writer->WriteTag(kProcedure);
|
| +
|
| + VariableScope<WriterHelper> parameters(writer->helper());
|
| + writer->WriteByte(kind_);
|
| + writer->WriteFlags(flags_);
|
| + name_->WriteTo(writer);
|
| + writer->WriteUInt(0);
|
| + annotations_.WriteTo(writer);
|
| + writer->WriteOptional<FunctionNode>(function_);
|
| +}
|
| +
|
| +
|
| +Initializer* Initializer::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + Tag tag = reader->ReadTag();
|
| + switch (tag) {
|
| + case kInvalidInitializer:
|
| + return InvalidInitializer::ReadFromImpl(reader);
|
| + case kFieldInitializer:
|
| + return FieldInitializer::ReadFromImpl(reader);
|
| + case kSuperInitializer:
|
| + return SuperInitializer::ReadFromImpl(reader);
|
| + case kRedirectingInitializer:
|
| + return RedirectingInitializer::ReadFromImpl(reader);
|
| + case kLocalInitializer:
|
| + return LocalInitializer::ReadFromImpl(reader);
|
| + default:
|
| + UNREACHABLE();
|
| + }
|
| + return NULL;
|
| +}
|
| +
|
| +
|
| +InvalidInitializer* InvalidInitializer::ReadFromImpl(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + return new InvalidInitializer();
|
| +}
|
| +
|
| +
|
| +void InvalidInitializer::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + writer->WriteTag(kInvalidInitializer);
|
| +}
|
| +
|
| +
|
| +FieldInitializer* FieldInitializer::ReadFromImpl(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + FieldInitializer* initializer = new FieldInitializer();
|
| + initializer->field_ = Field::Cast(Reference::ReadMemberFrom(reader));
|
| + initializer->value_ = Expression::ReadFrom(reader);
|
| + return initializer;
|
| +}
|
| +
|
| +
|
| +void FieldInitializer::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + writer->WriteTag(kFieldInitializer);
|
| + Reference::WriteMemberTo(writer, field_);
|
| + value_->WriteTo(writer);
|
| +}
|
| +
|
| +
|
| +SuperInitializer* SuperInitializer::ReadFromImpl(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + SuperInitializer* init = new SuperInitializer();
|
| + init->target_ = Constructor::Cast(Reference::ReadMemberFrom(reader));
|
| + init->arguments_ = Arguments::ReadFrom(reader);
|
| + return init;
|
| +}
|
| +
|
| +
|
| +void SuperInitializer::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + writer->WriteTag(kSuperInitializer);
|
| + Reference::WriteMemberTo(writer, target_);
|
| + arguments_->WriteTo(writer);
|
| +}
|
| +
|
| +
|
| +RedirectingInitializer* RedirectingInitializer::ReadFromImpl(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + RedirectingInitializer* init = new RedirectingInitializer();
|
| + init->target_ = Constructor::Cast(Reference::ReadMemberFrom(reader));
|
| + init->arguments_ = Arguments::ReadFrom(reader);
|
| + return init;
|
| +}
|
| +
|
| +
|
| +void RedirectingInitializer::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + writer->WriteTag(kRedirectingInitializer);
|
| + Reference::WriteMemberTo(writer, target_);
|
| + arguments_->WriteTo(writer);
|
| +}
|
| +
|
| +
|
| +LocalInitializer* LocalInitializer::ReadFromImpl(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + LocalInitializer* init = new LocalInitializer();
|
| + init->variable_ = VariableDeclaration::ReadFromImpl(reader);
|
| + return init;
|
| +}
|
| +
|
| +
|
| +void LocalInitializer::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + writer->WriteTag(kLocalInitializer);
|
| + variable_->WriteToImpl(writer);
|
| +}
|
| +
|
| +
|
| +Expression* Expression::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + uint8_t payload = 0;
|
| + Tag tag = reader->ReadTag(&payload);
|
| + switch (tag) {
|
| + case kInvalidExpression:
|
| + return InvalidExpression::ReadFrom(reader);
|
| + case kVariableGet:
|
| + return VariableGet::ReadFrom(reader);
|
| + case kSpecializedVariableGet:
|
| + return VariableGet::ReadFrom(reader, payload);
|
| + case kVariableSet:
|
| + return VariableSet::ReadFrom(reader);
|
| + case kSpecializedVariableSet:
|
| + return VariableSet::ReadFrom(reader, payload);
|
| + case kPropertyGet:
|
| + return PropertyGet::ReadFrom(reader);
|
| + case kPropertySet:
|
| + return PropertySet::ReadFrom(reader);
|
| + case kDirectPropertyGet:
|
| + return DirectPropertyGet::ReadFrom(reader);
|
| + case kDirectPropertySet:
|
| + return DirectPropertySet::ReadFrom(reader);
|
| + case kStaticGet:
|
| + return StaticGet::ReadFrom(reader);
|
| + case kStaticSet:
|
| + return StaticSet::ReadFrom(reader);
|
| + case kMethodInvocation:
|
| + return MethodInvocation::ReadFrom(reader);
|
| + case kDirectMethodInvocation:
|
| + return DirectMethodInvocation::ReadFrom(reader);
|
| + case kStaticInvocation:
|
| + return StaticInvocation::ReadFrom(reader, false);
|
| + case kConstStaticInvocation:
|
| + return StaticInvocation::ReadFrom(reader, true);
|
| + case kConstructorInvocation:
|
| + return ConstructorInvocation::ReadFrom(reader, false);
|
| + case kConstConstructorInvocation:
|
| + return ConstructorInvocation::ReadFrom(reader, true);
|
| + case kNot:
|
| + return Not::ReadFrom(reader);
|
| + case kLogicalExpression:
|
| + return LogicalExpression::ReadFrom(reader);
|
| + case kConditionalExpression:
|
| + return ConditionalExpression::ReadFrom(reader);
|
| + case kStringConcatenation:
|
| + return StringConcatenation::ReadFrom(reader);
|
| + case kIsExpression:
|
| + return IsExpression::ReadFrom(reader);
|
| + case kAsExpression:
|
| + return AsExpression::ReadFrom(reader);
|
| + case kSymbolLiteral:
|
| + return SymbolLiteral::ReadFrom(reader);
|
| + case kTypeLiteral:
|
| + return TypeLiteral::ReadFrom(reader);
|
| + case kThisExpression:
|
| + return ThisExpression::ReadFrom(reader);
|
| + case kRethrow:
|
| + return Rethrow::ReadFrom(reader);
|
| + case kThrow:
|
| + return Throw::ReadFrom(reader);
|
| + case kListLiteral:
|
| + return ListLiteral::ReadFrom(reader, false);
|
| + case kConstListLiteral:
|
| + return ListLiteral::ReadFrom(reader, true);
|
| + case kMapLiteral:
|
| + return MapLiteral::ReadFrom(reader, false);
|
| + case kConstMapLiteral:
|
| + return MapLiteral::ReadFrom(reader, true);
|
| + case kAwaitExpression:
|
| + return AwaitExpression::ReadFrom(reader);
|
| + case kFunctionExpression:
|
| + return FunctionExpression::ReadFrom(reader);
|
| + case kLet:
|
| + return Let::ReadFrom(reader);
|
| + case kBlockExpression:
|
| + return BlockExpression::ReadFrom(reader);
|
| + case kBigIntLiteral:
|
| + return BigintLiteral::ReadFrom(reader);
|
| + case kStringLiteral:
|
| + return StringLiteral::ReadFrom(reader);
|
| + case kSpecialIntLiteral:
|
| + return IntLiteral::ReadFrom(reader, payload);
|
| + case kNegativeIntLiteral:
|
| + return IntLiteral::ReadFrom(reader, true);
|
| + case kPositiveIntLiteral:
|
| + return IntLiteral::ReadFrom(reader, false);
|
| + case kDoubleLiteral:
|
| + return DoubleLiteral::ReadFrom(reader);
|
| + case kTrueLiteral:
|
| + return BoolLiteral::ReadFrom(reader, true);
|
| + case kFalseLiteral:
|
| + return BoolLiteral::ReadFrom(reader, false);
|
| + case kNullLiteral:
|
| + return NullLiteral::ReadFrom(reader);
|
| + default:
|
| + UNREACHABLE();
|
| + }
|
| + return NULL;
|
| +}
|
| +
|
| +
|
| +InvalidExpression* InvalidExpression::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + return new InvalidExpression();
|
| +}
|
| +
|
| +
|
| +void InvalidExpression::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + writer->WriteTag(kInvalidExpression);
|
| +}
|
| +
|
| +
|
| +VariableGet* VariableGet::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + VariableGet* get = new VariableGet();
|
| + get->variable_ = reader->helper()->variables().Lookup(reader->ReadUInt());
|
| + reader->ReadOptional<DartType>(); // Unused promoted type.
|
| + return get;
|
| +}
|
| +
|
| +
|
| +VariableGet* VariableGet::ReadFrom(Reader* reader, uint8_t payload) {
|
| + TRACE_READ_OFFSET();
|
| + VariableGet* get = new VariableGet();
|
| + get->variable_ = reader->helper()->variables().Lookup(payload);
|
| + return get;
|
| +}
|
| +
|
| +
|
| +void VariableGet::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + int index = writer->helper()->variables().Lookup(variable_);
|
| + if ((index & kSpecializedPayloadMask) == index) {
|
| + writer->WriteTag(kSpecializedVariableGet, static_cast<uint8_t>(index));
|
| + } else {
|
| + writer->WriteTag(kVariableGet);
|
| + writer->WriteUInt(index);
|
| + writer->WriteOptional<DartType>(NULL);
|
| + }
|
| +}
|
| +
|
| +
|
| +VariableSet* VariableSet::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + VariableSet* set = new VariableSet();
|
| + set->variable_ = reader->helper()->variables().Lookup(reader->ReadUInt());
|
| + set->expression_ = Expression::ReadFrom(reader);
|
| + return set;
|
| +}
|
| +
|
| +
|
| +VariableSet* VariableSet::ReadFrom(Reader* reader, uint8_t payload) {
|
| + TRACE_READ_OFFSET();
|
| + VariableSet* set = new VariableSet();
|
| + set->variable_ = reader->helper()->variables().Lookup(payload);
|
| + set->expression_ = Expression::ReadFrom(reader);
|
| + return set;
|
| +}
|
| +
|
| +
|
| +void VariableSet::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + int index = writer->helper()->variables().Lookup(variable_);
|
| + if ((index & kSpecializedPayloadMask) == index) {
|
| + writer->WriteTag(kSpecializedVariableSet, static_cast<uint8_t>(index));
|
| + } else {
|
| + writer->WriteTag(kVariableSet);
|
| + writer->WriteUInt(index);
|
| + }
|
| + expression_->WriteTo(writer);
|
| +}
|
| +
|
| +
|
| +PropertyGet* PropertyGet::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + PropertyGet* get = new PropertyGet();
|
| + reader->ReadUInt();
|
| + get->receiver_ = Expression::ReadFrom(reader);
|
| + get->name_ = Name::ReadFrom(reader);
|
| + get->interfaceTarget_ = Reference::ReadMemberFrom(reader, true);
|
| + return get;
|
| +}
|
| +
|
| +
|
| +void PropertyGet::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + writer->WriteTag(kPropertyGet);
|
| + writer->WriteUInt(0);
|
| + receiver_->WriteTo(writer);
|
| + name_->WriteTo(writer);
|
| + Reference::WriteMemberTo(writer, interfaceTarget_, true);
|
| +}
|
| +
|
| +
|
| +PropertySet* PropertySet::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + PropertySet* set = new PropertySet();
|
| + reader->ReadUInt();
|
| + set->receiver_ = Expression::ReadFrom(reader);
|
| + set->name_ = Name::ReadFrom(reader);
|
| + set->value_ = Expression::ReadFrom(reader);
|
| + set->interfaceTarget_ = Reference::ReadMemberFrom(reader, true);
|
| + return set;
|
| +}
|
| +
|
| +
|
| +void PropertySet::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + writer->WriteTag(kPropertySet);
|
| + writer->WriteUInt(0);
|
| + receiver_->WriteTo(writer);
|
| + name_->WriteTo(writer);
|
| + value_->WriteTo(writer);
|
| + Reference::WriteMemberTo(writer, interfaceTarget_, true);
|
| +}
|
| +
|
| +
|
| +DirectPropertyGet* DirectPropertyGet::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + DirectPropertyGet* get = new DirectPropertyGet();
|
| + get->receiver_ = Expression::ReadFrom(reader);
|
| + get->target_ = Reference::ReadMemberFrom(reader);
|
| + return get;
|
| +}
|
| +
|
| +
|
| +void DirectPropertyGet::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + writer->WriteTag(kDirectPropertyGet);
|
| + receiver_->WriteTo(writer);
|
| + Reference::WriteMemberTo(writer, target_);
|
| +}
|
| +
|
| +
|
| +DirectPropertySet* DirectPropertySet::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + DirectPropertySet* set = new DirectPropertySet();
|
| + set->receiver_ = Expression::ReadFrom(reader);
|
| + set->target_ = Reference::ReadMemberFrom(reader);
|
| + set->value_ = Expression::ReadFrom(reader);
|
| + return set;
|
| +}
|
| +
|
| +
|
| +void DirectPropertySet::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + writer->WriteTag(kDirectPropertySet);
|
| + receiver_->WriteTo(writer);
|
| + Reference::WriteMemberTo(writer, target_);
|
| + value_->WriteTo(writer);
|
| +}
|
| +
|
| +
|
| +StaticGet* StaticGet::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + StaticGet* get = new StaticGet();
|
| + reader->ReadUInt();
|
| + get->target_ = Reference::ReadMemberFrom(reader);
|
| + return get;
|
| +}
|
| +
|
| +
|
| +void StaticGet::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + writer->WriteTag(kStaticGet);
|
| + writer->WriteUInt(0);
|
| + Reference::WriteMemberTo(writer, target_);
|
| +}
|
| +
|
| +
|
| +StaticSet* StaticSet::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + StaticSet* set = new StaticSet();
|
| + set->target_ = Reference::ReadMemberFrom(reader);
|
| + set->expression_ = Expression::ReadFrom(reader);
|
| + return set;
|
| +}
|
| +
|
| +
|
| +void StaticSet::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + writer->WriteTag(kStaticSet);
|
| + Reference::WriteMemberTo(writer, target_);
|
| + expression_->WriteTo(writer);
|
| +}
|
| +
|
| +
|
| +Arguments* Arguments::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + Arguments* arguments = new Arguments();
|
| + arguments->types().ReadFromStatic<DartType>(reader);
|
| + arguments->positional().ReadFromStatic<Expression>(reader);
|
| + arguments->named().ReadFromStatic<NamedExpression>(reader);
|
| + return arguments;
|
| +}
|
| +
|
| +
|
| +void Arguments::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + types().WriteTo(writer);
|
| + positional().WriteTo(writer);
|
| + named().WriteTo(writer);
|
| +}
|
| +
|
| +
|
| +NamedExpression* NamedExpression::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + String* name = Reference::ReadStringFrom(reader);
|
| + Expression* expression = Expression::ReadFrom(reader);
|
| + return new NamedExpression(name, expression);
|
| +}
|
| +
|
| +
|
| +void NamedExpression::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + name_->WriteTo(writer);
|
| + expression_->WriteTo(writer);
|
| +}
|
| +
|
| +
|
| +MethodInvocation* MethodInvocation::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + MethodInvocation* invocation = new MethodInvocation();
|
| + reader->ReadUInt();
|
| + invocation->receiver_ = Expression::ReadFrom(reader);
|
| + invocation->name_ = Name::ReadFrom(reader);
|
| + invocation->arguments_ = Arguments::ReadFrom(reader);
|
| + invocation->interfaceTarget_ = Reference::ReadMemberFrom(reader, true);
|
| + return invocation;
|
| +}
|
| +
|
| +
|
| +void MethodInvocation::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + writer->WriteTag(kMethodInvocation);
|
| + writer->WriteUInt(0);
|
| + receiver_->WriteTo(writer);
|
| + name_->WriteTo(writer);
|
| + arguments_->WriteTo(writer);
|
| + Reference::WriteMemberTo(writer, interfaceTarget_, true);
|
| +}
|
| +
|
| +
|
| +DirectMethodInvocation* DirectMethodInvocation::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + DirectMethodInvocation* invocation = new DirectMethodInvocation();
|
| + invocation->receiver_ = Expression::ReadFrom(reader);
|
| + invocation->target_ = Procedure::Cast(Reference::ReadMemberFrom(reader));
|
| + invocation->arguments_ = Arguments::ReadFrom(reader);
|
| + return invocation;
|
| +}
|
| +
|
| +
|
| +void DirectMethodInvocation::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + writer->WriteTag(kDirectMethodInvocation);
|
| + receiver_->WriteTo(writer);
|
| + Reference::WriteMemberTo(writer, target_);
|
| + arguments_->WriteTo(writer);
|
| +}
|
| +
|
| +
|
| +StaticInvocation* StaticInvocation::ReadFrom(Reader* reader, bool is_const) {
|
| + TRACE_READ_OFFSET();
|
| +
|
| + reader->ReadUInt();
|
| + Member* member = Reference::ReadMemberFrom(reader);
|
| + Arguments* args = Arguments::ReadFrom(reader);
|
| +
|
| + return new StaticInvocation(Procedure::Cast(member), args, is_const);
|
| +}
|
| +
|
| +
|
| +void StaticInvocation::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + writer->WriteTag(is_const_ ? kConstStaticInvocation : kStaticInvocation);
|
| + writer->WriteUInt(0);
|
| + Reference::WriteMemberTo(writer, procedure_);
|
| + arguments_->WriteTo(writer);
|
| +}
|
| +
|
| +
|
| +ConstructorInvocation* ConstructorInvocation::ReadFrom(Reader* reader,
|
| + bool is_const) {
|
| + TRACE_READ_OFFSET();
|
| + ConstructorInvocation* invocation = new ConstructorInvocation();
|
| + invocation->is_const_ = is_const;
|
| + reader->ReadUInt();
|
| + invocation->target_ = Constructor::Cast(Reference::ReadMemberFrom(reader));
|
| + invocation->arguments_ = Arguments::ReadFrom(reader);
|
| + return invocation;
|
| +}
|
| +
|
| +
|
| +void ConstructorInvocation::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + writer->WriteTag(is_const_ ? kConstConstructorInvocation
|
| + : kConstructorInvocation);
|
| + writer->WriteUInt(0);
|
| + Reference::WriteMemberTo(writer, target_);
|
| + arguments_->WriteTo(writer);
|
| +}
|
| +
|
| +
|
| +Not* Not::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + Not* n = new Not();
|
| + n->expression_ = Expression::ReadFrom(reader);
|
| + return n;
|
| +}
|
| +
|
| +
|
| +void Not::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + writer->WriteTag(kNot);
|
| + expression_->WriteTo(writer);
|
| +}
|
| +
|
| +
|
| +LogicalExpression* LogicalExpression::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + LogicalExpression* expr = new LogicalExpression();
|
| + expr->left_ = Expression::ReadFrom(reader);
|
| + expr->operator_ = static_cast<Operator>(reader->ReadByte());
|
| + expr->right_ = Expression::ReadFrom(reader);
|
| + return expr;
|
| +}
|
| +
|
| +
|
| +void LogicalExpression::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + writer->WriteTag(kLogicalExpression);
|
| + left_->WriteTo(writer);
|
| + writer->WriteByte(operator_);
|
| + right_->WriteTo(writer);
|
| +}
|
| +
|
| +
|
| +ConditionalExpression* ConditionalExpression::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + ConditionalExpression* expr = new ConditionalExpression();
|
| + expr->condition_ = Expression::ReadFrom(reader);
|
| + expr->then_ = Expression::ReadFrom(reader);
|
| + expr->otherwise_ = Expression::ReadFrom(reader);
|
| + reader->ReadOptional<DartType>(); // Unused static type.
|
| + return expr;
|
| +}
|
| +
|
| +
|
| +void ConditionalExpression::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + writer->WriteTag(kConditionalExpression);
|
| + condition_->WriteTo(writer);
|
| + then_->WriteTo(writer);
|
| + otherwise_->WriteTo(writer);
|
| + writer->WriteOptional<DartType>(NULL); // Unused static type.
|
| +}
|
| +
|
| +
|
| +StringConcatenation* StringConcatenation::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + StringConcatenation* concat = new StringConcatenation();
|
| + concat->expressions_.ReadFromStatic<Expression>(reader);
|
| + return concat;
|
| +}
|
| +
|
| +
|
| +void StringConcatenation::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + writer->WriteTag(kStringConcatenation);
|
| + expressions_.WriteTo(writer);
|
| +}
|
| +
|
| +
|
| +IsExpression* IsExpression::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + IsExpression* expr = new IsExpression();
|
| + expr->operand_ = Expression::ReadFrom(reader);
|
| + expr->type_ = DartType::ReadFrom(reader);
|
| + return expr;
|
| +}
|
| +
|
| +
|
| +void IsExpression::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + writer->WriteTag(kIsExpression);
|
| + operand_->WriteTo(writer);
|
| + type_->WriteTo(writer);
|
| +}
|
| +
|
| +
|
| +AsExpression* AsExpression::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + AsExpression* expr = new AsExpression();
|
| + expr->operand_ = Expression::ReadFrom(reader);
|
| + expr->type_ = DartType::ReadFrom(reader);
|
| + return expr;
|
| +}
|
| +
|
| +
|
| +void AsExpression::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + writer->WriteTag(kAsExpression);
|
| + operand_->WriteTo(writer);
|
| + type_->WriteTo(writer);
|
| +}
|
| +
|
| +
|
| +StringLiteral* StringLiteral::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + return new StringLiteral(Reference::ReadStringFrom(reader));
|
| +}
|
| +
|
| +
|
| +void StringLiteral::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + writer->WriteTag(kStringLiteral);
|
| + value_->WriteTo(writer);
|
| +}
|
| +
|
| +
|
| +BigintLiteral* BigintLiteral::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + return new BigintLiteral(Reference::ReadStringFrom(reader));
|
| +}
|
| +
|
| +
|
| +void BigintLiteral::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + writer->WriteTag(kBigIntLiteral);
|
| + value_->WriteTo(writer);
|
| +}
|
| +
|
| +
|
| +IntLiteral* IntLiteral::ReadFrom(Reader* reader, bool is_negative) {
|
| + TRACE_READ_OFFSET();
|
| + IntLiteral* literal = new IntLiteral();
|
| + literal->value_ = is_negative ? -static_cast<int64_t>(reader->ReadUInt())
|
| + : reader->ReadUInt();
|
| + return literal;
|
| +}
|
| +
|
| +
|
| +IntLiteral* IntLiteral::ReadFrom(Reader* reader, uint8_t payload) {
|
| + TRACE_READ_OFFSET();
|
| + IntLiteral* literal = new IntLiteral();
|
| + literal->value_ = static_cast<int32_t>(payload) - SpecializedIntLiteralBias;
|
| + return literal;
|
| +}
|
| +
|
| +
|
| +void IntLiteral::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + int64_t payload = value_ + SpecializedIntLiteralBias;
|
| + if ((payload & kSpecializedPayloadMask) == payload) {
|
| + writer->WriteTag(kSpecialIntLiteral, static_cast<uint8_t>(payload));
|
| + } else {
|
| + writer->WriteTag(value_ < 0 ? kNegativeIntLiteral : kPositiveIntLiteral);
|
| + writer->WriteUInt(static_cast<uint32_t>(value_ < 0 ? -value_ : value_));
|
| + }
|
| +}
|
| +
|
| +
|
| +DoubleLiteral* DoubleLiteral::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + DoubleLiteral* literal = new DoubleLiteral();
|
| + literal->value_ = Reference::ReadStringFrom(reader);
|
| + return literal;
|
| +}
|
| +
|
| +
|
| +void DoubleLiteral::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + writer->WriteTag(kDoubleLiteral);
|
| + value_->WriteTo(writer);
|
| +}
|
| +
|
| +
|
| +BoolLiteral* BoolLiteral::ReadFrom(Reader* reader, bool value) {
|
| + TRACE_READ_OFFSET();
|
| + BoolLiteral* lit = new BoolLiteral();
|
| + lit->value_ = value;
|
| + return lit;
|
| +}
|
| +
|
| +
|
| +void BoolLiteral::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + writer->WriteTag(value_ ? kTrueLiteral : kFalseLiteral);
|
| +}
|
| +
|
| +
|
| +NullLiteral* NullLiteral::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + return new NullLiteral();
|
| +}
|
| +
|
| +
|
| +void NullLiteral::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + writer->WriteTag(kNullLiteral);
|
| +}
|
| +
|
| +
|
| +SymbolLiteral* SymbolLiteral::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + SymbolLiteral* lit = new SymbolLiteral();
|
| + lit->value_ = Reference::ReadStringFrom(reader);
|
| + return lit;
|
| +}
|
| +
|
| +
|
| +void SymbolLiteral::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + writer->WriteTag(kSymbolLiteral);
|
| + value_->WriteTo(writer);
|
| +}
|
| +
|
| +
|
| +TypeLiteral* TypeLiteral::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + TypeLiteral* literal = new TypeLiteral();
|
| + literal->type_ = DartType::ReadFrom(reader);
|
| + return literal;
|
| +}
|
| +
|
| +
|
| +void TypeLiteral::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + writer->WriteTag(kTypeLiteral);
|
| + type_->WriteTo(writer);
|
| +}
|
| +
|
| +
|
| +ThisExpression* ThisExpression::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + return new ThisExpression();
|
| +}
|
| +
|
| +
|
| +void ThisExpression::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + writer->WriteTag(kThisExpression);
|
| +}
|
| +
|
| +
|
| +Rethrow* Rethrow::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + return new Rethrow();
|
| +}
|
| +
|
| +
|
| +void Rethrow::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + writer->WriteTag(kRethrow);
|
| +}
|
| +
|
| +
|
| +Throw* Throw::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + Throw* t = new Throw();
|
| + reader->ReadUInt();
|
| + t->expression_ = Expression::ReadFrom(reader);
|
| + return t;
|
| +}
|
| +
|
| +
|
| +void Throw::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + writer->WriteTag(kThrow);
|
| + writer->WriteUInt(0);
|
| + expression_->WriteTo(writer);
|
| +}
|
| +
|
| +
|
| +ListLiteral* ListLiteral::ReadFrom(Reader* reader, bool is_const) {
|
| + TRACE_READ_OFFSET();
|
| + ListLiteral* literal = new ListLiteral();
|
| + literal->is_const_ = is_const;
|
| + literal->type_ = DartType::ReadFrom(reader);
|
| + literal->expressions_.ReadFromStatic<Expression>(reader);
|
| + return literal;
|
| +}
|
| +
|
| +
|
| +void ListLiteral::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + writer->WriteTag(is_const_ ? kConstListLiteral : kListLiteral);
|
| + type_->WriteTo(writer);
|
| + expressions_.WriteTo(writer);
|
| +}
|
| +
|
| +
|
| +MapLiteral* MapLiteral::ReadFrom(Reader* reader, bool is_const) {
|
| + TRACE_READ_OFFSET();
|
| + MapLiteral* literal = new MapLiteral();
|
| + literal->is_const_ = is_const;
|
| + literal->key_type_ = DartType::ReadFrom(reader);
|
| + literal->value_type_ = DartType::ReadFrom(reader);
|
| + literal->entries_.ReadFromStatic<MapEntry>(reader);
|
| + return literal;
|
| +}
|
| +
|
| +
|
| +void MapLiteral::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + writer->WriteTag(is_const_ ? kConstMapLiteral : kMapLiteral);
|
| + key_type_->WriteTo(writer);
|
| + value_type_->WriteTo(writer);
|
| + entries_.WriteTo(writer);
|
| +}
|
| +
|
| +
|
| +MapEntry* MapEntry::ReadFrom(Reader* reader) {
|
| + MapEntry* entry = new MapEntry();
|
| + entry->key_ = Expression::ReadFrom(reader);
|
| + entry->value_ = Expression::ReadFrom(reader);
|
| + return entry;
|
| +}
|
| +
|
| +
|
| +void MapEntry::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + key_->WriteTo(writer);
|
| + value_->WriteTo(writer);
|
| +}
|
| +
|
| +
|
| +AwaitExpression* AwaitExpression::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + AwaitExpression* await = new AwaitExpression();
|
| + await->operand_ = Expression::ReadFrom(reader);
|
| + return await;
|
| +}
|
| +
|
| +
|
| +void AwaitExpression::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + writer->WriteTag(kAwaitExpression);
|
| + operand_->WriteTo(writer);
|
| +}
|
| +
|
| +
|
| +FunctionExpression* FunctionExpression::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + VariableScope<ReaderHelper> parameters(reader->helper());
|
| + FunctionExpression* expr = new FunctionExpression();
|
| + expr->function_ = FunctionNode::ReadFrom(reader);
|
| + return expr;
|
| +}
|
| +
|
| +
|
| +void FunctionExpression::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + VariableScope<WriterHelper> parameters(writer->helper());
|
| + writer->WriteTag(kFunctionExpression);
|
| + function_->WriteTo(writer);
|
| +}
|
| +
|
| +
|
| +Let* Let::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + VariableScope<ReaderHelper> vars(reader->helper());
|
| + Let* let = new Let();
|
| + let->variable_ = VariableDeclaration::ReadFromImpl(reader);
|
| + let->body_ = Expression::ReadFrom(reader);
|
| + return let;
|
| +}
|
| +
|
| +
|
| +void Let::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + VariableScope<WriterHelper> vars(writer->helper());
|
| + writer->WriteTag(kLet);
|
| + variable_->WriteToImpl(writer);
|
| + body_->WriteTo(writer);
|
| +}
|
| +
|
| +
|
| +BlockExpression* BlockExpression::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + BlockExpression* be = new BlockExpression();
|
| + be->body_ = Block::ReadFromImpl(reader);
|
| + be->value_ = Expression::ReadFrom(reader);
|
| + return be;
|
| +}
|
| +
|
| +
|
| +void BlockExpression::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + writer->WriteTag(kBlockExpression);
|
| + body_->WriteToImpl(writer);
|
| + value_->WriteTo(writer);
|
| +}
|
| +
|
| +
|
| +Statement* Statement::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + Tag tag = reader->ReadTag();
|
| + switch (tag) {
|
| + case kInvalidStatement:
|
| + return InvalidStatement::ReadFrom(reader);
|
| + case kExpressionStatement:
|
| + return ExpressionStatement::ReadFrom(reader);
|
| + case kBlock:
|
| + return Block::ReadFromImpl(reader);
|
| + case kEmptyStatement:
|
| + return EmptyStatement::ReadFrom(reader);
|
| + case kAssertStatement:
|
| + return AssertStatement::ReadFrom(reader);
|
| + case kLabeledStatement:
|
| + return LabeledStatement::ReadFrom(reader);
|
| + case kBreakStatement:
|
| + return BreakStatement::ReadFrom(reader);
|
| + case kWhileStatement:
|
| + return WhileStatement::ReadFrom(reader);
|
| + case kDoStatement:
|
| + return DoStatement::ReadFrom(reader);
|
| + case kForStatement:
|
| + return ForStatement::ReadFrom(reader);
|
| + case kForInStatement:
|
| + return ForInStatement::ReadFrom(reader, false);
|
| + case kAsyncForInStatement:
|
| + return ForInStatement::ReadFrom(reader, true);
|
| + case kSwitchStatement:
|
| + return SwitchStatement::ReadFrom(reader);
|
| + case kContinueSwitchStatement:
|
| + return ContinueSwitchStatement::ReadFrom(reader);
|
| + case kIfStatement:
|
| + return IfStatement::ReadFrom(reader);
|
| + case kReturnStatement:
|
| + return ReturnStatement::ReadFrom(reader);
|
| + case kTryCatch:
|
| + return TryCatch::ReadFrom(reader);
|
| + case kTryFinally:
|
| + return TryFinally::ReadFrom(reader);
|
| + case kYieldStatement:
|
| + return YieldStatement::ReadFrom(reader);
|
| + case kVariableDeclaration:
|
| + return VariableDeclaration::ReadFromImpl(reader);
|
| + case kFunctionDeclaration:
|
| + return FunctionDeclaration::ReadFrom(reader);
|
| + default:
|
| + UNREACHABLE();
|
| + }
|
| + return NULL;
|
| +}
|
| +
|
| +
|
| +InvalidStatement* InvalidStatement::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + return new InvalidStatement();
|
| +}
|
| +
|
| +
|
| +void InvalidStatement::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + writer->WriteTag(kInvalidStatement);
|
| +}
|
| +
|
| +
|
| +ExpressionStatement* ExpressionStatement::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + return new ExpressionStatement(Expression::ReadFrom(reader));
|
| +}
|
| +
|
| +
|
| +void ExpressionStatement::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + writer->WriteTag(kExpressionStatement);
|
| + expression_->WriteTo(writer);
|
| +}
|
| +
|
| +
|
| +Block* Block::ReadFromImpl(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + VariableScope<ReaderHelper> vars(reader->helper());
|
| + Block* block = new Block();
|
| + block->statements().ReadFromStatic<Statement>(reader);
|
| + return block;
|
| +}
|
| +
|
| +
|
| +void Block::WriteTo(Writer* writer) {
|
| + writer->WriteTag(kBlock);
|
| + WriteToImpl(writer);
|
| +}
|
| +
|
| +
|
| +void Block::WriteToImpl(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + VariableScope<WriterHelper> vars(writer->helper());
|
| + statements_.WriteTo(writer);
|
| +}
|
| +
|
| +
|
| +EmptyStatement* EmptyStatement::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + return new EmptyStatement();
|
| +}
|
| +
|
| +
|
| +void EmptyStatement::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + writer->WriteTag(kEmptyStatement);
|
| +}
|
| +
|
| +
|
| +AssertStatement* AssertStatement::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + AssertStatement* stmt = new AssertStatement();
|
| + stmt->condition_ = Expression::ReadFrom(reader);
|
| + stmt->message_ = reader->ReadOptional<Expression>();
|
| + return stmt;
|
| +}
|
| +
|
| +
|
| +void AssertStatement::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + writer->WriteTag(kAssertStatement);
|
| + condition_->WriteTo(writer);
|
| + writer->WriteOptional<Expression>(message_);
|
| +}
|
| +
|
| +
|
| +LabeledStatement* LabeledStatement::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + LabeledStatement* stmt = new LabeledStatement();
|
| + reader->helper()->lables().Push(stmt);
|
| + stmt->body_ = Statement::ReadFrom(reader);
|
| + reader->helper()->lables().Pop(stmt);
|
| + return stmt;
|
| +}
|
| +
|
| +
|
| +void LabeledStatement::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + writer->WriteTag(kLabeledStatement);
|
| + writer->helper()->lables().Push(this);
|
| + body_->WriteTo(writer);
|
| + writer->helper()->lables().Pop(this);
|
| +}
|
| +
|
| +
|
| +BreakStatement* BreakStatement::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + BreakStatement* stmt = new BreakStatement();
|
| + stmt->target_ = reader->helper()->lables().Lookup(reader->ReadUInt());
|
| + return stmt;
|
| +}
|
| +
|
| +
|
| +void BreakStatement::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + writer->WriteTag(kBreakStatement);
|
| + writer->WriteUInt(writer->helper()->lables().Lookup(target_));
|
| +}
|
| +
|
| +
|
| +WhileStatement* WhileStatement::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + WhileStatement* stmt = new WhileStatement();
|
| + stmt->condition_ = Expression::ReadFrom(reader);
|
| + stmt->body_ = Statement::ReadFrom(reader);
|
| + return stmt;
|
| +}
|
| +
|
| +
|
| +void WhileStatement::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + writer->WriteTag(kWhileStatement);
|
| + condition_->WriteTo(writer);
|
| + body_->WriteTo(writer);
|
| +}
|
| +
|
| +
|
| +DoStatement* DoStatement::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + DoStatement* dostmt = new DoStatement();
|
| + dostmt->body_ = Statement::ReadFrom(reader);
|
| + dostmt->condition_ = Expression::ReadFrom(reader);
|
| + return dostmt;
|
| +}
|
| +
|
| +
|
| +void DoStatement::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + writer->WriteTag(kDoStatement);
|
| + body_->WriteTo(writer);
|
| + condition_->WriteTo(writer);
|
| +}
|
| +
|
| +
|
| +ForStatement* ForStatement::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + VariableScope<ReaderHelper> vars(reader->helper());
|
| + ForStatement* forstmt = new ForStatement();
|
| + forstmt->variables_.ReadFromStatic<VariableDeclarationImpl>(reader);
|
| + forstmt->condition_ = reader->ReadOptional<Expression>();
|
| + forstmt->updates_.ReadFromStatic<Expression>(reader);
|
| + forstmt->body_ = Statement::ReadFrom(reader);
|
| + return forstmt;
|
| +}
|
| +
|
| +
|
| +void ForStatement::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + writer->WriteTag(kForStatement);
|
| + VariableScope<WriterHelper> vars(writer->helper());
|
| + variables_.WriteToStatic<VariableDeclarationImpl>(writer);
|
| + writer->WriteOptional<Expression>(condition_);
|
| + updates_.WriteTo(writer);
|
| + body_->WriteTo(writer);
|
| +}
|
| +
|
| +
|
| +ForInStatement* ForInStatement::ReadFrom(Reader* reader, bool is_async) {
|
| + TRACE_READ_OFFSET();
|
| + VariableScope<ReaderHelper> vars(reader->helper());
|
| + ForInStatement* forinstmt = new ForInStatement();
|
| + forinstmt->is_async_ = is_async;
|
| + forinstmt->variable_ = VariableDeclaration::ReadFromImpl(reader);
|
| + forinstmt->iterable_ = Expression::ReadFrom(reader);
|
| + forinstmt->body_ = Statement::ReadFrom(reader);
|
| + return forinstmt;
|
| +}
|
| +
|
| +
|
| +void ForInStatement::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + writer->WriteTag(is_async_ ? kAsyncForInStatement : kForInStatement);
|
| + VariableScope<WriterHelper> vars(writer->helper());
|
| + variable_->WriteToImpl(writer);
|
| + iterable_->WriteTo(writer);
|
| + body_->WriteTo(writer);
|
| +}
|
| +
|
| +
|
| +SwitchStatement* SwitchStatement::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + SwitchCaseScope<ReaderHelper> scope(reader->helper());
|
| + SwitchStatement* stmt = new SwitchStatement();
|
| + stmt->condition_ = Expression::ReadFrom(reader);
|
| + // We need to explicitly create empty [SwitchCase]s first in order to add them
|
| + // to the [SwitchCaseScope]. This is necessary since a [Statement] in a switch
|
| + // case can refer to one defined later on.
|
| + int count = reader->ReadUInt();
|
| + for (int i = 0; i < count; i++) {
|
| + SwitchCase* sc = stmt->cases_.GetOrCreate<SwitchCase>(i);
|
| + reader->helper()->switch_cases().Push(sc);
|
| + }
|
| + for (int i = 0; i < count; i++) {
|
| + SwitchCase* sc = stmt->cases_[i];
|
| + sc->ReadFrom(reader);
|
| + }
|
| + return stmt;
|
| +}
|
| +
|
| +
|
| +void SwitchStatement::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + SwitchCaseScope<WriterHelper> scope(writer->helper());
|
| + writer->WriteTag(kSwitchStatement);
|
| + condition_->WriteTo(writer);
|
| + for (int i = 0; i < cases_.length(); i++) {
|
| + writer->helper()->switch_cases().Push(cases_[i]);
|
| + }
|
| + cases_.WriteTo(writer);
|
| +}
|
| +
|
| +
|
| +SwitchCase* SwitchCase::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + expressions_.ReadFromStatic<Expression>(reader);
|
| + is_default_ = reader->ReadBool();
|
| + body_ = Statement::ReadFrom(reader);
|
| + return this;
|
| +}
|
| +
|
| +
|
| +void SwitchCase::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + expressions_.WriteTo(writer);
|
| + writer->WriteBool(is_default_);
|
| + body_->WriteTo(writer);
|
| +}
|
| +
|
| +
|
| +ContinueSwitchStatement* ContinueSwitchStatement::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + ContinueSwitchStatement* stmt = new ContinueSwitchStatement();
|
| + stmt->target_ = reader->helper()->switch_cases().Lookup(reader->ReadUInt());
|
| + return stmt;
|
| +}
|
| +
|
| +
|
| +void ContinueSwitchStatement::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + writer->WriteTag(kContinueSwitchStatement);
|
| + writer->WriteUInt(writer->helper()->switch_cases().Lookup(target_));
|
| +}
|
| +
|
| +
|
| +IfStatement* IfStatement::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + IfStatement* ifstmt = new IfStatement();
|
| + ifstmt->condition_ = Expression::ReadFrom(reader);
|
| + ifstmt->then_ = Statement::ReadFrom(reader);
|
| + ifstmt->otherwise_ = Statement::ReadFrom(reader);
|
| + return ifstmt;
|
| +}
|
| +
|
| +
|
| +void IfStatement::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + writer->WriteTag(kIfStatement);
|
| + condition_->WriteTo(writer);
|
| + then_->WriteTo(writer);
|
| + otherwise_->WriteTo(writer);
|
| +}
|
| +
|
| +
|
| +ReturnStatement* ReturnStatement::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + ReturnStatement* ret = new ReturnStatement();
|
| + ret->expression_ = reader->ReadOptional<Expression>();
|
| + return ret;
|
| +}
|
| +
|
| +
|
| +void ReturnStatement::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + writer->WriteTag(kReturnStatement);
|
| + writer->WriteOptional<Expression>(expression_);
|
| +}
|
| +
|
| +
|
| +TryCatch* TryCatch::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + TryCatch* tc = new TryCatch();
|
| + tc->body_ = Statement::ReadFrom(reader);
|
| + tc->catches_.ReadFromStatic<Catch>(reader);
|
| + return tc;
|
| +}
|
| +
|
| +
|
| +void TryCatch::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + writer->WriteTag(kTryCatch);
|
| + body_->WriteTo(writer);
|
| + catches_.WriteTo(writer);
|
| +}
|
| +
|
| +
|
| +Catch* Catch::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + VariableScope<ReaderHelper> vars(reader->helper());
|
| + Catch* c = new Catch();
|
| + c->guard_ = DartType::ReadFrom(reader);
|
| + c->exception_ =
|
| + reader->ReadOptional<VariableDeclaration, VariableDeclarationImpl>();
|
| + c->stack_trace_ =
|
| + reader->ReadOptional<VariableDeclaration, VariableDeclarationImpl>();
|
| + c->body_ = Statement::ReadFrom(reader);
|
| + return c;
|
| +}
|
| +
|
| +
|
| +void Catch::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + VariableScope<WriterHelper> vars(writer->helper());
|
| + guard_->WriteTo(writer);
|
| + writer->WriteOptionalStatic<VariableDeclaration, VariableDeclarationImpl>(
|
| + exception_);
|
| + writer->WriteOptionalStatic<VariableDeclaration, VariableDeclarationImpl>(
|
| + stack_trace_);
|
| + body_->WriteTo(writer);
|
| +}
|
| +
|
| +
|
| +TryFinally* TryFinally::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + TryFinally* tf = new TryFinally();
|
| + tf->body_ = Statement::ReadFrom(reader);
|
| + tf->finalizer_ = Statement::ReadFrom(reader);
|
| + return tf;
|
| +}
|
| +
|
| +
|
| +void TryFinally::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + writer->WriteTag(kTryFinally);
|
| + body_->WriteTo(writer);
|
| + finalizer_->WriteTo(writer);
|
| +}
|
| +
|
| +
|
| +YieldStatement* YieldStatement::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + YieldStatement* stmt = new YieldStatement();
|
| + stmt->flags_ = reader->ReadByte();
|
| + stmt->expression_ = Expression::ReadFrom(reader);
|
| + return stmt;
|
| +}
|
| +
|
| +
|
| +void YieldStatement::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + writer->WriteTag(kYieldStatement);
|
| + writer->WriteByte(flags_);
|
| + expression_->WriteTo(writer);
|
| +}
|
| +
|
| +
|
| +VariableDeclaration* VariableDeclaration::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + Tag tag = reader->ReadTag();
|
| + ASSERT(tag == kVariableDeclaration);
|
| + return VariableDeclaration::ReadFromImpl(reader);
|
| +}
|
| +
|
| +
|
| +VariableDeclaration* VariableDeclaration::ReadFromImpl(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + VariableDeclaration* decl = new VariableDeclaration();
|
| + decl->flags_ = reader->ReadFlags();
|
| + decl->name_ = Reference::ReadStringFrom(reader);
|
| + decl->type_ = DartType::ReadFrom(reader);
|
| + decl->inferred_value_ = reader->ReadOptional<InferredValue>();
|
| + decl->initializer_ = reader->ReadOptional<Expression>();
|
| + reader->helper()->variables().Push(decl);
|
| + return decl;
|
| +}
|
| +
|
| +
|
| +void VariableDeclaration::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + writer->WriteTag(kVariableDeclaration);
|
| + WriteToImpl(writer);
|
| +}
|
| +
|
| +
|
| +void VariableDeclaration::WriteToImpl(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + writer->WriteFlags(flags_);
|
| + name_->WriteTo(writer);
|
| + type_->WriteTo(writer);
|
| + writer->WriteOptional<InferredValue>(inferred_value_);
|
| + writer->WriteOptional<Expression>(initializer_);
|
| + writer->helper()->variables().Push(this);
|
| +}
|
| +
|
| +
|
| +FunctionDeclaration* FunctionDeclaration::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + FunctionDeclaration* decl = new FunctionDeclaration();
|
| + decl->variable_ = VariableDeclaration::ReadFromImpl(reader);
|
| + VariableScope<ReaderHelper> parameters(reader->helper());
|
| + decl->function_ = FunctionNode::ReadFrom(reader);
|
| + return decl;
|
| +}
|
| +
|
| +
|
| +void FunctionDeclaration::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + writer->WriteTag(kFunctionDeclaration);
|
| + variable_->WriteToImpl(writer);
|
| + VariableScope<WriterHelper> parameters(writer->helper());
|
| + function_->WriteTo(writer);
|
| +}
|
| +
|
| +
|
| +Name* Name::ReadFrom(Reader* reader) {
|
| + String* string = Reference::ReadStringFrom(reader);
|
| + if (string->size() >= 1 && string->buffer()[0] == '_') {
|
| + int lib_index = reader->ReadUInt();
|
| + Library* library =
|
| + reader->helper()->program()->libraries().GetOrCreate<Library>(
|
| + lib_index);
|
| + return new Name(string, library);
|
| + } else {
|
| + return new Name(string, NULL);
|
| + }
|
| +}
|
| +
|
| +
|
| +void Name::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + string_->WriteTo(writer);
|
| + Library* library = library_;
|
| + bool is_private = library != NULL;
|
| + if (is_private) {
|
| + writer->WriteUInt(writer->helper()->libraries().Lookup(library_));
|
| + }
|
| +}
|
| +
|
| +
|
| +InferredValue* InferredValue::ReadFrom(Reader* reader) {
|
| + InferredValue* type = new InferredValue();
|
| + type->klass_ = Reference::ReadClassFrom(reader, true);
|
| + type->kind_ = static_cast<BaseClassKind>(reader->ReadByte());
|
| + type->value_bits_ = reader->ReadByte();
|
| + return type;
|
| +}
|
| +
|
| +
|
| +void InferredValue::WriteTo(Writer* writer) {
|
| + Reference::WriteClassTo(writer, klass_, true);
|
| + writer->WriteByte(static_cast<uint8_t>(kind_));
|
| + writer->WriteByte(value_bits_);
|
| +}
|
| +
|
| +
|
| +DartType* DartType::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + Tag tag = reader->ReadTag();
|
| + switch (tag) {
|
| + case kInvalidType:
|
| + return InvalidType::ReadFrom(reader);
|
| + case kDynamicType:
|
| + return DynamicType::ReadFrom(reader);
|
| + case kVoidType:
|
| + return VoidType::ReadFrom(reader);
|
| + case kInterfaceType:
|
| + return InterfaceType::ReadFrom(reader);
|
| + case kSimpleInterfaceType:
|
| + return InterfaceType::ReadFrom(reader, true);
|
| + case kFunctionType:
|
| + return FunctionType::ReadFrom(reader);
|
| + case kSimpleFunctionType:
|
| + return FunctionType::ReadFrom(reader, true);
|
| + case kTypeParameterType:
|
| + return TypeParameterType::ReadFrom(reader);
|
| + default:
|
| + UNREACHABLE();
|
| + }
|
| + UNREACHABLE();
|
| + return NULL;
|
| +}
|
| +
|
| +
|
| +InvalidType* InvalidType::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + return new InvalidType();
|
| +}
|
| +
|
| +
|
| +void InvalidType::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + writer->WriteTag(kInvalidType);
|
| +}
|
| +
|
| +
|
| +DynamicType* DynamicType::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + return new DynamicType();
|
| +}
|
| +
|
| +
|
| +void DynamicType::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + writer->WriteTag(kDynamicType);
|
| +}
|
| +
|
| +
|
| +VoidType* VoidType::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + return new VoidType();
|
| +}
|
| +
|
| +
|
| +void VoidType::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + writer->WriteTag(kVoidType);
|
| +}
|
| +
|
| +
|
| +InterfaceType* InterfaceType::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + Class* klass = Reference::ReadClassFrom(reader);
|
| + InterfaceType* type = new InterfaceType(klass);
|
| + type->type_arguments().ReadFromStatic<DartType>(reader);
|
| + return type;
|
| +}
|
| +
|
| +
|
| +InterfaceType* InterfaceType::ReadFrom(Reader* reader,
|
| + bool _without_type_arguments_) {
|
| + TRACE_READ_OFFSET();
|
| + Class* klass = Reference::ReadClassFrom(reader);
|
| + InterfaceType* type = new InterfaceType(klass);
|
| + ASSERT(_without_type_arguments_);
|
| + return type;
|
| +}
|
| +
|
| +
|
| +void InterfaceType::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + if (type_arguments_.length() == 0) {
|
| + writer->WriteTag(kSimpleInterfaceType);
|
| + Reference::WriteClassTo(writer, klass_);
|
| + } else {
|
| + writer->WriteTag(kInterfaceType);
|
| + Reference::WriteClassTo(writer, klass_);
|
| + type_arguments_.WriteTo(writer);
|
| + }
|
| +}
|
| +
|
| +
|
| +FunctionType* FunctionType::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + FunctionType* type = new FunctionType();
|
| + TypeParameterScope<ReaderHelper> scope(reader->helper());
|
| + type->type_parameters().ReadFrom(reader);
|
| + type->required_parameter_count_ = reader->ReadUInt();
|
| + type->positional_parameters().ReadFromStatic<DartType>(reader);
|
| + type->named_parameters().ReadFromStatic<Tuple<String, DartType> >(reader);
|
| + type->return_type_ = DartType::ReadFrom(reader);
|
| + return type;
|
| +}
|
| +
|
| +
|
| +FunctionType* FunctionType::ReadFrom(Reader* reader, bool _is_simple_) {
|
| + TRACE_READ_OFFSET();
|
| + FunctionType* type = new FunctionType();
|
| + ASSERT(_is_simple_);
|
| + type->positional_parameters().ReadFromStatic<DartType>(reader);
|
| + type->required_parameter_count_ = type->positional_parameters().length();
|
| + type->return_type_ = DartType::ReadFrom(reader);
|
| + return type;
|
| +}
|
| +
|
| +
|
| +void FunctionType::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| +
|
| + bool is_simple =
|
| + positional_parameters_.length() == required_parameter_count_ &&
|
| + type_parameters_.length() == 0 && named_parameters_.length() == 0;
|
| + if (is_simple) {
|
| + writer->WriteTag(kSimpleFunctionType);
|
| + positional_parameters_.WriteTo(writer);
|
| + return_type_->WriteTo(writer);
|
| + } else {
|
| + TypeParameterScope<WriterHelper> scope(writer->helper());
|
| + writer->WriteTag(kFunctionType);
|
| + type_parameters_.WriteTo(writer);
|
| + writer->WriteUInt(required_parameter_count_);
|
| + positional_parameters_.WriteTo(writer);
|
| + named_parameters_.WriteTo(writer);
|
| + return_type_->WriteTo(writer);
|
| + }
|
| +}
|
| +
|
| +
|
| +TypeParameterType* TypeParameterType::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + TypeParameterType* type = new TypeParameterType();
|
| + type->parameter_ =
|
| + reader->helper()->type_parameters().Lookup(reader->ReadUInt());
|
| + return type;
|
| +}
|
| +
|
| +
|
| +void TypeParameterType::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + writer->WriteTag(kTypeParameterType);
|
| + writer->WriteUInt(writer->helper()->type_parameters().Lookup(parameter_));
|
| +}
|
| +
|
| +
|
| +Program* Program::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + uint32_t magic = reader->ReadUInt32();
|
| + if (magic != kMagicProgramFile) FATAL("Invalid magic identifier");
|
| +
|
| + Program* program = new Program();
|
| + reader->helper()->set_program(program);
|
| +
|
| + program->string_table_.ReadFrom(reader);
|
| + StringTable dummy1;
|
| + dummy1.ReadFrom(reader);
|
| + LineStartingTable dummy2;
|
| + dummy2.ReadFrom(reader, dummy1.strings_.length());
|
| +
|
| + int libraries = reader->ReadUInt();
|
| + program->libraries().EnsureInitialized(libraries);
|
| + for (int i = 0; i < libraries; i++) {
|
| + program->libraries().GetOrCreate<Library>(i)->ReadFrom(reader);
|
| + }
|
| +
|
| + program->main_method_ = Procedure::Cast(Reference::ReadMemberFrom(reader));
|
| +
|
| + return program;
|
| +}
|
| +
|
| +
|
| +void Program::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| +
|
| + writer->helper()->SetProgram(this);
|
| +
|
| + writer->WriteUInt32(kMagicProgramFile);
|
| +
|
| + // NOTE: Currently we don't GC strings and we require that all referenced
|
| + // strings in nodes are present in [string_table_].
|
| + string_table_.WriteTo(writer);
|
| + StringTable dummy1;
|
| + dummy1.WriteTo(writer);
|
| + LineStartingTable dummy2;
|
| + dummy2.WriteTo(writer);
|
| +
|
| + libraries_.WriteTo(writer);
|
| + Reference::WriteMemberTo(writer, main_method_);
|
| +}
|
| +
|
| +
|
| +FunctionNode* FunctionNode::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + TypeParameterScope<ReaderHelper> scope(reader->helper());
|
| +
|
| + FunctionNode* function = new FunctionNode();
|
| + function->async_marker_ =
|
| + static_cast<FunctionNode::AsyncMarker>(reader->ReadByte());
|
| + function->type_parameters().ReadFrom(reader);
|
| + function->required_parameter_count_ = reader->ReadUInt();
|
| + function->positional_parameters().ReadFromStatic<VariableDeclarationImpl>(
|
| + reader);
|
| + function->named_parameters().ReadFromStatic<VariableDeclarationImpl>(reader);
|
| + function->return_type_ = DartType::ReadFrom(reader);
|
| + function->inferred_return_value_ = reader->ReadOptional<InferredValue>();
|
| +
|
| + VariableScope<ReaderHelper> vars(reader->helper());
|
| + function->body_ = reader->ReadOptional<Statement>();
|
| + return function;
|
| +}
|
| +
|
| +
|
| +void FunctionNode::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + TypeParameterScope<WriterHelper> scope(writer->helper());
|
| +
|
| + writer->WriteByte(static_cast<uint8_t>(async_marker_));
|
| + type_parameters().WriteTo(writer);
|
| + writer->WriteUInt(required_parameter_count());
|
| + positional_parameters().WriteToStatic<VariableDeclarationImpl>(writer);
|
| + named_parameters().WriteToStatic<VariableDeclarationImpl>(writer);
|
| + return_type_->WriteTo(writer);
|
| + writer->WriteOptional<InferredValue>(inferred_return_value_);
|
| +
|
| + VariableScope<WriterHelper> vars(writer->helper());
|
| + writer->WriteOptional<Statement>(body_);
|
| +}
|
| +
|
| +
|
| +TypeParameter* TypeParameter::ReadFrom(Reader* reader) {
|
| + TRACE_READ_OFFSET();
|
| + name_ = Reference::ReadStringFrom(reader);
|
| + bound_ = DartType::ReadFrom(reader);
|
| + return this;
|
| +}
|
| +
|
| +
|
| +void TypeParameter::WriteTo(Writer* writer) {
|
| + TRACE_WRITE_OFFSET();
|
| + name_->WriteTo(writer);
|
| + bound_->WriteTo(writer);
|
| +}
|
| +
|
| +
|
| +} // namespace kernel
|
| +
|
| +
|
| +kernel::Program* ReadPrecompiledKernelFromBuffer(const uint8_t* buffer,
|
| + intptr_t buffer_length) {
|
| + kernel::Reader reader(buffer, buffer_length);
|
| + return kernel::Program::ReadFrom(&reader);
|
| +}
|
| +
|
| +
|
| +void WritePrecompiledKernel(ByteWriter* byte_writer, kernel::Program* program) {
|
| + ASSERT(byte_writer != NULL);
|
| +
|
| + kernel::Writer writer(byte_writer);
|
| + program->WriteTo(&writer);
|
| +}
|
| +
|
| +
|
| +} // namespace dart
|
|
|