// 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 "vm/kernel_binary.h"
#include "platform/globals.h"
#include "vm/flags.h"
#include "vm/growable_array.h"
#include "vm/kernel.h"
#include "vm/kernel_to_il.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)
#else
#define TRACE_READ_OFFSET()
#endif

namespace dart {


namespace kernel {


Reader::~Reader() {
  delete[] string_offsets_;
  delete[] canonical_name_parents_;
  delete[] canonical_name_strings_;
}


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 (intptr_t 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 (intptr_t 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 (intptr_t i = 0; i < length_; i++) {
    ASSERT(array_[i] == NULL);
    array_[i] = IT::ReadFrom(reader);
  }
}


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 (intptr_t 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 (intptr_t i = 0; i < length; i++) {
    (*this)[i]->ReadFrom(reader);
  }
}


NamedParameter* NamedParameter::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  StringIndex name_index(reader->ReadUInt());
  DartType* type = DartType::ReadFrom(reader);
  return new NamedParameter(name_index, type);
}


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


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


void SourceTable::ReadFrom(Reader* reader) {
  size_ = reader->ReadUInt();
  sources_ = new Source[size_];

  // Build a table of the URI offsets.
  intptr_t* end_offsets = new intptr_t[size_];
  for (intptr_t i = 0; i < size_; ++i) {
    end_offsets[i] = reader->ReadUInt();
  }

  // Read the URI strings.
  intptr_t start_offset = 0;
  for (intptr_t i = 0; i < size_; ++i) {
    intptr_t length = end_offsets[i] - start_offset;
    uint8_t* buffer = new uint8_t[length];
    memmove(buffer, reader->buffer() + reader->offset(), length);
    reader->Consume(length);

    sources_[i].uri_ = buffer;
    sources_[i].uri_size_ = length;

    start_offset = end_offsets[i];
  }

  // Read the source code strings and line starts.
  for (intptr_t i = 0; i < size_; ++i) {
    intptr_t length = reader->ReadUInt();
    uint8_t* string_buffer = new uint8_t[length];
    memmove(string_buffer, reader->buffer() + reader->offset(), length);
    reader->Consume(length);
    intptr_t line_count = reader->ReadUInt();
    intptr_t* line_starts = new intptr_t[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;
    }

    sources_[i].source_code_ = string_buffer;
    sources_[i].source_code_size_ = length;
    sources_[i].line_starts_ = line_starts;
    sources_[i].line_count_ = line_count;
  }
}


Library* Library::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  int flags = reader->ReadFlags();
  ASSERT(flags == 0);  // external libraries not supported
  kernel_data_ = reader->buffer();
  kernel_data_size_ = reader->size();

  canonical_name_ = reader->ReadCanonicalNameReference();
  name_index_ = StringIndex(reader->ReadUInt());
  import_uri_index_ = reader->CanonicalNameString(canonical_name_);
  source_uri_index_ = reader->ReadUInt();
  reader->set_current_script_id(source_uri_index_);

  annotations_.ReadFromStatic<Expression>(reader);
  dependencies().ReadFromStatic<LibraryDependency>(reader);
  int num_typedefs = reader->ReadUInt();
  typedefs().EnsureInitialized(num_typedefs);
  for (intptr_t i = 0; i < num_typedefs; i++) {
    typedefs().GetOrCreate<Typedef>(i, this)->ReadFrom(reader);
  }
  int num_classes = reader->ReadUInt();
  classes().EnsureInitialized(num_classes);
  for (intptr_t i = 0; i < num_classes; i++) {
    Tag tag = reader->ReadTag();
    ASSERT(tag == kClass);
    NormalClass* klass = classes().GetOrCreate<NormalClass>(i, this);
    klass->ReadFrom(reader);
  }

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

  can_stream_ =
      classes().CanStream() && fields().CanStream() && procedures().CanStream();

  return this;
}


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

  LibraryDependency* node = new LibraryDependency();
  node->flags_ = reader->ReadFlags();
  node->annotations_.ReadFromStatic<Expression>(reader);
  node->target_reference_ = Reference::ReadLibraryFrom(reader);
  node->name_index_ = StringIndex(reader->ReadUInt());
  node->combinators_.ReadFromStatic<Combinator>(reader);

  return node;
}


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

  Combinator* node = new Combinator();
  node->is_show_ = (reader->ReadByte() == 1);
  int num_names = reader->ReadUInt();
  node->name_indices_.Initialize(num_names);
  for (intptr_t i = 0; i < num_names; ++i) {
    node->name_indices_[i] = reader->ReadUInt();
  }

  return node;
}


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

  canonical_name_ = reader->ReadCanonicalNameReference();
  position_ = reader->ReadPosition(false);
  name_index_ = StringIndex(reader->ReadUInt());
  source_uri_index_ = reader->ReadUInt();
  type_parameters_.ReadFrom(reader);
  type_ = DartType::ReadFrom(reader);

  return this;
}


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

  canonical_name_ = reader->ReadCanonicalNameReference();
  position_ = reader->ReadPosition(false);
  is_abstract_ = reader->ReadBool();
  name_index_ = StringIndex(reader->ReadUInt());
  source_uri_index_ = reader->ReadUInt();
  reader->set_current_script_id(source_uri_index_);
  reader->record_token_position(position_);
  annotations_.ReadFromStatic<Expression>(reader);

  can_stream_ = annotations_.CanStream();

  return this;
}


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);
  reader->ReadOptional<DartType>();  // Mixed-in type is unused.
  implemented_classes_.ReadFromStatic<DowncastReader<DartType, InterfaceType> >(
      reader);
  fields_.ReadFrom<Field>(reader, this);
  constructors_.ReadFrom<Constructor>(reader, this);
  procedures_.ReadFrom<Procedure>(reader, this);

  can_stream_ = can_stream_ && fields_.CanStream() &&
                constructors_.CanStream() && procedures_.CanStream();

  return this;
}


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);

  can_stream_ = constructors_.CanStream();

  return this;
}


