// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include <map>
#include <vector>

#include "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_;
};


class ReaderHelper {
 public:
  ReaderHelper() : program_(NULL) {}
  ~ReaderHelper() {}

  Program* program() { return program_; }
  void set_program(Program* program) { program_ = program; }

  BlockStack<VariableDeclaration>& variables() { return scope_; }
  BlockStack<TypeParameter>& type_parameters() { return type_parameters_; }
  BlockStack<LabeledStatement>& lables() { return labels_; }
  BlockStack<SwitchCase>& switch_cases() { return switch_cases_; }

 private:
  Program* program_;
  BlockStack<VariableDeclaration> scope_;
  BlockStack<TypeParameter> type_parameters_;
  BlockStack<LabeledStatement> labels_;
  BlockStack<SwitchCase> switch_cases_;
};


class Reader {
 public:
  Reader(const uint8_t* buffer, int64_t size)
      : buffer_(buffer), size_(size), offset_(0) {}

  uint32_t ReadUInt32() {
    ASSERT(offset_ + 4 <= size_);

    uint32_t value = (buffer_[offset_ + 0] << 24) |
                     (buffer_[offset_ + 1] << 16) |
                     (buffer_[offset_ + 2] << 8) | (buffer_[offset_ + 3] << 0);
    offset_ += 4;
    return value;
  }

  uint32_t ReadUInt() {
    ASSERT(offset_ + 1 <= size_);
    uint8_t byte0 = buffer_[offset_];
    if ((byte0 & 0x80) == 0) {
      // 0...
      offset_++;
      return byte0;
    } else if ((byte0 & 0xc0) == 0x80) {
      // 10...
      ASSERT(offset_ + 2 <= size_);
      uint32_t value = ((byte0 & ~0x80) << 8) | (buffer_[offset_ + 1]);
      offset_ += 2;
      return value;
    } else {
      // 11...
      ASSERT(offset_ + 4 <= size_);
      uint32_t value = ((byte0 & ~0xc0) << 24) | (buffer_[offset_ + 1] << 16) |
                       (buffer_[offset_ + 2] << 8) |
                       (buffer_[offset_ + 3] << 0);
      offset_ += 4;
      return value;
    }
  }

  intptr_t ReadListLength() { return ReadUInt(); }

  uint8_t ReadByte() { return buffer_[offset_++]; }

  bool ReadBool() { return (ReadByte() & 1) == 1; }

  word ReadFlags() { return ReadByte(); }

  Tag ReadTag(uint8_t* payload = NULL) {
    uint8_t byte = ReadByte();
    bool has_payload = (byte & kSpecializedTagHighBit) != 0;
    if (has_payload) {
      if (payload != NULL) {
        *payload = byte & kSpecializedPayloadMask;
      }
      return static_cast<Tag>(byte & kSpecializedTagMask);
    } else {
      return static_cast<Tag>(byte);
    }
  }

  const uint8_t* Consume(int count) {
    ASSERT(offset_ + count <= size_);
    const uint8_t* old = buffer_ + offset_;
    offset_ += count;
    return old;
  }

  void EnsureEnd() {
    if (offset_ != size_) {
      FATAL2(
          "Reading Kernel file: Expected to be at EOF "
          "(offset: %" Pd64 ", size: %" Pd64 ")",
          offset_, size_);
    }
  }

  void DumpOffset(const char* str) {
    OS::PrintErr("@%" Pd64 " %s\n", offset_, str);
  }

  template <typename T, typename RT>
  T* ReadOptional() {
    Tag tag = ReadTag();
    if (tag == kNothing) {
      return NULL;
    }
    ASSERT(tag == kSomething);
    return RT::ReadFrom(this);
  }

  template <typename T>
  T* ReadOptional() {
    return ReadOptional<T, T>();
  }

  ReaderHelper* helper() { return &builder_; }

 private:
  const uint8_t* buffer_;
  int64_t size_;
  int64_t offset_;
  ReaderHelper builder_;
};


class WriterHelper {
 public:
  void SetProgram(Program* program) {
    program_ = program;
    for (int i = 0; i < program->libraries().length(); i++) {
      Library* lib = program->libraries()[i];
      libraries_.Set(lib, i);

      for (int j = 0; j < lib->classes().length(); j++) {
        Class* klass = lib->classes()[j];
        classes_.Set(klass, j);

        for (int k = 0; k < klass->fields().length(); k++) {
          Field* field = klass->fields()[k];
          fields_.Set(field, k);
        }
        for (int k = 0; k < klass->constructors().length(); k++) {
          Constructor* constructor = klass->constructors()[k];
          constructors_.Set(constructor, k);
        }
        for (int k = 0; k < klass->procedures().length(); k++) {
          Procedure* procedure = klass->procedures()[k];
          procedures_.Set(procedure, k);
        }
      }

      for (int k = 0; k < lib->fields().length(); k++) {
        Field* field = lib->fields()[k];
        fields_.Set(field, k);
      }

      for (int k = 0; k < lib->procedures().length(); k++) {
        Procedure* procedure = lib->procedures()[k];
        procedures_.Set(procedure, k);
      }
    }
  }

  Program* program() { return program_; }

  BlockMap<String>& strings() { return strings_; }
  BlockMap<Library>& libraries() { return libraries_; }
  BlockMap<Class>& classes() { return classes_; }
  BlockMap<Field>& fields() { return fields_; }
  BlockMap<Procedure>& procedures() { return procedures_; }
  BlockMap<Constructor>& constructors() { return constructors_; }

  BlockMap<VariableDeclaration>& variables() { return scope_; }
  BlockMap<TypeParameter>& type_parameters() { return type_parameters_; }
  BlockMap<LabeledStatement>& lables() { return labels_; }
  BlockMap<SwitchCase>& switch_cases() { return switch_cases_; }

 private:
  Program* program_;

  BlockMap<String> strings_;
  BlockMap<Library> libraries_;
  BlockMap<Class> classes_;
  BlockMap<Field> fields_;
  BlockMap<Procedure> procedures_;
  BlockMap<Constructor> constructors_;

  BlockMap<VariableDeclaration> scope_;
  BlockMap<TypeParameter> type_parameters_;
  BlockMap<LabeledStatement> labels_;
  BlockMap<SwitchCase> switch_cases_;
};


class Writer {
 public:
  explicit Writer(ByteWriter* writer) : out_(writer), offset_(0) {}

  void WriteUInt32(uint32_t value) {
    uint8_t buffer[4] = {
        static_cast<uint8_t>((value >> 24) & 0xff),
        static_cast<uint8_t>((value >> 16) & 0xff),
        static_cast<uint8_t>((value >> 8) & 0xff),
        static_cast<uint8_t>((value >> 0) & 0xff),
    };
    WriteBytes(buffer, 4);
  }

  void WriteUInt(uint32_t value) {
    if (value < 0x80) {
      // 0...
      WriteByte(static_cast<uint8_t>(value));
    } else if (value < 0x4000) {
      // 10...
      WriteByte(static_cast<uint8_t>(((value >> 8) & 0x3f) | 0x80));
      WriteByte(static_cast<uint8_t>(value & 0xff));
    } else {
      // 11...
      // Ensure the highest 2 bits is not used for anything (we use it to for
      // encoding).
      ASSERT(static_cast<uint8_t>((value >> 24) & 0xc0) == 0);
      uint8_t buffer[4] = {
          static_cast<uint8_t>(((value >> 24) & 0x7f) | 0xc0),
          static_cast<uint8_t>((value >> 16) & 0xff),
          static_cast<uint8_t>((value >> 8) & 0xff),
          static_cast<uint8_t>((value >> 0) & 0xff),
      };
      WriteBytes(buffer, 4);
    }
  }

  void WriteListLength(intptr_t value) { return WriteUInt(value); }

  void WriteByte(uint8_t value) {
    out_->WriteByte(value);
    offset_++;
  }

  void WriteBool(bool value) { WriteByte(value ? 1 : 0); }

  void WriteFlags(uint8_t value) { WriteByte(value); }

  void WriteTag(Tag tag) { WriteByte(static_cast<uint8_t>(tag)); }

  void WriteTag(Tag tag, uint8_t payload) {
    ASSERT((payload & ~kSpecializedPayloadMask) == 0);
    WriteByte(kSpecializedTagHighBit | static_cast<uint8_t>(tag) | payload);
  }

  void WriteBytes(uint8_t* bytes, int length) {
    out_->WriteBytes(bytes, length);
    offset_ += length;
  }

  template <typename T>
  void WriteOptional(T* object) {
    if (object == NULL) {
      WriteTag(kNothing);
    } else {
      WriteTag(kSomething);
      object->WriteTo(this);
    }
  }

  template <typename T, typename WT>
  void WriteOptionalStatic(T* object) {
    if (object == NULL) {
      WriteTag(kNothing);
    } else {
      WriteTag(kSomething);
      WT::WriteTo(this, object);
    }
  }

  template <typename T>
  void WriteOptionalStatic(T* object) {
    return WriteOptionalStatic<T, T>(object);
  }

  void DumpOffset(const char* str) {
    OS::PrintErr("@%" Pd64 " %s\n", offset_, str);
  }

