Index: runtime/vm/kernel_reader.cc |
diff --git a/runtime/vm/kernel_reader.cc b/runtime/vm/kernel_reader.cc |
index f2923d5623bcea97b86d82bf68734d46bad99900..3c6aaa0b63f1c7b7a83a5452da4a938509c92264 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 annotation_count = builder_.ReadUInt(); // read list length. |
+ for (intptr_t i = 0; i < annotation_count; ++i) { |
+ builder_.SkipExpression(); // read ith annotation expression. |
+ } |
+ |
+ intptr_t dependency_count = builder_.ReadUInt(); // read list length. |
+ for (intptr_t i = 0; i < dependency_count; ++i) { |
+ builder_.ReadFlags(); // read flags. |
+ annotation_count = builder_.ReadUInt(); // read list length. |
+ for (intptr_t i = 0; i < annotation_count; ++i) { |
+ builder_.SkipExpression(); // read ith annotation expression. |
+ } |
+ builder_.ReadCanonicalNameReference(); // read target_reference. |
+ builder_.ReadStringReference(); // read name_index. |
+ intptr_t combinator_count = builder_.ReadListLength(); // read list length. |
+ for (intptr_t i = 0; i < combinator_count; ++i) { |
+ builder_.ReadBool(); // read is_show. |
+ intptr_t name_count = builder_.ReadUInt(); // read list length. |
+ for (intptr_t j = 0; j < name_count; ++j) { |
+ builder_.ReadUInt(); // read ith entry of name_indices. |
+ } |
+ } |
+ } |
+ |
+ // Skip typedefs. |
+ intptr_t typedef_count = builder_.ReadListLength(); // read list length. |
+ for (intptr_t i = 0; i < typedef_count; 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 class_count = builder_.ReadListLength(); // read list length. |
+ for (intptr_t i = 0; i < class_count; ++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 field_count = builder_.ReadListLength(); // read list length. |
+ for (intptr_t i = 0; i < field_count; ++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 procedure_count = builder_.ReadListLength(); // read list length. |
+ for (intptr_t i = 0; i < procedure_count; ++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 type_parameter_count) { |
+ // 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) { |
+ if (type_parameter_count > 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); |
+ type_parameters = TypeArguments::New(type_parameter_count); |
+ { |
+ AlternativeReadingScope alt(builder_.reader_); |
+ for (intptr_t i = 0; i < type_parameter_count; 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]; |
+ for (intptr_t i = 0; i < type_parameter_count; 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 field_count = builder_.ReadListLength(); // read list length. |
+ for (intptr_t i = 0; i < field_count; ++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 constructor_count = builder_.ReadListLength(); // read list length. |
+ for (intptr_t i = 0; i < constructor_count; ++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 procedure_count = builder_.ReadListLength(); // read list length. |
+ for (intptr_t i = 0; i < procedure_count; ++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 annotation_count = builder_.ReadListLength(); // read list length. |
+ for (int i = 0; i < annotation_count; ++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 < annotation_count; ++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 { |