NameIndex Reference::ReadMemberFrom(Reader* reader, bool allow_null) {
  TRACE_READ_OFFSET();
  NameIndex canonical_name = reader->ReadCanonicalNameReference();
  if ((canonical_name == -1) && !allow_null) {
    FATAL("Expected a valid member reference, but got `null`");
  }
  return canonical_name;
}


NameIndex Reference::ReadClassFrom(Reader* reader, bool allow_null) {
  TRACE_READ_OFFSET();
  NameIndex canonical_name = reader->ReadCanonicalNameReference();
  if ((canonical_name == -1) && !allow_null) {
    FATAL("Expected a valid class reference, but got `null`");
  }
  return canonical_name;
}


NameIndex Reference::ReadTypedefFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  NameIndex canonical_name = reader->ReadCanonicalNameReference();
  if (canonical_name == -1) {
    FATAL("Expected a valid typedef reference, but got `null`");
  }
  return canonical_name;
}


NameIndex Reference::ReadLibraryFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  NameIndex canonical_name = reader->ReadCanonicalNameReference();
  if (canonical_name == -1) {
    FATAL("Expected a valid typedef reference, but got `null`");
  }
  return canonical_name;
}


Field* Field::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  kernel_offset_ = reader->offset();  // Notice the ReadTag() below.
  Tag tag = reader->ReadTag();
  ASSERT(tag == kField);

  canonical_name_ = reader->ReadCanonicalNameReference();
  position_ = reader->ReadPosition(false);
  end_position_ = reader->ReadPosition(false);
  flags_ = reader->ReadFlags();
  name_ = Name::ReadFrom(reader);
  source_uri_index_ = reader->ReadUInt();
  reader->set_current_script_id(source_uri_index_);
  reader->record_token_position(position_);
  reader->record_token_position(end_position_);
  annotations_.ReadFromStatic<Expression>(reader);
  type_ = DartType::ReadFrom(reader);
  initializer_ = reader->ReadOptional<Expression>();

  can_stream_ = (initializer_ == NULL || initializer_->can_stream()) &&
                annotations_.CanStream();

  return this;
}


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

  canonical_name_ = reader->ReadCanonicalNameReference();
  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);

  can_stream_ = annotations_.CanStream() && function_->can_stream() &&
                initializers_.CanStream();

  return this;
}


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

  canonical_name_ = reader->ReadCanonicalNameReference();
  VariableScope<ReaderHelper> parameters(reader->helper());
  position_ = reader->ReadPosition(false);
  end_position_ = reader->ReadPosition(false);
  kind_ = static_cast<ProcedureKind>(reader->ReadByte());
  flags_ = reader->ReadFlags();
  name_ = Name::ReadFrom(reader);
  source_uri_index_ = reader->ReadUInt();
  reader->set_current_script_id(source_uri_index_);
  reader->record_token_position(position_);
  reader->record_token_position(end_position_);
  annotations_.ReadFromStatic<Expression>(reader);
  function_ = reader->ReadOptional<FunctionNode>();

  can_stream_ = annotations_.CanStream() &&
                (function_ == NULL || function_->can_stream());

  return this;
}


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();
}


FieldInitializer* FieldInitializer::ReadFromImpl(Reader* reader) {
  TRACE_READ_OFFSET();
  FieldInitializer* initializer = new FieldInitializer();
  initializer->field_reference_ = Reference::ReadMemberFrom(reader);
  initializer->value_ = Expression::ReadFrom(reader);

  initializer->can_stream_ = initializer->value_->can_stream();

  return initializer;
}


SuperInitializer* SuperInitializer::ReadFromImpl(Reader* reader) {
  TRACE_READ_OFFSET();
  SuperInitializer* init = new SuperInitializer();
  init->target_reference_ = Reference::ReadMemberFrom(reader);
  init->arguments_ = Arguments::ReadFrom(reader);

  init->can_stream_ = init->arguments_->can_stream();

  return init;
}