  WriterHelper* helper() { return &helper_; }

 private:
  ByteWriter* out_;
  WriterHelper helper_;
  int64_t offset_;
};


template <typename T>
template <typename IT>
void List<T>::ReadFrom(Reader* reader, TreeNode* parent) {
  TRACE_READ_OFFSET();
  ASSERT(parent != NULL);
  int length = reader->ReadListLength();
  EnsureInitialized(length);

  for (int i = 0; i < length_; i++) {
    IT* object = GetOrCreate<IT>(i, parent);
    object->ReadFrom(reader);
  }
}


template <typename T>
template <typename IT>
void List<T>::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  int length = reader->ReadListLength();
  EnsureInitialized(length);

  for (int i = 0; i < length_; i++) {
    GetOrCreate<IT>(i)->ReadFrom(reader);
  }
}


template <typename T>
template <typename IT>
void List<T>::ReadFromStatic(Reader* reader) {
  TRACE_READ_OFFSET();
  int length = reader->ReadListLength();
  EnsureInitialized(length);

  for (int i = 0; i < length_; i++) {
    ASSERT(array_[i] == NULL);
    array_[i] = IT::ReadFrom(reader);
  }
}


template <typename T>
void List<T>::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();

  // NOTE: We only support dense lists.
  writer->WriteListLength(length_);
  for (int i = 0; i < length_; i++) {
    T* object = array_[i];
    ASSERT(object != NULL);
    object->WriteTo(writer);
  }
}


template <typename T>
template <typename IT>
void List<T>::WriteToStatic(Writer* writer) {
  TRACE_WRITE_OFFSET();

  // NOTE: We only support dense lists.
  writer->WriteListLength(length_);
  for (int i = 0; i < length_; i++) {
    T* object = array_[i];
    ASSERT(object != NULL);
    IT::WriteTo(writer, object);
  }
}


void TypeParameterList::ReadFrom(Reader* reader) {
  // It is possible for the bound of the first type parameter to refer to
  // the second type parameter. This means we need to create [TypeParameter]
  // objects before reading the bounds.
  int length = reader->ReadListLength();
  EnsureInitialized(length);

  // Make all [TypeParameter]s available in scope.
  for (int i = 0; i < length; i++) {
    TypeParameter* parameter = (*this)[i] = new TypeParameter();
    reader->helper()->type_parameters().Push(parameter);
  }

  // Read all [TypeParameter]s and their bounds.
  for (int i = 0; i < length; i++) {
    (*this)[i]->ReadFrom(reader);
  }
}


void TypeParameterList::WriteTo(Writer* writer) {
  writer->WriteListLength(length());

  // Make all [TypeParameter]s available in scope.
  for (int i = 0; i < length(); i++) {
    TypeParameter* parameter = (*this)[i];
    writer->helper()->type_parameters().Push(parameter);
  }

  // Write all [TypeParameter]s and their bounds.
  for (int i = 0; i < length(); i++) {
    TypeParameter* parameter = (*this)[i];
    parameter->WriteTo(writer);
  }
}


template <typename A, typename B>
Tuple<A, B>* Tuple<A, B>::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  A* first = A::ReadFrom(reader);
  B* second = B::ReadFrom(reader);
  return new Tuple<A, B>(first, second);
}


template <typename A, typename B>
void Tuple<A, B>::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  first_->WriteTo(writer);
  second_->WriteTo(writer);
}


template <typename B, typename S>
class DowncastReader {
 public:
  static S* ReadFrom(Reader* reader) {
    TRACE_READ_OFFSET();
    return S::Cast(B::ReadFrom(reader));
  }
};


class StringImpl {
 public:
  static String* ReadFrom(Reader* reader) {
    TRACE_READ_OFFSET();
    return String::ReadFromImpl(reader);
  }

  static void WriteTo(Writer* writer, String* string) {
    TRACE_WRITE_OFFSET();
    string->WriteToImpl(writer);
  }
};


class VariableDeclarationImpl {
 public:
  static VariableDeclaration* ReadFrom(Reader* reader) {
    TRACE_READ_OFFSET();
    return VariableDeclaration::ReadFromImpl(reader);
  }

  static void WriteTo(Writer* writer, VariableDeclaration* d) {
    TRACE_WRITE_OFFSET();
    d->WriteToImpl(writer);
  }
};


String* String::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  return Reference::ReadStringFrom(reader);
}


String* String::ReadFromImpl(Reader* reader) {
  TRACE_READ_OFFSET();
  uint32_t bytes = reader->ReadUInt();
  String* string = new String(reader->Consume(bytes), bytes);
  return string;
}


void String::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  Reference::WriteStringTo(writer, this);
}


void String::WriteToImpl(Writer* writer) {
  TRACE_WRITE_OFFSET();
  writer->WriteUInt(size_);
  writer->WriteBytes(buffer_, size_);
}


void StringTable::ReadFrom(Reader* reader) {
  strings_.ReadFromStatic<StringImpl>(reader);
}


void StringTable::WriteTo(Writer* writer) {
  strings_.WriteToStatic<StringImpl>(writer);

  // Build up the "String* -> index" table.
  WriterHelper* helper = writer->helper();
  for (int i = 0; i < strings_.length(); i++) {
    helper->strings().Push(strings_[i]);
  }
}


void LineStartingTable::ReadFrom(Reader* reader, intptr_t length) {
  size_ = length;
  values_ = new intptr_t*[size_];
  for (intptr_t i = 0; i < size_; ++i) {
    intptr_t line_count = reader->ReadUInt();
    intptr_t* line_starts = new intptr_t[line_count + 1];
    line_starts[0] = line_count;
    intptr_t previous_line_start = 0;
    for (intptr_t j = 0; j < line_count; ++j) {
      intptr_t lineStart = reader->ReadUInt() + previous_line_start;
      line_starts[j + 1] = lineStart;
      previous_line_start = lineStart;
    }
    values_[i] = line_starts;
  }
}


void LineStartingTable::WriteTo(Writer* writer) {
  for (intptr_t i = 0; i < size_; ++i) {
    intptr_t* line_starts = values_[i];
    intptr_t line_count = line_starts[0];
    writer->WriteUInt(line_count);

    intptr_t previous_line_start = 0;
    for (intptr_t j = 0; j < line_count; ++j) {
      intptr_t line_start = line_starts[j + 1];
      writer->WriteUInt(line_start - previous_line_start);
      previous_line_start = line_start;
    }
  }
}


Library* Library::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  int flags = reader->ReadFlags();
  ASSERT(flags == 0);  // external libraries not supported
  name_ = Reference::ReadStringFrom(reader);
  import_uri_ = Reference::ReadStringFrom(reader);
  reader->ReadUInt();

  int num_classes = reader->ReadUInt();
  classes().EnsureInitialized(num_classes);
  for (int i = 0; i < num_classes; i++) {
    Tag tag = reader->ReadTag();
    if (tag == kNormalClass) {
      NormalClass* klass = classes().GetOrCreate<NormalClass>(i, this);
      klass->ReadFrom(reader);
    } else {
      ASSERT(tag == kMixinClass);
      MixinClass* klass = classes().GetOrCreate<MixinClass>(i, this);
      klass->ReadFrom(reader);
    }
  }

  fields().ReadFrom<Field>(reader, this);
  procedures().ReadFrom<Procedure>(reader, this);
  return this;
}


void Library::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  name_->WriteTo(writer);
  import_uri_->WriteTo(writer);
  writer->WriteUInt(0);

  writer->WriteUInt(classes_.length());
  for (int i = 0; i < classes_.length(); i++) {
    Class* klass = classes_[i];
    if (klass->IsNormalClass()) {
      writer->WriteTag(kNormalClass);
      NormalClass::Cast(klass)->WriteTo(writer);
    } else {
      writer->WriteTag(kMixinClass);
      MixinClass::Cast(klass)->WriteTo(writer);
    }
  }
  fields().WriteTo(writer);
  procedures().WriteTo(writer);
}


Class* Class::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();

  is_abstract_ = reader->ReadBool();
  name_ = Reference::ReadStringFrom(reader);
  reader->ReadUInt();
  annotations_.ReadFromStatic<Expression>(reader);

  return this;
}


void Class::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  writer->WriteBool(is_abstract_);
  name_->WriteTo(writer);
  writer->WriteUInt(0);
  annotations_.WriteTo(writer);
}


NormalClass* NormalClass::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  Class::ReadFrom(reader);
  TypeParameterScope<ReaderHelper> scope(reader->helper());

  type_parameters_.ReadFrom(reader);
  DartType* type = reader->ReadOptional<DartType>();

  super_class_ = InterfaceType::Cast(type);
  implemented_classes_.ReadFromStatic<DowncastReader<DartType, InterfaceType> >(
      reader);
  fields_.ReadFrom<Field>(reader, this);
  constructors_.ReadFrom<Constructor>(reader, this);
  procedures_.ReadFrom<Procedure>(reader, this);

  return this;
}


