// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. #if !defined(DART_PRECOMPILED_RUNTIME) #include "vm/kernel_binary.h" #include "platform/globals.h" #include "vm/flags.h" #include "vm/growable_array.h" #include "vm/kernel.h" #include "vm/kernel_to_il.h" #include "vm/os.h" #if defined(DEBUG) #define TRACE_READ_OFFSET() \ do { \ if (FLAG_trace_kernel_binary) reader->DumpOffset(DART_PRETTY_FUNCTION); \ } while (0) #else #define TRACE_READ_OFFSET() #endif namespace dart { namespace kernel { Reader::~Reader() { delete[] string_offsets_; delete[] canonical_name_parents_; delete[] canonical_name_strings_; } template template void List::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(i, parent); object->ReadFrom(reader); } } template template void List::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); int length = reader->ReadListLength(); EnsureInitialized(length); for (intptr_t i = 0; i < length_; i++) { GetOrCreate(i)->ReadFrom(reader); } } template template void List::ReadFromStatic(Reader* reader) { TRACE_READ_OFFSET(); int length = reader->ReadListLength(); EnsureInitialized(length); for (intptr_t i = 0; i < length_; i++) { ASSERT(array_[i] == NULL); array_[i] = IT::ReadFrom(reader); } } void TypeParameterList::ReadFrom(Reader* reader) { // It is possible for the bound of the first type parameter to refer to // the second type parameter. This means we need to create [TypeParameter] // objects before reading the bounds. int length = reader->ReadListLength(); EnsureInitialized(length); // Make all [TypeParameter]s available in scope. for (intptr_t i = 0; i < length; i++) { TypeParameter* parameter = (*this)[i] = new TypeParameter(); reader->helper()->type_parameters().Push(parameter); } // Read all [TypeParameter]s and their bounds. for (intptr_t i = 0; i < length; i++) { (*this)[i]->ReadFrom(reader); } } NamedParameter* NamedParameter::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); StringIndex name_index(reader->ReadUInt()); DartType* type = DartType::ReadFrom(reader); return new NamedParameter(name_index, type); } template class DowncastReader { public: static S* ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); return S::Cast(B::ReadFrom(reader)); } }; class VariableDeclarationImpl { public: static VariableDeclaration* ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); return VariableDeclaration::ReadFromImpl(reader, false); } }; void SourceTable::ReadFrom(Reader* reader) { size_ = reader->ReadUInt(); sources_ = new Source[size_]; // Build a table of the URI offsets. intptr_t* end_offsets = new intptr_t[size_]; for (intptr_t i = 0; i < size_; ++i) { end_offsets[i] = reader->ReadUInt(); } // Read the URI strings. intptr_t start_offset = 0; for (intptr_t i = 0; i < size_; ++i) { intptr_t length = end_offsets[i] - start_offset; uint8_t* buffer = new uint8_t[length]; memmove(buffer, reader->buffer() + reader->offset(), length); reader->Consume(length); sources_[i].uri_ = buffer; sources_[i].uri_size_ = length; start_offset = end_offsets[i]; } // Read the source code strings and line starts. for (intptr_t i = 0; i < size_; ++i) { intptr_t length = reader->ReadUInt(); uint8_t* string_buffer = new uint8_t[length]; memmove(string_buffer, reader->buffer() + reader->offset(), length); reader->Consume(length); intptr_t line_count = reader->ReadUInt(); intptr_t* line_starts = new intptr_t[line_count]; intptr_t previous_line_start = 0; for (intptr_t j = 0; j < line_count; ++j) { intptr_t line_start = reader->ReadUInt() + previous_line_start; line_starts[j] = line_start; previous_line_start = line_start; } sources_[i].source_code_ = string_buffer; sources_[i].source_code_size_ = length; sources_[i].line_starts_ = line_starts; sources_[i].line_count_ = line_count; } } Library* Library::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); int flags = reader->ReadFlags(); ASSERT(flags == 0); // external libraries not supported kernel_data_ = reader->buffer(); kernel_data_size_ = reader->size(); canonical_name_ = reader->ReadCanonicalNameReference(); name_index_ = StringIndex(reader->ReadUInt()); import_uri_index_ = reader->CanonicalNameString(canonical_name_); source_uri_index_ = reader->ReadUInt(); reader->set_current_script_id(source_uri_index_); int num_imports = reader->ReadUInt(); if (num_imports != 0) { FATAL("Deferred imports not implemented in VM"); } int num_typedefs = reader->ReadUInt(); typedefs().EnsureInitialized(num_typedefs); for (intptr_t i = 0; i < num_typedefs; i++) { typedefs().GetOrCreate(i, this)->ReadFrom(reader); } int num_classes = reader->ReadUInt(); classes().EnsureInitialized(num_classes); for (intptr_t i = 0; i < num_classes; i++) { Tag tag = reader->ReadTag(); ASSERT(tag == kClass); NormalClass* klass = classes().GetOrCreate(i, this); klass->ReadFrom(reader); } fields().ReadFrom(reader, this); procedures().ReadFrom(reader, this); can_stream_ = classes().CanStream() && fields().CanStream() && procedures().CanStream(); return this; } Typedef* Typedef::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); canonical_name_ = reader->ReadCanonicalNameReference(); position_ = reader->ReadPosition(false); name_index_ = StringIndex(reader->ReadUInt()); source_uri_index_ = reader->ReadUInt(); type_parameters_.ReadFrom(reader); type_ = DartType::ReadFrom(reader); return this; } Class* Class::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); canonical_name_ = reader->ReadCanonicalNameReference(); position_ = reader->ReadPosition(false); is_abstract_ = reader->ReadBool(); name_index_ = StringIndex(reader->ReadUInt()); source_uri_index_ = reader->ReadUInt(); reader->set_current_script_id(source_uri_index_); reader->record_token_position(position_); annotations_.ReadFromStatic(reader); can_stream_ = annotations_.CanStream(); return this; } NormalClass* NormalClass::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); Class::ReadFrom(reader); TypeParameterScope scope(reader->helper()); type_parameters_.ReadFrom(reader); DartType* type = reader->ReadOptional(); super_class_ = InterfaceType::Cast(type); reader->ReadOptional(); // Mixed-in type is unused. implemented_classes_.ReadFromStatic >( reader); fields_.ReadFrom(reader, this); constructors_.ReadFrom(reader, this); procedures_.ReadFrom(reader, this); can_stream_ = can_stream_ && fields_.CanStream() && constructors_.CanStream() && procedures_.CanStream(); return this; } MixinClass* MixinClass::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); TypeParameterScope 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 >( reader); constructors_.ReadFrom(reader, this); can_stream_ = constructors_.CanStream(); return this; } NameIndex Reference::ReadMemberFrom(Reader* reader, bool allow_null) { TRACE_READ_OFFSET(); NameIndex canonical_name = reader->ReadCanonicalNameReference(); if ((canonical_name == -1) && !allow_null) { FATAL("Expected a valid member reference, but got `null`"); } return canonical_name; } NameIndex Reference::ReadClassFrom(Reader* reader, bool allow_null) { TRACE_READ_OFFSET(); NameIndex canonical_name = reader->ReadCanonicalNameReference(); if ((canonical_name == -1) && !allow_null) { FATAL("Expected a valid class reference, but got `null`"); } return canonical_name; } NameIndex Reference::ReadTypedefFrom(Reader* reader) { TRACE_READ_OFFSET(); NameIndex canonical_name = reader->ReadCanonicalNameReference(); if (canonical_name == -1) { FATAL("Expected a valid typedef reference, but got `null`"); } return canonical_name; } Field* Field::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); kernel_offset_ = reader->offset(); // Notice the ReadTag() below. Tag tag = reader->ReadTag(); ASSERT(tag == kField); canonical_name_ = reader->ReadCanonicalNameReference(); position_ = reader->ReadPosition(false); end_position_ = reader->ReadPosition(false); flags_ = reader->ReadFlags(); name_ = Name::ReadFrom(reader); source_uri_index_ = reader->ReadUInt(); reader->set_current_script_id(source_uri_index_); reader->record_token_position(position_); reader->record_token_position(end_position_); annotations_.ReadFromStatic(reader); type_ = DartType::ReadFrom(reader); initializer_ = reader->ReadOptional(); can_stream_ = (initializer_ == NULL || initializer_->can_stream()) && annotations_.CanStream(); return this; } Constructor* Constructor::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); Tag tag = reader->ReadTag(); ASSERT(tag == kConstructor); canonical_name_ = reader->ReadCanonicalNameReference(); VariableScope parameters(reader->helper()); position_ = reader->ReadPosition(); end_position_ = reader->ReadPosition(); flags_ = reader->ReadFlags(); name_ = Name::ReadFrom(reader); annotations_.ReadFromStatic(reader); function_ = FunctionNode::ReadFrom(reader); initializers_.ReadFromStatic(reader); can_stream_ = annotations_.CanStream() && function_->can_stream() && initializers_.CanStream(); return this; } Procedure* Procedure::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); Tag tag = reader->ReadTag(); ASSERT(tag == kProcedure); canonical_name_ = reader->ReadCanonicalNameReference(); VariableScope parameters(reader->helper()); position_ = reader->ReadPosition(false); end_position_ = reader->ReadPosition(false); kind_ = static_cast(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(reader); function_ = reader->ReadOptional(); can_stream_ = annotations_.CanStream() && (function_ == NULL || function_->can_stream()); return this; } Initializer* Initializer::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); Tag tag = reader->ReadTag(); switch (tag) { case kInvalidInitializer: return InvalidInitializer::ReadFromImpl(reader); case kFieldInitializer: return FieldInitializer::ReadFromImpl(reader); case kSuperInitializer: return SuperInitializer::ReadFromImpl(reader); case kRedirectingInitializer: return RedirectingInitializer::ReadFromImpl(reader); case kLocalInitializer: return LocalInitializer::ReadFromImpl(reader); default: UNREACHABLE(); } return NULL; } InvalidInitializer* InvalidInitializer::ReadFromImpl(Reader* reader) { TRACE_READ_OFFSET(); return new InvalidInitializer(); } FieldInitializer* FieldInitializer::ReadFromImpl(Reader* reader) { TRACE_READ_OFFSET(); FieldInitializer* initializer = new FieldInitializer(); initializer->field_reference_ = Reference::ReadMemberFrom(reader); initializer->value_ = Expression::ReadFrom(reader); initializer->can_stream_ = initializer->value_->can_stream(); return initializer; } SuperInitializer* SuperInitializer::ReadFromImpl(Reader* reader) { TRACE_READ_OFFSET(); SuperInitializer* init = new SuperInitializer(); init->target_reference_ = Reference::ReadMemberFrom(reader); init->arguments_ = Arguments::ReadFrom(reader); init->can_stream_ = init->arguments_->can_stream(); return init; } RedirectingInitializer* RedirectingInitializer::ReadFromImpl(Reader* reader) { TRACE_READ_OFFSET(); RedirectingInitializer* init = new RedirectingInitializer(); init->target_reference_ = Reference::ReadMemberFrom(reader); init->arguments_ = Arguments::ReadFrom(reader); init->can_stream_ = init->arguments_->can_stream(); return init; } LocalInitializer* LocalInitializer::ReadFromImpl(Reader* reader) { TRACE_READ_OFFSET(); LocalInitializer* init = new LocalInitializer(); init->variable_ = VariableDeclaration::ReadFromImpl(reader, false); init->can_stream_ = init->variable_->can_stream(); return init; } Expression* Expression::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); uint8_t payload = 0; Tag tag = reader->ReadTag(&payload); switch (tag) { case kInvalidExpression: return InvalidExpression::ReadFrom(reader); case kVariableGet: return VariableGet::ReadFrom(reader); case kSpecializedVariableGet: return VariableGet::ReadFrom(reader, payload); case kVariableSet: return VariableSet::ReadFrom(reader); case kSpecializedVariableSet: return VariableSet::ReadFrom(reader, payload); case kPropertyGet: return PropertyGet::ReadFrom(reader); case kPropertySet: return PropertySet::ReadFrom(reader); case kDirectPropertyGet: return DirectPropertyGet::ReadFrom(reader); case kDirectPropertySet: return DirectPropertySet::ReadFrom(reader); case kStaticGet: return StaticGet::ReadFrom(reader); case kStaticSet: return StaticSet::ReadFrom(reader); case kMethodInvocation: return MethodInvocation::ReadFrom(reader); case kDirectMethodInvocation: return DirectMethodInvocation::ReadFrom(reader); case kStaticInvocation: return StaticInvocation::ReadFrom(reader, false); case kConstStaticInvocation: return StaticInvocation::ReadFrom(reader, true); case kConstructorInvocation: return ConstructorInvocation::ReadFrom(reader, false); case kConstConstructorInvocation: return ConstructorInvocation::ReadFrom(reader, true); case kNot: return Not::ReadFrom(reader); case kLogicalExpression: return LogicalExpression::ReadFrom(reader); case kConditionalExpression: return ConditionalExpression::ReadFrom(reader); case kStringConcatenation: return StringConcatenation::ReadFrom(reader); case kIsExpression: return IsExpression::ReadFrom(reader); case kAsExpression: return AsExpression::ReadFrom(reader); case kSymbolLiteral: return SymbolLiteral::ReadFrom(reader); case kTypeLiteral: return TypeLiteral::ReadFrom(reader); case kThisExpression: return ThisExpression::ReadFrom(reader); case kRethrow: return Rethrow::ReadFrom(reader); case kThrow: return Throw::ReadFrom(reader); case kListLiteral: return ListLiteral::ReadFrom(reader, false); case kConstListLiteral: return ListLiteral::ReadFrom(reader, true); case kMapLiteral: return MapLiteral::ReadFrom(reader, false); case kConstMapLiteral: return MapLiteral::ReadFrom(reader, true); case kAwaitExpression: return AwaitExpression::ReadFrom(reader); case kFunctionExpression: return FunctionExpression::ReadFrom(reader); case kLet: return Let::ReadFrom(reader); case kVectorCreation: return VectorCreation::ReadFrom(reader); case kVectorGet: return VectorGet::ReadFrom(reader); case kVectorSet: return VectorSet::ReadFrom(reader); case kVectorCopy: return VectorCopy::ReadFrom(reader); case kClosureCreation: return ClosureCreation::ReadFrom(reader); case kBigIntLiteral: return BigintLiteral::ReadFrom(reader); case kStringLiteral: return StringLiteral::ReadFrom(reader); case kSpecialIntLiteral: return IntLiteral::ReadFrom(reader, payload); case kNegativeIntLiteral: return IntLiteral::ReadFrom(reader, true); case kPositiveIntLiteral: return IntLiteral::ReadFrom(reader, false); case kDoubleLiteral: return DoubleLiteral::ReadFrom(reader); case kTrueLiteral: return BoolLiteral::ReadFrom(reader, true); case kFalseLiteral: return BoolLiteral::ReadFrom(reader, false); case kNullLiteral: return NullLiteral::ReadFrom(reader); default: UNREACHABLE(); } return NULL; } InvalidExpression* InvalidExpression::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); InvalidExpression* invalid_expression = new InvalidExpression(); invalid_expression->kernel_offset_ = reader->offset() - 1; // -1 to include tag byte. return invalid_expression; } VariableGet* VariableGet::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); VariableGet* get = new VariableGet(); get->kernel_offset_ = reader->offset() - 1; // -1 to include tag byte. get->position_ = reader->ReadPosition(); get->variable_kernel_offset_ = reader->ReadUInt(); get->variable_ = reader->helper()->variables().Lookup(reader->ReadUInt()); ASSERT(get->variable_->kernel_offset() == get->variable_kernel_offset_); reader->ReadOptional(); // Unused promoted type. return get; } VariableGet* VariableGet::ReadFrom(Reader* reader, uint8_t payload) { TRACE_READ_OFFSET(); VariableGet* get = new VariableGet(); get->kernel_offset_ = reader->offset() - 1; // -1 to include tag byte. get->position_ = reader->ReadPosition(); get->variable_kernel_offset_ = reader->ReadUInt(); get->variable_ = reader->helper()->variables().Lookup(payload); ASSERT(get->variable_->kernel_offset() == get->variable_kernel_offset_); return get; } VariableSet* VariableSet::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); VariableSet* set = new VariableSet(); set->kernel_offset_ = reader->offset() - 1; // -1 to include tag byte. set->position_ = reader->ReadPosition(); set->variable_kernel_offset_ = reader->ReadUInt(); set->variable_ = reader->helper()->variables().Lookup(reader->ReadUInt()); ASSERT(set->variable_->kernel_offset() == set->variable_kernel_offset_); set->expression_ = Expression::ReadFrom(reader); set->can_stream_ = set->expression_->can_stream(); return set; } VariableSet* VariableSet::ReadFrom(Reader* reader, uint8_t payload) { TRACE_READ_OFFSET(); VariableSet* set = new VariableSet(); set->kernel_offset_ = reader->offset() - 1; // -1 to include tag byte. set->variable_ = reader->helper()->variables().Lookup(payload); set->position_ = reader->ReadPosition(); set->variable_kernel_offset_ = reader->ReadUInt(); ASSERT(set->variable_->kernel_offset() == set->variable_kernel_offset_); set->expression_ = Expression::ReadFrom(reader); set->can_stream_ = set->expression_->can_stream(); return set; } PropertyGet* PropertyGet::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); PropertyGet* get = new PropertyGet(); get->kernel_offset_ = reader->offset() - 1; // -1 to include tag byte. get->position_ = reader->ReadPosition(); get->receiver_ = Expression::ReadFrom(reader); get->name_ = Name::ReadFrom(reader); get->interface_target_reference_ = Reference::ReadMemberFrom(reader, true); get->can_stream_ = get->receiver_->can_stream(); return get; } PropertySet* PropertySet::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); PropertySet* set = new PropertySet(); set->kernel_offset_ = reader->offset() - 1; // -1 to include tag byte. set->position_ = reader->ReadPosition(); set->receiver_ = Expression::ReadFrom(reader); set->name_ = Name::ReadFrom(reader); set->value_ = Expression::ReadFrom(reader); set->interface_target_reference_ = Reference::ReadMemberFrom(reader, true); set->can_stream_ = set->receiver_->can_stream() && set->value_->can_stream(); return set; } DirectPropertyGet* DirectPropertyGet::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); DirectPropertyGet* get = new DirectPropertyGet(); get->kernel_offset_ = reader->offset() - 1; // -1 to include tag byte. get->position_ = reader->ReadPosition(); get->receiver_ = Expression::ReadFrom(reader); get->target_reference_ = Reference::ReadMemberFrom(reader); get->can_stream_ = get->receiver_->can_stream(); return get; } DirectPropertySet* DirectPropertySet::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); DirectPropertySet* set = new DirectPropertySet(); set->kernel_offset_ = reader->offset() - 1; // -1 to include tag byte. set->position_ = reader->ReadPosition(); set->receiver_ = Expression::ReadFrom(reader); set->target_reference_ = Reference::ReadMemberFrom(reader); set->value_ = Expression::ReadFrom(reader); set->can_stream_ = set->receiver_->can_stream() && set->value_->can_stream(); return set; } StaticGet* StaticGet::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); StaticGet* get = new StaticGet(); get->kernel_offset_ = reader->offset() - 1; // -1 to include tag byte. get->position_ = reader->ReadPosition(); get->target_reference_ = Reference::ReadMemberFrom(reader); return get; } StaticSet* StaticSet::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); StaticSet* set = new StaticSet(); set->kernel_offset_ = reader->offset() - 1; // -1 to include tag byte. set->position_ = reader->ReadPosition(); set->target_reference_ = Reference::ReadMemberFrom(reader); set->expression_ = Expression::ReadFrom(reader); set->can_stream_ = set->expression_->can_stream(); return set; } Arguments* Arguments::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); Arguments* arguments = new Arguments(); intptr_t num_arguments = reader->ReadUInt(); arguments->types().ReadFromStatic(reader); arguments->positional().ReadFromStatic(reader); arguments->named().ReadFromStatic(reader); ASSERT(arguments->count() == num_arguments); arguments->can_stream_ = arguments->positional().CanStream() && arguments->named().CanStream(); return arguments; } NamedExpression* NamedExpression::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); StringIndex name_index(reader->ReadUInt()); Expression* expression = Expression::ReadFrom(reader); NamedExpression* named = new NamedExpression(name_index, expression); named->can_stream_ = expression->can_stream(); return named; } MethodInvocation* MethodInvocation::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); MethodInvocation* invocation = new MethodInvocation(); invocation->kernel_offset_ = reader->offset() - 1; // -1 to include tag byte. invocation->position_ = reader->ReadPosition(); invocation->receiver_ = Expression::ReadFrom(reader); invocation->name_ = Name::ReadFrom(reader); invocation->arguments_ = Arguments::ReadFrom(reader); invocation->interface_target_reference_ = Reference::ReadMemberFrom(reader, true); invocation->can_stream_ = invocation->receiver_->can_stream() && invocation->arguments_->can_stream(); return invocation; } DirectMethodInvocation* DirectMethodInvocation::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); DirectMethodInvocation* invocation = new DirectMethodInvocation(); invocation->kernel_offset_ = reader->offset() - 1; // -1 to include tag byte. invocation->receiver_ = Expression::ReadFrom(reader); invocation->target_reference_ = Reference::ReadMemberFrom(reader); invocation->arguments_ = Arguments::ReadFrom(reader); invocation->can_stream_ = invocation->receiver_->can_stream() && invocation->arguments_->can_stream(); return invocation; } StaticInvocation* StaticInvocation::ReadFrom(Reader* reader, bool is_const) { TRACE_READ_OFFSET(); StaticInvocation* invocation = new StaticInvocation(); invocation->kernel_offset_ = reader->offset() - 1; // -1 to include tag byte. invocation->is_const_ = is_const; invocation->position_ = reader->ReadPosition(); invocation->procedure_reference_ = Reference::ReadMemberFrom(reader); invocation->arguments_ = Arguments::ReadFrom(reader); invocation->can_stream_ = invocation->arguments_->can_stream(); return invocation; } ConstructorInvocation* ConstructorInvocation::ReadFrom(Reader* reader, bool is_const) { TRACE_READ_OFFSET(); ConstructorInvocation* invocation = new ConstructorInvocation(); invocation->kernel_offset_ = reader->offset() - 1; // -1 to include tag byte. invocation->is_const_ = is_const; invocation->position_ = reader->ReadPosition(); invocation->target_reference_ = Reference::ReadMemberFrom(reader); invocation->arguments_ = Arguments::ReadFrom(reader); invocation->can_stream_ = invocation->arguments_->can_stream(); return invocation; } Not* Not::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); Not* n = new Not(); n->kernel_offset_ = reader->offset() - 1; // -1 to include tag byte. n->expression_ = Expression::ReadFrom(reader); n->can_stream_ = n->expression_->can_stream(); return n; } LogicalExpression* LogicalExpression::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); LogicalExpression* expr = new LogicalExpression(); expr->kernel_offset_ = reader->offset() - 1; // -1 to include tag byte. expr->left_ = Expression::ReadFrom(reader); expr->operator_ = static_cast(reader->ReadByte()); expr->right_ = Expression::ReadFrom(reader); expr->can_stream_ = expr->left_->can_stream() && expr->right_->can_stream(); return expr; } ConditionalExpression* ConditionalExpression::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); ConditionalExpression* expr = new ConditionalExpression(); expr->kernel_offset_ = reader->offset() - 1; // -1 to include tag byte. expr->condition_ = Expression::ReadFrom(reader); expr->then_ = Expression::ReadFrom(reader); expr->otherwise_ = Expression::ReadFrom(reader); reader->ReadOptional(); // Unused static type. expr->can_stream_ = expr->condition_->can_stream() && expr->then_->can_stream() && expr->otherwise_->can_stream(); return expr; } StringConcatenation* StringConcatenation::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); StringConcatenation* concat = new StringConcatenation(); concat->kernel_offset_ = reader->offset() - 1; // -1 to include tag byte. concat->position_ = reader->ReadPosition(); concat->expressions_.ReadFromStatic(reader); concat->can_stream_ = concat->expressions_.CanStream(); return concat; } IsExpression* IsExpression::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); IsExpression* expr = new IsExpression(); expr->kernel_offset_ = reader->offset() - 1; // -1 to include tag byte. expr->position_ = reader->ReadPosition(); expr->operand_ = Expression::ReadFrom(reader); expr->type_ = DartType::ReadFrom(reader); expr->can_stream_ = expr->operand_->can_stream(); return expr; } AsExpression* AsExpression::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); AsExpression* expr = new AsExpression(); expr->kernel_offset_ = reader->offset() - 1; // -1 to include tag byte. expr->position_ = reader->ReadPosition(); expr->operand_ = Expression::ReadFrom(reader); expr->type_ = DartType::ReadFrom(reader); expr->can_stream_ = expr->operand_->can_stream(); return expr; } StringLiteral* StringLiteral::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); intptr_t offset = reader->offset() - 1; // -1 to include tag byte. StringLiteral* lit = new StringLiteral(StringIndex(reader->ReadUInt())); lit->kernel_offset_ = offset; return lit; } BigintLiteral* BigintLiteral::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); intptr_t offset = reader->offset() - 1; // -1 to include tag byte. BigintLiteral* lit = new BigintLiteral(StringIndex(reader->ReadUInt())); lit->kernel_offset_ = offset; return lit; } IntLiteral* IntLiteral::ReadFrom(Reader* reader, bool is_negative) { TRACE_READ_OFFSET(); IntLiteral* literal = new IntLiteral(); literal->kernel_offset_ = reader->offset() - 1; // -1 to include tag byte. literal->value_ = is_negative ? -static_cast(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(payload) - SpecializedIntLiteralBias; return literal; } DoubleLiteral* DoubleLiteral::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); DoubleLiteral* literal = new DoubleLiteral(); literal->kernel_offset_ = reader->offset() - 1; // -1 to include tag byte. literal->value_index_ = StringIndex(reader->ReadUInt()); return literal; } BoolLiteral* BoolLiteral::ReadFrom(Reader* reader, bool value) { TRACE_READ_OFFSET(); BoolLiteral* lit = new BoolLiteral(); lit->kernel_offset_ = reader->offset() - 1; // -1 to include tag byte. lit->value_ = value; return lit; } NullLiteral* NullLiteral::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); NullLiteral* lit = new NullLiteral(); lit->kernel_offset_ = reader->offset() - 1; // -1 to include tag byte. return lit; } SymbolLiteral* SymbolLiteral::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); SymbolLiteral* lit = new SymbolLiteral(); lit->kernel_offset_ = reader->offset() - 1; // -1 to include tag byte. lit->value_index_ = StringIndex(reader->ReadUInt()); return lit; } TypeLiteral* TypeLiteral::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); TypeLiteral* literal = new TypeLiteral(); literal->kernel_offset_ = reader->offset() - 1; // -1 to include tag byte. literal->type_ = DartType::ReadFrom(reader); return literal; } ThisExpression* ThisExpression::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); ThisExpression* this_expr = new ThisExpression(); this_expr->kernel_offset_ = reader->offset() - 1; // -1 to include tag byte. return this_expr; } Rethrow* Rethrow::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); Rethrow* rethrow = new Rethrow(); rethrow->kernel_offset_ = reader->offset() - 1; // -1 to include tag byte. rethrow->position_ = reader->ReadPosition(); return rethrow; } Throw* Throw::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); Throw* t = new Throw(); t->kernel_offset_ = reader->offset() - 1; // -1 to include tag byte. t->position_ = reader->ReadPosition(); t->expression_ = Expression::ReadFrom(reader); t->can_stream_ = t->expression_->can_stream(); return t; } ListLiteral* ListLiteral::ReadFrom(Reader* reader, bool is_const) { TRACE_READ_OFFSET(); ListLiteral* literal = new ListLiteral(); literal->kernel_offset_ = reader->offset() - 1; // -1 to include tag byte. literal->is_const_ = is_const; literal->position_ = reader->ReadPosition(); literal->type_ = DartType::ReadFrom(reader); literal->expressions_.ReadFromStatic(reader); literal->can_stream_ = literal->expressions_.CanStream(); return literal; } MapLiteral* MapLiteral::ReadFrom(Reader* reader, bool is_const) { TRACE_READ_OFFSET(); MapLiteral* literal = new MapLiteral(); literal->kernel_offset_ = reader->offset() - 1; // -1 to include tag byte. literal->is_const_ = is_const; literal->position_ = reader->ReadPosition(); literal->key_type_ = DartType::ReadFrom(reader); literal->value_type_ = DartType::ReadFrom(reader); literal->entries_.ReadFromStatic(reader); literal->can_stream_ = literal->entries_.CanStream(); return literal; } MapEntry* MapEntry::ReadFrom(Reader* reader) { MapEntry* entry = new MapEntry(); entry->key_ = Expression::ReadFrom(reader); entry->value_ = Expression::ReadFrom(reader); entry->can_stream_ = entry->key_->can_stream() && entry->value_->can_stream(); return entry; } AwaitExpression* AwaitExpression::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); AwaitExpression* await = new AwaitExpression(); await->kernel_offset_ = reader->offset() - 1; // -1 to include tag byte. await->operand_ = Expression::ReadFrom(reader); await->can_stream_ = await->operand_->can_stream(); return await; } FunctionExpression* FunctionExpression::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); VariableScope parameters(reader->helper()); FunctionExpression* expr = new FunctionExpression(); expr->kernel_offset_ = reader->offset() - 1; // -1 to include tag byte. expr->function_ = FunctionNode::ReadFrom(reader); expr->can_stream_ = false; return expr; } Let* Let::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); VariableScope vars(reader->helper()); PositionScope scope(reader); Let* let = new Let(); let->kernel_offset_ = reader->offset() - 1; // -1 to include tag byte. let->variable_ = VariableDeclaration::ReadFromImpl(reader, false); let->body_ = Expression::ReadFrom(reader); let->position_ = reader->min_position(); let->end_position_ = reader->max_position(); let->can_stream_ = let->variable_->can_stream() && let->body_->can_stream(); return let; } VectorCreation* VectorCreation::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); VectorCreation* vector_creation = new VectorCreation(); vector_creation->kernel_offset_ = reader->offset() - 1; // -1 to include tag byte. vector_creation->value_ = reader->ReadUInt(); return vector_creation; } VectorGet* VectorGet::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); VectorGet* vector_get = new VectorGet(); vector_get->kernel_offset_ = reader->offset() - 1; // -1 to include tag byte. vector_get->vector_expression_ = Expression::ReadFrom(reader); vector_get->index_ = reader->ReadUInt(); vector_get->can_stream_ = false; return vector_get; } VectorSet* VectorSet::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); VectorSet* vector_set = new VectorSet(); vector_set->kernel_offset_ = reader->offset() - 1; // -1 to include tag byte. vector_set->vector_expression_ = Expression::ReadFrom(reader); vector_set->index_ = reader->ReadUInt(); vector_set->value_ = Expression::ReadFrom(reader); vector_set->can_stream_ = false; return vector_set; } VectorCopy* VectorCopy::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); VectorCopy* vector_copy = new VectorCopy(); vector_copy->kernel_offset_ = reader->offset() - 1; // -1 to include tag byte. vector_copy->vector_expression_ = Expression::ReadFrom(reader); vector_copy->can_stream_ = false; return vector_copy; } ClosureCreation* ClosureCreation::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); ClosureCreation* closure_creation = new ClosureCreation(); closure_creation->kernel_offset_ = reader->offset() - 1; // to include tag byte. closure_creation->top_level_function_reference_ = Reference::ReadMemberFrom(reader); closure_creation->context_vector_ = Expression::ReadFrom(reader); closure_creation->function_type_ = FunctionType::Cast(DartType::ReadFrom(reader)); closure_creation->can_stream_ = false; return closure_creation; } Statement* Statement::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); Tag tag = reader->ReadTag(); switch (tag) { case kInvalidStatement: return InvalidStatement::ReadFrom(reader); case kExpressionStatement: return ExpressionStatement::ReadFrom(reader); case kBlock: return Block::ReadFromImpl(reader); case kEmptyStatement: return EmptyStatement::ReadFrom(reader); case kAssertStatement: return AssertStatement::ReadFrom(reader); case kLabeledStatement: return LabeledStatement::ReadFrom(reader); case kBreakStatement: return BreakStatement::ReadFrom(reader); case kWhileStatement: return WhileStatement::ReadFrom(reader); case kDoStatement: return DoStatement::ReadFrom(reader); case kForStatement: return ForStatement::ReadFrom(reader); case kForInStatement: return ForInStatement::ReadFrom(reader, false); case kAsyncForInStatement: return ForInStatement::ReadFrom(reader, true); case kSwitchStatement: return SwitchStatement::ReadFrom(reader); case kContinueSwitchStatement: return ContinueSwitchStatement::ReadFrom(reader); case kIfStatement: return IfStatement::ReadFrom(reader); case kReturnStatement: return ReturnStatement::ReadFrom(reader); case kTryCatch: return TryCatch::ReadFrom(reader); case kTryFinally: return TryFinally::ReadFrom(reader); case kYieldStatement: return YieldStatement::ReadFrom(reader); case kVariableDeclaration: return VariableDeclaration::ReadFromImpl(reader, true); case kFunctionDeclaration: return FunctionDeclaration::ReadFrom(reader); default: UNREACHABLE(); } return NULL; } InvalidStatement* InvalidStatement::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); InvalidStatement* stmt = new InvalidStatement(); stmt->kernel_offset_ = reader->offset() - 1; // -1 to include tag byte. return stmt; } ExpressionStatement* ExpressionStatement::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); intptr_t offset = reader->offset() - 1; // -1 to include tag byte. ExpressionStatement* stmt = new ExpressionStatement(Expression::ReadFrom(reader)); stmt->kernel_offset_ = offset; stmt->can_stream_ = stmt->expression_->can_stream(); return stmt; } Block* Block::ReadFromImpl(Reader* reader) { TRACE_READ_OFFSET(); PositionScope scope(reader); VariableScope vars(reader->helper()); Block* block = new Block(); block->kernel_offset_ = reader->offset() - 1; // -1 to include tag byte. block->statements().ReadFromStatic(reader); block->position_ = reader->min_position(); block->end_position_ = reader->max_position(); block->can_stream_ = block->statements().CanStream(); return block; } EmptyStatement* EmptyStatement::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); EmptyStatement* stmt = new EmptyStatement(); stmt->kernel_offset_ = reader->offset() - 1; // -1 to include tag byte. return stmt; } AssertStatement* AssertStatement::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); AssertStatement* stmt = new AssertStatement(); stmt->kernel_offset_ = reader->offset() - 1; // -1 to include tag byte. stmt->condition_ = Expression::ReadFrom(reader); stmt->message_ = reader->ReadOptional(); stmt->can_stream_ = stmt->condition_->can_stream() && (stmt->message_ == NULL || stmt->message_->can_stream()); return stmt; } LabeledStatement* LabeledStatement::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); LabeledStatement* stmt = new LabeledStatement(); stmt->kernel_offset_ = reader->offset() - 1; // -1 to include tag byte. reader->helper()->labels()->Push(stmt); stmt->body_ = Statement::ReadFrom(reader); reader->helper()->labels()->Pop(stmt); stmt->can_stream_ = stmt->body_->can_stream(); return stmt; } BreakStatement* BreakStatement::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); BreakStatement* stmt = new BreakStatement(); stmt->kernel_offset_ = reader->offset() - 1; // -1 to include tag byte. stmt->position_ = reader->ReadPosition(); stmt->target_index_ = reader->ReadUInt(); return stmt; } WhileStatement* WhileStatement::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); WhileStatement* stmt = new WhileStatement(); stmt->kernel_offset_ = reader->offset() - 1; // -1 to include tag byte. stmt->condition_ = Expression::ReadFrom(reader); stmt->body_ = Statement::ReadFrom(reader); stmt->can_stream_ = stmt->condition_->can_stream() && stmt->body_->can_stream(); return stmt; } DoStatement* DoStatement::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); DoStatement* dostmt = new DoStatement(); dostmt->kernel_offset_ = reader->offset() - 1; // -1 to include tag byte. dostmt->body_ = Statement::ReadFrom(reader); dostmt->condition_ = Expression::ReadFrom(reader); dostmt->can_stream_ = dostmt->body_->can_stream() && dostmt->condition_->can_stream(); return dostmt; } ForStatement* ForStatement::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); VariableScope vars(reader->helper()); PositionScope scope(reader); ForStatement* forstmt = new ForStatement(); forstmt->kernel_offset_ = reader->offset() - 1; // -1 to include tag byte. forstmt->variables_.ReadFromStatic(reader); forstmt->condition_ = reader->ReadOptional(); forstmt->updates_.ReadFromStatic(reader); forstmt->body_ = Statement::ReadFrom(reader); forstmt->end_position_ = reader->max_position(); forstmt->position_ = reader->min_position(); forstmt->can_stream_ = forstmt->body_->can_stream() && (forstmt->condition_ == NULL || forstmt->condition_->can_stream()) && forstmt->variables_.CanStream() && forstmt->updates_.CanStream(); return forstmt; } ForInStatement* ForInStatement::ReadFrom(Reader* reader, bool is_async) { TRACE_READ_OFFSET(); VariableScope vars(reader->helper()); PositionScope scope(reader); ForInStatement* forinstmt = new ForInStatement(); forinstmt->kernel_offset_ = reader->offset() - 1; // -1 to include tag byte. forinstmt->is_async_ = is_async; forinstmt->position_ = reader->ReadPosition(); forinstmt->variable_ = VariableDeclaration::ReadFromImpl(reader, false); forinstmt->iterable_ = Expression::ReadFrom(reader); forinstmt->body_ = Statement::ReadFrom(reader); forinstmt->end_position_ = reader->max_position(); if (!forinstmt->position_.IsReal()) { forinstmt->position_ = reader->min_position(); } forinstmt->variable_->set_end_position(forinstmt->position_); forinstmt->can_stream_ = forinstmt->variable_->can_stream() && forinstmt->iterable_->can_stream() && forinstmt->body_->can_stream(); return forinstmt; } SwitchStatement* SwitchStatement::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); SwitchStatement* stmt = new SwitchStatement(); stmt->kernel_offset_ = reader->offset() - 1; // -1 to include tag byte. stmt->condition_ = Expression::ReadFrom(reader); int count = reader->ReadUInt(); stmt->cases_.EnsureInitialized(count); for (intptr_t i = 0; i < count; i++) { SwitchCase* sc = stmt->cases_.GetOrCreate(i); sc->ReadFrom(reader); } stmt->can_stream_ = stmt->condition_->can_stream() && stmt->cases_.CanStream(); return stmt; } SwitchCase* SwitchCase::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); int length = reader->ReadListLength(); expressions_.EnsureInitialized(length); for (intptr_t i = 0; i < length; i++) { ASSERT(expressions_[i] == NULL); TokenPosition position = reader->ReadPosition(); expressions_[i] = Expression::ReadFrom(reader); expressions_[i]->set_position(position); } is_default_ = reader->ReadBool(); body_ = Statement::ReadFrom(reader); can_stream_ = expressions_.CanStream() && body_->can_stream(); return this; } ContinueSwitchStatement* ContinueSwitchStatement::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); ContinueSwitchStatement* stmt = new ContinueSwitchStatement(); stmt->kernel_offset_ = reader->offset() - 1; // -1 to include tag byte. stmt->target_index_ = reader->ReadUInt(); return stmt; } IfStatement* IfStatement::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); IfStatement* ifstmt = new IfStatement(); ifstmt->kernel_offset_ = reader->offset() - 1; // -1 to include tag byte. ifstmt->condition_ = Expression::ReadFrom(reader); ifstmt->then_ = Statement::ReadFrom(reader); ifstmt->otherwise_ = Statement::ReadFrom(reader); ifstmt->can_stream_ = ifstmt->condition_->can_stream() && ifstmt->then_->can_stream() && ifstmt->otherwise_->can_stream(); return ifstmt; } ReturnStatement* ReturnStatement::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); ReturnStatement* ret = new ReturnStatement(); ret->kernel_offset_ = reader->offset() - 1; // -1 to include tag byte. ret->position_ = reader->ReadPosition(); ret->expression_ = reader->ReadOptional(); ret->can_stream_ = (ret->expression_ == NULL || ret->expression_->can_stream()); return ret; } TryCatch* TryCatch::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); PositionScope scope(reader); TryCatch* tc = new TryCatch(); tc->kernel_offset_ = reader->offset() - 1; // -1 to include tag byte. tc->body_ = Statement::ReadFrom(reader); reader->ReadBool(); // whether any catch needs a stacktrace. tc->catches_.ReadFromStatic(reader); tc->position_ = reader->min_position(); tc->can_stream_ = tc->body_->can_stream() && tc->catches_.CanStream(); return tc; } Catch* Catch::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); VariableScope 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(); c->stack_trace_ = reader->ReadOptional(); c->body_ = Statement::ReadFrom(reader); c->end_position_ = reader->max_position(); c->position_ = reader->min_position(); c->can_stream_ = c->body_->can_stream(); return c; } TryFinally* TryFinally::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); TryFinally* tf = new TryFinally(); tf->kernel_offset_ = reader->offset() - 1; // -1 to include tag byte. tf->body_ = Statement::ReadFrom(reader); tf->finalizer_ = Statement::ReadFrom(reader); tf->can_stream_ = tf->body_->can_stream() && tf->finalizer_->can_stream(); return tf; } YieldStatement* YieldStatement::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); YieldStatement* stmt = new YieldStatement(); stmt->kernel_offset_ = reader->offset() - 1; // -1 to include tag byte. stmt->position_ = reader->ReadPosition(); reader->record_yield_token_position(stmt->position_); stmt->flags_ = reader->ReadByte(); stmt->expression_ = Expression::ReadFrom(reader); stmt->can_stream_ = stmt->expression_->can_stream(); return stmt; } VariableDeclaration* VariableDeclaration::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); Tag tag = reader->ReadTag(); ASSERT(tag == kVariableDeclaration); return VariableDeclaration::ReadFromImpl(reader, true); } VariableDeclaration* VariableDeclaration::ReadFromImpl(Reader* reader, bool read_tag) { TRACE_READ_OFFSET(); PositionScope scope(reader); VariableDeclaration* decl = new VariableDeclaration(); // -1 or -0 depending on whether there's a tag or not. decl->kernel_offset_ = reader->offset() - (read_tag ? 1 : 0); decl->position_ = reader->ReadPosition(); decl->equals_position_ = reader->ReadPosition(); decl->flags_ = reader->ReadFlags(); decl->name_index_ = StringIndex(reader->ReadUInt()); decl->type_ = DartType::ReadFrom(reader); decl->initializer_ = reader->ReadOptional(); // Go to next token position so it ends *after* the last potentially // debuggable position in the initializer. TokenPosition position = reader->max_position(); if (position.IsReal()) position.Next(); decl->end_position_ = position; reader->helper()->variables().Push(decl); decl->can_stream_ = (decl->initializer_ == NULL || decl->initializer_->can_stream()); return decl; } FunctionDeclaration* FunctionDeclaration::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); FunctionDeclaration* decl = new FunctionDeclaration(); decl->kernel_offset_ = reader->offset() - 1; // -1 to include tag byte. decl->position_ = reader->ReadPosition(); decl->variable_ = VariableDeclaration::ReadFromImpl(reader, false); VariableScope parameters(reader->helper()); decl->function_ = FunctionNode::ReadFrom(reader); decl->can_stream_ = false; return decl; } Name* Name::ReadFrom(Reader* reader) { StringIndex name_index(reader->ReadUInt()); if ((reader->StringLength(name_index) >= 1) && (reader->CharacterAt(name_index, 0) == '_')) { intptr_t library_reference = reader->ReadCanonicalNameReference(); return new Name(name_index, library_reference); } else { return new Name(name_index, NULL); } } DartType* DartType::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); Tag tag = reader->ReadTag(); switch (tag) { case kInvalidType: return InvalidType::ReadFrom(reader); case kDynamicType: return DynamicType::ReadFrom(reader); case kVoidType: return VoidType::ReadFrom(reader); case kBottomType: return BottomType::ReadFrom(reader); case kInterfaceType: return InterfaceType::ReadFrom(reader); case kSimpleInterfaceType: return InterfaceType::ReadFrom(reader, true); case kFunctionType: return FunctionType::ReadFrom(reader); case kSimpleFunctionType: return FunctionType::ReadFrom(reader, true); case kTypeParameterType: return TypeParameterType::ReadFrom(reader); case kVectorType: return VectorType::ReadFrom(reader); case kTypedefType: return TypedefType::ReadFrom(reader); default: UNREACHABLE(); } UNREACHABLE(); return NULL; } InvalidType* InvalidType::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); return new InvalidType(); } DynamicType* DynamicType::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); return new DynamicType(); } VoidType* VoidType::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); return new VoidType(); } BottomType* BottomType::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); return new BottomType(); } InterfaceType* InterfaceType::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); NameIndex klass_name = Reference::ReadClassFrom(reader); InterfaceType* type = new InterfaceType(klass_name); type->type_arguments().ReadFromStatic(reader); return type; } InterfaceType* InterfaceType::ReadFrom(Reader* reader, bool _without_type_arguments_) { TRACE_READ_OFFSET(); NameIndex klass_name = Reference::ReadClassFrom(reader); InterfaceType* type = new InterfaceType(klass_name); ASSERT(_without_type_arguments_); return type; } TypedefType* TypedefType::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); NameIndex typedef_name = Reference::ReadTypedefFrom(reader); TypedefType* type = new TypedefType(typedef_name); type->type_arguments().ReadFromStatic(reader); return type; } FunctionType* FunctionType::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); FunctionType* type = new FunctionType(); TypeParameterScope scope(reader->helper()); type->type_parameters().ReadFrom(reader); type->required_parameter_count_ = reader->ReadUInt(); intptr_t total_parameter_count = reader->ReadUInt(); type->positional_parameters().ReadFromStatic(reader); type->named_parameters().ReadFromStatic(reader); ASSERT(type->positional_parameters().length() + type->named_parameters().length() == total_parameter_count); type->return_type_ = DartType::ReadFrom(reader); return type; } FunctionType* FunctionType::ReadFrom(Reader* reader, bool _is_simple_) { TRACE_READ_OFFSET(); FunctionType* type = new FunctionType(); ASSERT(_is_simple_); type->positional_parameters().ReadFromStatic(reader); type->required_parameter_count_ = type->positional_parameters().length(); type->return_type_ = DartType::ReadFrom(reader); return type; } TypeParameterType* TypeParameterType::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); TypeParameterType* type = new TypeParameterType(); type->parameter_ = reader->helper()->type_parameters().Lookup(reader->ReadUInt()); reader->ReadUInt(); // binary offset of parameter // There is an optional promoted bound, currently ignored. delete reader->ReadOptional(); return type; } VectorType* VectorType::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); VectorType* type = new VectorType(); return type; } Program* Program::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); uint32_t magic = reader->ReadUInt32(); if (magic != kMagicProgramFile) FATAL("Invalid magic identifier"); Program* program = new Program(); reader->helper()->set_program(program); // Deserialize the string offset table to give fast access to the string data // during deserialization. program->string_table_offset_ = reader->offset(); intptr_t string_count = reader->ReadUInt(); reader->string_offsets_ = new intptr_t[string_count + 1]; intptr_t offset = 0; for (intptr_t i = 0; i < string_count; ++i) { reader->string_offsets_[i] = offset; offset = reader->ReadUInt(); } reader->string_offsets_[string_count] = offset; // Skip the UTF-8 encoded strings. reader->MarkStringDataOffset(); reader->Consume(offset); program->source_table_.ReadFrom(reader); // Deserialize the canonical name table to give fast access to canonical names // during deserialization. program->name_table_offset_ = reader->offset(); intptr_t name_count = reader->ReadUInt(); reader->canonical_name_parents_ = new NameIndex[name_count]; reader->canonical_name_strings_ = new StringIndex[name_count]; for (int i = 0; i < name_count; ++i) { // The parent name index is biased: 0 is the root name and otherwise N+1 is // the Nth name. reader->canonical_name_parents_[i] = reader->ReadCanonicalNameReference(); reader->canonical_name_strings_[i] = StringIndex(reader->ReadUInt()); } int libraries = reader->ReadUInt(); program->libraries().EnsureInitialized(libraries); for (intptr_t i = 0; i < libraries; i++) { program->libraries().GetOrCreate(i)->ReadFrom(reader); } program->main_method_reference_ = Reference::ReadMemberFrom(reader, /*allow_null=*/true); program->can_stream_ = false; return program; } FunctionNode* FunctionNode::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); TypeParameterScope 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(reader->ReadByte()); function->dart_async_marker_ = static_cast(reader->ReadByte()); function->type_parameters().ReadFrom(reader); function->required_parameter_count_ = reader->ReadUInt(); function->positional_parameters().ReadFromStatic( reader); function->named_parameters().ReadFromStatic(reader); function->return_type_ = DartType::ReadFrom(reader); LabelScope > labels( reader->helper()); VariableScope vars(reader->helper()); function->body_ = reader->ReadOptional(); function->can_stream_ = function->positional_parameters_.CanStream() && function->named_parameters_.CanStream() && (function->body_ == NULL || function->body_->can_stream()); return function; } TypeParameter* TypeParameter::ReadFrom(Reader* reader) { TRACE_READ_OFFSET(); kernel_offset_ = reader->offset(); name_index_ = StringIndex(reader->ReadUInt()); bound_ = DartType::ReadFrom(reader); return this; } } // namespace kernel kernel::Program* ReadPrecompiledKernelFromBuffer(const uint8_t* buffer, intptr_t buffer_length) { kernel::Reader reader(buffer, buffer_length); return kernel::Program::ReadFrom(&reader); } } // namespace dart #endif // !defined(DART_PRECOMPILED_RUNTIME)