RedirectingInitializer* RedirectingInitializer::ReadFromImpl(Reader* reader) {
  TRACE_READ_OFFSET();
  RedirectingInitializer* init = new RedirectingInitializer();
  init->target_reference_ = Reference::ReadMemberFrom(reader);
  init->arguments_ = Arguments::ReadFrom(reader);

  init->can_stream_ = init->arguments_->can_stream();

  return init;
}


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

  init->can_stream_ = init->variable_->can_stream();

  return init;
}


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 kVectorCreation:
      return VectorCreation::ReadFrom(reader);
    case kVectorGet:
      return VectorGet::ReadFrom(reader);
    case kVectorSet:
      return VectorSet::ReadFrom(reader);
    case kVectorCopy:
      return VectorCopy::ReadFrom(reader);
    case kClosureCreation:
      return ClosureCreation::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();
  InvalidExpression* invalid_expression = new InvalidExpression();
  invalid_expression->kernel_offset_ =
      reader->offset() - 1;  // -1 to include tag byte.
  return invalid_expression;
}


VariableGet* VariableGet::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  VariableGet* get = new VariableGet();
  get->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
  get->position_ = reader->ReadPosition();
  get->variable_kernel_offset_ = reader->ReadUInt();
  get->variable_ = reader->helper()->variables().Lookup(reader->ReadUInt());
  ASSERT(get->variable_->kernel_offset() == get->variable_kernel_offset_);
  reader->ReadOptional<DartType>();  // Unused promoted type.
  return get;
}


VariableGet* VariableGet::ReadFrom(Reader* reader, uint8_t payload) {
  TRACE_READ_OFFSET();
  VariableGet* get = new VariableGet();
  get->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
  get->position_ = reader->ReadPosition();
  get->variable_kernel_offset_ = reader->ReadUInt();
  get->variable_ = reader->helper()->variables().Lookup(payload);
  ASSERT(get->variable_->kernel_offset() == get->variable_kernel_offset_);
  return get;
}


VariableSet* VariableSet::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  VariableSet* set = new VariableSet();
  set->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
  set->position_ = reader->ReadPosition();
  set->variable_kernel_offset_ = reader->ReadUInt();
  set->variable_ = reader->helper()->variables().Lookup(reader->ReadUInt());
  ASSERT(set->variable_->kernel_offset() == set->variable_kernel_offset_);
  set->expression_ = Expression::ReadFrom(reader);

  set->can_stream_ = set->expression_->can_stream();

  return set;
}


VariableSet* VariableSet::ReadFrom(Reader* reader, uint8_t payload) {
  TRACE_READ_OFFSET();
  VariableSet* set = new VariableSet();
  set->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
  set->variable_ = reader->helper()->variables().Lookup(payload);
  set->position_ = reader->ReadPosition();
  set->variable_kernel_offset_ = reader->ReadUInt();
  ASSERT(set->variable_->kernel_offset() == set->variable_kernel_offset_);
  set->expression_ = Expression::ReadFrom(reader);

  set->can_stream_ = set->expression_->can_stream();

  return set;
}


PropertyGet* PropertyGet::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  PropertyGet* get = new PropertyGet();
  get->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
  get->position_ = reader->ReadPosition();
  get->receiver_ = Expression::ReadFrom(reader);
  get->name_ = Name::ReadFrom(reader);
  get->interface_target_reference_ = Reference::ReadMemberFrom(reader, true);

  get->can_stream_ = get->receiver_->can_stream();

  return get;
}


PropertySet* PropertySet::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  PropertySet* set = new PropertySet();
  set->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
  set->position_ = reader->ReadPosition();
  set->receiver_ = Expression::ReadFrom(reader);
  set->name_ = Name::ReadFrom(reader);
  set->value_ = Expression::ReadFrom(reader);
  set->interface_target_reference_ = Reference::ReadMemberFrom(reader, true);

  set->can_stream_ = set->receiver_->can_stream() && set->value_->can_stream();

  return set;
}


DirectPropertyGet* DirectPropertyGet::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  DirectPropertyGet* get = new DirectPropertyGet();
  get->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
  get->position_ = reader->ReadPosition();
  get->receiver_ = Expression::ReadFrom(reader);
  get->target_reference_ = Reference::ReadMemberFrom(reader);

  get->can_stream_ = get->receiver_->can_stream();

  return get;
}


DirectPropertySet* DirectPropertySet::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  DirectPropertySet* set = new DirectPropertySet();
  set->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
  set->position_ = reader->ReadPosition();
  set->receiver_ = Expression::ReadFrom(reader);
  set->target_reference_ = Reference::ReadMemberFrom(reader);
  set->value_ = Expression::ReadFrom(reader);

  set->can_stream_ = set->receiver_->can_stream() && set->value_->can_stream();

  return set;
}


StaticGet* StaticGet::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  StaticGet* get = new StaticGet();
  get->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
  get->position_ = reader->ReadPosition();
  get->target_reference_ = Reference::ReadMemberFrom(reader);
  return get;
}


StaticSet* StaticSet::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  StaticSet* set = new StaticSet();
  set->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
  set->position_ = reader->ReadPosition();
  set->target_reference_ = Reference::ReadMemberFrom(reader);
  set->expression_ = Expression::ReadFrom(reader);

  set->can_stream_ = set->expression_->can_stream();

  return set;
}


Arguments* Arguments::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  Arguments* arguments = new Arguments();
  intptr_t num_arguments = reader->ReadUInt();
  arguments->types().ReadFromStatic<DartType>(reader);
  arguments->positional().ReadFromStatic<Expression>(reader);
  arguments->named().ReadFromStatic<NamedExpression>(reader);
  ASSERT(arguments->count() == num_arguments);

  arguments->can_stream_ =
      arguments->positional().CanStream() && arguments->named().CanStream();

  return arguments;
}