void NormalClass::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  Class::WriteTo(writer);
  TypeParameterScope<WriterHelper> scope(writer->helper());

  type_parameters().WriteTo(writer);
  writer->WriteOptional<DartType>(super_class_);
  implemented_classes().WriteTo(writer);
  fields_.WriteTo(writer);
  constructors_.WriteTo(writer);
  procedures_.WriteTo(writer);
}


MixinClass* MixinClass::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  TypeParameterScope<ReaderHelper> scope(reader->helper());

  Class::ReadFrom(reader);
  type_parameters_.ReadFrom(reader);
  first_ = InterfaceType::Cast(DartType::ReadFrom(reader));
  second_ = InterfaceType::Cast(DartType::ReadFrom(reader));
  implemented_classes_.ReadFromStatic<DowncastReader<DartType, InterfaceType> >(
      reader);
  constructors_.ReadFrom<Constructor>(reader, this);
  return this;
}


void MixinClass::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  TypeParameterScope<WriterHelper> scope(writer->helper());

  Class::WriteTo(writer);
  type_parameters_.WriteTo(writer);
  first_->WriteTo(writer);
  second_->WriteTo(writer);
  implemented_classes_.WriteTo(writer);
  constructors_.WriteTo(writer);
}


Member* Reference::ReadMemberFrom(Reader* reader, bool allow_null) {
  TRACE_READ_OFFSET();

  Program* program = reader->helper()->program();
  Tag tag = reader->ReadTag();
  switch (tag) {
    case kLibraryFieldReference: {
      int library_idx = reader->ReadUInt();
      int field_idx = reader->ReadUInt();
      Library* library = program->libraries().GetOrCreate<Library>(library_idx);
      return library->fields().GetOrCreate<Field>(field_idx, library);
    }
    case kLibraryProcedureReference: {
      int library_idx = reader->ReadUInt();
      int procedure_idx = reader->ReadUInt();
      Library* library = program->libraries().GetOrCreate<Library>(library_idx);
      return library->procedures().GetOrCreate<Procedure>(procedure_idx,
                                                          library);
    }
    case kClassFieldReference:
    case kClassConstructorReference:
    case kClassProcedureReference: {
      Class* klass = Reference::ReadClassFrom(reader);
      if (tag == kClassFieldReference) {
        int field_idx = reader->ReadUInt();
        return klass->fields().GetOrCreate<Field>(field_idx, klass);
      } else if (tag == kClassConstructorReference) {
        int constructor_idx = reader->ReadUInt();
        return klass->constructors().GetOrCreate<Constructor>(constructor_idx,
                                                              klass);
      } else {
        ASSERT(tag == kClassProcedureReference);
        int procedure_idx = reader->ReadUInt();
        return klass->procedures().GetOrCreate<Procedure>(procedure_idx, klass);
      }
    }
    case kNullReference:
      if (allow_null) {
        return NULL;
      } else {
        FATAL("Expected a valid member reference, but got `null`");
      }
    default:
      UNREACHABLE();
      break;
  }

  UNREACHABLE();
  return NULL;
}


void Reference::WriteMemberTo(Writer* writer, Member* member, bool allow_null) {
  TRACE_WRITE_OFFSET();
  if (member == NULL) {
    if (allow_null) {
      writer->WriteTag(kNullReference);
      return;
    } else {
      FATAL("Expected a valid member reference but got `null`");
    }
  }
  TreeNode* node = member->parent();

  WriterHelper* helper = writer->helper();

  if (node->IsLibrary()) {
    Library* library = Library::Cast(node);
    if (member->IsField()) {
      Field* field = Field::Cast(member);
      writer->WriteTag(kLibraryFieldReference);
      writer->WriteUInt(helper->libraries().Lookup(library));
      writer->WriteUInt(helper->fields().Lookup(field));
    } else {
      Procedure* procedure = Procedure::Cast(member);
      writer->WriteTag(kLibraryProcedureReference);
      writer->WriteUInt(helper->libraries().Lookup(library));
      writer->WriteUInt(helper->procedures().Lookup(procedure));
    }
  } else {
    Class* klass = Class::Cast(node);

    if (member->IsField()) {
      Field* field = Field::Cast(member);
      writer->WriteTag(kClassFieldReference);
      Reference::WriteClassTo(writer, klass);
      writer->WriteUInt(helper->fields().Lookup(field));
    } else if (member->IsConstructor()) {
      Constructor* constructor = Constructor::Cast(member);
      writer->WriteTag(kClassConstructorReference);
      Reference::WriteClassTo(writer, klass);
      writer->WriteUInt(helper->constructors().Lookup(constructor));
    } else {
      Procedure* procedure = Procedure::Cast(member);
      writer->WriteTag(kClassProcedureReference);
      Reference::WriteClassTo(writer, klass);
      writer->WriteUInt(helper->procedures().Lookup(procedure));
    }
  }
}


Class* Reference::ReadClassFrom(Reader* reader, bool allow_null) {
  TRACE_READ_OFFSET();
  Program* program = reader->helper()->program();

  Tag klass_member_tag = reader->ReadTag();
  if (klass_member_tag == kNullReference) {
    if (allow_null) {
      return NULL;
    } else {
      FATAL("Expected a valid class reference but got `null`.");
    }
  }
  int library_idx = reader->ReadUInt();
  int class_idx = reader->ReadUInt();

  Library* library = program->libraries().GetOrCreate<Library>(library_idx);
  Class* klass;
  if (klass_member_tag == kNormalClassReference) {
    klass = library->classes().GetOrCreate<NormalClass>(class_idx, library);
  } else {
    ASSERT(klass_member_tag == kMixinClassReference);
    klass = library->classes().GetOrCreate<MixinClass>(class_idx, library);
  }
  return klass;
}


void Reference::WriteClassTo(Writer* writer, Class* klass, bool allow_null) {
  TRACE_WRITE_OFFSET();
  if (klass == NULL) {
    if (allow_null) {
      writer->WriteTag(kNullReference);
      return;
    } else {
      FATAL("Expected a valid class reference but got `null`.");
    }
  }
  if (klass->IsNormalClass()) {
    writer->WriteTag(kNormalClassReference);
  } else {
    ASSERT(klass->IsMixinClass());
    writer->WriteTag(kMixinClassReference);
  }

  writer->WriteUInt(writer->helper()->libraries().Lookup(klass->parent()));
  writer->WriteUInt(writer->helper()->classes().Lookup(klass));
}


String* Reference::ReadStringFrom(Reader* reader) {
  int index = reader->ReadUInt();
  return reader->helper()->program()->string_table().strings()[index];
}


void Reference::WriteStringTo(Writer* writer, String* string) {
  int index = writer->helper()->strings().Lookup(string);
  writer->WriteUInt(index);
}


Field* Field::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  Tag tag = reader->ReadTag();
  ASSERT(tag == kField);

  reader->ReadUInt();
  flags_ = reader->ReadFlags();
  name_ = Name::ReadFrom(reader);
  reader->ReadUInt();
  annotations_.ReadFromStatic<Expression>(reader);
  type_ = DartType::ReadFrom(reader);
  inferred_value_ = reader->ReadOptional<InferredValue>();
  initializer_ = reader->ReadOptional<Expression>();
  return this;
}


void Field::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  writer->WriteTag(kField);
  writer->WriteUInt(0);
  writer->WriteFlags(flags_);
  name_->WriteTo(writer);
  writer->WriteUInt(0);
  annotations_.WriteTo(writer);
  type_->WriteTo(writer);
  writer->WriteOptional<InferredValue>(inferred_value_);
  writer->WriteOptional<Expression>(initializer_);
}


Constructor* Constructor::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  Tag tag = reader->ReadTag();
  ASSERT(tag == kConstructor);

  VariableScope<ReaderHelper> parameters(reader->helper());
  flags_ = reader->ReadFlags();
  name_ = Name::ReadFrom(reader);
  annotations_.ReadFromStatic<Expression>(reader);
  function_ = FunctionNode::ReadFrom(reader);
  initializers_.ReadFromStatic<Initializer>(reader);
  return this;
}


void Constructor::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  writer->WriteTag(kConstructor);

  VariableScope<WriterHelper> parameters(writer->helper());
  writer->WriteFlags(flags_);
  name_->WriteTo(writer);
  annotations_.WriteTo(writer);
  function_->WriteTo(writer);
  initializers_.WriteTo(writer);
}


Procedure* Procedure::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  Tag tag = reader->ReadTag();
  ASSERT(tag == kProcedure);

  VariableScope<ReaderHelper> parameters(reader->helper());
  kind_ = static_cast<ProcedureKind>(reader->ReadByte());
  flags_ = reader->ReadFlags();
  name_ = Name::ReadFrom(reader);
  reader->ReadUInt();
  annotations_.ReadFromStatic<Expression>(reader);
  function_ = reader->ReadOptional<FunctionNode>();
  return this;
}


void Procedure::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  writer->WriteTag(kProcedure);

  VariableScope<WriterHelper> parameters(writer->helper());
  writer->WriteByte(kind_);
  writer->WriteFlags(flags_);
  name_->WriteTo(writer);
  writer->WriteUInt(0);
  annotations_.WriteTo(writer);
  writer->WriteOptional<FunctionNode>(function_);
}


