Files
sdk/runtime/vm/kernel_binary.cc
T
Kevin Millikin 385f8fb054 Read platform.dill in the VM.
1. A --platform flag is added to dart to give a path to a Kernel
   binary for the platform libraries (as produced by building the
   runtime_kernel target).

2. This binary is used for bootstrapping.  Since it contains libraries
   other then the VM's bootstrap libraries, they are also loaded.

3. The frontend does not send any library with a dart: import URI
   scheme.  Note that it does not (yet) prune the canonical name
   table, which will contain a lot of unnecessary names used for
   internal linkages in the platform libraries.

4. There is a single dependency in the platform libraries on the
   script: _getMainClosure in dart:_builtin.  This is patched after
   the script is loaded.

BUG=
R=ahe@google.com, kustermann@google.com, vegorov@google.com

Review-Url: https://codereview.chromium.org/2786083002 .
2017-04-25 20:04:25 +02:00

1590 lines
48 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 {
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)