NamedExpression* NamedExpression::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  StringIndex name_index(reader->ReadUInt());
  Expression* expression = Expression::ReadFrom(reader);
  NamedExpression* named = new NamedExpression(name_index, expression);

  named->can_stream_ = expression->can_stream();

  return named;
}


MethodInvocation* MethodInvocation::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  MethodInvocation* invocation = new MethodInvocation();
  invocation->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
  invocation->position_ = reader->ReadPosition();
  invocation->receiver_ = Expression::ReadFrom(reader);
  invocation->name_ = Name::ReadFrom(reader);
  invocation->arguments_ = Arguments::ReadFrom(reader);
  invocation->interface_target_reference_ =
      Reference::ReadMemberFrom(reader, true);

  invocation->can_stream_ = invocation->receiver_->can_stream() &&
                            invocation->arguments_->can_stream();

  return invocation;
}


DirectMethodInvocation* DirectMethodInvocation::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  DirectMethodInvocation* invocation = new DirectMethodInvocation();
  invocation->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
  invocation->receiver_ = Expression::ReadFrom(reader);
  invocation->target_reference_ = Reference::ReadMemberFrom(reader);
  invocation->arguments_ = Arguments::ReadFrom(reader);

  invocation->can_stream_ = invocation->receiver_->can_stream() &&
                            invocation->arguments_->can_stream();

  return invocation;
}


StaticInvocation* StaticInvocation::ReadFrom(Reader* reader, bool is_const) {
  TRACE_READ_OFFSET();
  StaticInvocation* invocation = new StaticInvocation();
  invocation->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
  invocation->is_const_ = is_const;
  invocation->position_ = reader->ReadPosition();
  invocation->procedure_reference_ = Reference::ReadMemberFrom(reader);
  invocation->arguments_ = Arguments::ReadFrom(reader);

  invocation->can_stream_ = invocation->arguments_->can_stream();

  return invocation;
}


ConstructorInvocation* ConstructorInvocation::ReadFrom(Reader* reader,
                                                       bool is_const) {
  TRACE_READ_OFFSET();
  ConstructorInvocation* invocation = new ConstructorInvocation();
  invocation->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
  invocation->is_const_ = is_const;
  invocation->position_ = reader->ReadPosition();
  invocation->target_reference_ = Reference::ReadMemberFrom(reader);
  invocation->arguments_ = Arguments::ReadFrom(reader);

  invocation->can_stream_ = invocation->arguments_->can_stream();

  return invocation;
}


Not* Not::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  Not* n = new Not();
  n->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
  n->expression_ = Expression::ReadFrom(reader);

  n->can_stream_ = n->expression_->can_stream();

  return n;
}


LogicalExpression* LogicalExpression::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  LogicalExpression* expr = new LogicalExpression();
  expr->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
  expr->left_ = Expression::ReadFrom(reader);
  expr->operator_ = static_cast<Operator>(reader->ReadByte());
  expr->right_ = Expression::ReadFrom(reader);

  expr->can_stream_ = expr->left_->can_stream() && expr->right_->can_stream();

  return expr;
}


ConditionalExpression* ConditionalExpression::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  ConditionalExpression* expr = new ConditionalExpression();
  expr->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
  expr->condition_ = Expression::ReadFrom(reader);
  expr->then_ = Expression::ReadFrom(reader);
  expr->otherwise_ = Expression::ReadFrom(reader);
  reader->ReadOptional<DartType>();  // Unused static type.

  expr->can_stream_ = expr->condition_->can_stream() &&
                      expr->then_->can_stream() &&
                      expr->otherwise_->can_stream();

  return expr;
}


StringConcatenation* StringConcatenation::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  StringConcatenation* concat = new StringConcatenation();
  concat->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
  concat->position_ = reader->ReadPosition();
  concat->expressions_.ReadFromStatic<Expression>(reader);

  concat->can_stream_ = concat->expressions_.CanStream();

  return concat;
}


IsExpression* IsExpression::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  IsExpression* expr = new IsExpression();
  expr->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
  expr->position_ = reader->ReadPosition();
  expr->operand_ = Expression::ReadFrom(reader);
  expr->type_ = DartType::ReadFrom(reader);

  expr->can_stream_ = expr->operand_->can_stream();

  return expr;
}


AsExpression* AsExpression::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  AsExpression* expr = new AsExpression();
  expr->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
  expr->position_ = reader->ReadPosition();
  expr->operand_ = Expression::ReadFrom(reader);
  expr->type_ = DartType::ReadFrom(reader);

  expr->can_stream_ = expr->operand_->can_stream();

  return expr;
}


StringLiteral* StringLiteral::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  intptr_t offset = reader->offset() - 1;  // -1 to include tag byte.
  StringLiteral* lit = new StringLiteral(StringIndex(reader->ReadUInt()));
  lit->kernel_offset_ = offset;
  return lit;
}