Initializer* Initializer::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  Tag tag = reader->ReadTag();
  switch (tag) {
    case kInvalidInitializer:
      return InvalidInitializer::ReadFromImpl(reader);
    case kFieldInitializer:
      return FieldInitializer::ReadFromImpl(reader);
    case kSuperInitializer:
      return SuperInitializer::ReadFromImpl(reader);
    case kRedirectingInitializer:
      return RedirectingInitializer::ReadFromImpl(reader);
    case kLocalInitializer:
      return LocalInitializer::ReadFromImpl(reader);
    default:
      UNREACHABLE();
  }
  return NULL;
}


InvalidInitializer* InvalidInitializer::ReadFromImpl(Reader* reader) {
  TRACE_READ_OFFSET();
  return new InvalidInitializer();
}


void InvalidInitializer::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  writer->WriteTag(kInvalidInitializer);
}


FieldInitializer* FieldInitializer::ReadFromImpl(Reader* reader) {
  TRACE_READ_OFFSET();
  FieldInitializer* initializer = new FieldInitializer();
  initializer->field_ = Field::Cast(Reference::ReadMemberFrom(reader));
  initializer->value_ = Expression::ReadFrom(reader);
  return initializer;
}


void FieldInitializer::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  writer->WriteTag(kFieldInitializer);
  Reference::WriteMemberTo(writer, field_);
  value_->WriteTo(writer);
}


SuperInitializer* SuperInitializer::ReadFromImpl(Reader* reader) {
  TRACE_READ_OFFSET();
  SuperInitializer* init = new SuperInitializer();
  init->target_ = Constructor::Cast(Reference::ReadMemberFrom(reader));
  init->arguments_ = Arguments::ReadFrom(reader);
  return init;
}


void SuperInitializer::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  writer->WriteTag(kSuperInitializer);
  Reference::WriteMemberTo(writer, target_);
  arguments_->WriteTo(writer);
}


RedirectingInitializer* RedirectingInitializer::ReadFromImpl(Reader* reader) {
  TRACE_READ_OFFSET();
  RedirectingInitializer* init = new RedirectingInitializer();
  init->target_ = Constructor::Cast(Reference::ReadMemberFrom(reader));
  init->arguments_ = Arguments::ReadFrom(reader);
  return init;
}


void RedirectingInitializer::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  writer->WriteTag(kRedirectingInitializer);
  Reference::WriteMemberTo(writer, target_);
  arguments_->WriteTo(writer);
}


LocalInitializer* LocalInitializer::ReadFromImpl(Reader* reader) {
  TRACE_READ_OFFSET();
  LocalInitializer* init = new LocalInitializer();
  init->variable_ = VariableDeclaration::ReadFromImpl(reader);
  return init;
}


void LocalInitializer::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  writer->WriteTag(kLocalInitializer);
  variable_->WriteToImpl(writer);
}


Expression* Expression::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  uint8_t payload = 0;
  Tag tag = reader->ReadTag(&payload);
  switch (tag) {
    case kInvalidExpression:
      return InvalidExpression::ReadFrom(reader);
    case kVariableGet:
      return VariableGet::ReadFrom(reader);
    case kSpecializedVariableGet:
      return VariableGet::ReadFrom(reader, payload);
    case kVariableSet:
      return VariableSet::ReadFrom(reader);
    case kSpecializedVariableSet:
      return VariableSet::ReadFrom(reader, payload);
    case kPropertyGet:
      return PropertyGet::ReadFrom(reader);
    case kPropertySet:
      return PropertySet::ReadFrom(reader);
    case kDirectPropertyGet:
      return DirectPropertyGet::ReadFrom(reader);
    case kDirectPropertySet:
      return DirectPropertySet::ReadFrom(reader);
    case kStaticGet:
      return StaticGet::ReadFrom(reader);
    case kStaticSet:
      return StaticSet::ReadFrom(reader);
    case kMethodInvocation:
      return MethodInvocation::ReadFrom(reader);
    case kDirectMethodInvocation:
      return DirectMethodInvocation::ReadFrom(reader);
    case kStaticInvocation:
      return StaticInvocation::ReadFrom(reader, false);
    case kConstStaticInvocation:
      return StaticInvocation::ReadFrom(reader, true);
    case kConstructorInvocation:
      return ConstructorInvocation::ReadFrom(reader, false);
    case kConstConstructorInvocation:
      return ConstructorInvocation::ReadFrom(reader, true);
    case kNot:
      return Not::ReadFrom(reader);
    case kLogicalExpression:
      return LogicalExpression::ReadFrom(reader);
    case kConditionalExpression:
      return ConditionalExpression::ReadFrom(reader);
    case kStringConcatenation:
      return StringConcatenation::ReadFrom(reader);
    case kIsExpression:
      return IsExpression::ReadFrom(reader);
    case kAsExpression:
      return AsExpression::ReadFrom(reader);
    case kSymbolLiteral:
      return SymbolLiteral::ReadFrom(reader);
    case kTypeLiteral:
      return TypeLiteral::ReadFrom(reader);
    case kThisExpression:
      return ThisExpression::ReadFrom(reader);
    case kRethrow:
      return Rethrow::ReadFrom(reader);
    case kThrow:
      return Throw::ReadFrom(reader);
    case kListLiteral:
      return ListLiteral::ReadFrom(reader, false);
    case kConstListLiteral:
      return ListLiteral::ReadFrom(reader, true);
    case kMapLiteral:
      return MapLiteral::ReadFrom(reader, false);
    case kConstMapLiteral:
      return MapLiteral::ReadFrom(reader, true);
    case kAwaitExpression:
      return AwaitExpression::ReadFrom(reader);
    case kFunctionExpression:
      return FunctionExpression::ReadFrom(reader);
    case kLet:
      return Let::ReadFrom(reader);
    case kBlockExpression:
      return BlockExpression::ReadFrom(reader);
    case kBigIntLiteral:
      return BigintLiteral::ReadFrom(reader);
    case kStringLiteral:
      return StringLiteral::ReadFrom(reader);
    case kSpecialIntLiteral:
      return IntLiteral::ReadFrom(reader, payload);
    case kNegativeIntLiteral:
      return IntLiteral::ReadFrom(reader, true);
    case kPositiveIntLiteral:
      return IntLiteral::ReadFrom(reader, false);
    case kDoubleLiteral:
      return DoubleLiteral::ReadFrom(reader);
    case kTrueLiteral:
      return BoolLiteral::ReadFrom(reader, true);
    case kFalseLiteral:
      return BoolLiteral::ReadFrom(reader, false);
    case kNullLiteral:
      return NullLiteral::ReadFrom(reader);
    default:
      UNREACHABLE();
  }
  return NULL;
}


InvalidExpression* InvalidExpression::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  return new InvalidExpression();
}


void InvalidExpression::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  writer->WriteTag(kInvalidExpression);
}


VariableGet* VariableGet::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  VariableGet* get = new VariableGet();
  get->variable_ = reader->helper()->variables().Lookup(reader->ReadUInt());
  reader->ReadOptional<DartType>();  // Unused promoted type.
  return get;
}


VariableGet* VariableGet::ReadFrom(Reader* reader, uint8_t payload) {
  TRACE_READ_OFFSET();
  VariableGet* get = new VariableGet();
  get->variable_ = reader->helper()->variables().Lookup(payload);
  return get;
}


void VariableGet::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  int index = writer->helper()->variables().Lookup(variable_);
  if ((index & kSpecializedPayloadMask) == index) {
    writer->WriteTag(kSpecializedVariableGet, static_cast<uint8_t>(index));
  } else {
    writer->WriteTag(kVariableGet);
    writer->WriteUInt(index);
    writer->WriteOptional<DartType>(NULL);
  }
}


VariableSet* VariableSet::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  VariableSet* set = new VariableSet();
  set->variable_ = reader->helper()->variables().Lookup(reader->ReadUInt());
  set->expression_ = Expression::ReadFrom(reader);
  return set;
}


VariableSet* VariableSet::ReadFrom(Reader* reader, uint8_t payload) {
  TRACE_READ_OFFSET();
  VariableSet* set = new VariableSet();
  set->variable_ = reader->helper()->variables().Lookup(payload);
  set->expression_ = Expression::ReadFrom(reader);
  return set;
}


void VariableSet::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  int index = writer->helper()->variables().Lookup(variable_);
  if ((index & kSpecializedPayloadMask) == index) {
    writer->WriteTag(kSpecializedVariableSet, static_cast<uint8_t>(index));
  } else {
    writer->WriteTag(kVariableSet);
    writer->WriteUInt(index);
  }
  expression_->WriteTo(writer);
}


PropertyGet* PropertyGet::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  PropertyGet* get = new PropertyGet();
  reader->ReadUInt();
  get->receiver_ = Expression::ReadFrom(reader);
  get->name_ = Name::ReadFrom(reader);
  get->interfaceTarget_ = Reference::ReadMemberFrom(reader, true);
  return get;
}


void PropertyGet::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  writer->WriteTag(kPropertyGet);
  writer->WriteUInt(0);
  receiver_->WriteTo(writer);
  name_->WriteTo(writer);
  Reference::WriteMemberTo(writer, interfaceTarget_, true);
}


