| // 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. |
| #if !defined(DART_PRECOMPILED_RUNTIME) |
| |
| #include <map> |
| #include <vector> |
| |
| #include "platform/globals.h" |
| #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(DART_PRETTY_FUNCTION); \ |
| } while (0) |
| #define TRACE_WRITE_OFFSET() \ |
| do { \ |
| if (FLAG_trace_kernel_binary) writer->DumpOffset(DART_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_; |
| }; |
| |
| |
| // Unlike other scopes, labels from enclosing functions are not visible in |
| // nested functions. The LabelScope class is used to hide outer labels. |
| template <typename Builder, typename Block> |
| class LabelScope { |
| public: |
| explicit LabelScope(Builder* builder) : builder_(builder) { |
| outer_block_ = builder_->labels(); |
| builder_->set_labels(&block_); |
| } |
| ~LabelScope() { builder_->set_labels(outer_block_); } |
| |
| private: |
| Builder* builder_; |
| Block block_; |
| Block* outer_block_; |
| }; |
| |
| class ReaderHelper { |
| public: |
| ReaderHelper() : program_(NULL), labels_(NULL) {} |
| |
| Program* program() { return program_; } |
| void set_program(Program* program) { program_ = program; } |
| |
| BlockStack<VariableDeclaration>& variables() { return scope_; } |
| BlockStack<TypeParameter>& type_parameters() { return type_parameters_; } |
| BlockStack<SwitchCase>& switch_cases() { return switch_cases_; } |
| |
| BlockStack<LabeledStatement>* labels() { return labels_; } |
| void set_labels(BlockStack<LabeledStatement>* labels) { labels_ = labels; } |
| |
| private: |
| Program* program_; |
| BlockStack<VariableDeclaration> scope_; |
| BlockStack<TypeParameter> type_parameters_; |
| BlockStack<SwitchCase> switch_cases_; |
| BlockStack<LabeledStatement>* labels_; |
| }; |
| |
| |
| 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; |
| } |
| } |
| |
| TokenPosition ReadPosition() { |
| intptr_t value = ReadUInt(); |
| // Position is saved as unsigned, |
| // but actually ranges from -1 and up (thus the -1) |
| return TokenPosition(value - 1); |
| } |
| |
| 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: |
| WriterHelper() : labels_(NULL) {} |
| |
| 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<SwitchCase>& switch_cases() { return switch_cases_; } |
| |
| BlockMap<LabeledStatement>* labels() { return labels_; } |
| void set_labels(BlockMap<LabeledStatement>* labels) { labels_ = labels; } |
| |
| 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<SwitchCase> switch_cases_; |
| BlockMap<LabeledStatement>* labels_; |
| }; |
| |
| |
| 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; |
| } |
| |
| void WritePosition(TokenPosition position) { |
| intptr_t value = position.value() + 1; |
| WriteUInt(value); |
| } |
| |
| 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) { |
| size_ = reader->helper()->program()->source_uri_table().strings().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 line_start = reader->ReadUInt() + previous_line_start; |
| line_starts[j + 1] = line_start; |
| previous_line_start = line_start; |
| } |
| 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); |
| source_uri_index_ = 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(source_uri_index_); |
| |
| 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); |
| source_uri_index_ = 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(source_uri_index_); |
| 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); |
| |
| position_ = reader->ReadPosition(); |
| flags_ = reader->ReadFlags(); |
| name_ = Name::ReadFrom(reader); |
| source_uri_index_ = 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->WritePosition(position_); |
| writer->WriteFlags(flags_); |
| name_->WriteTo(writer); |
| writer->WriteUInt(source_uri_index_); |
| 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); |
| source_uri_index_ = 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(source_uri_index_); |
| 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(); |
| get->position_ = reader->ReadPosition(); |
| 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->WritePosition(position_); |
| receiver_->WriteTo(writer); |
| name_->WriteTo(writer); |
| Reference::WriteMemberTo(writer, interfaceTarget_, true); |
| } |
| |
| |
| PropertySet* PropertySet::ReadFrom(Reader* reader) { |
| TRACE_READ_OFFSET(); |
| PropertySet* set = new PropertySet(); |
| set->position_ = reader->ReadPosition(); |
| 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->WritePosition(position_); |
| 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(); |
| get->position_ = reader->ReadPosition(); |
| get->target_ = Reference::ReadMemberFrom(reader); |
| return get; |
| } |
| |
| |
| void StaticGet::WriteTo(Writer* writer) { |
| TRACE_WRITE_OFFSET(); |
| writer->WriteTag(kStaticGet); |
| writer->WritePosition(position_); |
| 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(); |
| invocation->position_ = reader->ReadPosition(); |
| 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->WritePosition(position_); |
| 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(); |
| StaticInvocation* invocation = new StaticInvocation(); |
| invocation->is_const_ = is_const; |
| invocation->position_ = reader->ReadPosition(); |
| invocation->procedure_ = Procedure::Cast(Reference::ReadMemberFrom(reader)); |
| invocation->arguments_ = Arguments::ReadFrom(reader); |
| return invocation; |
| } |
| |
| |
| void StaticInvocation::WriteTo(Writer* writer) { |
| TRACE_WRITE_OFFSET(); |
| writer->WriteTag(is_const_ ? kConstStaticInvocation : kStaticInvocation); |
| writer->WritePosition(position_); |
| 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; |
| invocation->position_ = reader->ReadPosition(); |
| 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->WritePosition(position_); |
| 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(); |
| t->position_ = reader->ReadPosition(); |
| t->expression_ = Expression::ReadFrom(reader); |
| return t; |
| } |
| |
| |
| void Throw::WriteTo(Writer* writer) { |
| TRACE_WRITE_OFFSET(); |
| writer->WriteTag(kThrow); |
| writer->WritePosition(position_); |
| 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()->labels()->Push(stmt); |
| stmt->body_ = Statement::ReadFrom(reader); |
| reader->helper()->labels()->Pop(stmt); |
| return stmt; |
| } |
| |
| |
| void LabeledStatement::WriteTo(Writer* writer) { |
| TRACE_WRITE_OFFSET(); |
| writer->WriteTag(kLabeledStatement); |
| writer->helper()->labels()->Push(this); |
| body_->WriteTo(writer); |
| writer->helper()->labels()->Pop(this); |
| } |
| |
| |
| BreakStatement* BreakStatement::ReadFrom(Reader* reader) { |
| TRACE_READ_OFFSET(); |
| BreakStatement* stmt = new BreakStatement(); |
| stmt->target_ = reader->helper()->labels()->Lookup(reader->ReadUInt()); |
| return stmt; |
| } |
| |
| |
| void BreakStatement::WriteTo(Writer* writer) { |
| TRACE_WRITE_OFFSET(); |
| writer->WriteTag(kBreakStatement); |
| writer->WriteUInt(writer->helper()->labels()->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); |
| program->source_uri_table_.ReadFrom(reader); |
| program->line_starting_table_.ReadFrom(reader); |
| |
| 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); |
| source_uri_table_.WriteTo(writer); |
| line_starting_table_.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>(); |
| |
| LabelScope<ReaderHelper, BlockStack<LabeledStatement> > labels( |
| reader->helper()); |
| 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_); |
| |
| LabelScope<WriterHelper, BlockMap<LabeledStatement> > labels( |
| writer->helper()); |
| 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 |
| #endif // !defined(DART_PRECOMPILED_RUNTIME) |