BigintLiteral* BigintLiteral::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  intptr_t offset = reader->offset() - 1;  // -1 to include tag byte.
  BigintLiteral* lit = new BigintLiteral(StringIndex(reader->ReadUInt()));
  lit->kernel_offset_ = offset;
  return lit;
}


IntLiteral* IntLiteral::ReadFrom(Reader* reader, bool is_negative) {
  TRACE_READ_OFFSET();
  IntLiteral* literal = new IntLiteral();
  literal->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
  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->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
  literal->value_ = static_cast<int32_t>(payload) - SpecializedIntLiteralBias;
  return literal;
}


DoubleLiteral* DoubleLiteral::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  DoubleLiteral* literal = new DoubleLiteral();
  literal->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
  literal->value_index_ = StringIndex(reader->ReadUInt());
  return literal;
}


BoolLiteral* BoolLiteral::ReadFrom(Reader* reader, bool value) {
  TRACE_READ_OFFSET();
  BoolLiteral* lit = new BoolLiteral();
  lit->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
  lit->value_ = value;
  return lit;
}


NullLiteral* NullLiteral::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  NullLiteral* lit = new NullLiteral();
  lit->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
  return lit;
}


SymbolLiteral* SymbolLiteral::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  SymbolLiteral* lit = new SymbolLiteral();
  lit->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
  lit->value_index_ = StringIndex(reader->ReadUInt());
  return lit;
}


TypeLiteral* TypeLiteral::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  TypeLiteral* literal = new TypeLiteral();
  literal->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
  literal->type_ = DartType::ReadFrom(reader);
  return literal;
}


ThisExpression* ThisExpression::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  ThisExpression* this_expr = new ThisExpression();
  this_expr->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
  return this_expr;
}


Rethrow* Rethrow::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  Rethrow* rethrow = new Rethrow();
  rethrow->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
  rethrow->position_ = reader->ReadPosition();
  return rethrow;
}


Throw* Throw::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  Throw* t = new Throw();
  t->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
  t->position_ = reader->ReadPosition();
  t->expression_ = Expression::ReadFrom(reader);

  t->can_stream_ = t->expression_->can_stream();

  return t;
}


ListLiteral* ListLiteral::ReadFrom(Reader* reader, bool is_const) {
  TRACE_READ_OFFSET();
  ListLiteral* literal = new ListLiteral();
  literal->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
  literal->is_const_ = is_const;
  literal->position_ = reader->ReadPosition();
  literal->type_ = DartType::ReadFrom(reader);
  literal->expressions_.ReadFromStatic<Expression>(reader);

  literal->can_stream_ = literal->expressions_.CanStream();

  return literal;
}


MapLiteral* MapLiteral::ReadFrom(Reader* reader, bool is_const) {
  TRACE_READ_OFFSET();
  MapLiteral* literal = new MapLiteral();
  literal->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
  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);

  literal->can_stream_ = literal->entries_.CanStream();

  return literal;
}


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

  entry->can_stream_ = entry->key_->can_stream() && entry->value_->can_stream();

  return entry;
}


AwaitExpression* AwaitExpression::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  AwaitExpression* await = new AwaitExpression();
  await->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
  await->operand_ = Expression::ReadFrom(reader);

  await->can_stream_ = await->operand_->can_stream();

  return await;
}


FunctionExpression* FunctionExpression::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  VariableScope<ReaderHelper> parameters(reader->helper());
  FunctionExpression* expr = new FunctionExpression();
  expr->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
  expr->function_ = FunctionNode::ReadFrom(reader);

  expr->can_stream_ = false;

  return expr;
}


Let* Let::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  VariableScope<ReaderHelper> vars(reader->helper());
  PositionScope scope(reader);

  Let* let = new Let();
  let->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
  let->variable_ = VariableDeclaration::ReadFromImpl(reader, false);
  let->body_ = Expression::ReadFrom(reader);
  let->position_ = reader->min_position();
  let->end_position_ = reader->max_position();

  let->can_stream_ = let->variable_->can_stream() && let->body_->can_stream();

  return let;
}


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

  VectorCreation* vector_creation = new VectorCreation();
  vector_creation->kernel_offset_ =
      reader->offset() - 1;  // -1 to include tag byte.
  vector_creation->value_ = reader->ReadUInt();

  return vector_creation;
}


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

  VectorGet* vector_get = new VectorGet();
  vector_get->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
  vector_get->vector_expression_ = Expression::ReadFrom(reader);
  vector_get->index_ = reader->ReadUInt();

  vector_get->can_stream_ = false;

  return vector_get;
}


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

  VectorSet* vector_set = new VectorSet();
  vector_set->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
  vector_set->vector_expression_ = Expression::ReadFrom(reader);
  vector_set->index_ = reader->ReadUInt();
  vector_set->value_ = Expression::ReadFrom(reader);

  vector_set->can_stream_ = false;

  return vector_set;
}


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

  VectorCopy* vector_copy = new VectorCopy();
  vector_copy->kernel_offset_ =
      reader->offset() - 1;  // -1 to include tag byte.
  vector_copy->vector_expression_ = Expression::ReadFrom(reader);

  vector_copy->can_stream_ = false;

  return vector_copy;
}


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

  ClosureCreation* closure_creation = new ClosureCreation();
  closure_creation->kernel_offset_ =
      reader->offset() - 1;  // to include tag byte.
  closure_creation->top_level_function_reference_ =
      Reference::ReadMemberFrom(reader);
  closure_creation->context_vector_ = Expression::ReadFrom(reader);
  closure_creation->function_type_ =
      FunctionType::Cast(DartType::ReadFrom(reader));

  closure_creation->can_stream_ = false;

  return closure_creation;
}


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, true);
    case kFunctionDeclaration:
      return FunctionDeclaration::ReadFrom(reader);
    default:
      UNREACHABLE();
  }
  return NULL;
}


