Files
sdk/runtime/vm/kernel_binary.cc
T
Jens Johansen 414d66dce6 More offsets in kernel
Added offsets to more nodes.
Added end offsets to some nodes.
Added functionnode debuggability flag.

This changes the dill format.
The new offsets et al. are read on the C++ side, but not used
for anything usefull yet.

This is step #2 in introducing these things, next step(s) will be
using it on the C++ side.

R=asgerf@google.com

Review-Url: https://codereview.chromium.org/2626613002 .
2017-01-11 09:59:52 +01:00

2964 lines
79 KiB
C++

// 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,
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 SourceTable::ReadFrom(Reader* reader) {
size_ = reader->helper()->program()->source_uri_table().strings().length();
source_code_ = new String*[size_];
line_starts_ = new intptr_t*[size_];
line_count_ = new intptr_t[size_];
for (intptr_t i = 0; i < size_; ++i) {
source_code_[i] = StringImpl::ReadFrom(reader);
intptr_t line_count = reader->ReadUInt();
intptr_t* line_starts = new intptr_t[line_count];
line_count_[i] = 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] = line_start;
previous_line_start = line_start;
}
line_starts_[i] = line_starts;
}
}
void SourceTable::WriteTo(Writer* writer) {
for (intptr_t i = 0; i < size_; ++i) {
StringImpl::WriteTo(writer, source_code_[i]);
intptr_t* line_starts = line_starts_[i];
intptr_t line_count = line_count_[i];
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];
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();
position_ = reader->ReadPosition();
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->WritePosition(position_);
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();
end_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->WritePosition(end_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());
position_ = reader->ReadPosition();
end_position_ = reader->ReadPosition();
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);
writer->WritePosition(position_);
writer->WritePosition(end_position_);
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());
position_ = reader->ReadPosition();
end_position_ = reader->ReadPosition();
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);
writer->WritePosition(position_);
writer->WritePosition(end_position_);
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 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->position_ = reader->ReadPosition();
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->position_ = reader->ReadPosition();
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));
writer->WritePosition(position_);
} else {
writer->WriteTag(kVariableGet);
writer->WritePosition(position_);
writer->WriteUInt(index);
writer->WriteOptional<DartType>(NULL);
}
}
VariableSet* VariableSet::ReadFrom(Reader* reader) {
TRACE_READ_OFFSET();
VariableSet* set = new VariableSet();
set->position_ = reader->ReadPosition();
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->position_ = reader->ReadPosition();
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));
writer->WritePosition(position_);
} else {
writer->WriteTag(kVariableSet);
writer->WritePosition(position_);
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->position_ = reader->ReadPosition();
concat->expressions_.ReadFromStatic<Expression>(reader);
return concat;
}
void StringConcatenation::WriteTo(Writer* writer) {
TRACE_WRITE_OFFSET();
writer->WriteTag(kStringConcatenation);
writer->WritePosition(position_);
expressions_.WriteTo(writer);
}
IsExpression* IsExpression::ReadFrom(Reader* reader) {
TRACE_READ_OFFSET();
IsExpression* expr = new IsExpression();
expr->position_ = reader->ReadPosition();
expr->operand_ = Expression::ReadFrom(reader);
expr->type_ = DartType::ReadFrom(reader);
return expr;
}
void IsExpression::WriteTo(Writer* writer) {
TRACE_WRITE_OFFSET();
writer->WriteTag(kIsExpression);
writer->WritePosition(position_);
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->position_ = reader->ReadPosition();
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);
writer->WritePosition(position_);
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);
}
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->position_ = reader->ReadPosition();
ret->expression_ = reader->ReadOptional<Expression>();
return ret;
}
void ReturnStatement::WriteTo(Writer* writer) {
TRACE_WRITE_OFFSET();
writer->WriteTag(kReturnStatement);
writer->WritePosition(position_);
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->position_ = reader->ReadPosition();
stmt->flags_ = reader->ReadByte();
stmt->expression_ = Expression::ReadFrom(reader);
return stmt;
}
void YieldStatement::WriteTo(Writer* writer) {
TRACE_WRITE_OFFSET();
writer->WriteTag(kYieldStatement);
writer->WritePosition(position_);
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->position_ = reader->ReadPosition();
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->WritePosition(position_);
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->position_ = reader->ReadPosition();
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);
writer->WritePosition(position_);
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->source_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);
source_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->position_ = reader->ReadPosition();
function->end_position_ = reader->ReadPosition();
function->async_marker_ =
static_cast<FunctionNode::AsyncMarker>(reader->ReadByte());
function->debuggable_ = reader->ReadByte() == 1 ? true : false;
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->WritePosition(position_);
writer->WritePosition(end_position_);
writer->WriteByte(static_cast<uint8_t>(async_marker_));
writer->WriteByte(debuggable_ ? 1 : 0);
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)