blob: e0a81d73ffbf3e43638ffcab268b012213e92933 [file] [log] [blame]
// 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 {
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);
}
}
template <typename A, typename B>
Tuple<A, B>* Tuple<A, B>::ReadFrom(Reader* reader) {
TRACE_READ_OFFSET();
A* first = A::ReadFrom(reader);
B* second = B::ReadFrom(reader);
return new Tuple<A, B>(first, second);
}
template <typename 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);
}
};
String* String::ReadFrom(Reader* reader) {
TRACE_READ_OFFSET();
return Reference::ReadStringFrom(reader);
}
String* String::ReadRaw(Reader* reader, intptr_t size) {
ASSERT(reader->string_data_offset() >= 0);
String* result =
new String(reader->offset() - reader->string_data_offset(), size);
reader->Consume(size);
return result;
}
void StringTable::ReadFrom(Reader* reader) {
TRACE_READ_OFFSET();
// Read the table of end offsets.
intptr_t length = reader->ReadUInt();
intptr_t* end_offsets = new intptr_t[length];
for (intptr_t i = 0; i < length; ++i) {
end_offsets[i] = reader->ReadUInt();
}
// Read the UTF-8 encoded strings.
reader->MarkStringDataOffset();
strings_.EnsureInitialized(length);
intptr_t start_offset = 0;
for (intptr_t i = 0; i < length; ++i) {
ASSERT(strings_[i] == NULL);
strings_[i] = String::ReadRaw(reader, end_offsets[i] - start_offset);
start_offset = end_offsets[i];
}
delete[] end_offsets;
}
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_ = Reference::ReadStringFrom(reader);
import_uri_ = canonical_name_->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_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);
return this;
}
Class* Class::ReadFrom(Reader* reader) {
TRACE_READ_OFFSET();
canonical_name_ = reader->ReadCanonicalNameReference();
position_ = reader->ReadPosition(false);
is_abstract_ = reader->ReadBool();
name_ = Reference::ReadStringFrom(reader);
source_uri_index_ = reader->ReadUInt();
reader->set_current_script_id(source_uri_index_);
reader->record_token_position(position_);
annotations_.ReadFromStatic<Expression>(reader);
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);
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);
return this;
}
CanonicalName* Reference::ReadMemberFrom(Reader* reader, bool allow_null) {
TRACE_READ_OFFSET();
CanonicalName* canonical_name = reader->ReadCanonicalNameReference();
if (canonical_name == NULL && !allow_null) {
FATAL("Expected a valid member reference, but got `null`");
}
if (canonical_name != NULL) {
canonical_name->set_referenced(true);
}
return canonical_name;
}
CanonicalName* Reference::ReadClassFrom(Reader* reader, bool allow_null) {
TRACE_READ_OFFSET();
CanonicalName* canonical_name = reader->ReadCanonicalNameReference();
if (canonical_name == NULL && !allow_null) {
FATAL("Expected a valid class reference, but got `null`");
}
if (canonical_name != NULL) {
canonical_name->set_referenced(true);
}
return canonical_name;
}
String* Reference::ReadStringFrom(Reader* reader) {
int index = reader->ReadUInt();
return reader->helper()->program()->string_table().strings()[index];
}
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>();
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);
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>();
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);
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);
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);
return init;
}
LocalInitializer* LocalInitializer::ReadFromImpl(Reader* reader) {
TRACE_READ_OFFSET();
LocalInitializer* init = new LocalInitializer();
init->variable_ = VariableDeclaration::ReadFromImpl(reader, false);
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_ = reader->helper()->variables().Lookup(reader->ReadUInt());
reader->ReadOptional<DartType>(); // Unused promoted type.
return get;
}
VariableGet* VariableGet::ReadFrom(Reader* reader, uint8_t payload) {
TRACE_READ_OFFSET();
VariableGet* get = new VariableGet();
get->kernel_offset_ = reader->offset() - 1; // -1 to include tag byte.
get->position_ = reader->ReadPosition();
get->variable_ = reader->helper()->variables().Lookup(payload);
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_ = reader->helper()->variables().Lookup(reader->ReadUInt());
set->expression_ = Expression::ReadFrom(reader);
return set;
}
VariableSet* VariableSet::ReadFrom(Reader* reader, uint8_t payload) {
TRACE_READ_OFFSET();
VariableSet* set = new VariableSet();
set->kernel_offset_ = reader->offset() - 1; // -1 to include tag byte.
set->variable_ = reader->helper()->variables().Lookup(payload);
set->position_ = reader->ReadPosition();
set->expression_ = Expression::ReadFrom(reader);
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);
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);
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);
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);
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);
return set;
}
Arguments* Arguments::ReadFrom(Reader* reader) {
TRACE_READ_OFFSET();
Arguments* arguments = new Arguments();
arguments->types().ReadFromStatic<DartType>(reader);
arguments->positional().ReadFromStatic<Expression>(reader);
arguments->named().ReadFromStatic<NamedExpression>(reader);
return arguments;
}
NamedExpression* NamedExpression::ReadFrom(Reader* reader) {
TRACE_READ_OFFSET();
String* name = Reference::ReadStringFrom(reader);
Expression* expression = Expression::ReadFrom(reader);
return new NamedExpression(name, expression);
}
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);
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);
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);
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);
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);
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);
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.
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);
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);
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);
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(Reference::ReadStringFrom(reader));
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(Reference::ReadStringFrom(reader));
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_ = Reference::ReadStringFrom(reader);
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_ = Reference::ReadStringFrom(reader);
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);
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);
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);
return literal;
}
MapEntry* MapEntry::ReadFrom(Reader* reader) {
MapEntry* entry = new MapEntry();
entry->key_ = Expression::ReadFrom(reader);
entry->value_ = Expression::ReadFrom(reader);
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);
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);
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();
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();
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);
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);
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));
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();
return new InvalidStatement();
}
ExpressionStatement* ExpressionStatement::ReadFrom(Reader* reader) {
TRACE_READ_OFFSET();
return new ExpressionStatement(Expression::ReadFrom(reader));
}
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();
return block;
}
EmptyStatement* EmptyStatement::ReadFrom(Reader* reader) {
TRACE_READ_OFFSET();
return new EmptyStatement();
}
AssertStatement* AssertStatement::ReadFrom(Reader* reader) {
TRACE_READ_OFFSET();
AssertStatement* stmt = new AssertStatement();
stmt->condition_ = Expression::ReadFrom(reader);
stmt->message_ = reader->ReadOptional<Expression>();
return stmt;
}
LabeledStatement* LabeledStatement::ReadFrom(Reader* reader) {
TRACE_READ_OFFSET();
LabeledStatement* stmt = new LabeledStatement();
reader->helper()->labels()->Push(stmt);
stmt->body_ = Statement::ReadFrom(reader);
reader->helper()->labels()->Pop(stmt);
return stmt;
}
BreakStatement* BreakStatement::ReadFrom(Reader* reader) {
TRACE_READ_OFFSET();
BreakStatement* stmt = new BreakStatement();
stmt->position_ = reader->ReadPosition();
stmt->target_ = reader->helper()->labels()->Lookup(reader->ReadUInt());
return stmt;
}
WhileStatement* WhileStatement::ReadFrom(Reader* reader) {
TRACE_READ_OFFSET();
WhileStatement* stmt = new WhileStatement();
stmt->condition_ = Expression::ReadFrom(reader);
stmt->body_ = Statement::ReadFrom(reader);
return stmt;
}
DoStatement* DoStatement::ReadFrom(Reader* reader) {
TRACE_READ_OFFSET();
DoStatement* dostmt = new DoStatement();
dostmt->body_ = Statement::ReadFrom(reader);
dostmt->condition_ = Expression::ReadFrom(reader);
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();
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_);
return forinstmt;
}
SwitchStatement* SwitchStatement::ReadFrom(Reader* reader) {
TRACE_READ_OFFSET();
SwitchCaseScope<ReaderHelper> scope(reader->helper());
SwitchStatement* stmt = new SwitchStatement();
stmt->condition_ = Expression::ReadFrom(reader);
// We need to explicitly create empty [SwitchCase]s first in order to add them
// to the [SwitchCaseScope]. This is necessary since a [Statement] in a switch
// case can refer to one defined later on.
int count = reader->ReadUInt();
for (intptr_t i = 0; i < count; i++) {
SwitchCase* sc = stmt->cases_.GetOrCreate<SwitchCase>(i);
reader->helper()->switch_cases().Push(sc);
}
for (intptr_t i = 0; i < count; i++) {
SwitchCase* sc = stmt->cases_[i];
sc->ReadFrom(reader);
}
return stmt;
}
SwitchCase* SwitchCase::ReadFrom(Reader* reader) {
TRACE_READ_OFFSET();
expressions_.ReadFromStatic<Expression>(reader);
for (intptr_t i = 0; i < expressions_.length(); ++i) {
expressions_[i]->set_position(reader->ReadPosition());
}
is_default_ = reader->ReadBool();
body_ = Statement::ReadFrom(reader);
return this;
}
ContinueSwitchStatement* ContinueSwitchStatement::ReadFrom(Reader* reader) {
TRACE_READ_OFFSET();
ContinueSwitchStatement* stmt = new ContinueSwitchStatement();
stmt->target_ = reader->helper()->switch_cases().Lookup(reader->ReadUInt());
return stmt;
}
IfStatement* IfStatement::ReadFrom(Reader* reader) {
TRACE_READ_OFFSET();
IfStatement* ifstmt = new IfStatement();
ifstmt->condition_ = Expression::ReadFrom(reader);
ifstmt->then_ = Statement::ReadFrom(reader);
ifstmt->otherwise_ = Statement::ReadFrom(reader);
return ifstmt;
}
ReturnStatement* ReturnStatement::ReadFrom(Reader* reader) {
TRACE_READ_OFFSET();
ReturnStatement* ret = new ReturnStatement();
ret->position_ = reader->ReadPosition();
ret->expression_ = reader->ReadOptional<Expression>();
return ret;
}
TryCatch* TryCatch::ReadFrom(Reader* reader) {
TRACE_READ_OFFSET();
PositionScope scope(reader);
TryCatch* tc = new TryCatch();
tc->body_ = Statement::ReadFrom(reader);
tc->catches_.ReadFromStatic<Catch>(reader);
tc->position_ = reader->min_position();
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();
return c;
}
TryFinally* TryFinally::ReadFrom(Reader* reader) {
TRACE_READ_OFFSET();
TryFinally* tf = new TryFinally();
tf->body_ = Statement::ReadFrom(reader);
tf->finalizer_ = Statement::ReadFrom(reader);
return tf;
}
YieldStatement* YieldStatement::ReadFrom(Reader* reader) {
TRACE_READ_OFFSET();
YieldStatement* stmt = new YieldStatement();
stmt->position_ = reader->ReadPosition();
reader->record_yield_token_position(stmt->position_);
stmt->flags_ = reader->ReadByte();
stmt->expression_ = Expression::ReadFrom(reader);
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_ = Reference::ReadStringFrom(reader);
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);
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);
return decl;
}
Name* Name::ReadFrom(Reader* reader) {
String* name = Reference::ReadStringFrom(reader);
if (name->size() >= 1 && reader->CharacterAt(name, 0) == '_') {
CanonicalName* library_reference = reader->ReadCanonicalNameReference();
return new Name(name, library_reference);
} else {
return new Name(name, 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 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);
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();
}
InterfaceType* InterfaceType::ReadFrom(Reader* reader) {
TRACE_READ_OFFSET();
CanonicalName* 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();
CanonicalName* klass_name = Reference::ReadClassFrom(reader);
InterfaceType* type = new InterfaceType(klass_name);
ASSERT(_without_type_arguments_);
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();
type->positional_parameters().ReadFromStatic<DartType>(reader);
type->named_parameters().ReadFromStatic<Tuple<String, DartType> >(reader);
type->return_type_ = DartType::ReadFrom(reader);
return type;
}
FunctionType* FunctionType::ReadFrom(Reader* reader, bool _is_simple_) {
TRACE_READ_OFFSET();
FunctionType* type = new FunctionType();
ASSERT(_is_simple_);
type->positional_parameters().ReadFromStatic<DartType>(reader);
type->required_parameter_count_ = type->positional_parameters().length();
type->return_type_ = DartType::ReadFrom(reader);
return type;
}
TypeParameterType* TypeParameterType::ReadFrom(Reader* reader) {
TRACE_READ_OFFSET();
TypeParameterType* type = new TypeParameterType();
type->parameter_ =
reader->helper()->type_parameters().Lookup(reader->ReadUInt());
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();
program->canonical_name_root_ = CanonicalName::NewRoot();
reader->helper()->set_program(program);
program->string_table_.ReadFrom(reader);
program->string_data_offset_ = reader->string_data_offset();
ASSERT(program->string_data_offset_ >= 0);
program->source_table_.ReadFrom(reader);
int canonical_names = reader->ReadUInt();
reader->helper()->SetCanonicalNameCount(canonical_names);
for (int i = 0; i < canonical_names; ++i) {
int biased_parent_index = reader->ReadUInt();
CanonicalName* parent;
if (biased_parent_index != 0) {
parent = reader->helper()->GetCanonicalName(biased_parent_index - 1);
} else {
parent = program->canonical_name_root();
}
ASSERT(parent != NULL);
int name_index = reader->ReadUInt();
String* name = program->string_table().strings()[name_index];
CanonicalName* canonical_name = parent->AddChild(name);
reader->helper()->SetCanonicalName(i, canonical_name);
}
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);
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>();
return function;
}
TypeParameter* TypeParameter::ReadFrom(Reader* reader) {
TRACE_READ_OFFSET();
name_ = Reference::ReadStringFrom(reader);
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)