InvalidStatement* InvalidStatement::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  InvalidStatement* stmt = new InvalidStatement();
  stmt->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
  return stmt;
}


ExpressionStatement* ExpressionStatement::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  intptr_t offset = reader->offset() - 1;  // -1 to include tag byte.
  ExpressionStatement* stmt =
      new ExpressionStatement(Expression::ReadFrom(reader));
  stmt->kernel_offset_ = offset;

  stmt->can_stream_ = stmt->expression_->can_stream();

  return stmt;
}


Block* Block::ReadFromImpl(Reader* reader) {
  TRACE_READ_OFFSET();
  PositionScope scope(reader);

  VariableScope<ReaderHelper> vars(reader->helper());
  Block* block = new Block();
  block->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
  block->statements().ReadFromStatic<Statement>(reader);
  block->position_ = reader->min_position();
  block->end_position_ = reader->max_position();

  block->can_stream_ = block->statements().CanStream();

  return block;
}


EmptyStatement* EmptyStatement::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  EmptyStatement* stmt = new EmptyStatement();
  stmt->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
  return stmt;
}


AssertStatement* AssertStatement::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  AssertStatement* stmt = new AssertStatement();
  stmt->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
  stmt->condition_ = Expression::ReadFrom(reader);
  stmt->message_ = reader->ReadOptional<Expression>();

  stmt->can_stream_ = stmt->condition_->can_stream() &&
                      (stmt->message_ == NULL || stmt->message_->can_stream());

  return stmt;
}


LabeledStatement* LabeledStatement::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  LabeledStatement* stmt = new LabeledStatement();
  stmt->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.

  reader->helper()->labels()->Push(stmt);
  stmt->body_ = Statement::ReadFrom(reader);
  reader->helper()->labels()->Pop(stmt);

  stmt->can_stream_ = stmt->body_->can_stream();

  return stmt;
}


BreakStatement* BreakStatement::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  BreakStatement* stmt = new BreakStatement();
  stmt->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
  stmt->position_ = reader->ReadPosition();
  stmt->target_index_ = reader->ReadUInt();
  return stmt;
}


WhileStatement* WhileStatement::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  WhileStatement* stmt = new WhileStatement();
  stmt->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
  stmt->condition_ = Expression::ReadFrom(reader);
  stmt->body_ = Statement::ReadFrom(reader);

  stmt->can_stream_ =
      stmt->condition_->can_stream() && stmt->body_->can_stream();

  return stmt;
}


DoStatement* DoStatement::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  DoStatement* dostmt = new DoStatement();
  dostmt->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
  dostmt->body_ = Statement::ReadFrom(reader);
  dostmt->condition_ = Expression::ReadFrom(reader);

  dostmt->can_stream_ =
      dostmt->body_->can_stream() && dostmt->condition_->can_stream();

  return dostmt;
}


ForStatement* ForStatement::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  VariableScope<ReaderHelper> vars(reader->helper());
  PositionScope scope(reader);

  ForStatement* forstmt = new ForStatement();
  forstmt->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
  forstmt->variables_.ReadFromStatic<VariableDeclarationImpl>(reader);
  forstmt->condition_ = reader->ReadOptional<Expression>();
  forstmt->updates_.ReadFromStatic<Expression>(reader);
  forstmt->body_ = Statement::ReadFrom(reader);
  forstmt->end_position_ = reader->max_position();
  forstmt->position_ = reader->min_position();

  forstmt->can_stream_ =
      forstmt->body_->can_stream() &&
      (forstmt->condition_ == NULL || forstmt->condition_->can_stream()) &&
      forstmt->variables_.CanStream() && forstmt->updates_.CanStream();

  return forstmt;
}


ForInStatement* ForInStatement::ReadFrom(Reader* reader, bool is_async) {
  TRACE_READ_OFFSET();
  VariableScope<ReaderHelper> vars(reader->helper());
  PositionScope scope(reader);

  ForInStatement* forinstmt = new ForInStatement();
  forinstmt->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
  forinstmt->is_async_ = is_async;
  forinstmt->position_ = reader->ReadPosition();
  forinstmt->variable_ = VariableDeclaration::ReadFromImpl(reader, false);
  forinstmt->iterable_ = Expression::ReadFrom(reader);
  forinstmt->body_ = Statement::ReadFrom(reader);
  forinstmt->end_position_ = reader->max_position();
  if (!forinstmt->position_.IsReal()) {
    forinstmt->position_ = reader->min_position();
  }
  forinstmt->variable_->set_end_position(forinstmt->position_);

  forinstmt->can_stream_ = forinstmt->variable_->can_stream() &&
                           forinstmt->iterable_->can_stream() &&
                           forinstmt->body_->can_stream();

  return forinstmt;
}