PropertySet* PropertySet::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  PropertySet* set = new PropertySet();
  reader->ReadUInt();
  set->receiver_ = Expression::ReadFrom(reader);
  set->name_ = Name::ReadFrom(reader);
  set->value_ = Expression::ReadFrom(reader);
  set->interfaceTarget_ = Reference::ReadMemberFrom(reader, true);
  return set;
}


void PropertySet::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  writer->WriteTag(kPropertySet);
  writer->WriteUInt(0);
  receiver_->WriteTo(writer);
  name_->WriteTo(writer);
  value_->WriteTo(writer);
  Reference::WriteMemberTo(writer, interfaceTarget_, true);
}


DirectPropertyGet* DirectPropertyGet::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  DirectPropertyGet* get = new DirectPropertyGet();
  get->receiver_ = Expression::ReadFrom(reader);
  get->target_ = Reference::ReadMemberFrom(reader);
  return get;
}


void DirectPropertyGet::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  writer->WriteTag(kDirectPropertyGet);
  receiver_->WriteTo(writer);
  Reference::WriteMemberTo(writer, target_);
}


DirectPropertySet* DirectPropertySet::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  DirectPropertySet* set = new DirectPropertySet();
  set->receiver_ = Expression::ReadFrom(reader);
  set->target_ = Reference::ReadMemberFrom(reader);
  set->value_ = Expression::ReadFrom(reader);
  return set;
}


void DirectPropertySet::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  writer->WriteTag(kDirectPropertySet);
  receiver_->WriteTo(writer);
  Reference::WriteMemberTo(writer, target_);
  value_->WriteTo(writer);
}


StaticGet* StaticGet::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  StaticGet* get = new StaticGet();
  reader->ReadUInt();
  get->target_ = Reference::ReadMemberFrom(reader);
  return get;
}


void StaticGet::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  writer->WriteTag(kStaticGet);
  writer->WriteUInt(0);
  Reference::WriteMemberTo(writer, target_);
}


StaticSet* StaticSet::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  StaticSet* set = new StaticSet();
  set->target_ = Reference::ReadMemberFrom(reader);
  set->expression_ = Expression::ReadFrom(reader);
  return set;
}


void StaticSet::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  writer->WriteTag(kStaticSet);
  Reference::WriteMemberTo(writer, target_);
  expression_->WriteTo(writer);
}


Arguments* Arguments::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  Arguments* arguments = new Arguments();
  arguments->types().ReadFromStatic<DartType>(reader);
  arguments->positional().ReadFromStatic<Expression>(reader);
  arguments->named().ReadFromStatic<NamedExpression>(reader);
  return arguments;
}


void Arguments::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  types().WriteTo(writer);
  positional().WriteTo(writer);
  named().WriteTo(writer);
}


NamedExpression* NamedExpression::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  String* name = Reference::ReadStringFrom(reader);
  Expression* expression = Expression::ReadFrom(reader);
  return new NamedExpression(name, expression);
}


void NamedExpression::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  name_->WriteTo(writer);
  expression_->WriteTo(writer);
}


MethodInvocation* MethodInvocation::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  MethodInvocation* invocation = new MethodInvocation();
  reader->ReadUInt();
  invocation->receiver_ = Expression::ReadFrom(reader);
  invocation->name_ = Name::ReadFrom(reader);
  invocation->arguments_ = Arguments::ReadFrom(reader);
  invocation->interfaceTarget_ = Reference::ReadMemberFrom(reader, true);
  return invocation;
}


void MethodInvocation::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  writer->WriteTag(kMethodInvocation);
  writer->WriteUInt(0);
  receiver_->WriteTo(writer);
  name_->WriteTo(writer);
  arguments_->WriteTo(writer);
  Reference::WriteMemberTo(writer, interfaceTarget_, true);
}


DirectMethodInvocation* DirectMethodInvocation::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  DirectMethodInvocation* invocation = new DirectMethodInvocation();
  invocation->receiver_ = Expression::ReadFrom(reader);
  invocation->target_ = Procedure::Cast(Reference::ReadMemberFrom(reader));
  invocation->arguments_ = Arguments::ReadFrom(reader);
  return invocation;
}


void DirectMethodInvocation::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  writer->WriteTag(kDirectMethodInvocation);
  receiver_->WriteTo(writer);
  Reference::WriteMemberTo(writer, target_);
  arguments_->WriteTo(writer);
}


StaticInvocation* StaticInvocation::ReadFrom(Reader* reader, bool is_const) {
  TRACE_READ_OFFSET();

  reader->ReadUInt();
  Member* member = Reference::ReadMemberFrom(reader);
  Arguments* args = Arguments::ReadFrom(reader);

  return new StaticInvocation(Procedure::Cast(member), args, is_const);
}


void StaticInvocation::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  writer->WriteTag(is_const_ ? kConstStaticInvocation : kStaticInvocation);
  writer->WriteUInt(0);
  Reference::WriteMemberTo(writer, procedure_);
  arguments_->WriteTo(writer);
}


ConstructorInvocation* ConstructorInvocation::ReadFrom(Reader* reader,
                                                       bool is_const) {
  TRACE_READ_OFFSET();
  ConstructorInvocation* invocation = new ConstructorInvocation();
  invocation->is_const_ = is_const;
  reader->ReadUInt();
  invocation->target_ = Constructor::Cast(Reference::ReadMemberFrom(reader));
  invocation->arguments_ = Arguments::ReadFrom(reader);
  return invocation;
}


void ConstructorInvocation::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  writer->WriteTag(is_const_ ? kConstConstructorInvocation
                             : kConstructorInvocation);
  writer->WriteUInt(0);
  Reference::WriteMemberTo(writer, target_);
  arguments_->WriteTo(writer);
}


Not* Not::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  Not* n = new Not();
  n->expression_ = Expression::ReadFrom(reader);
  return n;
}


void Not::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  writer->WriteTag(kNot);
  expression_->WriteTo(writer);
}


LogicalExpression* LogicalExpression::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  LogicalExpression* expr = new LogicalExpression();
  expr->left_ = Expression::ReadFrom(reader);
  expr->operator_ = static_cast<Operator>(reader->ReadByte());
  expr->right_ = Expression::ReadFrom(reader);
  return expr;
}


void LogicalExpression::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  writer->WriteTag(kLogicalExpression);
  left_->WriteTo(writer);
  writer->WriteByte(operator_);
  right_->WriteTo(writer);
}


ConditionalExpression* ConditionalExpression::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  ConditionalExpression* expr = new ConditionalExpression();
  expr->condition_ = Expression::ReadFrom(reader);
  expr->then_ = Expression::ReadFrom(reader);
  expr->otherwise_ = Expression::ReadFrom(reader);
  reader->ReadOptional<DartType>();  // Unused static type.
  return expr;
}


void ConditionalExpression::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  writer->WriteTag(kConditionalExpression);
  condition_->WriteTo(writer);
  then_->WriteTo(writer);
  otherwise_->WriteTo(writer);
  writer->WriteOptional<DartType>(NULL);  // Unused static type.
}


StringConcatenation* StringConcatenation::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  StringConcatenation* concat = new StringConcatenation();
  concat->expressions_.ReadFromStatic<Expression>(reader);
  return concat;
}


void StringConcatenation::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  writer->WriteTag(kStringConcatenation);
  expressions_.WriteTo(writer);
}


IsExpression* IsExpression::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  IsExpression* expr = new IsExpression();
  expr->operand_ = Expression::ReadFrom(reader);
  expr->type_ = DartType::ReadFrom(reader);
  return expr;
}


void IsExpression::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  writer->WriteTag(kIsExpression);
  operand_->WriteTo(writer);
  type_->WriteTo(writer);
}


AsExpression* AsExpression::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  AsExpression* expr = new AsExpression();
  expr->operand_ = Expression::ReadFrom(reader);
  expr->type_ = DartType::ReadFrom(reader);
  return expr;
}


void AsExpression::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  writer->WriteTag(kAsExpression);
  operand_->WriteTo(writer);
  type_->WriteTo(writer);
}


StringLiteral* StringLiteral::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  return new StringLiteral(Reference::ReadStringFrom(reader));
}


void StringLiteral::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  writer->WriteTag(kStringLiteral);
  value_->WriteTo(writer);
}


BigintLiteral* BigintLiteral::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  return new BigintLiteral(Reference::ReadStringFrom(reader));
}


void BigintLiteral::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  writer->WriteTag(kBigIntLiteral);
  value_->WriteTo(writer);
}


IntLiteral* IntLiteral::ReadFrom(Reader* reader, bool is_negative) {
  TRACE_READ_OFFSET();
  IntLiteral* literal = new IntLiteral();
  literal->value_ = is_negative ? -static_cast<int64_t>(reader->ReadUInt())
                                : reader->ReadUInt();
  return literal;
}


IntLiteral* IntLiteral::ReadFrom(Reader* reader, uint8_t payload) {
  TRACE_READ_OFFSET();
  IntLiteral* literal = new IntLiteral();
  literal->value_ = static_cast<int32_t>(payload) - SpecializedIntLiteralBias;
  return literal;
}


