| 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/longjump.h" | 10 #include "vm/longjump.h" |
| 11 #include "vm/object_store.h" | 11 #include "vm/object_store.h" |
| 12 #include "vm/parser.h" | 12 #include "vm/parser.h" |
| 13 #include "vm/symbols.h" | 13 #include "vm/symbols.h" |
| 14 | 14 |
| 15 #if !defined(DART_PRECOMPILED_RUNTIME) | 15 #if !defined(DART_PRECOMPILED_RUNTIME) |
| 16 namespace dart { | 16 namespace dart { |
| 17 namespace kernel { | 17 namespace kernel { |
| 18 | 18 |
| 19 #define Z (zone_) | 19 #define Z (zone_) |
| 20 #define I (isolate_) | 20 #define I (isolate_) |
| 21 #define T (type_translator_) | 21 #define T (type_translator_) |
| 22 #define H (translation_helper_) | 22 #define H (translation_helper_) |
| 23 | 23 |
| 24 class SimpleExpressionConverter : public ExpressionVisitor { | 24 class SimpleExpressionConverter : public ExpressionVisitor { |
| 25 public: | 25 public: |
| 26 explicit SimpleExpressionConverter(Thread* thread) | 26 explicit SimpleExpressionConverter(TranslationHelper* helper) |
| 27 : translation_helper_(thread), | 27 : translation_helper_(*helper), |
| 28 zone_(translation_helper_.zone()), | 28 zone_(translation_helper_.zone()), |
| 29 is_simple_(false), | 29 is_simple_(false), |
| 30 simple_value_(NULL) {} | 30 simple_value_(NULL) {} |
| 31 | 31 |
| 32 virtual void VisitDefaultExpression(Expression* node) { is_simple_ = false; } | 32 virtual void VisitDefaultExpression(Expression* node) { is_simple_ = false; } |
| 33 | 33 |
| 34 virtual void VisitIntLiteral(IntLiteral* node) { | 34 virtual void VisitIntLiteral(IntLiteral* node) { |
| 35 is_simple_ = true; | 35 is_simple_ = true; |
| 36 simple_value_ = | 36 simple_value_ = |
| 37 &Integer::ZoneHandle(Z, Integer::New(node->value(), Heap::kOld)); | 37 &Integer::ZoneHandle(Z, Integer::New(node->value(), Heap::kOld)); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 69 | 69 |
| 70 bool IsSimple(Expression* expression) { | 70 bool IsSimple(Expression* expression) { |
| 71 expression->AcceptExpressionVisitor(this); | 71 expression->AcceptExpressionVisitor(this); |
| 72 return is_simple_; | 72 return is_simple_; |
| 73 } | 73 } |
| 74 | 74 |
| 75 const dart::Instance& SimpleValue() { return *simple_value_; } | 75 const dart::Instance& SimpleValue() { return *simple_value_; } |
| 76 dart::Zone* zone() const { return zone_; } | 76 dart::Zone* zone() const { return zone_; } |
| 77 | 77 |
| 78 private: | 78 private: |
| 79 TranslationHelper translation_helper_; | 79 TranslationHelper& translation_helper_; |
| 80 dart::Zone* zone_; | 80 dart::Zone* zone_; |
| 81 bool is_simple_; | 81 bool is_simple_; |
| 82 dart::Instance* simple_value_; | 82 dart::Instance* simple_value_; |
| 83 }; | 83 }; |
| 84 | 84 |
| 85 | 85 |
| 86 RawArray* KernelReader::MakeFunctionsArray() { | 86 RawArray* KernelReader::MakeFunctionsArray() { |
| 87 const intptr_t len = functions_.length(); | 87 const intptr_t len = functions_.length(); |
| 88 const Array& res = Array::Handle(zone_, Array::New(len, Heap::kOld)); | 88 const Array& res = Array::Handle(zone_, Array::New(len, Heap::kOld)); |
| 89 for (intptr_t i = 0; i < len; i++) { | 89 for (intptr_t i = 0; i < len; i++) { |
| 90 res.SetAt(i, *functions_[i]); | 90 res.SetAt(i, *functions_[i]); |
| 91 } | 91 } |
| 92 return res.raw(); | 92 return res.raw(); |
| 93 } | 93 } |
| 94 | 94 |
| 95 | 95 |
| 96 RawLibrary* BuildingTranslationHelper::LookupLibraryByKernelLibrary( | 96 RawLibrary* BuildingTranslationHelper::LookupLibraryByKernelLibrary( |
| 97 CanonicalName* library) { | 97 CanonicalName* library) { |
| 98 return reader_->LookupLibrary(library).raw(); | 98 return reader_->LookupLibrary(library).raw(); |
| 99 } | 99 } |
| 100 | 100 |
| 101 | 101 |
| 102 RawClass* BuildingTranslationHelper::LookupClassByKernelClass( | 102 RawClass* BuildingTranslationHelper::LookupClassByKernelClass( |
| 103 CanonicalName* klass) { | 103 CanonicalName* klass) { |
| 104 return reader_->LookupClass(klass).raw(); | 104 return reader_->LookupClass(klass).raw(); |
| 105 } | 105 } |
| 106 | 106 |
| 107 |
| 107 KernelReader::KernelReader(Program* program) | 108 KernelReader::KernelReader(Program* program) |
| 108 : program_(program), | 109 : program_(program), |
| 109 thread_(dart::Thread::Current()), | 110 thread_(dart::Thread::Current()), |
| 110 zone_(thread_->zone()), | 111 zone_(thread_->zone()), |
| 111 isolate_(thread_->isolate()), | 112 isolate_(thread_->isolate()), |
| 112 scripts_(Array::ZoneHandle(zone_)), | 113 scripts_(Array::ZoneHandle(zone_)), |
| 113 translation_helper_(this, thread_), | 114 translation_helper_(this, thread_), |
| 114 type_translator_(&translation_helper_, | 115 type_translator_(&translation_helper_, |
| 115 &active_class_, | 116 &active_class_, |
| 116 /*finalize=*/false) { | 117 /*finalize=*/false) { |
| 117 intptr_t source_file_count = program_->source_table().size(); | 118 intptr_t source_file_count = program->source_table().size(); |
| 118 scripts_ = Array::New(source_file_count, Heap::kOld); | 119 scripts_ = Array::New(source_file_count, Heap::kOld); |
| 120 |
| 121 // Copy the Kernel strings out of the binary and into the VM's heap. The size |
| 122 // of the string data can be computed from the offset and size of the last |
| 123 // string. This relies on the strings occurring in order in the program's |
| 124 // string table. |
| 125 List<String>& strings = program->string_table().strings(); |
| 126 String* last_string = strings[strings.length() - 1]; |
| 127 intptr_t size = last_string->offset() + last_string->size(); |
| 128 TypedData& data = TypedData::Handle( |
| 129 Z, TypedData::New(kTypedDataUint8ArrayCid, size, Heap::kOld)); |
| 130 ASSERT(program->string_data_offset() >= 0); |
| 131 // We need at least one library to get access to the binary. |
| 132 ASSERT(program->libraries().length() > 0); |
| 133 { |
| 134 NoSafepointScope no_safepoint; |
| 135 memmove(data.DataAddr(0), program->libraries()[0]->kernel_data() + |
| 136 program->string_data_offset(), |
| 137 size); |
| 138 } |
| 139 H.SetStringData(data); |
| 119 } | 140 } |
| 120 | 141 |
| 142 |
| 121 Object& KernelReader::ReadProgram() { | 143 Object& KernelReader::ReadProgram() { |
| 122 LongJumpScope jump; | 144 LongJumpScope jump; |
| 123 if (setjmp(*jump.Set()) == 0) { | 145 if (setjmp(*jump.Set()) == 0) { |
| 124 intptr_t length = program_->libraries().length(); | 146 intptr_t length = program_->libraries().length(); |
| 125 for (intptr_t i = 0; i < length; i++) { | 147 for (intptr_t i = 0; i < length; i++) { |
| 126 Library* kernel_library = program_->libraries()[i]; | 148 Library* kernel_library = program_->libraries()[i]; |
| 127 ReadLibrary(kernel_library); | 149 ReadLibrary(kernel_library); |
| 128 } | 150 } |
| 129 | 151 |
| 130 for (intptr_t i = 0; i < length; i++) { | 152 for (intptr_t i = 0; i < length; i++) { |
| 131 dart::Library& library = | 153 dart::Library& library = |
| 132 LookupLibrary(program_->libraries()[i]->canonical_name()); | 154 LookupLibrary(program_->libraries()[i]->canonical_name()); |
| 133 if (!library.Loaded()) library.SetLoaded(); | 155 if (!library.Loaded()) library.SetLoaded(); |
| 134 } | 156 } |
| 135 | 157 |
| 136 if (ClassFinalizer::ProcessPendingClasses(/*from_kernel=*/true)) { | 158 if (ClassFinalizer::ProcessPendingClasses(/*from_kernel=*/true)) { |
| 137 CanonicalName* main = program_->main_method(); | 159 CanonicalName* main = program_->main_method(); |
| 138 dart::Library& library = LookupLibrary(main->EnclosingName()); | 160 dart::Library& library = LookupLibrary(H.EnclosingName(main)); |
| 139 | 161 |
| 140 // Sanity check that we can find the main entrypoint. | 162 // Sanity check that we can find the main entrypoint. |
| 141 Object& main_obj = Object::Handle( | 163 Object& main_obj = Object::Handle( |
| 142 Z, library.LookupObjectAllowPrivate(H.DartSymbol("main"))); | 164 Z, library.LookupObjectAllowPrivate(H.DartSymbol("main"))); |
| 143 ASSERT(!main_obj.IsNull()); | 165 ASSERT(!main_obj.IsNull()); |
| 144 return library; | 166 return library; |
| 145 } | 167 } |
| 146 } | 168 } |
| 147 | 169 |
| 148 // Either class finalization failed or we caught a compile error. | 170 // Either class finalization failed or we caught a compile error. |
| (...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 421 dart::String* native_name = NULL; | 443 dart::String* native_name = NULL; |
| 422 if (is_external) { | 444 if (is_external) { |
| 423 // Maybe it has a native implementation, which is not external as far as | 445 // Maybe it has a native implementation, which is not external as far as |
| 424 // the VM is concerned because it does have an implementation. Check for | 446 // the VM is concerned because it does have an implementation. Check for |
| 425 // an ExternalName annotation and extract the string from it. | 447 // an ExternalName annotation and extract the string from it. |
| 426 for (int i = 0; i < kernel_procedure->annotations().length(); ++i) { | 448 for (int i = 0; i < kernel_procedure->annotations().length(); ++i) { |
| 427 Expression* annotation = kernel_procedure->annotations()[i]; | 449 Expression* annotation = kernel_procedure->annotations()[i]; |
| 428 if (!annotation->IsConstructorInvocation()) continue; | 450 if (!annotation->IsConstructorInvocation()) continue; |
| 429 ConstructorInvocation* invocation = | 451 ConstructorInvocation* invocation = |
| 430 ConstructorInvocation::Cast(annotation); | 452 ConstructorInvocation::Cast(annotation); |
| 431 CanonicalName* annotation_class = invocation->target()->EnclosingName(); | 453 CanonicalName* annotation_class = H.EnclosingName(invocation->target()); |
| 432 ASSERT(annotation_class->IsClass()); | 454 ASSERT(H.IsClass(annotation_class)); |
| 433 String* class_name = annotation_class->name(); | 455 String* class_name = annotation_class->name(); |
| 434 // Just compare by name, do not generate the annotation class. | 456 // Just compare by name, do not generate the annotation class. |
| 435 int length = sizeof("ExternalName") - 1; | 457 if (!H.StringEquals(class_name, "ExternalName")) continue; |
| 436 if (class_name->size() != length) continue; | 458 ASSERT(H.IsLibrary(annotation_class->parent())); |
| 437 if (memcmp(class_name->buffer(), "ExternalName", length) != 0) continue; | |
| 438 ASSERT(annotation_class->parent()->IsLibrary()); | |
| 439 String* library_name = annotation_class->parent()->name(); | 459 String* library_name = annotation_class->parent()->name(); |
| 440 length = sizeof("dart:_internal") - 1; | 460 if (!H.StringEquals(library_name, "dart:_internal")) continue; |
| 441 if (library_name->size() != length) continue; | |
| 442 if (memcmp(library_name->buffer(), "dart:_internal", length) != 0) { | |
| 443 continue; | |
| 444 } | |
| 445 | 461 |
| 446 is_external = false; | 462 is_external = false; |
| 447 ASSERT(invocation->arguments()->positional().length() == 1 && | 463 ASSERT(invocation->arguments()->positional().length() == 1 && |
| 448 invocation->arguments()->named().length() == 0); | 464 invocation->arguments()->named().length() == 0); |
| 449 StringLiteral* literal = | 465 StringLiteral* literal = |
| 450 StringLiteral::Cast(invocation->arguments()->positional()[0]); | 466 StringLiteral::Cast(invocation->arguments()->positional()[0]); |
| 451 native_name = &H.DartSymbol(literal->value()); | 467 native_name = &H.DartSymbol(literal->value()); |
| 452 break; | 468 break; |
| 453 } | 469 } |
| 454 } | 470 } |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 537 source->Sort(LowestFirst); | 553 source->Sort(LowestFirst); |
| 538 | 554 |
| 539 intptr_t size = source->length(); | 555 intptr_t size = source->length(); |
| 540 intptr_t last = 0; | 556 intptr_t last = 0; |
| 541 for (intptr_t current = 1; current < size; ++current) { | 557 for (intptr_t current = 1; current < size; ++current) { |
| 542 if (source->At(last) != source->At(current)) { | 558 if (source->At(last) != source->At(current)) { |
| 543 (*source)[++last] = source->At(current); | 559 (*source)[++last] = source->At(current); |
| 544 } | 560 } |
| 545 } | 561 } |
| 546 Array& array_object = Array::Handle(); | 562 Array& array_object = Array::Handle(); |
| 547 array_object ^= Array::New(last + 1, Heap::kOld); | 563 array_object = Array::New(last + 1, Heap::kOld); |
| 548 Smi& smi_value = Smi::Handle(); | 564 Smi& smi_value = Smi::Handle(); |
| 549 for (intptr_t i = 0; i <= last; ++i) { | 565 for (intptr_t i = 0; i <= last; ++i) { |
| 550 smi_value = Smi::New(source->At(i)); | 566 smi_value = Smi::New(source->At(i)); |
| 551 array_object.SetAt(i, smi_value); | 567 array_object.SetAt(i, smi_value); |
| 552 } | 568 } |
| 553 return array_object.raw(); | 569 return array_object.raw(); |
| 554 } else { | 570 } else { |
| 555 return Array::New(0); | 571 return Array::New(0); |
| 556 } | 572 } |
| 557 } | 573 } |
| 558 | 574 |
| 559 Script& KernelReader::ScriptAt(intptr_t source_uri_index, String* import_uri) { | 575 Script& KernelReader::ScriptAt(intptr_t index, String* import_uri) { |
| 560 Script& script = Script::ZoneHandle(Z); | 576 Script& script = Script::ZoneHandle(Z); |
| 561 script ^= scripts_.At(source_uri_index); | 577 script ^= scripts_.At(index); |
| 562 if (script.IsNull()) { | 578 if (script.IsNull()) { |
| 563 // Create script with correct uri(s). | 579 // Create script with correct uri(s). |
| 564 String* uri = program_->source_uri_table().strings()[source_uri_index]; | 580 uint8_t* uri_buffer = program_->source_table().UriFor(index); |
| 565 dart::String& uri_string = H.DartString(uri, Heap::kOld); | 581 intptr_t uri_size = program_->source_table().UriSizeFor(index); |
| 582 dart::String& uri_string = H.DartString(uri_buffer, uri_size, Heap::kOld); |
| 566 dart::String& import_uri_string = | 583 dart::String& import_uri_string = |
| 567 import_uri == NULL ? uri_string : H.DartString(import_uri, Heap::kOld); | 584 import_uri == NULL ? uri_string : H.DartString(import_uri, Heap::kOld); |
| 568 dart::String& source_code = H.DartString( | 585 uint8_t* source_buffer = program_->source_table().SourceCodeFor(index); |
| 569 program_->source_table().SourceFor(source_uri_index), Heap::kOld); | 586 intptr_t source_size = program_->source_table().SourceCodeSizeFor(index); |
| 587 dart::String& source_code = |
| 588 H.DartString(source_buffer, source_size, Heap::kOld); |
| 570 script = Script::New(import_uri_string, uri_string, source_code, | 589 script = Script::New(import_uri_string, uri_string, source_code, |
| 571 RawScript::kKernelTag); | 590 RawScript::kKernelTag); |
| 572 scripts_.SetAt(source_uri_index, script); | 591 script.set_kernel_strings(H.string_data()); |
| 592 scripts_.SetAt(index, script); |
| 573 | 593 |
| 574 // Create line_starts array for the script. | 594 // Create line_starts array for the script. |
| 575 intptr_t* line_starts = | 595 intptr_t* line_starts = program_->source_table().LineStartsFor(index); |
| 576 program_->source_table().LineStartsFor(source_uri_index); | 596 intptr_t line_count = program_->source_table().LineCountFor(index); |
| 577 intptr_t line_count = | |
| 578 program_->source_table().LineCountFor(source_uri_index); | |
| 579 Array& array_object = Array::Handle(Z, Array::New(line_count, Heap::kOld)); | 597 Array& array_object = Array::Handle(Z, Array::New(line_count, Heap::kOld)); |
| 580 Smi& value = Smi::Handle(Z); | 598 Smi& value = Smi::Handle(Z); |
| 581 for (intptr_t i = 0; i < line_count; ++i) { | 599 for (intptr_t i = 0; i < line_count; ++i) { |
| 582 value = Smi::New(line_starts[i]); | 600 value = Smi::New(line_starts[i]); |
| 583 array_object.SetAt(i, value); | 601 array_object.SetAt(i, value); |
| 584 } | 602 } |
| 585 script.set_line_starts(array_object); | 603 script.set_line_starts(array_object); |
| 586 | 604 |
| 587 // Create tokens_seen array for the script. | 605 // Create tokens_seen array for the script. |
| 588 array_object ^= AsSortedDuplicateFreeArray( | 606 array_object = |
| 589 source_uri_index, &program_->valid_token_positions); | 607 AsSortedDuplicateFreeArray(index, &program_->valid_token_positions); |
| 590 script.set_debug_positions(array_object); | 608 script.set_debug_positions(array_object); |
| 591 | 609 |
| 592 // Create yield_positions array for the script. | 610 // Create yield_positions array for the script. |
| 593 array_object ^= AsSortedDuplicateFreeArray( | 611 array_object = |
| 594 source_uri_index, &program_->yield_token_positions); | 612 AsSortedDuplicateFreeArray(index, &program_->yield_token_positions); |
| 595 script.set_yield_positions(array_object); | 613 script.set_yield_positions(array_object); |
| 596 } | 614 } |
| 597 return script; | 615 return script; |
| 598 } | 616 } |
| 599 | 617 |
| 600 void KernelReader::GenerateFieldAccessors(const dart::Class& klass, | 618 void KernelReader::GenerateFieldAccessors(const dart::Class& klass, |
| 601 const dart::Field& field, | 619 const dart::Field& field, |
| 602 Field* kernel_field) { | 620 Field* kernel_field) { |
| 603 if (kernel_field->IsStatic() && kernel_field->initializer() == NULL) { | 621 if (kernel_field->IsStatic() && kernel_field->initializer() == NULL) { |
| 604 // Static fields without an initializer are implicitly initialized to null. | 622 // Static fields without an initializer are implicitly initialized to null. |
| 605 // We do not need a getter. | 623 // We do not need a getter. |
| 606 field.SetStaticValue(Instance::Handle(Z), true); | 624 field.SetStaticValue(Instance::Handle(Z), true); |
| 607 return; | 625 return; |
| 608 } | 626 } |
| 609 if (kernel_field->initializer() != NULL) { | 627 if (kernel_field->initializer() != NULL) { |
| 610 SimpleExpressionConverter converter(H.thread()); | 628 SimpleExpressionConverter converter(&H); |
| 611 const bool has_simple_initializer = | 629 const bool has_simple_initializer = |
| 612 converter.IsSimple(kernel_field->initializer()); | 630 converter.IsSimple(kernel_field->initializer()); |
| 613 if (kernel_field->IsStatic()) { | 631 if (kernel_field->IsStatic()) { |
| 614 // Static fields with initializers either have the static value set to the | 632 // Static fields with initializers either have the static value set to the |
| 615 // initializer value if it is simple enough or else set to an | 633 // initializer value if it is simple enough or else set to an |
| 616 // uninitialized sentinel. | 634 // uninitialized sentinel. |
| 617 if (has_simple_initializer) { | 635 if (has_simple_initializer) { |
| 618 // We do not need a getter. | 636 // We do not need a getter. |
| 619 field.SetStaticValue(converter.SimpleValue(), true); | 637 field.SetStaticValue(converter.SimpleValue(), true); |
| 620 return; | 638 return; |
| (...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 864 initializer_fun.set_is_debuggable(false); | 882 initializer_fun.set_is_debuggable(false); |
| 865 initializer_fun.set_is_reflectable(false); | 883 initializer_fun.set_is_reflectable(false); |
| 866 initializer_fun.set_is_inlinable(false); | 884 initializer_fun.set_is_inlinable(false); |
| 867 return new (zone) ParsedFunction(thread, initializer_fun); | 885 return new (zone) ParsedFunction(thread, initializer_fun); |
| 868 } | 886 } |
| 869 | 887 |
| 870 | 888 |
| 871 } // namespace kernel | 889 } // namespace kernel |
| 872 } // namespace dart | 890 } // namespace dart |
| 873 #endif // !defined(DART_PRECOMPILED_RUNTIME) | 891 #endif // !defined(DART_PRECOMPILED_RUNTIME) |
| OLD | NEW |