SwitchStatement* SwitchStatement::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  SwitchStatement* stmt = new SwitchStatement();
  stmt->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
  stmt->condition_ = Expression::ReadFrom(reader);
  int count = reader->ReadUInt();
  stmt->cases_.EnsureInitialized(count);
  for (intptr_t i = 0; i < count; i++) {
    SwitchCase* sc = stmt->cases_.GetOrCreate<SwitchCase>(i);
    sc->ReadFrom(reader);
  }

  stmt->can_stream_ =
      stmt->condition_->can_stream() && stmt->cases_.CanStream();

  return stmt;
}


SwitchCase* SwitchCase::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  int length = reader->ReadListLength();
  expressions_.EnsureInitialized(length);

  for (intptr_t i = 0; i < length; i++) {
    ASSERT(expressions_[i] == NULL);
    TokenPosition position = reader->ReadPosition();
    expressions_[i] = Expression::ReadFrom(reader);
    expressions_[i]->set_position(position);
  }
  is_default_ = reader->ReadBool();
  body_ = Statement::ReadFrom(reader);

  can_stream_ = expressions_.CanStream() && body_->can_stream();

  return this;
}


ContinueSwitchStatement* ContinueSwitchStatement::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  ContinueSwitchStatement* stmt = new ContinueSwitchStatement();
  stmt->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
  stmt->target_index_ = reader->ReadUInt();

  return stmt;
}


IfStatement* IfStatement::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  IfStatement* ifstmt = new IfStatement();
  ifstmt->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
  ifstmt->condition_ = Expression::ReadFrom(reader);
  ifstmt->then_ = Statement::ReadFrom(reader);
  ifstmt->otherwise_ = Statement::ReadFrom(reader);

  ifstmt->can_stream_ = ifstmt->condition_->can_stream() &&
                        ifstmt->then_->can_stream() &&
                        ifstmt->otherwise_->can_stream();

  return ifstmt;
}


ReturnStatement* ReturnStatement::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  ReturnStatement* ret = new ReturnStatement();
  ret->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
  ret->position_ = reader->ReadPosition();
  ret->expression_ = reader->ReadOptional<Expression>();

  ret->can_stream_ =
      (ret->expression_ == NULL || ret->expression_->can_stream());

  return ret;
}


TryCatch* TryCatch::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  PositionScope scope(reader);

  TryCatch* tc = new TryCatch();
  tc->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
  tc->body_ = Statement::ReadFrom(reader);
  reader->ReadBool();  // whether any catch needs a stacktrace.
  tc->catches_.ReadFromStatic<Catch>(reader);
  tc->position_ = reader->min_position();

  tc->can_stream_ = tc->body_->can_stream() && tc->catches_.CanStream();

  return tc;
}


Catch* Catch::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  VariableScope<ReaderHelper> vars(reader->helper());
  PositionScope scope(reader);

  Catch* c = new Catch();
  c->kernel_offset_ = reader->offset();  // Catch has no tag.
  c->guard_ = DartType::ReadFrom(reader);
  c->exception_ =
      reader->ReadOptional<VariableDeclaration, VariableDeclarationImpl>();
  c->stack_trace_ =
      reader->ReadOptional<VariableDeclaration, VariableDeclarationImpl>();
  c->body_ = Statement::ReadFrom(reader);
  c->end_position_ = reader->max_position();
  c->position_ = reader->min_position();

  c->can_stream_ = c->body_->can_stream();

  return c;
}


TryFinally* TryFinally::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  TryFinally* tf = new TryFinally();
  tf->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
  tf->body_ = Statement::ReadFrom(reader);
  tf->finalizer_ = Statement::ReadFrom(reader);

  tf->can_stream_ = tf->body_->can_stream() && tf->finalizer_->can_stream();

  return tf;
}


YieldStatement* YieldStatement::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  YieldStatement* stmt = new YieldStatement();
  stmt->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
  stmt->position_ = reader->ReadPosition();
  reader->record_yield_token_position(stmt->position_);
  stmt->flags_ = reader->ReadByte();
  stmt->expression_ = Expression::ReadFrom(reader);

  stmt->can_stream_ = stmt->expression_->can_stream();

  return stmt;
}


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


VariableDeclaration* VariableDeclaration::ReadFromImpl(Reader* reader,
                                                       bool read_tag) {
  TRACE_READ_OFFSET();
  PositionScope scope(reader);

  VariableDeclaration* decl = new VariableDeclaration();
  // -1 or -0 depending on whether there's a tag or not.
  decl->kernel_offset_ = reader->offset() - (read_tag ? 1 : 0);
  decl->position_ = reader->ReadPosition();
  decl->equals_position_ = reader->ReadPosition();
  decl->flags_ = reader->ReadFlags();
  decl->name_index_ = StringIndex(reader->ReadUInt());
  decl->type_ = DartType::ReadFrom(reader);
  decl->initializer_ = reader->ReadOptional<Expression>();

  // Go to next token position so it ends *after* the last potentially
  // debuggable position in the initializer.
  TokenPosition position = reader->max_position();
  if (position.IsReal()) position.Next();
  decl->end_position_ = position;
  reader->helper()->variables().Push(decl);

  decl->can_stream_ =
      (decl->initializer_ == NULL || decl->initializer_->can_stream());

  return decl;
}