void IntLiteral::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  int64_t payload = value_ + SpecializedIntLiteralBias;
  if ((payload & kSpecializedPayloadMask) == payload) {
    writer->WriteTag(kSpecialIntLiteral, static_cast<uint8_t>(payload));
  } else {
    writer->WriteTag(value_ < 0 ? kNegativeIntLiteral : kPositiveIntLiteral);
    writer->WriteUInt(static_cast<uint32_t>(value_ < 0 ? -value_ : value_));
  }
}


DoubleLiteral* DoubleLiteral::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  DoubleLiteral* literal = new DoubleLiteral();
  literal->value_ = Reference::ReadStringFrom(reader);
  return literal;
}


void DoubleLiteral::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  writer->WriteTag(kDoubleLiteral);
  value_->WriteTo(writer);
}


BoolLiteral* BoolLiteral::ReadFrom(Reader* reader, bool value) {
  TRACE_READ_OFFSET();
  BoolLiteral* lit = new BoolLiteral();
  lit->value_ = value;
  return lit;
}


void BoolLiteral::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  writer->WriteTag(value_ ? kTrueLiteral : kFalseLiteral);
}


NullLiteral* NullLiteral::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  return new NullLiteral();
}


void NullLiteral::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  writer->WriteTag(kNullLiteral);
}


SymbolLiteral* SymbolLiteral::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  SymbolLiteral* lit = new SymbolLiteral();
  lit->value_ = Reference::ReadStringFrom(reader);
  return lit;
}


void SymbolLiteral::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  writer->WriteTag(kSymbolLiteral);
  value_->WriteTo(writer);
}


TypeLiteral* TypeLiteral::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  TypeLiteral* literal = new TypeLiteral();
  literal->type_ = DartType::ReadFrom(reader);
  return literal;
}


void TypeLiteral::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  writer->WriteTag(kTypeLiteral);
  type_->WriteTo(writer);
}


ThisExpression* ThisExpression::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  return new ThisExpression();
}


void ThisExpression::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  writer->WriteTag(kThisExpression);
}


Rethrow* Rethrow::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  return new Rethrow();
}


void Rethrow::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  writer->WriteTag(kRethrow);
}


Throw* Throw::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  Throw* t = new Throw();
  reader->ReadUInt();
  t->expression_ = Expression::ReadFrom(reader);
  return t;
}


void Throw::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  writer->WriteTag(kThrow);
  writer->WriteUInt(0);
  expression_->WriteTo(writer);
}


ListLiteral* ListLiteral::ReadFrom(Reader* reader, bool is_const) {
  TRACE_READ_OFFSET();
  ListLiteral* literal = new ListLiteral();
  literal->is_const_ = is_const;
  literal->type_ = DartType::ReadFrom(reader);
  literal->expressions_.ReadFromStatic<Expression>(reader);
  return literal;
}


void ListLiteral::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  writer->WriteTag(is_const_ ? kConstListLiteral : kListLiteral);
  type_->WriteTo(writer);
  expressions_.WriteTo(writer);
}


MapLiteral* MapLiteral::ReadFrom(Reader* reader, bool is_const) {
  TRACE_READ_OFFSET();
  MapLiteral* literal = new MapLiteral();
  literal->is_const_ = is_const;
  literal->key_type_ = DartType::ReadFrom(reader);
  literal->value_type_ = DartType::ReadFrom(reader);
  literal->entries_.ReadFromStatic<MapEntry>(reader);
  return literal;
}


void MapLiteral::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  writer->WriteTag(is_const_ ? kConstMapLiteral : kMapLiteral);
  key_type_->WriteTo(writer);
  value_type_->WriteTo(writer);
  entries_.WriteTo(writer);
}


MapEntry* MapEntry::ReadFrom(Reader* reader) {
  MapEntry* entry = new MapEntry();
  entry->key_ = Expression::ReadFrom(reader);
  entry->value_ = Expression::ReadFrom(reader);
  return entry;
}


void MapEntry::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  key_->WriteTo(writer);
  value_->WriteTo(writer);
}


AwaitExpression* AwaitExpression::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  AwaitExpression* await = new AwaitExpression();
  await->operand_ = Expression::ReadFrom(reader);
  return await;
}


void AwaitExpression::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  writer->WriteTag(kAwaitExpression);
  operand_->WriteTo(writer);
}


FunctionExpression* FunctionExpression::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  VariableScope<ReaderHelper> parameters(reader->helper());
  FunctionExpression* expr = new FunctionExpression();
  expr->function_ = FunctionNode::ReadFrom(reader);
  return expr;
}


void FunctionExpression::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  VariableScope<WriterHelper> parameters(writer->helper());
  writer->WriteTag(kFunctionExpression);
  function_->WriteTo(writer);
}


Let* Let::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  VariableScope<ReaderHelper> vars(reader->helper());
  Let* let = new Let();
  let->variable_ = VariableDeclaration::ReadFromImpl(reader);
  let->body_ = Expression::ReadFrom(reader);
  return let;
}


void Let::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  VariableScope<WriterHelper> vars(writer->helper());
  writer->WriteTag(kLet);
  variable_->WriteToImpl(writer);
  body_->WriteTo(writer);
}


BlockExpression* BlockExpression::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  BlockExpression* be = new BlockExpression();
  be->body_ = Block::ReadFromImpl(reader);
  be->value_ = Expression::ReadFrom(reader);
  return be;
}


void BlockExpression::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  writer->WriteTag(kBlockExpression);
  body_->WriteToImpl(writer);
  value_->WriteTo(writer);
}


Statement* Statement::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  Tag tag = reader->ReadTag();
  switch (tag) {
    case kInvalidStatement:
      return InvalidStatement::ReadFrom(reader);
    case kExpressionStatement:
      return ExpressionStatement::ReadFrom(reader);
    case kBlock:
      return Block::ReadFromImpl(reader);
    case kEmptyStatement:
      return EmptyStatement::ReadFrom(reader);
    case kAssertStatement:
      return AssertStatement::ReadFrom(reader);
    case kLabeledStatement:
      return LabeledStatement::ReadFrom(reader);
    case kBreakStatement:
      return BreakStatement::ReadFrom(reader);
    case kWhileStatement:
      return WhileStatement::ReadFrom(reader);
    case kDoStatement:
      return DoStatement::ReadFrom(reader);
    case kForStatement:
      return ForStatement::ReadFrom(reader);
    case kForInStatement:
      return ForInStatement::ReadFrom(reader, false);
    case kAsyncForInStatement:
      return ForInStatement::ReadFrom(reader, true);
    case kSwitchStatement:
      return SwitchStatement::ReadFrom(reader);
    case kContinueSwitchStatement:
      return ContinueSwitchStatement::ReadFrom(reader);
    case kIfStatement:
      return IfStatement::ReadFrom(reader);
    case kReturnStatement:
      return ReturnStatement::ReadFrom(reader);
    case kTryCatch:
      return TryCatch::ReadFrom(reader);
    case kTryFinally:
      return TryFinally::ReadFrom(reader);
    case kYieldStatement:
      return YieldStatement::ReadFrom(reader);
    case kVariableDeclaration:
      return VariableDeclaration::ReadFromImpl(reader);
    case kFunctionDeclaration:
      return FunctionDeclaration::ReadFrom(reader);
    default:
      UNREACHABLE();
  }
  return NULL;
}


InvalidStatement* InvalidStatement::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  return new InvalidStatement();
}


void InvalidStatement::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  writer->WriteTag(kInvalidStatement);
}


ExpressionStatement* ExpressionStatement::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  return new ExpressionStatement(Expression::ReadFrom(reader));
}


void ExpressionStatement::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  writer->WriteTag(kExpressionStatement);
  expression_->WriteTo(writer);
}


Block* Block::ReadFromImpl(Reader* reader) {
  TRACE_READ_OFFSET();
  VariableScope<ReaderHelper> vars(reader->helper());
  Block* block = new Block();
  block->statements().ReadFromStatic<Statement>(reader);
  return block;
}


void Block::WriteTo(Writer* writer) {
  writer->WriteTag(kBlock);
  WriteToImpl(writer);
}


void Block::WriteToImpl(Writer* writer) {
  TRACE_WRITE_OFFSET();
  VariableScope<WriterHelper> vars(writer->helper());
  statements_.WriteTo(writer);
}


EmptyStatement* EmptyStatement::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  return new EmptyStatement();
}


void EmptyStatement::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  writer->WriteTag(kEmptyStatement);
}


AssertStatement* AssertStatement::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  AssertStatement* stmt = new AssertStatement();
  stmt->condition_ = Expression::ReadFrom(reader);
  stmt->message_ = reader->ReadOptional<Expression>();
  return stmt;
}


void AssertStatement::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  writer->WriteTag(kAssertStatement);
  condition_->WriteTo(writer);
  writer->WriteOptional<Expression>(message_);
}


LabeledStatement* LabeledStatement::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  LabeledStatement* stmt = new LabeledStatement();
  reader->helper()->lables().Push(stmt);
  stmt->body_ = Statement::ReadFrom(reader);
  reader->helper()->lables().Pop(stmt);
  return stmt;
}


