Files
sdk/runtime/vm/kernel_binary.cc
T
Jens Johansen d26558b7be [kernel] [partial] Streaming of kernel binary without AST nodes
This CL allows for streaming big parts of the binary,
i.e. without using the AST nodes.
It is thus a stepping-stone in getting rid of the AST nodes in the VM.

Generally, all Expressions except "FunctionExpression",
and all Statements except "FunctionDeclaration" can be streamed.

There are currently not streamed because they create new functions,
which has a pointer to an AstNode (which we don't have when streaming).

Once we no longer need AstNodes at all these can be streamed as well.
This is, I think, mostly a matter of streaming the ScopeBuilder as well,
something that is not currently done.

The way the streaming is build, one has to stream an entire subtree.
That means, that if an expression (or statement), A, that is generally
streamable contains an expression or a statement, B, that is not streamable,
A cannot be streamed.
The way this is build is by marking AstNodes as streamable or not
("cannot_stream_" field). That way we know up front whether we can stream
a subtree or not.

The streaming is done via "kernel_binary_flowgraph".

In this file there are many obvious comments, e.g.
```
  TokenPosition position = ReadPosition();  // read position.
```
This has been done in an attempt to add a comment to everything that
reads from the binary to make it stand out more.

All changes from kernel_to_il up to and including May 2nd 2017
should be included.

R=kmillikin@google.com

Review-Url: https://codereview.chromium.org/2854393002 .
2017-05-15 09:01:22 +02:00

1833 lines
56 KiB
C++

// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
#if !defined(DART_PRECOMPILED_RUNTIME)
#include "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_);
int num_imports = reader->ReadUInt();
if (num_imports != 0) {
FATAL("Deferred imports not implemented in VM");
}
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;
}
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;
}
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)