| OLD | NEW |
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/kernel_reader.h" | 5 #include "vm/kernel_reader.h" |
| 6 | 6 |
| 7 #include <string.h> | 7 #include <string.h> |
| 8 | 8 |
| 9 #include "vm/dart_api_impl.h" | 9 #include "vm/dart_api_impl.h" |
| 10 #include "vm/kernel_binary.h" | 10 #include "vm/kernel_binary.h" |
| 11 #include "vm/kernel_binary_flowgraph.h" |
| 11 #include "vm/longjump.h" | 12 #include "vm/longjump.h" |
| 12 #include "vm/object_store.h" | 13 #include "vm/object_store.h" |
| 13 #include "vm/parser.h" | 14 #include "vm/parser.h" |
| 14 #include "vm/symbols.h" | 15 #include "vm/symbols.h" |
| 15 | 16 |
| 16 #if !defined(DART_PRECOMPILED_RUNTIME) | 17 #if !defined(DART_PRECOMPILED_RUNTIME) |
| 17 namespace dart { | 18 namespace dart { |
| 18 namespace kernel { | 19 namespace kernel { |
| 19 | 20 |
| 20 #define Z (zone_) | 21 #define Z (zone_) |
| 21 #define I (isolate_) | 22 #define I (isolate_) |
| 22 #define T (type_translator_) | 23 #define T (builder_.type_translator_) |
| 23 #define H (translation_helper_) | 24 #define H (translation_helper_) |
| 24 | 25 |
| 25 class SimpleExpressionConverter : public ExpressionVisitor { | 26 class SimpleExpressionConverter { |
| 26 public: | 27 public: |
| 27 explicit SimpleExpressionConverter(TranslationHelper* helper) | 28 SimpleExpressionConverter(TranslationHelper* helper, |
| 29 StreamingFlowGraphBuilder* builder) |
| 28 : translation_helper_(*helper), | 30 : translation_helper_(*helper), |
| 29 zone_(translation_helper_.zone()), | 31 zone_(translation_helper_.zone()), |
| 30 is_simple_(false), | 32 simple_value_(NULL), |
| 31 simple_value_(NULL) {} | 33 builder_(builder) {} |
| 32 | 34 |
| 33 virtual void VisitDefaultExpression(Expression* node) { is_simple_ = false; } | |
| 34 | 35 |
| 35 virtual void VisitIntLiteral(IntLiteral* node) { | 36 bool IsSimple(intptr_t kernel_offset) { |
| 36 is_simple_ = true; | 37 AlternativeReadingScope alt(builder_->reader_, kernel_offset); |
| 37 simple_value_ = | 38 uint8_t payload = 0; |
| 38 &Integer::ZoneHandle(Z, Integer::New(node->value(), Heap::kOld)); | 39 Tag tag = builder_->ReadTag(&payload); // read tag. |
| 39 *simple_value_ = H.Canonicalize(*simple_value_); | 40 switch (tag) { |
| 40 } | 41 case kBigIntLiteral: |
| 41 | 42 simple_value_ = &Integer::ZoneHandle( |
| 42 virtual void VisitBigintLiteral(BigintLiteral* node) { | 43 Z, Integer::New( |
| 43 is_simple_ = true; | 44 H.DartString(builder_->ReadStringReference(), |
| 44 simple_value_ = &Integer::ZoneHandle( | 45 Heap::kOld))); // read index into string table. |
| 45 Z, Integer::New(H.DartString(node->value(), Heap::kOld))); | 46 *simple_value_ = H.Canonicalize(*simple_value_); |
| 46 *simple_value_ = H.Canonicalize(*simple_value_); | 47 return true; |
| 47 } | 48 case kStringLiteral: |
| 48 | 49 simple_value_ = &H.DartSymbol( |
| 49 virtual void VisitDoubleLiteral(DoubleLiteral* node) { | 50 builder_->ReadStringReference()); // read index into string table. |
| 50 is_simple_ = true; | 51 return true; |
| 51 simple_value_ = &Double::ZoneHandle( | 52 case kSpecialIntLiteral: |
| 52 Z, Double::New(H.DartString(node->value()), Heap::kOld)); | 53 simple_value_ = |
| 53 *simple_value_ = H.Canonicalize(*simple_value_); | 54 &Integer::ZoneHandle(Z, Integer::New(static_cast<int32_t>(payload) - |
| 54 } | 55 SpecializedIntLiteralBias, |
| 55 | 56 Heap::kOld)); |
| 56 virtual void VisitBoolLiteral(BoolLiteral* node) { | 57 *simple_value_ = H.Canonicalize(*simple_value_); |
| 57 is_simple_ = true; | 58 return true; |
| 58 simple_value_ = &Bool::Handle(Z, Bool::Get(node->value()).raw()); | 59 case kNegativeIntLiteral: |
| 59 } | 60 simple_value_ = &Integer::ZoneHandle( |
| 60 | 61 Z, Integer::New(-static_cast<int64_t>(builder_->ReadUInt()), |
| 61 virtual void VisitNullLiteral(NullLiteral* node) { | 62 Heap::kOld)); // read value. |
| 62 is_simple_ = true; | 63 *simple_value_ = H.Canonicalize(*simple_value_); |
| 63 simple_value_ = &dart::Instance::ZoneHandle(Z, dart::Instance::null()); | 64 return true; |
| 64 } | 65 case kPositiveIntLiteral: |
| 65 | 66 simple_value_ = &Integer::ZoneHandle( |
| 66 virtual void VisitStringLiteral(StringLiteral* node) { | 67 Z, Integer::New(static_cast<int64_t>(builder_->ReadUInt()), |
| 67 is_simple_ = true; | 68 Heap::kOld)); // read value. |
| 68 simple_value_ = &H.DartSymbol(node->value()); | 69 *simple_value_ = H.Canonicalize(*simple_value_); |
| 69 } | 70 return true; |
| 70 | 71 case kDoubleLiteral: |
| 71 bool IsSimple(Expression* expression) { | 72 simple_value_ = &Double::ZoneHandle( |
| 72 expression->AcceptExpressionVisitor(this); | 73 Z, Double::New(H.DartString(builder_->ReadStringReference()), |
| 73 return is_simple_; | 74 Heap::kOld)); // read string reference. |
| 75 *simple_value_ = H.Canonicalize(*simple_value_); |
| 76 return true; |
| 77 case kTrueLiteral: |
| 78 simple_value_ = &Bool::Handle(Z, Bool::Get(true).raw()); |
| 79 return true; |
| 80 case kFalseLiteral: |
| 81 simple_value_ = &Bool::Handle(Z, Bool::Get(false).raw()); |
| 82 return true; |
| 83 case kNullLiteral: |
| 84 simple_value_ = &dart::Instance::ZoneHandle(Z, dart::Instance::null()); |
| 85 return true; |
| 86 default: |
| 87 return false; |
| 88 } |
| 74 } | 89 } |
| 75 | 90 |
| 76 const dart::Instance& SimpleValue() { return *simple_value_; } | 91 const dart::Instance& SimpleValue() { return *simple_value_; } |
| 77 dart::Zone* zone() const { return zone_; } | 92 dart::Zone* zone() const { return zone_; } |
| 78 | 93 |
| 79 private: | 94 private: |
| 80 TranslationHelper& translation_helper_; | 95 TranslationHelper& translation_helper_; |
| 81 dart::Zone* zone_; | 96 dart::Zone* zone_; |
| 82 bool is_simple_; | |
| 83 dart::Instance* simple_value_; | 97 dart::Instance* simple_value_; |
| 98 StreamingFlowGraphBuilder* builder_; |
| 84 }; | 99 }; |
| 85 | 100 |
| 86 | 101 |
| 87 RawArray* KernelReader::MakeFunctionsArray() { | 102 RawArray* KernelReader::MakeFunctionsArray() { |
| 88 const intptr_t len = functions_.length(); | 103 const intptr_t len = functions_.length(); |
| 89 const Array& res = Array::Handle(zone_, Array::New(len, Heap::kOld)); | 104 const Array& res = Array::Handle(zone_, Array::New(len, Heap::kOld)); |
| 90 for (intptr_t i = 0; i < len; i++) { | 105 for (intptr_t i = 0; i < len; i++) { |
| 91 res.SetAt(i, *functions_[i]); | 106 res.SetAt(i, *functions_[i]); |
| 92 } | 107 } |
| 93 return res.raw(); | 108 return res.raw(); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 105 } | 120 } |
| 106 | 121 |
| 107 | 122 |
| 108 KernelReader::KernelReader(Program* program) | 123 KernelReader::KernelReader(Program* program) |
| 109 : program_(program), | 124 : program_(program), |
| 110 thread_(dart::Thread::Current()), | 125 thread_(dart::Thread::Current()), |
| 111 zone_(thread_->zone()), | 126 zone_(thread_->zone()), |
| 112 isolate_(thread_->isolate()), | 127 isolate_(thread_->isolate()), |
| 113 scripts_(Array::ZoneHandle(zone_)), | 128 scripts_(Array::ZoneHandle(zone_)), |
| 114 translation_helper_(this, thread_), | 129 translation_helper_(this, thread_), |
| 115 type_translator_(&translation_helper_, | 130 builder_(&translation_helper_, |
| 116 &active_class_, | 131 zone_, |
| 117 /*finalize=*/false) { | 132 program_->libraries()[0]->kernel_data(), |
| 133 program_->libraries()[0]->kernel_data_size()) { |
| 134 T.active_class_ = &active_class_; |
| 135 T.finalize_ = false; |
| 136 |
| 118 intptr_t source_file_count = program->source_table().size(); | 137 intptr_t source_file_count = program->source_table().size(); |
| 119 scripts_ = Array::New(source_file_count, Heap::kOld); | 138 scripts_ = Array::New(source_file_count, Heap::kOld); |
| 120 | 139 |
| 121 // We need at least one library to get access to the binary. | 140 // We need at least one library to get access to the binary. |
| 122 ASSERT(program->libraries().length() > 0); | 141 ASSERT(program->libraries().length() > 0); |
| 123 Library* library = program->libraries()[0]; | 142 Library* library = program->libraries()[0]; |
| 124 Reader reader(library->kernel_data(), library->kernel_data_size()); | 143 Reader reader(library->kernel_data(), library->kernel_data_size()); |
| 125 | 144 |
| 126 // Copy the Kernel string offsets out of the binary and into the VM's heap. | 145 // Copy the Kernel string offsets out of the binary and into the VM's heap. |
| 127 ASSERT(program->string_table_offset() >= 0); | 146 ASSERT(program->string_table_offset() >= 0); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 159 H.SetCanonicalNames(names); | 178 H.SetCanonicalNames(names); |
| 160 } | 179 } |
| 161 | 180 |
| 162 | 181 |
| 163 Object& KernelReader::ReadProgram() { | 182 Object& KernelReader::ReadProgram() { |
| 164 LongJumpScope jump; | 183 LongJumpScope jump; |
| 165 if (setjmp(*jump.Set()) == 0) { | 184 if (setjmp(*jump.Set()) == 0) { |
| 166 intptr_t length = program_->libraries().length(); | 185 intptr_t length = program_->libraries().length(); |
| 167 for (intptr_t i = 0; i < length; i++) { | 186 for (intptr_t i = 0; i < length; i++) { |
| 168 Library* kernel_library = program_->libraries()[i]; | 187 Library* kernel_library = program_->libraries()[i]; |
| 169 ReadLibrary(kernel_library); | 188 ReadLibrary(kernel_library->kernel_offset()); |
| 170 } | 189 } |
| 171 | 190 |
| 172 for (intptr_t i = 0; i < length; i++) { | 191 for (intptr_t i = 0; i < length; i++) { |
| 173 dart::Library& library = | 192 dart::Library& library = |
| 174 LookupLibrary(program_->libraries()[i]->canonical_name()); | 193 LookupLibrary(program_->libraries()[i]->canonical_name()); |
| 175 if (!library.Loaded()) library.SetLoaded(); | 194 if (!library.Loaded()) library.SetLoaded(); |
| 176 } | 195 } |
| 177 | 196 |
| 178 if (ClassFinalizer::ProcessPendingClasses(/*from_kernel=*/true)) { | 197 if (ClassFinalizer::ProcessPendingClasses(/*from_kernel=*/true)) { |
| 179 // If 'main' is not found return a null library, this is the case | 198 // If 'main' is not found return a null library, this is the case |
| (...skipping 14 matching lines...) Expand all Loading... |
| 194 | 213 |
| 195 // Either class finalization failed or we caught a compile error. | 214 // Either class finalization failed or we caught a compile error. |
| 196 // In both cases sticky error would be set. | 215 // In both cases sticky error would be set. |
| 197 Error& error = Error::Handle(Z); | 216 Error& error = Error::Handle(Z); |
| 198 error = thread_->sticky_error(); | 217 error = thread_->sticky_error(); |
| 199 thread_->clear_sticky_error(); | 218 thread_->clear_sticky_error(); |
| 200 return error; | 219 return error; |
| 201 } | 220 } |
| 202 | 221 |
| 203 | 222 |
| 204 void KernelReader::ReadLibrary(Library* kernel_library) { | 223 void KernelReader::ReadLibrary(intptr_t kernel_offset) { |
| 205 dart::Library& library = LookupLibrary(kernel_library->canonical_name()); | 224 builder_.SetOffset(kernel_offset); |
| 225 |
| 226 int flags = builder_.ReadFlags(); |
| 227 ASSERT(flags == 0); // external libraries not supported |
| 228 |
| 229 NameIndex canonical_name = |
| 230 builder_.ReadCanonicalNameReference(); // read canonical name. |
| 231 dart::Library& library = LookupLibrary(canonical_name); |
| 206 if (library.Loaded()) return; | 232 if (library.Loaded()) return; |
| 207 library.SetName(H.DartSymbol(kernel_library->name())); | 233 StringIndex name = builder_.ReadStringReference(); // read name. |
| 234 library.SetName(H.DartSymbol(name)); |
| 208 | 235 |
| 209 // The bootstrapper will take care of creating the native wrapper classes, but | 236 // The bootstrapper will take care of creating the native wrapper classes, but |
| 210 // we will add the synthetic constructors to them here. | 237 // we will add the synthetic constructors to them here. |
| 211 if (library.name() == | 238 if (library.name() == |
| 212 Symbols::Symbol(Symbols::kDartNativeWrappersLibNameId).raw()) { | 239 Symbols::Symbol(Symbols::kDartNativeWrappersLibNameId).raw()) { |
| 213 ASSERT(library.LoadInProgress()); | 240 ASSERT(library.LoadInProgress()); |
| 214 } else { | 241 } else { |
| 215 library.SetLoadInProgress(); | 242 library.SetLoadInProgress(); |
| 216 } | 243 } |
| 217 // Setup toplevel class (which contains library fields/procedures). | 244 // Setup toplevel class (which contains library fields/procedures). |
| 218 | 245 |
| 219 Script& script = ScriptAt(kernel_library->source_uri_index(), | 246 StringIndex import_uri_index = H.CanonicalNameString(canonical_name); |
| 220 kernel_library->import_uri()); | 247 intptr_t source_uri_index = builder_.ReadUInt(); // read source uri index. |
| 248 |
| 249 Script& script = ScriptAt(source_uri_index, import_uri_index); |
| 221 dart::Class& toplevel_class = dart::Class::Handle( | 250 dart::Class& toplevel_class = dart::Class::Handle( |
| 222 Z, dart::Class::New(library, Symbols::TopLevel(), script, | 251 Z, dart::Class::New(library, Symbols::TopLevel(), script, |
| 223 TokenPosition::kNoSource)); | 252 TokenPosition::kNoSource)); |
| 224 toplevel_class.set_is_cycle_free(); | 253 toplevel_class.set_is_cycle_free(); |
| 225 library.set_toplevel_class(toplevel_class); | 254 library.set_toplevel_class(toplevel_class); |
| 226 | 255 |
| 256 intptr_t annotation_count = builder_.ReadUInt(); // read list length. |
| 257 for (intptr_t i = 0; i < annotation_count; ++i) { |
| 258 builder_.SkipExpression(); // read ith annotation expression. |
| 259 } |
| 260 |
| 261 intptr_t dependency_count = builder_.ReadUInt(); // read list length. |
| 262 for (intptr_t i = 0; i < dependency_count; ++i) { |
| 263 builder_.ReadFlags(); // read flags. |
| 264 annotation_count = builder_.ReadUInt(); // read list length. |
| 265 for (intptr_t i = 0; i < annotation_count; ++i) { |
| 266 builder_.SkipExpression(); // read ith annotation expression. |
| 267 } |
| 268 builder_.ReadCanonicalNameReference(); // read target_reference. |
| 269 builder_.ReadStringReference(); // read name_index. |
| 270 intptr_t combinator_count = builder_.ReadListLength(); // read list length. |
| 271 for (intptr_t i = 0; i < combinator_count; ++i) { |
| 272 builder_.ReadBool(); // read is_show. |
| 273 intptr_t name_count = builder_.ReadUInt(); // read list length. |
| 274 for (intptr_t j = 0; j < name_count; ++j) { |
| 275 builder_.ReadUInt(); // read ith entry of name_indices. |
| 276 } |
| 277 } |
| 278 } |
| 279 |
| 280 // Skip typedefs. |
| 281 intptr_t typedef_count = builder_.ReadListLength(); // read list length. |
| 282 for (intptr_t i = 0; i < typedef_count; i++) { |
| 283 builder_.SkipCanonicalNameReference(); // read canonical name. |
| 284 builder_.ReadPosition(); // read position. |
| 285 builder_.SkipStringReference(); // read name index. |
| 286 builder_.ReadUInt(); // read source_uri_index. |
| 287 builder_.SkipListOfDartTypes(); // read type parameters. |
| 288 builder_.SkipDartType(); // read type. |
| 289 } |
| 290 |
| 291 const GrowableObjectArray& classes = |
| 292 GrowableObjectArray::Handle(Z, I->object_store()->pending_classes()); |
| 293 |
| 294 // Load all classes. |
| 295 int class_count = builder_.ReadListLength(); // read list length. |
| 296 for (intptr_t i = 0; i < class_count; ++i) { |
| 297 classes.Add(ReadClass(library, toplevel_class), Heap::kOld); |
| 298 } |
| 299 |
| 227 fields_.Clear(); | 300 fields_.Clear(); |
| 228 functions_.Clear(); | 301 functions_.Clear(); |
| 229 ActiveClassScope active_class_scope(&active_class_, NULL, &toplevel_class); | 302 ActiveClassScope active_class_scope(&active_class_, 0, -1, &toplevel_class); |
| 230 // Load toplevel fields. | 303 // Load toplevel fields. |
| 231 for (intptr_t i = 0; i < kernel_library->fields().length(); i++) { | 304 intptr_t field_count = builder_.ReadListLength(); // read list length. |
| 232 Field* kernel_field = kernel_library->fields()[i]; | 305 for (intptr_t i = 0; i < field_count; ++i) { |
| 233 | 306 intptr_t field_offset = builder_.ReaderOffset(); |
| 234 ActiveMemberScope active_member_scope(&active_class_, kernel_field); | 307 ActiveMemberScope active_member_scope(&active_class_, false, false, 0, -1); |
| 235 const dart::String& name = H.DartFieldName(kernel_field->name()); | 308 FieldHelper field_helper(&builder_); |
| 309 field_helper.ReadUntilExcluding(FieldHelper::kName); |
| 310 |
| 311 const dart::String& name = builder_.ReadNameAsFieldName(); |
| 312 field_helper.SetJustRead(FieldHelper::kName); |
| 313 field_helper.ReadUntilExcluding(FieldHelper::kType); |
| 236 const Object& script_class = | 314 const Object& script_class = |
| 237 ClassForScriptAt(toplevel_class, kernel_field->source_uri_index()); | 315 ClassForScriptAt(toplevel_class, field_helper.source_uri_index_); |
| 238 dart::Field& field = dart::Field::Handle( | 316 dart::Field& field = dart::Field::Handle( |
| 239 Z, dart::Field::NewTopLevel(name, kernel_field->IsFinal(), | 317 Z, dart::Field::NewTopLevel(name, field_helper.IsFinal(), |
| 240 kernel_field->IsConst(), script_class, | 318 field_helper.IsConst(), script_class, |
| 241 kernel_field->position())); | 319 field_helper.position_)); |
| 242 field.set_kernel_offset(kernel_field->kernel_offset()); | 320 field.set_kernel_offset(field_offset); |
| 243 const AbstractType& type = T.TranslateType(kernel_field->type()); | 321 const AbstractType& type = T.BuildType(); // read type. |
| 244 field.SetFieldType(type); | 322 field.SetFieldType(type); |
| 245 field.set_has_initializer(kernel_field->initializer() != NULL); | 323 field_helper.SetJustRead(FieldHelper::kType); |
| 246 GenerateFieldAccessors(toplevel_class, field, kernel_field); | 324 field_helper.ReadUntilExcluding(FieldHelper::kInitializer); |
| 325 field.set_has_initializer(builder_.PeekTag() == kSomething); |
| 326 GenerateFieldAccessors(toplevel_class, field, &field_helper, field_offset); |
| 327 field_helper.ReadUntilExcluding(FieldHelper::kEnd); |
| 247 fields_.Add(&field); | 328 fields_.Add(&field); |
| 248 library.AddObject(field, name); | 329 library.AddObject(field, name); |
| 249 } | 330 } |
| 250 toplevel_class.AddFields(fields_); | 331 toplevel_class.AddFields(fields_); |
| 251 | 332 |
| 252 // Load toplevel procedures. | 333 // Load toplevel procedures. |
| 253 for (intptr_t i = 0; i < kernel_library->procedures().length(); i++) { | 334 intptr_t procedure_count = builder_.ReadListLength(); // read list length. |
| 254 Procedure* kernel_procedure = kernel_library->procedures()[i]; | 335 for (intptr_t i = 0; i < procedure_count; ++i) { |
| 255 ReadProcedure(library, toplevel_class, kernel_procedure); | 336 ReadProcedure(library, toplevel_class, false); |
| 256 } | 337 } |
| 257 | 338 |
| 258 toplevel_class.SetFunctions(Array::Handle(MakeFunctionsArray())); | 339 toplevel_class.SetFunctions(Array::Handle(MakeFunctionsArray())); |
| 259 | 340 |
| 260 const GrowableObjectArray& classes = | |
| 261 GrowableObjectArray::Handle(Z, I->object_store()->pending_classes()); | |
| 262 | |
| 263 // Load all classes. | |
| 264 for (intptr_t i = 0; i < kernel_library->classes().length(); i++) { | |
| 265 Class* kernel_klass = kernel_library->classes()[i]; | |
| 266 classes.Add(ReadClass(library, toplevel_class, kernel_klass), Heap::kOld); | |
| 267 } | |
| 268 | |
| 269 classes.Add(toplevel_class, Heap::kOld); | 341 classes.Add(toplevel_class, Heap::kOld); |
| 270 } | 342 } |
| 271 | 343 |
| 272 | 344 |
| 273 void KernelReader::ReadPreliminaryClass(dart::Class* klass, | 345 void KernelReader::ReadPreliminaryClass(dart::Class* klass, |
| 274 Class* kernel_klass) { | 346 ClassHelper* class_helper, |
| 275 ASSERT(kernel_klass->IsNormalClass()); | 347 intptr_t type_parameter_count) { |
| 276 NormalClass* kernel_normal_class = NormalClass::Cast(kernel_klass); | 348 // Note: This assumes that ClassHelper is exactly at the position where |
| 277 | 349 // the length of the type parameters have been read, and that the order in |
| 278 ActiveClassScope active_class_scope(&active_class_, kernel_klass, klass); | 350 // the binary is as follows: [...], kTypeParameters, kSuperClass, kMixinType, |
| 351 // kImplementedClasses, [...]. |
| 279 | 352 |
| 280 // First setup the type parameters, so if any of the following code uses it | 353 // First setup the type parameters, so if any of the following code uses it |
| 281 // (in a recursive way) we're fine. | 354 // (in a recursive way) we're fine. |
| 282 TypeArguments& type_parameters = | 355 TypeArguments& type_parameters = |
| 283 TypeArguments::Handle(Z, TypeArguments::null()); | 356 TypeArguments::Handle(Z, TypeArguments::null()); |
| 284 intptr_t num_type_parameters = kernel_klass->type_parameters().length(); | 357 if (type_parameter_count > 0) { |
| 285 if (num_type_parameters > 0) { | |
| 286 dart::TypeParameter& parameter = dart::TypeParameter::Handle(Z); | 358 dart::TypeParameter& parameter = dart::TypeParameter::Handle(Z); |
| 287 Type& null_bound = Type::Handle(Z, Type::null()); | 359 Type& null_bound = Type::Handle(Z, Type::null()); |
| 288 | 360 |
| 289 // Step a) Create array of [TypeParameter] objects (without bound). | 361 // Step a) Create array of [TypeParameter] objects (without bound). |
| 290 type_parameters = TypeArguments::New(num_type_parameters); | 362 type_parameters = TypeArguments::New(type_parameter_count); |
| 291 for (intptr_t i = 0; i < num_type_parameters; i++) { | 363 { |
| 292 parameter = dart::TypeParameter::New( | 364 AlternativeReadingScope alt(builder_.reader_); |
| 293 *klass, Function::Handle(Z), i, | 365 for (intptr_t i = 0; i < type_parameter_count; i++) { |
| 294 H.DartSymbol(kernel_klass->type_parameters()[i]->name()), null_bound, | 366 parameter = dart::TypeParameter::New( |
| 295 TokenPosition::kNoSource); | 367 *klass, Function::Handle(Z), i, |
| 296 type_parameters.SetTypeAt(i, parameter); | 368 H.DartSymbol( |
| 369 builder_.ReadStringReference()), // read ith name index. |
| 370 null_bound, TokenPosition::kNoSource); |
| 371 type_parameters.SetTypeAt(i, parameter); |
| 372 builder_.SkipDartType(); // read guard. |
| 373 } |
| 297 } | 374 } |
| 298 klass->set_type_parameters(type_parameters); | 375 klass->set_type_parameters(type_parameters); |
| 299 | 376 |
| 300 // Step b) Fill in the bounds of all [TypeParameter]s. | 377 // Step b) Fill in the bounds of all [TypeParameter]s. |
| 301 for (intptr_t i = 0; i < num_type_parameters; i++) { | 378 for (intptr_t i = 0; i < type_parameter_count; i++) { |
| 302 TypeParameter* kernel_parameter = kernel_klass->type_parameters()[i]; | 379 builder_.SkipStringReference(); // read ith name index. |
| 380 |
| 303 // TODO(github.com/dart-lang/kernel/issues/42): This should be handled | 381 // TODO(github.com/dart-lang/kernel/issues/42): This should be handled |
| 304 // by the frontend. | 382 // by the frontend. |
| 305 if (kernel_parameter->bound()->IsDynamicType()) { | 383 parameter ^= type_parameters.TypeAt(i); |
| 306 parameter ^= type_parameters.TypeAt(i); | 384 Tag tag = builder_.PeekTag(); // peek ith bound type. |
| 385 if (tag == kDynamicType) { |
| 386 builder_.SkipDartType(); // read ith bound. |
| 307 parameter.set_bound(Type::Handle(Z, I->object_store()->object_type())); | 387 parameter.set_bound(Type::Handle(Z, I->object_store()->object_type())); |
| 308 } else { | 388 } else { |
| 309 AbstractType& bound = | 389 AbstractType& bound = |
| 310 T.TranslateTypeWithoutFinalization(kernel_parameter->bound()); | 390 T.BuildTypeWithoutFinalization(); // read ith bound. |
| 311 if (bound.IsMalformedOrMalbounded()) { | 391 if (bound.IsMalformedOrMalbounded()) { |
| 312 bound = I->object_store()->object_type(); | 392 bound = I->object_store()->object_type(); |
| 313 } | 393 } |
| 314 | |
| 315 parameter ^= type_parameters.TypeAt(i); | |
| 316 parameter.set_bound(bound); | 394 parameter.set_bound(bound); |
| 317 } | 395 } |
| 318 } | 396 } |
| 319 } | 397 } |
| 320 | 398 |
| 321 // Set super type. Some classes (e.g., Object) do not have one. | 399 // Set super type. Some classes (e.g., Object) do not have one. |
| 322 if (kernel_normal_class->super_class() != NULL) { | 400 Tag type_tag = builder_.ReadTag(); // read super class type (part 1). |
| 401 if (type_tag == kSomething) { |
| 323 AbstractType& super_type = | 402 AbstractType& super_type = |
| 324 T.TranslateTypeWithoutFinalization(kernel_normal_class->super_class()); | 403 T.BuildTypeWithoutFinalization(); // read super class type (part 2). |
| 325 if (super_type.IsMalformed()) H.ReportError("Malformed super type"); | 404 if (super_type.IsMalformed()) H.ReportError("Malformed super type"); |
| 326 klass->set_super_type(super_type); | 405 klass->set_super_type(super_type); |
| 327 } | 406 } |
| 328 | 407 |
| 408 class_helper->SetJustRead(ClassHelper::kSuperClass); |
| 409 class_helper->ReadUntilIncluding(ClassHelper::kMixinType); |
| 410 |
| 329 // Build implemented interface types | 411 // Build implemented interface types |
| 330 intptr_t interface_count = kernel_klass->implemented_classes().length(); | 412 intptr_t interface_count = builder_.ReadListLength(); |
| 331 const dart::Array& interfaces = | 413 const dart::Array& interfaces = |
| 332 dart::Array::Handle(Z, dart::Array::New(interface_count, Heap::kOld)); | 414 dart::Array::Handle(Z, dart::Array::New(interface_count, Heap::kOld)); |
| 333 for (intptr_t i = 0; i < interface_count; i++) { | 415 for (intptr_t i = 0; i < interface_count; i++) { |
| 334 InterfaceType* kernel_interface_type = | |
| 335 kernel_klass->implemented_classes()[i]; | |
| 336 const AbstractType& type = | 416 const AbstractType& type = |
| 337 T.TranslateTypeWithoutFinalization(kernel_interface_type); | 417 T.BuildTypeWithoutFinalization(); // read ith type. |
| 338 if (type.IsMalformed()) H.ReportError("Malformed interface type."); | 418 if (type.IsMalformed()) H.ReportError("Malformed interface type."); |
| 339 interfaces.SetAt(i, type); | 419 interfaces.SetAt(i, type); |
| 340 } | 420 } |
| 421 class_helper->SetJustRead(ClassHelper::kImplementedClasses); |
| 341 klass->set_interfaces(interfaces); | 422 klass->set_interfaces(interfaces); |
| 342 if (kernel_klass->is_abstract()) klass->set_is_abstract(); | 423 |
| 424 if (class_helper->is_abstract_) klass->set_is_abstract(); |
| 343 } | 425 } |
| 344 | 426 |
| 345 | 427 |
| 346 dart::Class& KernelReader::ReadClass(const dart::Library& library, | 428 dart::Class& KernelReader::ReadClass(const dart::Library& library, |
| 347 const dart::Class& toplevel_class, | 429 const dart::Class& toplevel_class) { |
| 348 Class* kernel_klass) { | 430 ClassHelper class_helper(&builder_); |
| 349 dart::Class& klass = LookupClass(kernel_klass->canonical_name()); | 431 intptr_t class_offset = builder_.ReaderOffset(); |
| 432 class_helper.ReadUntilIncluding(ClassHelper::kCanonicalName); |
| 433 dart::Class& klass = LookupClass(class_helper.canonical_name_); |
| 350 | 434 |
| 351 // The class needs to have a script because all the functions in the class | 435 // The class needs to have a script because all the functions in the class |
| 352 // will inherit it. The predicate Function::IsOptimizable uses the absence of | 436 // will inherit it. The predicate Function::IsOptimizable uses the absence of |
| 353 // a script to detect test functions that should not be optimized. | 437 // a script to detect test functions that should not be optimized. |
| 354 if (klass.script() == Script::null()) { | 438 if (klass.script() == Script::null()) { |
| 355 klass.set_script(ScriptAt(kernel_klass->source_uri_index())); | 439 class_helper.ReadUntilIncluding(ClassHelper::kSourceUriIndex); |
| 440 klass.set_script(ScriptAt(class_helper.source_uri_index_)); |
| 356 } | 441 } |
| 357 if (klass.token_pos() == TokenPosition::kNoSource) { | 442 if (klass.token_pos() == TokenPosition::kNoSource) { |
| 358 klass.set_token_pos(kernel_klass->position()); | 443 class_helper.ReadUntilIncluding(ClassHelper::kPosition); |
| 359 } | 444 klass.set_token_pos(class_helper.position_); |
| 445 } |
| 446 |
| 447 class_helper.ReadUntilExcluding(ClassHelper::kTypeParameters); |
| 448 intptr_t type_paremeter_counts = |
| 449 builder_.ReadListLength(); // read type_parameters list length. |
| 450 intptr_t type_paremeter_offset = builder_.ReaderOffset(); |
| 451 |
| 452 ActiveClassScope active_class_scope(&active_class_, type_paremeter_counts, |
| 453 type_paremeter_offset, &klass); |
| 360 if (!klass.is_cycle_free()) { | 454 if (!klass.is_cycle_free()) { |
| 361 ReadPreliminaryClass(&klass, kernel_klass); | 455 ReadPreliminaryClass(&klass, &class_helper, type_paremeter_counts); |
| 362 } | 456 } else { |
| 363 | 457 for (intptr_t i = 0; i < type_paremeter_counts; ++i) { |
| 364 ActiveClassScope active_class_scope(&active_class_, kernel_klass, &klass); | 458 builder_.SkipStringReference(); // read ith name index. |
| 459 builder_.SkipDartType(); // read ith bound. |
| 460 } |
| 461 class_helper.SetJustRead(ClassHelper::kTypeParameters); |
| 462 } |
| 463 |
| 365 fields_.Clear(); | 464 fields_.Clear(); |
| 366 functions_.Clear(); | 465 functions_.Clear(); |
| 367 | 466 |
| 368 if (library.raw() == dart::Library::InternalLibrary() && | 467 if (library.raw() == dart::Library::InternalLibrary() && |
| 369 klass.Name() == Symbols::ClassID().raw()) { | 468 klass.Name() == Symbols::ClassID().raw()) { |
| 370 // If this is a dart:internal.ClassID class ignore field declarations | 469 // If this is a dart:internal.ClassID class ignore field declarations |
| 371 // contained in the Kernel file and instead inject our own const | 470 // contained in the Kernel file and instead inject our own const |
| 372 // fields. | 471 // fields. |
| 373 klass.InjectCIDFields(); | 472 klass.InjectCIDFields(); |
| 374 } else { | 473 } else { |
| 375 for (intptr_t i = 0; i < kernel_klass->fields().length(); i++) { | 474 class_helper.ReadUntilExcluding(ClassHelper::kFields); |
| 376 Field* kernel_field = kernel_klass->fields()[i]; | 475 int field_count = builder_.ReadListLength(); // read list length. |
| 377 ActiveMemberScope active_member_scope(&active_class_, kernel_field); | 476 for (intptr_t i = 0; i < field_count; ++i) { |
| 477 intptr_t field_offset = builder_.ReaderOffset(); |
| 478 ActiveMemberScope active_member(&active_class_, false, false, 0, -1); |
| 479 FieldHelper field_helper(&builder_); |
| 480 field_helper.ReadUntilExcluding(FieldHelper::kName); |
| 378 | 481 |
| 379 const dart::String& name = H.DartFieldName(kernel_field->name()); | 482 const dart::String& name = builder_.ReadNameAsFieldName(); |
| 483 field_helper.SetJustRead(FieldHelper::kName); |
| 484 field_helper.ReadUntilExcluding(FieldHelper::kType); |
| 380 const AbstractType& type = | 485 const AbstractType& type = |
| 381 T.TranslateTypeWithoutFinalization(kernel_field->type()); | 486 T.BuildTypeWithoutFinalization(); // read type. |
| 487 field_helper.SetJustRead(FieldHelper::kType); |
| 382 const Object& script_class = | 488 const Object& script_class = |
| 383 ClassForScriptAt(klass, kernel_field->source_uri_index()); | 489 ClassForScriptAt(klass, field_helper.source_uri_index_); |
| 384 dart::Field& field = dart::Field::Handle( | 490 dart::Field& field = dart::Field::Handle( |
| 385 Z, | 491 Z, |
| 386 dart::Field::New(name, kernel_field->IsStatic(), | 492 dart::Field::New(name, field_helper.IsStatic(), |
| 387 // In the VM all const fields are implicitly final | 493 // In the VM all const fields are implicitly final |
| 388 // whereas in Kernel they are not final because they | 494 // whereas in Kernel they are not final because they |
| 389 // are not explicitly declared that way. | 495 // are not explicitly declared that way. |
| 390 kernel_field->IsFinal() || kernel_field->IsConst(), | 496 field_helper.IsFinal() || field_helper.IsConst(), |
| 391 kernel_field->IsConst(), | 497 field_helper.IsConst(), |
| 392 false, // is_reflectable | 498 false, // is_reflectable |
| 393 script_class, type, kernel_field->position())); | 499 script_class, type, field_helper.position_)); |
| 394 field.set_kernel_offset(kernel_field->kernel_offset()); | 500 field.set_kernel_offset(field_offset); |
| 395 field.set_has_initializer(kernel_field->initializer() != NULL); | 501 field_helper.ReadUntilExcluding(FieldHelper::kInitializer); |
| 396 GenerateFieldAccessors(klass, field, kernel_field); | 502 field.set_has_initializer(builder_.PeekTag() == kSomething); |
| 503 GenerateFieldAccessors(klass, field, &field_helper, field_offset); |
| 504 field_helper.ReadUntilExcluding(FieldHelper::kEnd); |
| 397 fields_.Add(&field); | 505 fields_.Add(&field); |
| 398 } | 506 } |
| 399 klass.AddFields(fields_); | 507 klass.AddFields(fields_); |
| 508 class_helper.SetJustRead(ClassHelper::kFields); |
| 400 } | 509 } |
| 401 | 510 |
| 402 for (intptr_t i = 0; i < kernel_klass->constructors().length(); i++) { | 511 class_helper.ReadUntilExcluding(ClassHelper::kConstructors); |
| 403 Constructor* kernel_constructor = kernel_klass->constructors()[i]; | 512 int constructor_count = builder_.ReadListLength(); // read list length. |
| 404 ActiveMemberScope active_member_scope(&active_class_, kernel_constructor); | 513 for (intptr_t i = 0; i < constructor_count; ++i) { |
| 514 intptr_t constructor_offset = builder_.ReaderOffset(); |
| 515 ActiveMemberScope active_member_scope(&active_class_, false, false, 0, -1); |
| 516 ConstructorHelper constructor_helper(&builder_); |
| 517 constructor_helper.ReadUntilExcluding(ConstructorHelper::kFunction); |
| 405 | 518 |
| 406 const dart::String& name = | 519 const dart::String& name = |
| 407 H.DartConstructorName(kernel_constructor->canonical_name()); | 520 H.DartConstructorName(constructor_helper.canonical_name_); |
| 408 Function& function = dart::Function::ZoneHandle( | 521 Function& function = dart::Function::ZoneHandle( |
| 409 Z, dart::Function::New(name, RawFunction::kConstructor, | 522 Z, dart::Function::New(name, RawFunction::kConstructor, |
| 410 false, // is_static | 523 false, // is_static |
| 411 kernel_constructor->IsConst(), | 524 constructor_helper.IsConst(), |
| 412 false, // is_abstract | 525 false, // is_abstract |
| 413 kernel_constructor->IsExternal(), | 526 constructor_helper.IsExternal(), |
| 414 false, // is_native | 527 false, // is_native |
| 415 klass, kernel_constructor->position())); | 528 klass, constructor_helper.position_)); |
| 416 function.set_end_token_pos(kernel_constructor->end_position()); | 529 function.set_end_token_pos(constructor_helper.end_position_); |
| 417 functions_.Add(&function); | 530 functions_.Add(&function); |
| 418 function.set_kernel_offset(kernel_constructor->kernel_offset()); | 531 function.set_kernel_offset(constructor_offset); |
| 419 function.set_result_type(T.ReceiverType(klass)); | 532 function.set_result_type(T.ReceiverType(klass)); |
| 420 SetupFunctionParameters(H, T, klass, function, | 533 |
| 421 kernel_constructor->function(), | 534 FunctionNodeHelper function_node_helper(&builder_); |
| 422 true, // is_method | 535 function_node_helper.ReadUntilExcluding( |
| 423 false); // is_closure | 536 FunctionNodeHelper::kRequiredParameterCount); |
| 537 builder_.SetupFunctionParameters(klass, function, |
| 538 true, // is_method |
| 539 false, // is_closure |
| 540 &function_node_helper); |
| 541 function_node_helper.ReadUntilExcluding(FunctionNodeHelper::kEnd); |
| 542 constructor_helper.SetJustRead(ConstructorHelper::kFunction); |
| 543 constructor_helper.ReadUntilExcluding(ConstructorHelper::kEnd); |
| 424 | 544 |
| 425 if (FLAG_enable_mirrors) { | 545 if (FLAG_enable_mirrors) { |
| 426 library.AddFunctionMetadata(function, TokenPosition::kNoSource, | 546 library.AddFunctionMetadata(function, TokenPosition::kNoSource, |
| 427 kernel_constructor->kernel_offset()); | 547 constructor_offset); |
| 428 } | 548 } |
| 429 } | 549 } |
| 550 class_helper.SetJustRead(ClassHelper::kConstructors); |
| 430 | 551 |
| 431 for (intptr_t i = 0; i < kernel_klass->procedures().length(); i++) { | 552 class_helper.ReadUntilExcluding(ClassHelper::kProcedures); |
| 432 Procedure* kernel_procedure = kernel_klass->procedures()[i]; | 553 int procedure_count = builder_.ReadListLength(); // read list length. |
| 433 ActiveMemberScope active_member_scope(&active_class_, kernel_procedure); | 554 for (intptr_t i = 0; i < procedure_count; ++i) { |
| 434 ReadProcedure(library, klass, kernel_procedure, kernel_klass); | 555 ReadProcedure(library, klass, true); |
| 435 } | 556 } |
| 557 class_helper.SetJustRead(ClassHelper::kProcedures); |
| 436 | 558 |
| 437 klass.SetFunctions(Array::Handle(MakeFunctionsArray())); | 559 klass.SetFunctions(Array::Handle(MakeFunctionsArray())); |
| 438 | 560 |
| 439 if (!klass.is_marked_for_parsing()) { | 561 if (!klass.is_marked_for_parsing()) { |
| 440 klass.set_is_marked_for_parsing(); | 562 klass.set_is_marked_for_parsing(); |
| 441 } | 563 } |
| 442 | 564 |
| 443 if (FLAG_enable_mirrors) { | 565 if (FLAG_enable_mirrors) { |
| 444 library.AddClassMetadata(klass, toplevel_class, TokenPosition::kNoSource, | 566 library.AddClassMetadata(klass, toplevel_class, TokenPosition::kNoSource, |
| 445 kernel_klass->kernel_offset()); | 567 class_offset); |
| 446 } | 568 } |
| 447 | 569 |
| 570 class_helper.ReadUntilExcluding(ClassHelper::kEnd); |
| 571 |
| 448 return klass; | 572 return klass; |
| 449 } | 573 } |
| 450 | 574 |
| 451 | 575 |
| 452 void KernelReader::ReadProcedure(const dart::Library& library, | 576 void KernelReader::ReadProcedure(const dart::Library& library, |
| 453 const dart::Class& owner, | 577 const dart::Class& owner, |
| 454 Procedure* kernel_procedure, | 578 bool in_class) { |
| 455 Class* kernel_klass) { | 579 intptr_t procedure_offset = builder_.ReaderOffset(); |
| 456 ActiveClassScope active_class_scope(&active_class_, kernel_klass, &owner); | 580 ProcedureHelper procedure_helper(&builder_); |
| 457 ActiveMemberScope active_member_scope(&active_class_, kernel_procedure); | |
| 458 | 581 |
| 582 bool member_is_procedure = false; |
| 583 bool is_factory_procedure = false; |
| 584 intptr_t member_type_parameters = 0; |
| 585 intptr_t member_type_parameters_offset_start = -1; |
| 586 builder_.GetTypeParameterInfoForPossibleProcedure( |
| 587 builder_.ReaderOffset(), &member_is_procedure, &is_factory_procedure, |
| 588 &member_type_parameters, &member_type_parameters_offset_start); |
| 589 |
| 590 ActiveMemberScope active_member(&active_class_, member_is_procedure, |
| 591 is_factory_procedure, member_type_parameters, |
| 592 member_type_parameters_offset_start); |
| 593 |
| 594 procedure_helper.ReadUntilExcluding(ProcedureHelper::kAnnotations); |
| 459 const dart::String& name = | 595 const dart::String& name = |
| 460 H.DartProcedureName(kernel_procedure->canonical_name()); | 596 H.DartProcedureName(procedure_helper.canonical_name_); |
| 461 bool is_method = kernel_klass != NULL && !kernel_procedure->IsStatic(); | 597 bool is_method = in_class && !procedure_helper.IsStatic(); |
| 462 bool is_abstract = kernel_procedure->IsAbstract(); | 598 bool is_abstract = procedure_helper.IsAbstract(); |
| 463 bool is_external = kernel_procedure->IsExternal(); | 599 bool is_external = procedure_helper.IsExternal(); |
| 464 dart::String* native_name = NULL; | 600 dart::String* native_name = NULL; |
| 465 if (is_external) { | 601 if (is_external) { |
| 466 // Maybe it has a native implementation, which is not external as far as | 602 // Maybe it has a native implementation, which is not external as far as |
| 467 // the VM is concerned because it does have an implementation. Check for | 603 // the VM is concerned because it does have an implementation. Check for |
| 468 // an ExternalName annotation and extract the string from it. | 604 // an ExternalName annotation and extract the string from it. |
| 469 for (int i = 0; i < kernel_procedure->annotations().length(); ++i) { | 605 intptr_t annotation_count = builder_.ReadListLength(); // read list length. |
| 470 Expression* annotation = kernel_procedure->annotations()[i]; | 606 for (int i = 0; i < annotation_count; ++i) { |
| 471 if (!annotation->IsConstructorInvocation()) continue; | 607 if (builder_.PeekTag() != kConstructorInvocation && |
| 472 ConstructorInvocation* invocation = | 608 builder_.PeekTag() != kConstConstructorInvocation) { |
| 473 ConstructorInvocation::Cast(annotation); | 609 builder_.SkipExpression(); |
| 474 NameIndex annotation_class = H.EnclosingName(invocation->target()); | 610 continue; |
| 611 } |
| 612 builder_.ReadTag(); |
| 613 builder_.ReadPosition(); |
| 614 NameIndex annotation_class = H.EnclosingName( |
| 615 builder_.ReadCanonicalNameReference()); // read target reference, |
| 475 ASSERT(H.IsClass(annotation_class)); | 616 ASSERT(H.IsClass(annotation_class)); |
| 476 StringIndex class_name_index = H.CanonicalNameString(annotation_class); | 617 StringIndex class_name_index = H.CanonicalNameString(annotation_class); |
| 477 // Just compare by name, do not generate the annotation class. | 618 // Just compare by name, do not generate the annotation class. |
| 478 if (!H.StringEquals(class_name_index, "ExternalName")) continue; | 619 if (!H.StringEquals(class_name_index, "ExternalName")) { |
| 620 builder_.SkipArguments(); |
| 621 continue; |
| 622 } |
| 479 ASSERT(H.IsLibrary(H.CanonicalNameParent(annotation_class))); | 623 ASSERT(H.IsLibrary(H.CanonicalNameParent(annotation_class))); |
| 480 StringIndex library_name_index = | 624 StringIndex library_name_index = |
| 481 H.CanonicalNameString(H.CanonicalNameParent(annotation_class)); | 625 H.CanonicalNameString(H.CanonicalNameParent(annotation_class)); |
| 482 if (!H.StringEquals(library_name_index, "dart:_internal")) continue; | 626 if (!H.StringEquals(library_name_index, "dart:_internal")) { |
| 627 builder_.SkipArguments(); |
| 628 continue; |
| 629 } |
| 483 | 630 |
| 484 is_external = false; | 631 is_external = false; |
| 485 ASSERT(invocation->arguments()->positional().length() == 1 && | 632 // Read arguments: |
| 486 invocation->arguments()->named().length() == 0); | 633 intptr_t total_arguments = builder_.ReadUInt(); // read argument count. |
| 487 StringLiteral* literal = | 634 builder_.SkipListOfDartTypes(); // read list of types. |
| 488 StringLiteral::Cast(invocation->arguments()->positional()[0]); | 635 intptr_t positional_arguments = builder_.ReadListLength(); |
| 489 native_name = &H.DartSymbol(literal->value()); | 636 ASSERT(total_arguments == 1 && positional_arguments == 1); |
| 637 |
| 638 Tag tag = builder_.ReadTag(); |
| 639 ASSERT(tag == kStringLiteral); |
| 640 native_name = &H.DartSymbol( |
| 641 builder_.ReadStringReference()); // read index into string table. |
| 642 |
| 643 // List of named. |
| 644 intptr_t list_length = builder_.ReadListLength(); // read list length. |
| 645 ASSERT(list_length == 0); |
| 646 |
| 647 // Skip remaining annotations |
| 648 for (++i; i < annotation_count; ++i) { |
| 649 builder_.SkipExpression(); // read ith annotation. |
| 650 } |
| 651 |
| 490 break; | 652 break; |
| 491 } | 653 } |
| 654 procedure_helper.SetJustRead(ProcedureHelper::kAnnotations); |
| 492 } | 655 } |
| 493 const Object& script_class = | 656 const Object& script_class = |
| 494 ClassForScriptAt(owner, kernel_procedure->source_uri_index()); | 657 ClassForScriptAt(owner, procedure_helper.source_uri_index_); |
| 495 dart::Function& function = dart::Function::ZoneHandle( | 658 dart::Function& function = dart::Function::ZoneHandle( |
| 496 Z, Function::New(name, GetFunctionType(kernel_procedure), | 659 Z, Function::New(name, GetFunctionType(procedure_helper.kind_), |
| 497 !is_method, // is_static | 660 !is_method, // is_static |
| 498 false, // is_const | 661 false, // is_const |
| 499 is_abstract, is_external, | 662 is_abstract, is_external, |
| 500 native_name != NULL, // is_native | 663 native_name != NULL, // is_native |
| 501 script_class, kernel_procedure->position())); | 664 script_class, procedure_helper.position_)); |
| 502 function.set_end_token_pos(kernel_procedure->end_position()); | 665 function.set_end_token_pos(procedure_helper.end_position_); |
| 503 functions_.Add(&function); | 666 functions_.Add(&function); |
| 504 function.set_kernel_offset(kernel_procedure->kernel_offset()); | 667 function.set_kernel_offset(procedure_offset); |
| 505 | 668 |
| 506 function.set_is_debuggable( | 669 procedure_helper.ReadUntilExcluding(ProcedureHelper::kFunction); |
| 507 kernel_procedure->function()->dart_async_marker() == FunctionNode::kSync); | 670 Tag function_node_tag = builder_.ReadTag(); |
| 508 switch (kernel_procedure->function()->dart_async_marker()) { | 671 ASSERT(function_node_tag == kSomething); |
| 672 FunctionNodeHelper function_node_helper(&builder_); |
| 673 function_node_helper.ReadUntilIncluding(FunctionNodeHelper::kDartAsyncMarker); |
| 674 function.set_is_debuggable(function_node_helper.dart_async_marker_ == |
| 675 FunctionNode::kSync); |
| 676 switch (function_node_helper.dart_async_marker_) { |
| 509 case FunctionNode::kSyncStar: | 677 case FunctionNode::kSyncStar: |
| 510 function.set_modifier(RawFunction::kSyncGen); | 678 function.set_modifier(RawFunction::kSyncGen); |
| 511 break; | 679 break; |
| 512 case FunctionNode::kAsync: | 680 case FunctionNode::kAsync: |
| 513 function.set_modifier(RawFunction::kAsync); | 681 function.set_modifier(RawFunction::kAsync); |
| 514 function.set_is_inlinable(!FLAG_causal_async_stacks); | 682 function.set_is_inlinable(!FLAG_causal_async_stacks); |
| 515 break; | 683 break; |
| 516 case FunctionNode::kAsyncStar: | 684 case FunctionNode::kAsyncStar: |
| 517 function.set_modifier(RawFunction::kAsyncGen); | 685 function.set_modifier(RawFunction::kAsyncGen); |
| 518 function.set_is_inlinable(!FLAG_causal_async_stacks); | 686 function.set_is_inlinable(!FLAG_causal_async_stacks); |
| 519 break; | 687 break; |
| 520 default: | 688 default: |
| 521 // no special modifier | 689 // no special modifier |
| 522 break; | 690 break; |
| 523 } | 691 } |
| 524 ASSERT(kernel_procedure->function()->async_marker() == FunctionNode::kSync); | 692 ASSERT(function_node_helper.async_marker_ == FunctionNode::kSync); |
| 525 | 693 |
| 526 if (native_name != NULL) { | 694 if (native_name != NULL) { |
| 527 function.set_native_name(*native_name); | 695 function.set_native_name(*native_name); |
| 528 } | 696 } |
| 529 | 697 |
| 530 SetupFunctionParameters(H, T, owner, function, kernel_procedure->function(), | 698 function_node_helper.ReadUntilExcluding( |
| 531 is_method, | 699 FunctionNodeHelper::kRequiredParameterCount); |
| 532 false); // is_closure | 700 builder_.SetupFunctionParameters(owner, function, is_method, |
| 701 false, // is_closure |
| 702 &function_node_helper); |
| 703 function_node_helper.ReadUntilExcluding(FunctionNodeHelper::kEnd); |
| 704 procedure_helper.SetJustRead(ProcedureHelper::kFunction); |
| 533 | 705 |
| 534 if (kernel_klass == NULL) { | 706 if (!in_class) { |
| 535 library.AddObject(function, name); | 707 library.AddObject(function, name); |
| 536 ASSERT(!Object::Handle( | 708 ASSERT(!Object::Handle( |
| 537 Z, library.LookupObjectAllowPrivate( | 709 Z, library.LookupObjectAllowPrivate( |
| 538 H.DartProcedureName(kernel_procedure->canonical_name()))) | 710 H.DartProcedureName(procedure_helper.canonical_name_))) |
| 539 .IsNull()); | 711 .IsNull()); |
| 540 } | 712 } |
| 541 if (FLAG_enable_mirrors) { | 713 if (FLAG_enable_mirrors) { |
| 542 library.AddFunctionMetadata(function, TokenPosition::kNoSource, | 714 library.AddFunctionMetadata(function, TokenPosition::kNoSource, |
| 543 kernel_procedure->kernel_offset()); | 715 procedure_offset); |
| 544 } | 716 } |
| 717 |
| 718 procedure_helper.ReadUntilExcluding(ProcedureHelper::kEnd); |
| 545 } | 719 } |
| 546 | 720 |
| 547 const Object& KernelReader::ClassForScriptAt(const dart::Class& klass, | 721 const Object& KernelReader::ClassForScriptAt(const dart::Class& klass, |
| 548 intptr_t source_uri_index) { | 722 intptr_t source_uri_index) { |
| 549 Script& correct_script = ScriptAt(source_uri_index); | 723 Script& correct_script = ScriptAt(source_uri_index); |
| 550 if (klass.script() != correct_script.raw()) { | 724 if (klass.script() != correct_script.raw()) { |
| 551 // TODO(jensj): We could probably cache this so we don't create | 725 // TODO(jensj): We could probably cache this so we don't create |
| 552 // new PatchClasses all the time | 726 // new PatchClasses all the time |
| 553 return PatchClass::ZoneHandle(Z, PatchClass::New(klass, correct_script)); | 727 return PatchClass::ZoneHandle(Z, PatchClass::New(klass, correct_script)); |
| 554 } | 728 } |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 636 // Create yield_positions array for the script. | 810 // Create yield_positions array for the script. |
| 637 array_object = | 811 array_object = |
| 638 AsSortedDuplicateFreeArray(index, &program_->yield_token_positions); | 812 AsSortedDuplicateFreeArray(index, &program_->yield_token_positions); |
| 639 script.set_yield_positions(array_object); | 813 script.set_yield_positions(array_object); |
| 640 } | 814 } |
| 641 return script; | 815 return script; |
| 642 } | 816 } |
| 643 | 817 |
| 644 void KernelReader::GenerateFieldAccessors(const dart::Class& klass, | 818 void KernelReader::GenerateFieldAccessors(const dart::Class& klass, |
| 645 const dart::Field& field, | 819 const dart::Field& field, |
| 646 Field* kernel_field) { | 820 FieldHelper* field_helper, |
| 647 if (kernel_field->IsStatic() && kernel_field->initializer() == NULL) { | 821 intptr_t field_offset) { |
| 822 Tag tag = builder_.PeekTag(); |
| 823 if (field_helper->IsStatic() && tag == kNothing) { |
| 648 // Static fields without an initializer are implicitly initialized to null. | 824 // Static fields without an initializer are implicitly initialized to null. |
| 649 // We do not need a getter. | 825 // We do not need a getter. |
| 650 field.SetStaticValue(Instance::Handle(Z), true); | 826 field.SetStaticValue(Instance::Handle(Z), true); |
| 651 return; | 827 return; |
| 652 } | 828 } |
| 653 if (kernel_field->initializer() != NULL) { | 829 if (tag == kSomething) { |
| 654 SimpleExpressionConverter converter(&H); | 830 SimpleExpressionConverter converter(&H, &builder_); |
| 655 const bool has_simple_initializer = | 831 const bool has_simple_initializer = |
| 656 converter.IsSimple(kernel_field->initializer()); | 832 converter.IsSimple(builder_.ReaderOffset() + 1); // ignore the tag. |
| 657 if (kernel_field->IsStatic()) { | 833 if (field_helper->IsStatic()) { |
| 658 // Static fields with initializers either have the static value set to the | 834 // Static fields with initializers either have the static value set to the |
| 659 // initializer value if it is simple enough or else set to an | 835 // initializer value if it is simple enough or else set to an |
| 660 // uninitialized sentinel. | 836 // uninitialized sentinel. |
| 661 if (has_simple_initializer) { | 837 if (has_simple_initializer) { |
| 662 // We do not need a getter. | 838 // We do not need a getter. |
| 663 field.SetStaticValue(converter.SimpleValue(), true); | 839 field.SetStaticValue(converter.SimpleValue(), true); |
| 664 return; | 840 return; |
| 665 } | 841 } |
| 666 // We do need a getter that evaluates the initializer if necessary. | 842 // We do need a getter that evaluates the initializer if necessary. |
| 667 field.SetStaticValue(Object::sentinel(), true); | 843 field.SetStaticValue(Object::sentinel(), true); |
| 668 } else if (has_simple_initializer) { | 844 } else if (has_simple_initializer) { |
| 669 // Note: optimizer relies on DoubleInitialized bit in its field-unboxing | 845 // Note: optimizer relies on DoubleInitialized bit in its field-unboxing |
| 670 // heuristics. See JitOptimizer::VisitStoreInstanceField for more details. | 846 // heuristics. See JitOptimizer::VisitStoreInstanceField for more details. |
| 671 field.RecordStore(converter.SimpleValue()); | 847 field.RecordStore(converter.SimpleValue()); |
| 672 if (!converter.SimpleValue().IsNull() && | 848 if (!converter.SimpleValue().IsNull() && |
| 673 converter.SimpleValue().IsDouble()) { | 849 converter.SimpleValue().IsDouble()) { |
| 674 field.set_is_double_initialized(true); | 850 field.set_is_double_initialized(true); |
| 675 } | 851 } |
| 676 } | 852 } |
| 677 } | 853 } |
| 678 | 854 |
| 679 const dart::String& getter_name = | 855 const dart::String& getter_name = |
| 680 H.DartGetterName(kernel_field->canonical_name()); | 856 H.DartGetterName(field_helper->canonical_name_); |
| 681 const Object& script_class = | 857 const Object& script_class = |
| 682 ClassForScriptAt(klass, kernel_field->source_uri_index()); | 858 ClassForScriptAt(klass, field_helper->source_uri_index_); |
| 683 Function& getter = Function::ZoneHandle( | 859 Function& getter = Function::ZoneHandle( |
| 684 Z, | 860 Z, |
| 685 Function::New( | 861 Function::New( |
| 686 getter_name, | 862 getter_name, |
| 687 kernel_field->IsStatic() ? RawFunction::kImplicitStaticFinalGetter | 863 field_helper->IsStatic() ? RawFunction::kImplicitStaticFinalGetter |
| 688 : RawFunction::kImplicitGetter, | 864 : RawFunction::kImplicitGetter, |
| 689 kernel_field->IsStatic(), | 865 field_helper->IsStatic(), |
| 690 // The functions created by the parser have is_const for static fields | 866 // The functions created by the parser have is_const for static fields |
| 691 // that are const (not just final) and they have is_const for | 867 // that are const (not just final) and they have is_const for |
| 692 // non-static | 868 // non-static |
| 693 // fields that are final. | 869 // fields that are final. |
| 694 kernel_field->IsStatic() ? kernel_field->IsConst() | 870 field_helper->IsStatic() ? field_helper->IsConst() |
| 695 : kernel_field->IsFinal(), | 871 : field_helper->IsFinal(), |
| 696 false, // is_abstract | 872 false, // is_abstract |
| 697 false, // is_external | 873 false, // is_external |
| 698 false, // is_native | 874 false, // is_native |
| 699 script_class, kernel_field->position())); | 875 script_class, field_helper->position_)); |
| 700 functions_.Add(&getter); | 876 functions_.Add(&getter); |
| 701 getter.set_end_token_pos(kernel_field->end_position()); | 877 getter.set_end_token_pos(field_helper->end_position_); |
| 702 getter.set_kernel_offset(kernel_field->kernel_offset()); | 878 getter.set_kernel_offset(field_offset); |
| 703 getter.set_result_type(AbstractType::Handle(Z, field.type())); | 879 getter.set_result_type(AbstractType::Handle(Z, field.type())); |
| 704 getter.set_is_debuggable(false); | 880 getter.set_is_debuggable(false); |
| 705 SetupFieldAccessorFunction(klass, getter); | 881 SetupFieldAccessorFunction(klass, getter); |
| 706 | 882 |
| 707 if (!kernel_field->IsStatic() && !kernel_field->IsFinal()) { | 883 if (!field_helper->IsStatic() && !field_helper->IsFinal()) { |
| 708 // Only static fields can be const. | 884 // Only static fields can be const. |
| 709 ASSERT(!kernel_field->IsConst()); | 885 ASSERT(!field_helper->IsConst()); |
| 710 const dart::String& setter_name = | 886 const dart::String& setter_name = |
| 711 H.DartSetterName(kernel_field->canonical_name()); | 887 H.DartSetterName(field_helper->canonical_name_); |
| 712 Function& setter = Function::ZoneHandle( | 888 Function& setter = Function::ZoneHandle( |
| 713 Z, Function::New(setter_name, RawFunction::kImplicitSetter, | 889 Z, Function::New(setter_name, RawFunction::kImplicitSetter, |
| 714 false, // is_static | 890 false, // is_static |
| 715 false, // is_const | 891 false, // is_const |
| 716 false, // is_abstract | 892 false, // is_abstract |
| 717 false, // is_external | 893 false, // is_external |
| 718 false, // is_native | 894 false, // is_native |
| 719 script_class, kernel_field->position())); | 895 script_class, field_helper->position_)); |
| 720 functions_.Add(&setter); | 896 functions_.Add(&setter); |
| 721 setter.set_end_token_pos(kernel_field->end_position()); | 897 setter.set_end_token_pos(field_helper->end_position_); |
| 722 setter.set_kernel_offset(kernel_field->kernel_offset()); | 898 setter.set_kernel_offset(field_offset); |
| 723 setter.set_result_type(Object::void_type()); | 899 setter.set_result_type(Object::void_type()); |
| 724 setter.set_is_debuggable(false); | 900 setter.set_is_debuggable(false); |
| 725 SetupFieldAccessorFunction(klass, setter); | 901 SetupFieldAccessorFunction(klass, setter); |
| 726 } | 902 } |
| 727 } | 903 } |
| 728 | 904 |
| 729 | 905 |
| 730 void KernelReader::SetupFunctionParameters(TranslationHelper translation_helper, | |
| 731 DartTypeTranslator type_translator, | |
| 732 const dart::Class& klass, | |
| 733 const dart::Function& function, | |
| 734 FunctionNode* node, | |
| 735 bool is_method, | |
| 736 bool is_closure) { | |
| 737 dart::Zone* zone = translation_helper.zone(); | |
| 738 | |
| 739 ASSERT(!(is_method && is_closure)); | |
| 740 bool is_factory = function.IsFactory(); | |
| 741 intptr_t extra_parameters = (is_method || is_closure || is_factory) ? 1 : 0; | |
| 742 | |
| 743 function.set_num_fixed_parameters(extra_parameters + | |
| 744 node->required_parameter_count()); | |
| 745 if (node->named_parameters().length() > 0) { | |
| 746 function.SetNumOptionalParameters(node->named_parameters().length(), false); | |
| 747 } else { | |
| 748 function.SetNumOptionalParameters(node->positional_parameters().length() - | |
| 749 node->required_parameter_count(), | |
| 750 true); | |
| 751 } | |
| 752 intptr_t num_parameters = extra_parameters + | |
| 753 node->positional_parameters().length() + | |
| 754 node->named_parameters().length(); | |
| 755 function.set_parameter_types( | |
| 756 Array::Handle(zone, Array::New(num_parameters, Heap::kOld))); | |
| 757 function.set_parameter_names( | |
| 758 Array::Handle(zone, Array::New(num_parameters, Heap::kOld))); | |
| 759 intptr_t pos = 0; | |
| 760 if (is_method) { | |
| 761 ASSERT(!klass.IsNull()); | |
| 762 function.SetParameterTypeAt(pos, | |
| 763 translation_helper.GetCanonicalType(klass)); | |
| 764 function.SetParameterNameAt(pos, Symbols::This()); | |
| 765 pos++; | |
| 766 } else if (is_closure) { | |
| 767 function.SetParameterTypeAt(pos, AbstractType::dynamic_type()); | |
| 768 function.SetParameterNameAt(pos, Symbols::ClosureParameter()); | |
| 769 pos++; | |
| 770 } else if (is_factory) { | |
| 771 function.SetParameterTypeAt(pos, AbstractType::dynamic_type()); | |
| 772 function.SetParameterNameAt(pos, Symbols::TypeArgumentsParameter()); | |
| 773 pos++; | |
| 774 } | |
| 775 for (intptr_t i = 0; i < node->positional_parameters().length(); i++, pos++) { | |
| 776 VariableDeclaration* kernel_variable = node->positional_parameters()[i]; | |
| 777 const AbstractType& type = type_translator.TranslateTypeWithoutFinalization( | |
| 778 kernel_variable->type()); | |
| 779 function.SetParameterTypeAt( | |
| 780 pos, type.IsMalformed() ? Type::dynamic_type() : type); | |
| 781 function.SetParameterNameAt( | |
| 782 pos, translation_helper.DartSymbol(kernel_variable->name())); | |
| 783 } | |
| 784 for (intptr_t i = 0; i < node->named_parameters().length(); i++, pos++) { | |
| 785 VariableDeclaration* named_expression = node->named_parameters()[i]; | |
| 786 const AbstractType& type = type_translator.TranslateTypeWithoutFinalization( | |
| 787 named_expression->type()); | |
| 788 function.SetParameterTypeAt( | |
| 789 pos, type.IsMalformed() ? Type::dynamic_type() : type); | |
| 790 function.SetParameterNameAt( | |
| 791 pos, translation_helper.DartSymbol(named_expression->name())); | |
| 792 } | |
| 793 | |
| 794 // The result type for generative constructors has already been set. | |
| 795 if (!function.IsGenerativeConstructor()) { | |
| 796 const AbstractType& return_type = | |
| 797 type_translator.TranslateTypeWithoutFinalization(node->return_type()); | |
| 798 function.set_result_type(return_type.IsMalformed() ? Type::dynamic_type() | |
| 799 : return_type); | |
| 800 } | |
| 801 } | |
| 802 | |
| 803 | |
| 804 void KernelReader::SetupFieldAccessorFunction(const dart::Class& klass, | 906 void KernelReader::SetupFieldAccessorFunction(const dart::Class& klass, |
| 805 const dart::Function& function) { | 907 const dart::Function& function) { |
| 806 bool is_setter = function.IsImplicitSetterFunction(); | 908 bool is_setter = function.IsImplicitSetterFunction(); |
| 807 bool is_method = !function.IsStaticFunction(); | 909 bool is_method = !function.IsStaticFunction(); |
| 808 intptr_t num_parameters = (is_method ? 1 : 0) + (is_setter ? 1 : 0); | 910 intptr_t num_parameters = (is_method ? 1 : 0) + (is_setter ? 1 : 0); |
| 809 | 911 |
| 810 function.SetNumOptionalParameters(0, false); | 912 function.SetNumOptionalParameters(0, false); |
| 811 function.set_num_fixed_parameters(num_parameters); | 913 function.set_num_fixed_parameters(num_parameters); |
| 812 function.set_parameter_types( | 914 function.set_parameter_types( |
| 813 Array::Handle(Z, Array::New(num_parameters, Heap::kOld))); | 915 Array::Handle(Z, Array::New(num_parameters, Heap::kOld))); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 858 } | 960 } |
| 859 // Insert the class in the cache before calling ReadPreliminaryClass so | 961 // Insert the class in the cache before calling ReadPreliminaryClass so |
| 860 // we do not risk allocating the class again by calling LookupClass | 962 // we do not risk allocating the class again by calling LookupClass |
| 861 // recursively from ReadPreliminaryClass for the same class. | 963 // recursively from ReadPreliminaryClass for the same class. |
| 862 classes_.Insert(klass, handle); | 964 classes_.Insert(klass, handle); |
| 863 } | 965 } |
| 864 return *handle; | 966 return *handle; |
| 865 } | 967 } |
| 866 | 968 |
| 867 | 969 |
| 868 RawFunction::Kind KernelReader::GetFunctionType(Procedure* kernel_procedure) { | 970 RawFunction::Kind KernelReader::GetFunctionType( |
| 971 Procedure::ProcedureKind procedure_kind) { |
| 869 intptr_t lookuptable[] = { | 972 intptr_t lookuptable[] = { |
| 870 RawFunction::kRegularFunction, // Procedure::kMethod | 973 RawFunction::kRegularFunction, // Procedure::kMethod |
| 871 RawFunction::kGetterFunction, // Procedure::kGetter | 974 RawFunction::kGetterFunction, // Procedure::kGetter |
| 872 RawFunction::kSetterFunction, // Procedure::kSetter | 975 RawFunction::kSetterFunction, // Procedure::kSetter |
| 873 RawFunction::kRegularFunction, // Procedure::kOperator | 976 RawFunction::kRegularFunction, // Procedure::kOperator |
| 874 RawFunction::kConstructor, // Procedure::kFactory | 977 RawFunction::kConstructor, // Procedure::kFactory |
| 875 }; | 978 }; |
| 876 intptr_t kind = static_cast<int>(kernel_procedure->kind()); | 979 intptr_t kind = static_cast<int>(procedure_kind); |
| 877 if (kind == Procedure::kIncompleteProcedure) { | 980 if (kind == Procedure::kIncompleteProcedure) { |
| 878 return RawFunction::kSignatureFunction; | 981 return RawFunction::kSignatureFunction; |
| 879 } else { | 982 } else { |
| 880 ASSERT(0 <= kind && kind <= Procedure::kFactory); | 983 ASSERT(0 <= kind && kind <= Procedure::kFactory); |
| 881 return static_cast<RawFunction::Kind>(lookuptable[kind]); | 984 return static_cast<RawFunction::Kind>(lookuptable[kind]); |
| 882 } | 985 } |
| 883 } | 986 } |
| 884 | 987 |
| 885 | 988 |
| 886 ParsedFunction* ParseStaticFieldInitializer(Zone* zone, | 989 ParsedFunction* ParseStaticFieldInitializer(Zone* zone, |
| (...skipping 19 matching lines...) Expand all Loading... |
| 906 initializer_fun.set_is_debuggable(false); | 1009 initializer_fun.set_is_debuggable(false); |
| 907 initializer_fun.set_is_reflectable(false); | 1010 initializer_fun.set_is_reflectable(false); |
| 908 initializer_fun.set_is_inlinable(false); | 1011 initializer_fun.set_is_inlinable(false); |
| 909 return new (zone) ParsedFunction(thread, initializer_fun); | 1012 return new (zone) ParsedFunction(thread, initializer_fun); |
| 910 } | 1013 } |
| 911 | 1014 |
| 912 | 1015 |
| 913 } // namespace kernel | 1016 } // namespace kernel |
| 914 } // namespace dart | 1017 } // namespace dart |
| 915 #endif // !defined(DART_PRECOMPILED_RUNTIME) | 1018 #endif // !defined(DART_PRECOMPILED_RUNTIME) |
| OLD | NEW |