void LabeledStatement::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  writer->WriteTag(kLabeledStatement);
  writer->helper()->lables().Push(this);
  body_->WriteTo(writer);
  writer->helper()->lables().Pop(this);
}


BreakStatement* BreakStatement::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  BreakStatement* stmt = new BreakStatement();
  stmt->target_ = reader->helper()->lables().Lookup(reader->ReadUInt());
  return stmt;
}


void BreakStatement::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  writer->WriteTag(kBreakStatement);
  writer->WriteUInt(writer->helper()->lables().Lookup(target_));
}


WhileStatement* WhileStatement::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  WhileStatement* stmt = new WhileStatement();
  stmt->condition_ = Expression::ReadFrom(reader);
  stmt->body_ = Statement::ReadFrom(reader);
  return stmt;
}


void WhileStatement::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  writer->WriteTag(kWhileStatement);
  condition_->WriteTo(writer);
  body_->WriteTo(writer);
}


DoStatement* DoStatement::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  DoStatement* dostmt = new DoStatement();
  dostmt->body_ = Statement::ReadFrom(reader);
  dostmt->condition_ = Expression::ReadFrom(reader);
  return dostmt;
}


void DoStatement::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  writer->WriteTag(kDoStatement);
  body_->WriteTo(writer);
  condition_->WriteTo(writer);
}


ForStatement* ForStatement::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  VariableScope<ReaderHelper> vars(reader->helper());
  ForStatement* forstmt = new ForStatement();
  forstmt->variables_.ReadFromStatic<VariableDeclarationImpl>(reader);
  forstmt->condition_ = reader->ReadOptional<Expression>();
  forstmt->updates_.ReadFromStatic<Expression>(reader);
  forstmt->body_ = Statement::ReadFrom(reader);
  return forstmt;
}


void ForStatement::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  writer->WriteTag(kForStatement);
  VariableScope<WriterHelper> vars(writer->helper());
  variables_.WriteToStatic<VariableDeclarationImpl>(writer);
  writer->WriteOptional<Expression>(condition_);
  updates_.WriteTo(writer);
  body_->WriteTo(writer);
}


ForInStatement* ForInStatement::ReadFrom(Reader* reader, bool is_async) {
  TRACE_READ_OFFSET();
  VariableScope<ReaderHelper> vars(reader->helper());
  ForInStatement* forinstmt = new ForInStatement();
  forinstmt->is_async_ = is_async;
  forinstmt->variable_ = VariableDeclaration::ReadFromImpl(reader);
  forinstmt->iterable_ = Expression::ReadFrom(reader);
  forinstmt->body_ = Statement::ReadFrom(reader);
  return forinstmt;
}


void ForInStatement::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  writer->WriteTag(is_async_ ? kAsyncForInStatement : kForInStatement);
  VariableScope<WriterHelper> vars(writer->helper());
  variable_->WriteToImpl(writer);
  iterable_->WriteTo(writer);
  body_->WriteTo(writer);
}


SwitchStatement* SwitchStatement::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  SwitchCaseScope<ReaderHelper> scope(reader->helper());
  SwitchStatement* stmt = new SwitchStatement();
  stmt->condition_ = Expression::ReadFrom(reader);
  // We need to explicitly create empty [SwitchCase]s first in order to add them
  // to the [SwitchCaseScope]. This is necessary since a [Statement] in a switch
  // case can refer to one defined later on.
  int count = reader->ReadUInt();
  for (int i = 0; i < count; i++) {
    SwitchCase* sc = stmt->cases_.GetOrCreate<SwitchCase>(i);
    reader->helper()->switch_cases().Push(sc);
  }
  for (int i = 0; i < count; i++) {
    SwitchCase* sc = stmt->cases_[i];
    sc->ReadFrom(reader);
  }
  return stmt;
}


void SwitchStatement::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  SwitchCaseScope<WriterHelper> scope(writer->helper());
  writer->WriteTag(kSwitchStatement);
  condition_->WriteTo(writer);
  for (int i = 0; i < cases_.length(); i++) {
    writer->helper()->switch_cases().Push(cases_[i]);
  }
  cases_.WriteTo(writer);
}


SwitchCase* SwitchCase::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  expressions_.ReadFromStatic<Expression>(reader);
  is_default_ = reader->ReadBool();
  body_ = Statement::ReadFrom(reader);
  return this;
}


void SwitchCase::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  expressions_.WriteTo(writer);
  writer->WriteBool(is_default_);
  body_->WriteTo(writer);
}


ContinueSwitchStatement* ContinueSwitchStatement::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  ContinueSwitchStatement* stmt = new ContinueSwitchStatement();
  stmt->target_ = reader->helper()->switch_cases().Lookup(reader->ReadUInt());
  return stmt;
}


void ContinueSwitchStatement::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  writer->WriteTag(kContinueSwitchStatement);
  writer->WriteUInt(writer->helper()->switch_cases().Lookup(target_));
}


IfStatement* IfStatement::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  IfStatement* ifstmt = new IfStatement();
  ifstmt->condition_ = Expression::ReadFrom(reader);
  ifstmt->then_ = Statement::ReadFrom(reader);
  ifstmt->otherwise_ = Statement::ReadFrom(reader);
  return ifstmt;
}


void IfStatement::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  writer->WriteTag(kIfStatement);
  condition_->WriteTo(writer);
  then_->WriteTo(writer);
  otherwise_->WriteTo(writer);
}


ReturnStatement* ReturnStatement::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  ReturnStatement* ret = new ReturnStatement();
  ret->expression_ = reader->ReadOptional<Expression>();
  return ret;
}


void ReturnStatement::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  writer->WriteTag(kReturnStatement);
  writer->WriteOptional<Expression>(expression_);
}


TryCatch* TryCatch::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  TryCatch* tc = new TryCatch();
  tc->body_ = Statement::ReadFrom(reader);
  tc->catches_.ReadFromStatic<Catch>(reader);
  return tc;
}


void TryCatch::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  writer->WriteTag(kTryCatch);
  body_->WriteTo(writer);
  catches_.WriteTo(writer);
}


Catch* Catch::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  VariableScope<ReaderHelper> vars(reader->helper());
  Catch* c = new Catch();
  c->guard_ = DartType::ReadFrom(reader);
  c->exception_ =
      reader->ReadOptional<VariableDeclaration, VariableDeclarationImpl>();
  c->stack_trace_ =
      reader->ReadOptional<VariableDeclaration, VariableDeclarationImpl>();
  c->body_ = Statement::ReadFrom(reader);
  return c;
}


void Catch::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  VariableScope<WriterHelper> vars(writer->helper());
  guard_->WriteTo(writer);
  writer->WriteOptionalStatic<VariableDeclaration, VariableDeclarationImpl>(
      exception_);
  writer->WriteOptionalStatic<VariableDeclaration, VariableDeclarationImpl>(
      stack_trace_);
  body_->WriteTo(writer);
}


TryFinally* TryFinally::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  TryFinally* tf = new TryFinally();
  tf->body_ = Statement::ReadFrom(reader);
  tf->finalizer_ = Statement::ReadFrom(reader);
  return tf;
}


void TryFinally::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  writer->WriteTag(kTryFinally);
  body_->WriteTo(writer);
  finalizer_->WriteTo(writer);
}


YieldStatement* YieldStatement::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  YieldStatement* stmt = new YieldStatement();
  stmt->flags_ = reader->ReadByte();
  stmt->expression_ = Expression::ReadFrom(reader);
  return stmt;
}


void YieldStatement::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  writer->WriteTag(kYieldStatement);
  writer->WriteByte(flags_);
  expression_->WriteTo(writer);
}


VariableDeclaration* VariableDeclaration::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  Tag tag = reader->ReadTag();
  ASSERT(tag == kVariableDeclaration);
  return VariableDeclaration::ReadFromImpl(reader);
}


VariableDeclaration* VariableDeclaration::ReadFromImpl(Reader* reader) {
  TRACE_READ_OFFSET();
  VariableDeclaration* decl = new VariableDeclaration();
  decl->flags_ = reader->ReadFlags();
  decl->name_ = Reference::ReadStringFrom(reader);
  decl->type_ = DartType::ReadFrom(reader);
  decl->inferred_value_ = reader->ReadOptional<InferredValue>();
  decl->initializer_ = reader->ReadOptional<Expression>();
  reader->helper()->variables().Push(decl);
  return decl;
}


void VariableDeclaration::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  writer->WriteTag(kVariableDeclaration);
  WriteToImpl(writer);
}


void VariableDeclaration::WriteToImpl(Writer* writer) {
  TRACE_WRITE_OFFSET();
  writer->WriteFlags(flags_);
  name_->WriteTo(writer);
  type_->WriteTo(writer);
  writer->WriteOptional<InferredValue>(inferred_value_);
  writer->WriteOptional<Expression>(initializer_);
  writer->helper()->variables().Push(this);
}


FunctionDeclaration* FunctionDeclaration::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  FunctionDeclaration* decl = new FunctionDeclaration();
  decl->variable_ = VariableDeclaration::ReadFromImpl(reader);
  VariableScope<ReaderHelper> parameters(reader->helper());
  decl->function_ = FunctionNode::ReadFrom(reader);
  return decl;
}