FunctionDeclaration* FunctionDeclaration::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  FunctionDeclaration* decl = new FunctionDeclaration();
  decl->kernel_offset_ = reader->offset() - 1;  // -1 to include tag byte.
  decl->position_ = reader->ReadPosition();
  decl->variable_ = VariableDeclaration::ReadFromImpl(reader, false);
  VariableScope<ReaderHelper> parameters(reader->helper());
  decl->function_ = FunctionNode::ReadFrom(reader);

  decl->can_stream_ = false;

  return decl;
}


Name* Name::ReadFrom(Reader* reader) {
  StringIndex name_index(reader->ReadUInt());
  if ((reader->StringLength(name_index) >= 1) &&
      (reader->CharacterAt(name_index, 0) == '_')) {
    intptr_t library_reference = reader->ReadCanonicalNameReference();
    return new Name(name_index, library_reference);
  } else {
    return new Name(name_index, NULL);
  }
}


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 kBottomType:
      return BottomType::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);
    case kVectorType:
      return VectorType::ReadFrom(reader);
    case kTypedefType:
      return TypedefType::ReadFrom(reader);
    default:
      UNREACHABLE();
  }
  UNREACHABLE();
  return NULL;
}


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


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


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


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


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


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


TypedefType* TypedefType::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  NameIndex typedef_name = Reference::ReadTypedefFrom(reader);
  TypedefType* type = new TypedefType(typedef_name);
  type->type_arguments().ReadFromStatic<DartType>(reader);
  return type;
}


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();
  intptr_t total_parameter_count = reader->ReadUInt();
  type->positional_parameters().ReadFromStatic<DartType>(reader);
  type->named_parameters().ReadFromStatic<NamedParameter>(reader);
  ASSERT(type->positional_parameters().length() +
             type->named_parameters().length() ==
         total_parameter_count);
  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;
}


TypeParameterType* TypeParameterType::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  TypeParameterType* type = new TypeParameterType();
  type->parameter_ =
      reader->helper()->type_parameters().Lookup(reader->ReadUInt());
  reader->ReadUInt();  // binary offset of parameter
  // There is an optional promoted bound, currently ignored.
  delete reader->ReadOptional<DartType>();
  return type;
}


VectorType* VectorType::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  VectorType* type = new VectorType();
  return type;
}


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);

  // Deserialize the string offset table to give fast access to the string data
  // during deserialization.
  program->string_table_offset_ = reader->offset();
  intptr_t string_count = reader->ReadUInt();
  reader->string_offsets_ = new intptr_t[string_count + 1];
  intptr_t offset = 0;
  for (intptr_t i = 0; i < string_count; ++i) {
    reader->string_offsets_[i] = offset;
    offset = reader->ReadUInt();
  }
  reader->string_offsets_[string_count] = offset;
  // Skip the UTF-8 encoded strings.
  reader->MarkStringDataOffset();
  reader->Consume(offset);

  program->source_table_.ReadFrom(reader);

  // Deserialize the canonical name table to give fast access to canonical names
  // during deserialization.
  program->name_table_offset_ = reader->offset();
  intptr_t name_count = reader->ReadUInt();
  reader->canonical_name_parents_ = new NameIndex[name_count];
  reader->canonical_name_strings_ = new StringIndex[name_count];
  for (int i = 0; i < name_count; ++i) {
    // The parent name index is biased: 0 is the root name and otherwise N+1 is
    // the Nth name.
    reader->canonical_name_parents_[i] = reader->ReadCanonicalNameReference();
    reader->canonical_name_strings_[i] = StringIndex(reader->ReadUInt());
  }

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

  program->main_method_reference_ =
      Reference::ReadMemberFrom(reader, /*allow_null=*/true);

  program->can_stream_ = false;

  return program;
}


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

  FunctionNode* function = new FunctionNode();
  function->kernel_offset_ = reader->offset();  // FunctionNode has no tag.
  function->position_ = reader->ReadPosition();
  function->end_position_ = reader->ReadPosition();
  function->async_marker_ =
      static_cast<FunctionNode::AsyncMarker>(reader->ReadByte());
  function->dart_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);

  LabelScope<ReaderHelper, BlockStack<LabeledStatement> > labels(
      reader->helper());
  VariableScope<ReaderHelper> vars(reader->helper());
  function->body_ = reader->ReadOptional<Statement>();

  function->can_stream_ =
      function->positional_parameters_.CanStream() &&
      function->named_parameters_.CanStream() &&
      (function->body_ == NULL || function->body_->can_stream());

  return function;
}


TypeParameter* TypeParameter::ReadFrom(Reader* reader) {
  TRACE_READ_OFFSET();
  kernel_offset_ = reader->offset();
  name_index_ = StringIndex(reader->ReadUInt());
  bound_ = DartType::ReadFrom(reader);
  return this;
}


}  // namespace kernel


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


}  // namespace dart
#endif  // !defined(DART_PRECOMPILED_RUNTIME)
