Chromium Code Reviews| Index: runtime/vm/kernel_reader.cc |
| diff --git a/runtime/vm/kernel_reader.cc b/runtime/vm/kernel_reader.cc |
| index f2923d5623bcea97b86d82bf68734d46bad99900..3dc1c98f5785b94e746048b1a107d2a0ec2f2451 100644 |
| --- a/runtime/vm/kernel_reader.cc |
| +++ b/runtime/vm/kernel_reader.cc |
| @@ -8,6 +8,7 @@ |
| #include "vm/dart_api_impl.h" |
| #include "vm/kernel_binary.h" |
| +#include "vm/kernel_binary_flowgraph.h" |
| #include "vm/longjump.h" |
| #include "vm/object_store.h" |
| #include "vm/parser.h" |
| @@ -19,58 +20,72 @@ namespace kernel { |
| #define Z (zone_) |
| #define I (isolate_) |
| -#define T (type_translator_) |
| +#define T (builder_.type_translator_) |
| #define H (translation_helper_) |
| -class SimpleExpressionConverter : public ExpressionVisitor { |
| +class SimpleExpressionConverter { |
| public: |
| - explicit SimpleExpressionConverter(TranslationHelper* helper) |
| + SimpleExpressionConverter(TranslationHelper* helper, |
| + StreamingFlowGraphBuilder* builder) |
| : translation_helper_(*helper), |
| zone_(translation_helper_.zone()), |
| - is_simple_(false), |
| - simple_value_(NULL) {} |
| - |
| - virtual void VisitDefaultExpression(Expression* node) { is_simple_ = false; } |
| - |
| - virtual void VisitIntLiteral(IntLiteral* node) { |
| - is_simple_ = true; |
| - simple_value_ = |
| - &Integer::ZoneHandle(Z, Integer::New(node->value(), Heap::kOld)); |
| - *simple_value_ = H.Canonicalize(*simple_value_); |
| - } |
| - |
| - virtual void VisitBigintLiteral(BigintLiteral* node) { |
| - is_simple_ = true; |
| - simple_value_ = &Integer::ZoneHandle( |
| - Z, Integer::New(H.DartString(node->value(), Heap::kOld))); |
| - *simple_value_ = H.Canonicalize(*simple_value_); |
| - } |
| - |
| - virtual void VisitDoubleLiteral(DoubleLiteral* node) { |
| - is_simple_ = true; |
| - simple_value_ = &Double::ZoneHandle( |
| - Z, Double::New(H.DartString(node->value()), Heap::kOld)); |
| - *simple_value_ = H.Canonicalize(*simple_value_); |
| - } |
| - |
| - virtual void VisitBoolLiteral(BoolLiteral* node) { |
| - is_simple_ = true; |
| - simple_value_ = &Bool::Handle(Z, Bool::Get(node->value()).raw()); |
| - } |
| - |
| - virtual void VisitNullLiteral(NullLiteral* node) { |
| - is_simple_ = true; |
| - simple_value_ = &dart::Instance::ZoneHandle(Z, dart::Instance::null()); |
| - } |
| - |
| - virtual void VisitStringLiteral(StringLiteral* node) { |
| - is_simple_ = true; |
| - simple_value_ = &H.DartSymbol(node->value()); |
| - } |
| - |
| - bool IsSimple(Expression* expression) { |
| - expression->AcceptExpressionVisitor(this); |
| - return is_simple_; |
| + simple_value_(NULL), |
| + builder_(builder) {} |
| + |
| + |
| + bool IsSimple(intptr_t kernel_offset) { |
| + AlternativeReadingScope alt(builder_->reader_, kernel_offset); |
| + uint8_t payload = 0; |
| + Tag tag = builder_->ReadTag(&payload); // read tag. |
| + switch (tag) { |
| + case kBigIntLiteral: |
| + simple_value_ = &Integer::ZoneHandle( |
| + Z, Integer::New( |
| + H.DartString(builder_->ReadStringReference(), |
| + Heap::kOld))); // read index into string table. |
| + *simple_value_ = H.Canonicalize(*simple_value_); |
| + return true; |
| + case kStringLiteral: |
| + simple_value_ = &H.DartSymbol( |
| + builder_->ReadStringReference()); // read index into string table. |
| + return true; |
| + case kSpecialIntLiteral: |
| + simple_value_ = |
| + &Integer::ZoneHandle(Z, Integer::New(static_cast<int32_t>(payload) - |
| + SpecializedIntLiteralBias, |
| + Heap::kOld)); |
| + *simple_value_ = H.Canonicalize(*simple_value_); |
| + return true; |
| + case kNegativeIntLiteral: |
| + simple_value_ = &Integer::ZoneHandle( |
| + Z, Integer::New(-static_cast<int64_t>(builder_->ReadUInt()), |
| + Heap::kOld)); // read value. |
| + *simple_value_ = H.Canonicalize(*simple_value_); |
| + return true; |
| + case kPositiveIntLiteral: |
| + simple_value_ = &Integer::ZoneHandle( |
| + Z, Integer::New(static_cast<int64_t>(builder_->ReadUInt()), |
| + Heap::kOld)); // read value. |
| + *simple_value_ = H.Canonicalize(*simple_value_); |
| + return true; |
| + case kDoubleLiteral: |
| + simple_value_ = &Double::ZoneHandle( |
| + Z, Double::New(H.DartString(builder_->ReadStringReference()), |
| + Heap::kOld)); // read string reference. |
| + *simple_value_ = H.Canonicalize(*simple_value_); |
| + return true; |
| + case kTrueLiteral: |
| + simple_value_ = &Bool::Handle(Z, Bool::Get(true).raw()); |
| + return true; |
| + case kFalseLiteral: |
| + simple_value_ = &Bool::Handle(Z, Bool::Get(false).raw()); |
| + return true; |
| + case kNullLiteral: |
| + simple_value_ = &dart::Instance::ZoneHandle(Z, dart::Instance::null()); |
| + return true; |
| + default: |
| + return false; |
| + } |
| } |
| const dart::Instance& SimpleValue() { return *simple_value_; } |
| @@ -79,8 +94,8 @@ class SimpleExpressionConverter : public ExpressionVisitor { |
| private: |
| TranslationHelper& translation_helper_; |
| dart::Zone* zone_; |
| - bool is_simple_; |
| dart::Instance* simple_value_; |
| + StreamingFlowGraphBuilder* builder_; |
| }; |
| @@ -112,9 +127,13 @@ KernelReader::KernelReader(Program* program) |
| isolate_(thread_->isolate()), |
| scripts_(Array::ZoneHandle(zone_)), |
| translation_helper_(this, thread_), |
| - type_translator_(&translation_helper_, |
| - &active_class_, |
| - /*finalize=*/false) { |
| + builder_(&translation_helper_, |
| + zone_, |
| + program_->libraries()[0]->kernel_data(), |
| + program_->libraries()[0]->kernel_data_size()) { |
| + T.active_class_ = &active_class_; |
| + T.finalize_ = false; |
| + |
| intptr_t source_file_count = program->source_table().size(); |
| scripts_ = Array::New(source_file_count, Heap::kOld); |
| @@ -166,7 +185,7 @@ Object& KernelReader::ReadProgram() { |
| intptr_t length = program_->libraries().length(); |
| for (intptr_t i = 0; i < length; i++) { |
| Library* kernel_library = program_->libraries()[i]; |
| - ReadLibrary(kernel_library); |
| + ReadLibrary(kernel_library->kernel_offset()); |
| } |
| for (intptr_t i = 0; i < length; i++) { |
| @@ -201,10 +220,18 @@ Object& KernelReader::ReadProgram() { |
| } |
| -void KernelReader::ReadLibrary(Library* kernel_library) { |
| - dart::Library& library = LookupLibrary(kernel_library->canonical_name()); |
| +void KernelReader::ReadLibrary(intptr_t kernel_offset) { |
| + builder_.SetOffset(kernel_offset); |
| + |
| + int flags = builder_.ReadFlags(); |
| + ASSERT(flags == 0); // external libraries not supported |
| + |
| + NameIndex canonical_name = |
| + builder_.ReadCanonicalNameReference(); // read canonical name. |
| + dart::Library& library = LookupLibrary(canonical_name); |
| if (library.Loaded()) return; |
| - library.SetName(H.DartSymbol(kernel_library->name())); |
| + StringIndex name = builder_.ReadStringReference(); // read name. |
| + library.SetName(H.DartSymbol(name)); |
| // The bootstrapper will take care of creating the native wrapper classes, but |
| // we will add the synthetic constructors to them here. |
| @@ -216,152 +243,224 @@ void KernelReader::ReadLibrary(Library* kernel_library) { |
| } |
| // Setup toplevel class (which contains library fields/procedures). |
| - Script& script = ScriptAt(kernel_library->source_uri_index(), |
| - kernel_library->import_uri()); |
| + StringIndex import_uri_index = H.CanonicalNameString(canonical_name); |
| + intptr_t source_uri_index = builder_.ReadUInt(); // read source uri index. |
| + |
| + Script& script = ScriptAt(source_uri_index, import_uri_index); |
| dart::Class& toplevel_class = dart::Class::Handle( |
| Z, dart::Class::New(library, Symbols::TopLevel(), script, |
| TokenPosition::kNoSource)); |
| toplevel_class.set_is_cycle_free(); |
| library.set_toplevel_class(toplevel_class); |
| + intptr_t num_annotations = builder_.ReadUInt(); // read list length. |
|
Kevin Millikin (Google)
2017/06/21 09:10:40
I prefer to call this annotation_count, and depend
|
| + for (intptr_t i = 0; i < num_annotations; ++i) { |
| + builder_.SkipExpression(); // read ith annotation expression. |
| + } |
| + |
| + intptr_t num_dependencies = builder_.ReadUInt(); // read list length. |
| + for (intptr_t i = 0; i < num_dependencies; ++i) { |
| + builder_.ReadFlags(); // read flags. |
| + num_annotations = builder_.ReadUInt(); // read list length. |
| + for (intptr_t i = 0; i < num_annotations; ++i) { |
| + builder_.SkipExpression(); // read ith annotation expression. |
| + } |
| + builder_.ReadCanonicalNameReference(); // read target_reference. |
| + builder_.ReadStringReference(); // read name_index. |
| + intptr_t num_combinators = builder_.ReadListLength(); // read list length. |
| + for (intptr_t i = 0; i < num_combinators; ++i) { |
| + builder_.ReadBool(); // read is_show. |
| + intptr_t num_names = builder_.ReadUInt(); // read list length. |
| + for (intptr_t j = 0; j < num_names; ++j) { |
| + builder_.ReadUInt(); // read ith entry of name_indices. |
| + } |
| + } |
| + } |
| + |
| + // Skip typedefs. |
| + intptr_t num_typedefs = builder_.ReadListLength(); // read list length. |
| + for (intptr_t i = 0; i < num_typedefs; i++) { |
| + builder_.SkipCanonicalNameReference(); // read canonical name. |
| + builder_.ReadPosition(); // read position. |
| + builder_.SkipStringReference(); // read name index. |
| + builder_.ReadUInt(); // read source_uri_index. |
| + builder_.SkipListOfDartTypes(); // read type parameters. |
| + builder_.SkipDartType(); // read type. |
| + } |
| + |
| + const GrowableObjectArray& classes = |
| + GrowableObjectArray::Handle(Z, I->object_store()->pending_classes()); |
| + |
| + // Load all classes. |
| + int num_classes = builder_.ReadListLength(); // read list length. |
| + for (intptr_t i = 0; i < num_classes; ++i) { |
| + classes.Add(ReadClass(library, toplevel_class), Heap::kOld); |
| + } |
| + |
| fields_.Clear(); |
| functions_.Clear(); |
| - ActiveClassScope active_class_scope(&active_class_, NULL, &toplevel_class); |
| + ActiveClassScope active_class_scope(&active_class_, 0, -1, &toplevel_class); |
| // Load toplevel fields. |
| - for (intptr_t i = 0; i < kernel_library->fields().length(); i++) { |
| - Field* kernel_field = kernel_library->fields()[i]; |
| - |
| - ActiveMemberScope active_member_scope(&active_class_, kernel_field); |
| - const dart::String& name = H.DartFieldName(kernel_field->name()); |
| + intptr_t num_fields = builder_.ReadListLength(); // read list length. |
| + for (intptr_t i = 0; i < num_fields; ++i) { |
| + intptr_t field_offset = builder_.ReaderOffset(); |
| + ActiveMemberScope active_member_scope(&active_class_, false, false, 0, -1); |
| + FieldHelper field_helper(&builder_); |
| + field_helper.ReadUntilExcluding(FieldHelper::kName); |
| + |
| + const dart::String& name = builder_.ReadNameAsFieldName(); |
| + field_helper.SetJustRead(FieldHelper::kName); |
| + field_helper.ReadUntilExcluding(FieldHelper::kType); |
| const Object& script_class = |
| - ClassForScriptAt(toplevel_class, kernel_field->source_uri_index()); |
| + ClassForScriptAt(toplevel_class, field_helper.source_uri_index_); |
| dart::Field& field = dart::Field::Handle( |
| - Z, dart::Field::NewTopLevel(name, kernel_field->IsFinal(), |
| - kernel_field->IsConst(), script_class, |
| - kernel_field->position())); |
| - field.set_kernel_offset(kernel_field->kernel_offset()); |
| - const AbstractType& type = T.TranslateType(kernel_field->type()); |
| + Z, dart::Field::NewTopLevel(name, field_helper.IsFinal(), |
| + field_helper.IsConst(), script_class, |
| + field_helper.position_)); |
| + field.set_kernel_offset(field_offset); |
| + const AbstractType& type = T.BuildType(); // read type. |
| field.SetFieldType(type); |
| - field.set_has_initializer(kernel_field->initializer() != NULL); |
| - GenerateFieldAccessors(toplevel_class, field, kernel_field); |
| + field_helper.SetJustRead(FieldHelper::kType); |
| + field_helper.ReadUntilExcluding(FieldHelper::kInitializer); |
| + field.set_has_initializer(builder_.PeekTag() == kSomething); |
| + GenerateFieldAccessors(toplevel_class, field, &field_helper, field_offset); |
| + field_helper.ReadUntilExcluding(FieldHelper::kEnd); |
| fields_.Add(&field); |
| library.AddObject(field, name); |
| } |
| toplevel_class.AddFields(fields_); |
| // Load toplevel procedures. |
| - for (intptr_t i = 0; i < kernel_library->procedures().length(); i++) { |
| - Procedure* kernel_procedure = kernel_library->procedures()[i]; |
| - ReadProcedure(library, toplevel_class, kernel_procedure); |
| + intptr_t num_procedures = builder_.ReadListLength(); // read list length. |
| + for (intptr_t i = 0; i < num_procedures; ++i) { |
| + ReadProcedure(library, toplevel_class, false); |
| } |
| toplevel_class.SetFunctions(Array::Handle(MakeFunctionsArray())); |
| - const GrowableObjectArray& classes = |
| - GrowableObjectArray::Handle(Z, I->object_store()->pending_classes()); |
| - |
| - // Load all classes. |
| - for (intptr_t i = 0; i < kernel_library->classes().length(); i++) { |
| - Class* kernel_klass = kernel_library->classes()[i]; |
| - classes.Add(ReadClass(library, toplevel_class, kernel_klass), Heap::kOld); |
| - } |
| - |
| classes.Add(toplevel_class, Heap::kOld); |
| } |
| void KernelReader::ReadPreliminaryClass(dart::Class* klass, |
| - Class* kernel_klass) { |
| - ASSERT(kernel_klass->IsNormalClass()); |
| - NormalClass* kernel_normal_class = NormalClass::Cast(kernel_klass); |
| - |
| - ActiveClassScope active_class_scope(&active_class_, kernel_klass, klass); |
| + ClassHelper* class_helper, |
| + intptr_t num_type_parameters) { |
| + // Note: This assumes that ClassHelper is exactly at the position where |
| + // the length of the type parameters have been read, and that the order in |
| + // the binary is as follows: [...], kTypeParameters, kSuperClass, kMixinType, |
| + // kImplementedClasses, [...]. |
| // First setup the type parameters, so if any of the following code uses it |
| // (in a recursive way) we're fine. |
| TypeArguments& type_parameters = |
| TypeArguments::Handle(Z, TypeArguments::null()); |
| - intptr_t num_type_parameters = kernel_klass->type_parameters().length(); |
| if (num_type_parameters > 0) { |
| dart::TypeParameter& parameter = dart::TypeParameter::Handle(Z); |
| Type& null_bound = Type::Handle(Z, Type::null()); |
| // Step a) Create array of [TypeParameter] objects (without bound). |
| type_parameters = TypeArguments::New(num_type_parameters); |
| - for (intptr_t i = 0; i < num_type_parameters; i++) { |
| - parameter = dart::TypeParameter::New( |
| - *klass, Function::Handle(Z), i, |
| - H.DartSymbol(kernel_klass->type_parameters()[i]->name()), null_bound, |
| - TokenPosition::kNoSource); |
| - type_parameters.SetTypeAt(i, parameter); |
| + { |
| + AlternativeReadingScope alt(builder_.reader_); |
| + for (intptr_t i = 0; i < num_type_parameters; i++) { |
| + parameter = dart::TypeParameter::New( |
| + *klass, Function::Handle(Z), i, |
| + H.DartSymbol( |
| + builder_.ReadStringReference()), // read ith name index. |
| + null_bound, TokenPosition::kNoSource); |
| + type_parameters.SetTypeAt(i, parameter); |
| + builder_.SkipDartType(); // read guard. |
| + } |
| } |
| klass->set_type_parameters(type_parameters); |
| // Step b) Fill in the bounds of all [TypeParameter]s. |
| for (intptr_t i = 0; i < num_type_parameters; i++) { |
| - TypeParameter* kernel_parameter = kernel_klass->type_parameters()[i]; |
| + builder_.SkipStringReference(); // read ith name index. |
| + |
| // TODO(github.com/dart-lang/kernel/issues/42): This should be handled |
| // by the frontend. |
| - if (kernel_parameter->bound()->IsDynamicType()) { |
| - parameter ^= type_parameters.TypeAt(i); |
| + parameter ^= type_parameters.TypeAt(i); |
| + Tag tag = builder_.PeekTag(); // peek ith bound type. |
| + if (tag == kDynamicType) { |
| + builder_.SkipDartType(); // read ith bound. |
| parameter.set_bound(Type::Handle(Z, I->object_store()->object_type())); |
| } else { |
| AbstractType& bound = |
| - T.TranslateTypeWithoutFinalization(kernel_parameter->bound()); |
| + T.BuildTypeWithoutFinalization(); // read ith bound. |
| if (bound.IsMalformedOrMalbounded()) { |
| bound = I->object_store()->object_type(); |
| } |
| - |
| - parameter ^= type_parameters.TypeAt(i); |
| parameter.set_bound(bound); |
| } |
| } |
| } |
| // Set super type. Some classes (e.g., Object) do not have one. |
| - if (kernel_normal_class->super_class() != NULL) { |
| + Tag type_tag = builder_.ReadTag(); // read super class type (part 1). |
| + if (type_tag == kSomething) { |
| AbstractType& super_type = |
| - T.TranslateTypeWithoutFinalization(kernel_normal_class->super_class()); |
| + T.BuildTypeWithoutFinalization(); // read super class type (part 2). |
| if (super_type.IsMalformed()) H.ReportError("Malformed super type"); |
| klass->set_super_type(super_type); |
| } |
| + class_helper->SetJustRead(ClassHelper::kSuperClass); |
| + class_helper->ReadUntilIncluding(ClassHelper::kMixinType); |
| + |
| // Build implemented interface types |
| - intptr_t interface_count = kernel_klass->implemented_classes().length(); |
| + intptr_t interface_count = builder_.ReadListLength(); |
| const dart::Array& interfaces = |
| dart::Array::Handle(Z, dart::Array::New(interface_count, Heap::kOld)); |
| for (intptr_t i = 0; i < interface_count; i++) { |
| - InterfaceType* kernel_interface_type = |
| - kernel_klass->implemented_classes()[i]; |
| const AbstractType& type = |
| - T.TranslateTypeWithoutFinalization(kernel_interface_type); |
| + T.BuildTypeWithoutFinalization(); // read ith type. |
| if (type.IsMalformed()) H.ReportError("Malformed interface type."); |
| interfaces.SetAt(i, type); |
| } |
| + class_helper->SetJustRead(ClassHelper::kImplementedClasses); |
| klass->set_interfaces(interfaces); |
| - if (kernel_klass->is_abstract()) klass->set_is_abstract(); |
| + |
| + if (class_helper->is_abstract_) klass->set_is_abstract(); |
| } |
| dart::Class& KernelReader::ReadClass(const dart::Library& library, |
| - const dart::Class& toplevel_class, |
| - Class* kernel_klass) { |
| - dart::Class& klass = LookupClass(kernel_klass->canonical_name()); |
| + const dart::Class& toplevel_class) { |
| + ClassHelper class_helper(&builder_); |
| + intptr_t class_offset = builder_.ReaderOffset(); |
| + class_helper.ReadUntilIncluding(ClassHelper::kCanonicalName); |
| + dart::Class& klass = LookupClass(class_helper.canonical_name_); |
| // The class needs to have a script because all the functions in the class |
| // will inherit it. The predicate Function::IsOptimizable uses the absence of |
| // a script to detect test functions that should not be optimized. |
| if (klass.script() == Script::null()) { |
| - klass.set_script(ScriptAt(kernel_klass->source_uri_index())); |
| + class_helper.ReadUntilIncluding(ClassHelper::kSourceUriIndex); |
| + klass.set_script(ScriptAt(class_helper.source_uri_index_)); |
| } |
| if (klass.token_pos() == TokenPosition::kNoSource) { |
| - klass.set_token_pos(kernel_klass->position()); |
| + class_helper.ReadUntilIncluding(ClassHelper::kPosition); |
| + klass.set_token_pos(class_helper.position_); |
| } |
| + |
| + class_helper.ReadUntilExcluding(ClassHelper::kTypeParameters); |
| + intptr_t type_paremeter_counts = |
| + builder_.ReadListLength(); // read type_parameters list length. |
| + intptr_t type_paremeter_offset = builder_.ReaderOffset(); |
| + |
| + ActiveClassScope active_class_scope(&active_class_, type_paremeter_counts, |
| + type_paremeter_offset, &klass); |
| if (!klass.is_cycle_free()) { |
| - ReadPreliminaryClass(&klass, kernel_klass); |
| + ReadPreliminaryClass(&klass, &class_helper, type_paremeter_counts); |
| + } else { |
| + for (intptr_t i = 0; i < type_paremeter_counts; ++i) { |
| + builder_.SkipStringReference(); // read ith name index. |
| + builder_.SkipDartType(); // read ith bound. |
| + } |
| + class_helper.SetJustRead(ClassHelper::kTypeParameters); |
| } |
| - ActiveClassScope active_class_scope(&active_class_, kernel_klass, &klass); |
| fields_.Clear(); |
| functions_.Clear(); |
| @@ -372,67 +471,90 @@ dart::Class& KernelReader::ReadClass(const dart::Library& library, |
| // fields. |
| klass.InjectCIDFields(); |
| } else { |
| - for (intptr_t i = 0; i < kernel_klass->fields().length(); i++) { |
| - Field* kernel_field = kernel_klass->fields()[i]; |
| - ActiveMemberScope active_member_scope(&active_class_, kernel_field); |
| - |
| - const dart::String& name = H.DartFieldName(kernel_field->name()); |
| + class_helper.ReadUntilExcluding(ClassHelper::kFields); |
| + int num_fields = builder_.ReadListLength(); // read list length. |
| + for (intptr_t i = 0; i < num_fields; ++i) { |
| + intptr_t field_offset = builder_.ReaderOffset(); |
| + ActiveMemberScope active_member(&active_class_, false, false, 0, -1); |
| + FieldHelper field_helper(&builder_); |
| + field_helper.ReadUntilExcluding(FieldHelper::kName); |
| + |
| + const dart::String& name = builder_.ReadNameAsFieldName(); |
| + field_helper.SetJustRead(FieldHelper::kName); |
| + field_helper.ReadUntilExcluding(FieldHelper::kType); |
| const AbstractType& type = |
| - T.TranslateTypeWithoutFinalization(kernel_field->type()); |
| + T.BuildTypeWithoutFinalization(); // read type. |
| + field_helper.SetJustRead(FieldHelper::kType); |
| const Object& script_class = |
| - ClassForScriptAt(klass, kernel_field->source_uri_index()); |
| + ClassForScriptAt(klass, field_helper.source_uri_index_); |
| dart::Field& field = dart::Field::Handle( |
| Z, |
| - dart::Field::New(name, kernel_field->IsStatic(), |
| + dart::Field::New(name, field_helper.IsStatic(), |
| // In the VM all const fields are implicitly final |
| // whereas in Kernel they are not final because they |
| // are not explicitly declared that way. |
| - kernel_field->IsFinal() || kernel_field->IsConst(), |
| - kernel_field->IsConst(), |
| + field_helper.IsFinal() || field_helper.IsConst(), |
| + field_helper.IsConst(), |
| false, // is_reflectable |
| - script_class, type, kernel_field->position())); |
| - field.set_kernel_offset(kernel_field->kernel_offset()); |
| - field.set_has_initializer(kernel_field->initializer() != NULL); |
| - GenerateFieldAccessors(klass, field, kernel_field); |
| + script_class, type, field_helper.position_)); |
| + field.set_kernel_offset(field_offset); |
| + field_helper.ReadUntilExcluding(FieldHelper::kInitializer); |
| + field.set_has_initializer(builder_.PeekTag() == kSomething); |
| + GenerateFieldAccessors(klass, field, &field_helper, field_offset); |
| + field_helper.ReadUntilExcluding(FieldHelper::kEnd); |
| fields_.Add(&field); |
| } |
| klass.AddFields(fields_); |
| + class_helper.SetJustRead(ClassHelper::kFields); |
| } |
| - for (intptr_t i = 0; i < kernel_klass->constructors().length(); i++) { |
| - Constructor* kernel_constructor = kernel_klass->constructors()[i]; |
| - ActiveMemberScope active_member_scope(&active_class_, kernel_constructor); |
| + class_helper.ReadUntilExcluding(ClassHelper::kConstructors); |
| + int num_constructors = builder_.ReadListLength(); // read list length. |
| + for (intptr_t i = 0; i < num_constructors; ++i) { |
| + intptr_t constructor_offset = builder_.ReaderOffset(); |
| + ActiveMemberScope active_member_scope(&active_class_, false, false, 0, -1); |
| + ConstructorHelper constructor_helper(&builder_); |
| + constructor_helper.ReadUntilExcluding(ConstructorHelper::kFunction); |
| const dart::String& name = |
| - H.DartConstructorName(kernel_constructor->canonical_name()); |
| + H.DartConstructorName(constructor_helper.canonical_name_); |
| Function& function = dart::Function::ZoneHandle( |
| Z, dart::Function::New(name, RawFunction::kConstructor, |
| false, // is_static |
| - kernel_constructor->IsConst(), |
| + constructor_helper.IsConst(), |
| false, // is_abstract |
| - kernel_constructor->IsExternal(), |
| + constructor_helper.IsExternal(), |
| false, // is_native |
| - klass, kernel_constructor->position())); |
| - function.set_end_token_pos(kernel_constructor->end_position()); |
| + klass, constructor_helper.position_)); |
| + function.set_end_token_pos(constructor_helper.end_position_); |
| functions_.Add(&function); |
| - function.set_kernel_offset(kernel_constructor->kernel_offset()); |
| + function.set_kernel_offset(constructor_offset); |
| function.set_result_type(T.ReceiverType(klass)); |
| - SetupFunctionParameters(H, T, klass, function, |
| - kernel_constructor->function(), |
| - true, // is_method |
| - false); // is_closure |
| + |
| + FunctionNodeHelper function_node_helper(&builder_); |
| + function_node_helper.ReadUntilExcluding( |
| + FunctionNodeHelper::kRequiredParameterCount); |
| + builder_.SetupFunctionParameters(klass, function, |
| + true, // is_method |
| + false, // is_closure |
| + &function_node_helper); |
| + function_node_helper.ReadUntilExcluding(FunctionNodeHelper::kEnd); |
| + constructor_helper.SetJustRead(ConstructorHelper::kFunction); |
| + constructor_helper.ReadUntilExcluding(ConstructorHelper::kEnd); |
| if (FLAG_enable_mirrors) { |
| library.AddFunctionMetadata(function, TokenPosition::kNoSource, |
| - kernel_constructor->kernel_offset()); |
| + constructor_offset); |
| } |
| } |
| + class_helper.SetJustRead(ClassHelper::kConstructors); |
| - for (intptr_t i = 0; i < kernel_klass->procedures().length(); i++) { |
| - Procedure* kernel_procedure = kernel_klass->procedures()[i]; |
| - ActiveMemberScope active_member_scope(&active_class_, kernel_procedure); |
| - ReadProcedure(library, klass, kernel_procedure, kernel_klass); |
| + class_helper.ReadUntilExcluding(ClassHelper::kProcedures); |
| + int num_procedures = builder_.ReadListLength(); // read list length. |
| + for (intptr_t i = 0; i < num_procedures; ++i) { |
| + ReadProcedure(library, klass, true); |
| } |
| + class_helper.SetJustRead(ClassHelper::kProcedures); |
| klass.SetFunctions(Array::Handle(MakeFunctionsArray())); |
| @@ -442,70 +564,116 @@ dart::Class& KernelReader::ReadClass(const dart::Library& library, |
| if (FLAG_enable_mirrors) { |
| library.AddClassMetadata(klass, toplevel_class, TokenPosition::kNoSource, |
| - kernel_klass->kernel_offset()); |
| + class_offset); |
| } |
| + class_helper.ReadUntilExcluding(ClassHelper::kEnd); |
| + |
| return klass; |
| } |
| void KernelReader::ReadProcedure(const dart::Library& library, |
| const dart::Class& owner, |
| - Procedure* kernel_procedure, |
| - Class* kernel_klass) { |
| - ActiveClassScope active_class_scope(&active_class_, kernel_klass, &owner); |
| - ActiveMemberScope active_member_scope(&active_class_, kernel_procedure); |
| - |
| + bool in_class) { |
| + intptr_t procedure_offset = builder_.ReaderOffset(); |
| + ProcedureHelper procedure_helper(&builder_); |
| + |
| + bool member_is_procedure = false; |
| + bool is_factory_procedure = false; |
| + intptr_t member_type_parameters = 0; |
| + intptr_t member_type_parameters_offset_start = -1; |
| + builder_.GetTypeParameterInfoForPossibleProcedure( |
| + builder_.ReaderOffset(), &member_is_procedure, &is_factory_procedure, |
| + &member_type_parameters, &member_type_parameters_offset_start); |
| + |
| + ActiveMemberScope active_member(&active_class_, member_is_procedure, |
| + is_factory_procedure, member_type_parameters, |
| + member_type_parameters_offset_start); |
| + |
| + procedure_helper.ReadUntilExcluding(ProcedureHelper::kAnnotations); |
| const dart::String& name = |
| - H.DartProcedureName(kernel_procedure->canonical_name()); |
| - bool is_method = kernel_klass != NULL && !kernel_procedure->IsStatic(); |
| - bool is_abstract = kernel_procedure->IsAbstract(); |
| - bool is_external = kernel_procedure->IsExternal(); |
| + H.DartProcedureName(procedure_helper.canonical_name_); |
| + bool is_method = in_class && !procedure_helper.IsStatic(); |
| + bool is_abstract = procedure_helper.IsAbstract(); |
| + bool is_external = procedure_helper.IsExternal(); |
| dart::String* native_name = NULL; |
| if (is_external) { |
| // Maybe it has a native implementation, which is not external as far as |
| // the VM is concerned because it does have an implementation. Check for |
| // an ExternalName annotation and extract the string from it. |
| - for (int i = 0; i < kernel_procedure->annotations().length(); ++i) { |
| - Expression* annotation = kernel_procedure->annotations()[i]; |
| - if (!annotation->IsConstructorInvocation()) continue; |
| - ConstructorInvocation* invocation = |
| - ConstructorInvocation::Cast(annotation); |
| - NameIndex annotation_class = H.EnclosingName(invocation->target()); |
| + intptr_t num_annotations = builder_.ReadListLength(); // read list length. |
| + for (int i = 0; i < num_annotations; ++i) { |
| + if (builder_.PeekTag() != kConstructorInvocation && |
| + builder_.PeekTag() != kConstConstructorInvocation) { |
| + builder_.SkipExpression(); |
| + continue; |
| + } |
| + builder_.ReadTag(); |
| + builder_.ReadPosition(); |
| + NameIndex annotation_class = H.EnclosingName( |
| + builder_.ReadCanonicalNameReference()); // read target reference, |
| ASSERT(H.IsClass(annotation_class)); |
| StringIndex class_name_index = H.CanonicalNameString(annotation_class); |
| // Just compare by name, do not generate the annotation class. |
| - if (!H.StringEquals(class_name_index, "ExternalName")) continue; |
| + if (!H.StringEquals(class_name_index, "ExternalName")) { |
| + builder_.SkipArguments(); |
| + continue; |
| + } |
| ASSERT(H.IsLibrary(H.CanonicalNameParent(annotation_class))); |
| StringIndex library_name_index = |
| H.CanonicalNameString(H.CanonicalNameParent(annotation_class)); |
| - if (!H.StringEquals(library_name_index, "dart:_internal")) continue; |
| + if (!H.StringEquals(library_name_index, "dart:_internal")) { |
| + builder_.SkipArguments(); |
| + continue; |
| + } |
| is_external = false; |
| - ASSERT(invocation->arguments()->positional().length() == 1 && |
| - invocation->arguments()->named().length() == 0); |
| - StringLiteral* literal = |
| - StringLiteral::Cast(invocation->arguments()->positional()[0]); |
| - native_name = &H.DartSymbol(literal->value()); |
| + // Read arguments: |
| + intptr_t total_arguments = builder_.ReadUInt(); // read argument count. |
| + builder_.SkipListOfDartTypes(); // read list of types. |
| + intptr_t positional_arguments = builder_.ReadListLength(); |
| + ASSERT(total_arguments == 1 && positional_arguments == 1); |
| + |
| + Tag tag = builder_.ReadTag(); |
| + ASSERT(tag == kStringLiteral); |
| + native_name = &H.DartSymbol( |
| + builder_.ReadStringReference()); // read index into string table. |
| + |
| + // List of named. |
| + intptr_t list_length = builder_.ReadListLength(); // read list length. |
| + ASSERT(list_length == 0); |
| + |
| + // Skip remaining annotations |
| + for (++i; i < num_annotations; ++i) { |
| + builder_.SkipExpression(); // read ith annotation. |
| + } |
| + |
| break; |
| } |
| + procedure_helper.SetJustRead(ProcedureHelper::kAnnotations); |
| } |
| const Object& script_class = |
| - ClassForScriptAt(owner, kernel_procedure->source_uri_index()); |
| + ClassForScriptAt(owner, procedure_helper.source_uri_index_); |
| dart::Function& function = dart::Function::ZoneHandle( |
| - Z, Function::New(name, GetFunctionType(kernel_procedure), |
| + Z, Function::New(name, GetFunctionType(procedure_helper.kind_), |
| !is_method, // is_static |
| false, // is_const |
| is_abstract, is_external, |
| native_name != NULL, // is_native |
| - script_class, kernel_procedure->position())); |
| - function.set_end_token_pos(kernel_procedure->end_position()); |
| + script_class, procedure_helper.position_)); |
| + function.set_end_token_pos(procedure_helper.end_position_); |
| functions_.Add(&function); |
| - function.set_kernel_offset(kernel_procedure->kernel_offset()); |
| - |
| - function.set_is_debuggable( |
| - kernel_procedure->function()->dart_async_marker() == FunctionNode::kSync); |
| - switch (kernel_procedure->function()->dart_async_marker()) { |
| + function.set_kernel_offset(procedure_offset); |
| + |
| + procedure_helper.ReadUntilExcluding(ProcedureHelper::kFunction); |
| + Tag function_node_tag = builder_.ReadTag(); |
| + ASSERT(function_node_tag == kSomething); |
| + FunctionNodeHelper function_node_helper(&builder_); |
| + function_node_helper.ReadUntilIncluding(FunctionNodeHelper::kDartAsyncMarker); |
| + function.set_is_debuggable(function_node_helper.dart_async_marker_ == |
| + FunctionNode::kSync); |
| + switch (function_node_helper.dart_async_marker_) { |
| case FunctionNode::kSyncStar: |
| function.set_modifier(RawFunction::kSyncGen); |
| break; |
| @@ -521,27 +689,33 @@ void KernelReader::ReadProcedure(const dart::Library& library, |
| // no special modifier |
| break; |
| } |
| - ASSERT(kernel_procedure->function()->async_marker() == FunctionNode::kSync); |
| + ASSERT(function_node_helper.async_marker_ == FunctionNode::kSync); |
| if (native_name != NULL) { |
| function.set_native_name(*native_name); |
| } |
| - SetupFunctionParameters(H, T, owner, function, kernel_procedure->function(), |
| - is_method, |
| - false); // is_closure |
| + function_node_helper.ReadUntilExcluding( |
| + FunctionNodeHelper::kRequiredParameterCount); |
| + builder_.SetupFunctionParameters(owner, function, is_method, |
| + false, // is_closure |
| + &function_node_helper); |
| + function_node_helper.ReadUntilExcluding(FunctionNodeHelper::kEnd); |
| + procedure_helper.SetJustRead(ProcedureHelper::kFunction); |
| - if (kernel_klass == NULL) { |
| + if (!in_class) { |
| library.AddObject(function, name); |
| ASSERT(!Object::Handle( |
| Z, library.LookupObjectAllowPrivate( |
| - H.DartProcedureName(kernel_procedure->canonical_name()))) |
| + H.DartProcedureName(procedure_helper.canonical_name_))) |
| .IsNull()); |
| } |
| if (FLAG_enable_mirrors) { |
| library.AddFunctionMetadata(function, TokenPosition::kNoSource, |
| - kernel_procedure->kernel_offset()); |
| + procedure_offset); |
| } |
| + |
| + procedure_helper.ReadUntilExcluding(ProcedureHelper::kEnd); |
| } |
| const Object& KernelReader::ClassForScriptAt(const dart::Class& klass, |
| @@ -643,18 +817,20 @@ Script& KernelReader::ScriptAt(intptr_t index, StringIndex import_uri) { |
| void KernelReader::GenerateFieldAccessors(const dart::Class& klass, |
| const dart::Field& field, |
| - Field* kernel_field) { |
| - if (kernel_field->IsStatic() && kernel_field->initializer() == NULL) { |
| + FieldHelper* field_helper, |
| + intptr_t field_offset) { |
| + Tag tag = builder_.PeekTag(); |
| + if (field_helper->IsStatic() && tag == kNothing) { |
| // Static fields without an initializer are implicitly initialized to null. |
| // We do not need a getter. |
| field.SetStaticValue(Instance::Handle(Z), true); |
| return; |
| } |
| - if (kernel_field->initializer() != NULL) { |
| - SimpleExpressionConverter converter(&H); |
| + if (tag == kSomething) { |
| + SimpleExpressionConverter converter(&H, &builder_); |
| const bool has_simple_initializer = |
| - converter.IsSimple(kernel_field->initializer()); |
| - if (kernel_field->IsStatic()) { |
| + converter.IsSimple(builder_.ReaderOffset() + 1); // ignore the tag. |
| + if (field_helper->IsStatic()) { |
| // Static fields with initializers either have the static value set to the |
| // initializer value if it is simple enough or else set to an |
| // uninitialized sentinel. |
| @@ -677,38 +853,38 @@ void KernelReader::GenerateFieldAccessors(const dart::Class& klass, |
| } |
| const dart::String& getter_name = |
| - H.DartGetterName(kernel_field->canonical_name()); |
| + H.DartGetterName(field_helper->canonical_name_); |
| const Object& script_class = |
| - ClassForScriptAt(klass, kernel_field->source_uri_index()); |
| + ClassForScriptAt(klass, field_helper->source_uri_index_); |
| Function& getter = Function::ZoneHandle( |
| Z, |
| Function::New( |
| getter_name, |
| - kernel_field->IsStatic() ? RawFunction::kImplicitStaticFinalGetter |
| + field_helper->IsStatic() ? RawFunction::kImplicitStaticFinalGetter |
| : RawFunction::kImplicitGetter, |
| - kernel_field->IsStatic(), |
| + field_helper->IsStatic(), |
| // The functions created by the parser have is_const for static fields |
| // that are const (not just final) and they have is_const for |
| // non-static |
| // fields that are final. |
| - kernel_field->IsStatic() ? kernel_field->IsConst() |
| - : kernel_field->IsFinal(), |
| + field_helper->IsStatic() ? field_helper->IsConst() |
| + : field_helper->IsFinal(), |
| false, // is_abstract |
| false, // is_external |
| false, // is_native |
| - script_class, kernel_field->position())); |
| + script_class, field_helper->position_)); |
| functions_.Add(&getter); |
| - getter.set_end_token_pos(kernel_field->end_position()); |
| - getter.set_kernel_offset(kernel_field->kernel_offset()); |
| + getter.set_end_token_pos(field_helper->end_position_); |
| + getter.set_kernel_offset(field_offset); |
| getter.set_result_type(AbstractType::Handle(Z, field.type())); |
| getter.set_is_debuggable(false); |
| SetupFieldAccessorFunction(klass, getter); |
| - if (!kernel_field->IsStatic() && !kernel_field->IsFinal()) { |
| + if (!field_helper->IsStatic() && !field_helper->IsFinal()) { |
| // Only static fields can be const. |
| - ASSERT(!kernel_field->IsConst()); |
| + ASSERT(!field_helper->IsConst()); |
| const dart::String& setter_name = |
| - H.DartSetterName(kernel_field->canonical_name()); |
| + H.DartSetterName(field_helper->canonical_name_); |
| Function& setter = Function::ZoneHandle( |
| Z, Function::New(setter_name, RawFunction::kImplicitSetter, |
| false, // is_static |
| @@ -716,10 +892,10 @@ void KernelReader::GenerateFieldAccessors(const dart::Class& klass, |
| false, // is_abstract |
| false, // is_external |
| false, // is_native |
| - script_class, kernel_field->position())); |
| + script_class, field_helper->position_)); |
| functions_.Add(&setter); |
| - setter.set_end_token_pos(kernel_field->end_position()); |
| - setter.set_kernel_offset(kernel_field->kernel_offset()); |
| + setter.set_end_token_pos(field_helper->end_position_); |
| + setter.set_kernel_offset(field_offset); |
| setter.set_result_type(Object::void_type()); |
| setter.set_is_debuggable(false); |
| SetupFieldAccessorFunction(klass, setter); |
| @@ -727,80 +903,6 @@ void KernelReader::GenerateFieldAccessors(const dart::Class& klass, |
| } |
| -void KernelReader::SetupFunctionParameters(TranslationHelper translation_helper, |
| - DartTypeTranslator type_translator, |
| - const dart::Class& klass, |
| - const dart::Function& function, |
| - FunctionNode* node, |
| - bool is_method, |
| - bool is_closure) { |
| - dart::Zone* zone = translation_helper.zone(); |
| - |
| - ASSERT(!(is_method && is_closure)); |
| - bool is_factory = function.IsFactory(); |
| - intptr_t extra_parameters = (is_method || is_closure || is_factory) ? 1 : 0; |
| - |
| - function.set_num_fixed_parameters(extra_parameters + |
| - node->required_parameter_count()); |
| - if (node->named_parameters().length() > 0) { |
| - function.SetNumOptionalParameters(node->named_parameters().length(), false); |
| - } else { |
| - function.SetNumOptionalParameters(node->positional_parameters().length() - |
| - node->required_parameter_count(), |
| - true); |
| - } |
| - intptr_t num_parameters = extra_parameters + |
| - node->positional_parameters().length() + |
| - node->named_parameters().length(); |
| - function.set_parameter_types( |
| - Array::Handle(zone, Array::New(num_parameters, Heap::kOld))); |
| - function.set_parameter_names( |
| - Array::Handle(zone, Array::New(num_parameters, Heap::kOld))); |
| - intptr_t pos = 0; |
| - if (is_method) { |
| - ASSERT(!klass.IsNull()); |
| - function.SetParameterTypeAt(pos, |
| - translation_helper.GetCanonicalType(klass)); |
| - function.SetParameterNameAt(pos, Symbols::This()); |
| - pos++; |
| - } else if (is_closure) { |
| - function.SetParameterTypeAt(pos, AbstractType::dynamic_type()); |
| - function.SetParameterNameAt(pos, Symbols::ClosureParameter()); |
| - pos++; |
| - } else if (is_factory) { |
| - function.SetParameterTypeAt(pos, AbstractType::dynamic_type()); |
| - function.SetParameterNameAt(pos, Symbols::TypeArgumentsParameter()); |
| - pos++; |
| - } |
| - for (intptr_t i = 0; i < node->positional_parameters().length(); i++, pos++) { |
| - VariableDeclaration* kernel_variable = node->positional_parameters()[i]; |
| - const AbstractType& type = type_translator.TranslateTypeWithoutFinalization( |
| - kernel_variable->type()); |
| - function.SetParameterTypeAt( |
| - pos, type.IsMalformed() ? Type::dynamic_type() : type); |
| - function.SetParameterNameAt( |
| - pos, translation_helper.DartSymbol(kernel_variable->name())); |
| - } |
| - for (intptr_t i = 0; i < node->named_parameters().length(); i++, pos++) { |
| - VariableDeclaration* named_expression = node->named_parameters()[i]; |
| - const AbstractType& type = type_translator.TranslateTypeWithoutFinalization( |
| - named_expression->type()); |
| - function.SetParameterTypeAt( |
| - pos, type.IsMalformed() ? Type::dynamic_type() : type); |
| - function.SetParameterNameAt( |
| - pos, translation_helper.DartSymbol(named_expression->name())); |
| - } |
| - |
| - // The result type for generative constructors has already been set. |
| - if (!function.IsGenerativeConstructor()) { |
| - const AbstractType& return_type = |
| - type_translator.TranslateTypeWithoutFinalization(node->return_type()); |
| - function.set_result_type(return_type.IsMalformed() ? Type::dynamic_type() |
| - : return_type); |
| - } |
| -} |
| - |
| - |
| void KernelReader::SetupFieldAccessorFunction(const dart::Class& klass, |
| const dart::Function& function) { |
| bool is_setter = function.IsImplicitSetterFunction(); |
| @@ -865,7 +967,8 @@ dart::Class& KernelReader::LookupClass(NameIndex klass) { |
| } |
| -RawFunction::Kind KernelReader::GetFunctionType(Procedure* kernel_procedure) { |
| +RawFunction::Kind KernelReader::GetFunctionType( |
| + Procedure::ProcedureKind procedure_kind) { |
| intptr_t lookuptable[] = { |
| RawFunction::kRegularFunction, // Procedure::kMethod |
| RawFunction::kGetterFunction, // Procedure::kGetter |
| @@ -873,7 +976,7 @@ RawFunction::Kind KernelReader::GetFunctionType(Procedure* kernel_procedure) { |
| RawFunction::kRegularFunction, // Procedure::kOperator |
| RawFunction::kConstructor, // Procedure::kFactory |
| }; |
| - intptr_t kind = static_cast<int>(kernel_procedure->kind()); |
| + intptr_t kind = static_cast<int>(procedure_kind); |
| if (kind == Procedure::kIncompleteProcedure) { |
| return RawFunction::kSignatureFunction; |
| } else { |