void FunctionDeclaration::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  writer->WriteTag(kFunctionDeclaration);
  variable_->WriteToImpl(writer);
  VariableScope<WriterHelper> parameters(writer->helper());
  function_->WriteTo(writer);
}


Name* Name::ReadFrom(Reader* reader) {
  String* string = Reference::ReadStringFrom(reader);
  if (string->size() >= 1 && string->buffer()[0] == '_') {
    int lib_index = reader->ReadUInt();
    Library* library =
        reader->helper()->program()->libraries().GetOrCreate<Library>(
            lib_index);
    return new Name(string, library);
  } else {
    return new Name(string, NULL);
  }
}


void Name::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  string_->WriteTo(writer);
  Library* library = library_;
  bool is_private = library != NULL;
  if (is_private) {
    writer->WriteUInt(writer->helper()->libraries().Lookup(library_));
  }
}


InferredValue* InferredValue::ReadFrom(Reader* reader) {
  InferredValue* type = new InferredValue();
  type->klass_ = Reference::ReadClassFrom(reader, true);
  type->kind_ = static_cast<BaseClassKind>(reader->ReadByte());
  type->value_bits_ = reader->ReadByte();
  return type;
}


void InferredValue::WriteTo(Writer* writer) {
  Reference::WriteClassTo(writer, klass_, true);
  writer->WriteByte(static_cast<uint8_t>(kind_));
  writer->WriteByte(value_bits_);
}


DartType* DartType::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  Tag tag = reader->ReadTag();
  switch (tag) {
    case kInvalidType:
      return InvalidType::ReadFrom(reader);
    case kDynamicType:
      return DynamicType::ReadFrom(reader);
    case kVoidType:
      return VoidType::ReadFrom(reader);
    case kInterfaceType:
      return InterfaceType::ReadFrom(reader);
    case kSimpleInterfaceType:
      return InterfaceType::ReadFrom(reader, true);
    case kFunctionType:
      return FunctionType::ReadFrom(reader);
    case kSimpleFunctionType:
      return FunctionType::ReadFrom(reader, true);
    case kTypeParameterType:
      return TypeParameterType::ReadFrom(reader);
    default:
      UNREACHABLE();
  }
  UNREACHABLE();
  return NULL;
}


InvalidType* InvalidType::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  return new InvalidType();
}


void InvalidType::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  writer->WriteTag(kInvalidType);
}


DynamicType* DynamicType::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  return new DynamicType();
}


void DynamicType::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  writer->WriteTag(kDynamicType);
}


VoidType* VoidType::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  return new VoidType();
}


void VoidType::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  writer->WriteTag(kVoidType);
}


InterfaceType* InterfaceType::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  Class* klass = Reference::ReadClassFrom(reader);
  InterfaceType* type = new InterfaceType(klass);
  type->type_arguments().ReadFromStatic<DartType>(reader);
  return type;
}


InterfaceType* InterfaceType::ReadFrom(Reader* reader,
                                       bool _without_type_arguments_) {
  TRACE_READ_OFFSET();
  Class* klass = Reference::ReadClassFrom(reader);
  InterfaceType* type = new InterfaceType(klass);
  ASSERT(_without_type_arguments_);
  return type;
}


void InterfaceType::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  if (type_arguments_.length() == 0) {
    writer->WriteTag(kSimpleInterfaceType);
    Reference::WriteClassTo(writer, klass_);
  } else {
    writer->WriteTag(kInterfaceType);
    Reference::WriteClassTo(writer, klass_);
    type_arguments_.WriteTo(writer);
  }
}


FunctionType* FunctionType::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  FunctionType* type = new FunctionType();
  TypeParameterScope<ReaderHelper> scope(reader->helper());
  type->type_parameters().ReadFrom(reader);
  type->required_parameter_count_ = reader->ReadUInt();
  type->positional_parameters().ReadFromStatic<DartType>(reader);
  type->named_parameters().ReadFromStatic<Tuple<String, DartType> >(reader);
  type->return_type_ = DartType::ReadFrom(reader);
  return type;
}


FunctionType* FunctionType::ReadFrom(Reader* reader, bool _is_simple_) {
  TRACE_READ_OFFSET();
  FunctionType* type = new FunctionType();
  ASSERT(_is_simple_);
  type->positional_parameters().ReadFromStatic<DartType>(reader);
  type->required_parameter_count_ = type->positional_parameters().length();
  type->return_type_ = DartType::ReadFrom(reader);
  return type;
}


void FunctionType::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();

  bool is_simple =
      positional_parameters_.length() == required_parameter_count_ &&
      type_parameters_.length() == 0 && named_parameters_.length() == 0;
  if (is_simple) {
    writer->WriteTag(kSimpleFunctionType);
    positional_parameters_.WriteTo(writer);
    return_type_->WriteTo(writer);
  } else {
    TypeParameterScope<WriterHelper> scope(writer->helper());
    writer->WriteTag(kFunctionType);
    type_parameters_.WriteTo(writer);
    writer->WriteUInt(required_parameter_count_);
    positional_parameters_.WriteTo(writer);
    named_parameters_.WriteTo(writer);
    return_type_->WriteTo(writer);
  }
}


TypeParameterType* TypeParameterType::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  TypeParameterType* type = new TypeParameterType();
  type->parameter_ =
      reader->helper()->type_parameters().Lookup(reader->ReadUInt());
  return type;
}


void TypeParameterType::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  writer->WriteTag(kTypeParameterType);
  writer->WriteUInt(writer->helper()->type_parameters().Lookup(parameter_));
}


Program* Program::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  uint32_t magic = reader->ReadUInt32();
  if (magic != kMagicProgramFile) FATAL("Invalid magic identifier");

  Program* program = new Program();
  reader->helper()->set_program(program);

  program->string_table_.ReadFrom(reader);
  StringTable dummy1;
  dummy1.ReadFrom(reader);
  LineStartingTable dummy2;
  dummy2.ReadFrom(reader, dummy1.strings_.length());

  int libraries = reader->ReadUInt();
  program->libraries().EnsureInitialized(libraries);
  for (int i = 0; i < libraries; i++) {
    program->libraries().GetOrCreate<Library>(i)->ReadFrom(reader);
  }

  program->main_method_ = Procedure::Cast(Reference::ReadMemberFrom(reader));

  return program;
}


void Program::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();

  writer->helper()->SetProgram(this);

  writer->WriteUInt32(kMagicProgramFile);

  // NOTE: Currently we don't GC strings and we require that all referenced
  // strings in nodes are present in [string_table_].
  string_table_.WriteTo(writer);
  StringTable dummy1;
  dummy1.WriteTo(writer);
  LineStartingTable dummy2;
  dummy2.WriteTo(writer);

  libraries_.WriteTo(writer);
  Reference::WriteMemberTo(writer, main_method_);
}


FunctionNode* FunctionNode::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  TypeParameterScope<ReaderHelper> scope(reader->helper());

  FunctionNode* function = new FunctionNode();
  function->async_marker_ =
      static_cast<FunctionNode::AsyncMarker>(reader->ReadByte());
  function->type_parameters().ReadFrom(reader);
  function->required_parameter_count_ = reader->ReadUInt();
  function->positional_parameters().ReadFromStatic<VariableDeclarationImpl>(
      reader);
  function->named_parameters().ReadFromStatic<VariableDeclarationImpl>(reader);
  function->return_type_ = DartType::ReadFrom(reader);
  function->inferred_return_value_ = reader->ReadOptional<InferredValue>();

  VariableScope<ReaderHelper> vars(reader->helper());
  function->body_ = reader->ReadOptional<Statement>();
  return function;
}


void FunctionNode::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  TypeParameterScope<WriterHelper> scope(writer->helper());

  writer->WriteByte(static_cast<uint8_t>(async_marker_));
  type_parameters().WriteTo(writer);
  writer->WriteUInt(required_parameter_count());
  positional_parameters().WriteToStatic<VariableDeclarationImpl>(writer);
  named_parameters().WriteToStatic<VariableDeclarationImpl>(writer);
  return_type_->WriteTo(writer);
  writer->WriteOptional<InferredValue>(inferred_return_value_);

  VariableScope<WriterHelper> vars(writer->helper());
  writer->WriteOptional<Statement>(body_);
}


TypeParameter* TypeParameter::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  name_ = Reference::ReadStringFrom(reader);
  bound_ = DartType::ReadFrom(reader);
  return this;
}


void TypeParameter::WriteTo(Writer* writer) {
  TRACE_WRITE_OFFSET();
  name_->WriteTo(writer);
  bound_->WriteTo(writer);
}


}  // namespace kernel


kernel::Program* ReadPrecompiledKernelFromBuffer(const uint8_t* buffer,
                                                 intptr_t buffer_length) {
  kernel::Reader reader(buffer, buffer_length);
  return kernel::Program::ReadFrom(&reader);
}


void WritePrecompiledKernel(ByteWriter* byte_writer, kernel::Program* program) {
  ASSERT(byte_writer != NULL);

  kernel::Writer writer(byte_writer);
  program->WriteTo(&writer);
}


}  // namespace dart
