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" |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
122 | 122 |
123 KernelReader::KernelReader(Program* program) | 123 KernelReader::KernelReader(Program* program) |
124 : program_(program), | 124 : program_(program), |
125 thread_(dart::Thread::Current()), | 125 thread_(dart::Thread::Current()), |
126 zone_(thread_->zone()), | 126 zone_(thread_->zone()), |
127 isolate_(thread_->isolate()), | 127 isolate_(thread_->isolate()), |
128 scripts_(Array::ZoneHandle(zone_)), | 128 scripts_(Array::ZoneHandle(zone_)), |
129 translation_helper_(this, thread_), | 129 translation_helper_(this, thread_), |
130 builder_(&translation_helper_, | 130 builder_(&translation_helper_, |
131 zone_, | 131 zone_, |
132 program_->libraries()[0]->kernel_data(), | 132 program_->kernel_data(), |
133 program_->libraries()[0]->kernel_data_size()) { | 133 program_->kernel_data_size()) { |
134 T.active_class_ = &active_class_; | 134 T.active_class_ = &active_class_; |
135 T.finalize_ = false; | 135 T.finalize_ = false; |
136 | 136 |
137 intptr_t source_file_count = program->source_table().size(); | 137 scripts_ = Array::New(builder_.SourceTableSize(), Heap::kOld); |
138 scripts_ = Array::New(source_file_count, Heap::kOld); | |
139 | |
140 // We need at least one library to get access to the binary. | |
141 ASSERT(program->libraries().length() > 0); | |
142 Library* library = program->libraries()[0]; | |
143 Reader reader(library->kernel_data(), library->kernel_data_size()); | |
144 | 138 |
145 // Copy the Kernel string offsets out of the binary and into the VM's heap. | 139 // Copy the Kernel string offsets out of the binary and into the VM's heap. |
146 ASSERT(program->string_table_offset() >= 0); | 140 ASSERT(program->string_table_offset() >= 0); |
| 141 Reader reader(program->kernel_data(), program->kernel_data_size()); |
147 reader.set_offset(program->string_table_offset()); | 142 reader.set_offset(program->string_table_offset()); |
148 intptr_t count = reader.ReadUInt() + 1; | 143 intptr_t count = reader.ReadUInt() + 1; |
149 TypedData& offsets = TypedData::Handle( | 144 TypedData& offsets = TypedData::Handle( |
150 Z, TypedData::New(kTypedDataUint32ArrayCid, count, Heap::kOld)); | 145 Z, TypedData::New(kTypedDataUint32ArrayCid, count, Heap::kOld)); |
151 offsets.SetUint32(0, 0); | 146 offsets.SetUint32(0, 0); |
152 intptr_t end_offset = 0; | 147 intptr_t end_offset = 0; |
153 for (intptr_t i = 1; i < count; ++i) { | 148 for (intptr_t i = 1; i < count; ++i) { |
154 end_offset = reader.ReadUInt(); | 149 end_offset = reader.ReadUInt(); |
155 offsets.SetUint32(i << 2, end_offset); | 150 offsets.SetUint32(i << 2, end_offset); |
156 } | 151 } |
(...skipping 18 matching lines...) Expand all Loading... |
175 | 170 |
176 H.SetStringOffsets(offsets); | 171 H.SetStringOffsets(offsets); |
177 H.SetStringData(data); | 172 H.SetStringData(data); |
178 H.SetCanonicalNames(names); | 173 H.SetCanonicalNames(names); |
179 } | 174 } |
180 | 175 |
181 | 176 |
182 Object& KernelReader::ReadProgram() { | 177 Object& KernelReader::ReadProgram() { |
183 LongJumpScope jump; | 178 LongJumpScope jump; |
184 if (setjmp(*jump.Set()) == 0) { | 179 if (setjmp(*jump.Set()) == 0) { |
185 intptr_t length = program_->libraries().length(); | 180 intptr_t length = program_->library_count(); |
186 for (intptr_t i = 0; i < length; i++) { | 181 for (intptr_t i = 0; i < length; i++) { |
187 Library* kernel_library = program_->libraries()[i]; | 182 ReadLibrary(library_offset(i)); |
188 ReadLibrary(kernel_library->kernel_offset()); | |
189 } | 183 } |
190 | 184 |
191 for (intptr_t i = 0; i < length; i++) { | 185 for (intptr_t i = 0; i < length; i++) { |
192 dart::Library& library = | 186 dart::Library& library = LookupLibrary(library_canonical_name(i)); |
193 LookupLibrary(program_->libraries()[i]->canonical_name()); | |
194 if (!library.Loaded()) library.SetLoaded(); | 187 if (!library.Loaded()) library.SetLoaded(); |
195 } | 188 } |
196 | 189 |
197 if (ClassFinalizer::ProcessPendingClasses(/*from_kernel=*/true)) { | 190 if (ClassFinalizer::ProcessPendingClasses(/*from_kernel=*/true)) { |
198 // If 'main' is not found return a null library, this is the case | 191 // If 'main' is not found return a null library, this is the case |
199 // when bootstrapping is in progress. | 192 // when bootstrapping is in progress. |
200 NameIndex main = program_->main_method(); | 193 NameIndex main = program_->main_method(); |
201 if (main == -1) { | 194 if (main == -1) { |
202 return dart::Library::Handle(Z); | 195 return dart::Library::Handle(Z); |
203 } | 196 } |
(...skipping 11 matching lines...) Expand all Loading... |
215 // In both cases sticky error would be set. | 208 // In both cases sticky error would be set. |
216 Error& error = Error::Handle(Z); | 209 Error& error = Error::Handle(Z); |
217 error = thread_->sticky_error(); | 210 error = thread_->sticky_error(); |
218 thread_->clear_sticky_error(); | 211 thread_->clear_sticky_error(); |
219 return error; | 212 return error; |
220 } | 213 } |
221 | 214 |
222 | 215 |
223 void KernelReader::ReadLibrary(intptr_t kernel_offset) { | 216 void KernelReader::ReadLibrary(intptr_t kernel_offset) { |
224 builder_.SetOffset(kernel_offset); | 217 builder_.SetOffset(kernel_offset); |
| 218 LibraryHelper library_helper(&builder_); |
| 219 library_helper.ReadUntilIncluding(LibraryHelper::kCanonicalName); |
| 220 dart::Library& library = LookupLibrary(library_helper.canonical_name_); |
| 221 if (library.Loaded()) return; |
225 | 222 |
226 int flags = builder_.ReadFlags(); | 223 library_helper.ReadUntilIncluding(LibraryHelper::kName); |
227 ASSERT(flags == 0); // external libraries not supported | 224 library.SetName(H.DartSymbol(library_helper.name_index_)); |
228 | |
229 NameIndex canonical_name = | |
230 builder_.ReadCanonicalNameReference(); // read canonical name. | |
231 dart::Library& library = LookupLibrary(canonical_name); | |
232 if (library.Loaded()) return; | |
233 StringIndex name = builder_.ReadStringReference(); // read name. | |
234 library.SetName(H.DartSymbol(name)); | |
235 | 225 |
236 // The bootstrapper will take care of creating the native wrapper classes, but | 226 // The bootstrapper will take care of creating the native wrapper classes, but |
237 // we will add the synthetic constructors to them here. | 227 // we will add the synthetic constructors to them here. |
238 if (library.name() == | 228 if (library.name() == |
239 Symbols::Symbol(Symbols::kDartNativeWrappersLibNameId).raw()) { | 229 Symbols::Symbol(Symbols::kDartNativeWrappersLibNameId).raw()) { |
240 ASSERT(library.LoadInProgress()); | 230 ASSERT(library.LoadInProgress()); |
241 } else { | 231 } else { |
242 library.SetLoadInProgress(); | 232 library.SetLoadInProgress(); |
243 } | 233 } |
244 // Setup toplevel class (which contains library fields/procedures). | 234 // Setup toplevel class (which contains library fields/procedures). |
245 | 235 |
246 StringIndex import_uri_index = H.CanonicalNameString(canonical_name); | 236 StringIndex import_uri_index = |
247 intptr_t source_uri_index = builder_.ReadUInt(); // read source uri index. | 237 H.CanonicalNameString(library_helper.canonical_name_); |
| 238 library_helper.ReadUntilIncluding(LibraryHelper::kSourceUriIndex); |
| 239 Script& script = ScriptAt(library_helper.source_uri_index_, import_uri_index); |
248 | 240 |
249 Script& script = ScriptAt(source_uri_index, import_uri_index); | |
250 dart::Class& toplevel_class = dart::Class::Handle( | 241 dart::Class& toplevel_class = dart::Class::Handle( |
251 Z, dart::Class::New(library, Symbols::TopLevel(), script, | 242 Z, dart::Class::New(library, Symbols::TopLevel(), script, |
252 TokenPosition::kNoSource)); | 243 TokenPosition::kNoSource)); |
253 toplevel_class.set_is_cycle_free(); | 244 toplevel_class.set_is_cycle_free(); |
254 library.set_toplevel_class(toplevel_class); | 245 library.set_toplevel_class(toplevel_class); |
255 | 246 |
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 = | 247 const GrowableObjectArray& classes = |
292 GrowableObjectArray::Handle(Z, I->object_store()->pending_classes()); | 248 GrowableObjectArray::Handle(Z, I->object_store()->pending_classes()); |
293 | 249 |
| 250 library_helper.ReadUntilExcluding(LibraryHelper::kClasses); |
| 251 |
294 // Load all classes. | 252 // Load all classes. |
295 int class_count = builder_.ReadListLength(); // read list length. | 253 int class_count = builder_.ReadListLength(); // read list length. |
296 for (intptr_t i = 0; i < class_count; ++i) { | 254 for (intptr_t i = 0; i < class_count; ++i) { |
297 classes.Add(ReadClass(library, toplevel_class), Heap::kOld); | 255 classes.Add(ReadClass(library, toplevel_class), Heap::kOld); |
298 } | 256 } |
299 | 257 |
300 fields_.Clear(); | 258 fields_.Clear(); |
301 functions_.Clear(); | 259 functions_.Clear(); |
302 ActiveClassScope active_class_scope(&active_class_, 0, -1, &toplevel_class); | 260 ActiveClassScope active_class_scope(&active_class_, 0, -1, &toplevel_class); |
303 // Load toplevel fields. | 261 // Load toplevel fields. |
(...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
722 intptr_t source_uri_index) { | 680 intptr_t source_uri_index) { |
723 Script& correct_script = ScriptAt(source_uri_index); | 681 Script& correct_script = ScriptAt(source_uri_index); |
724 if (klass.script() != correct_script.raw()) { | 682 if (klass.script() != correct_script.raw()) { |
725 // TODO(jensj): We could probably cache this so we don't create | 683 // TODO(jensj): We could probably cache this so we don't create |
726 // new PatchClasses all the time | 684 // new PatchClasses all the time |
727 return PatchClass::ZoneHandle(Z, PatchClass::New(klass, correct_script)); | 685 return PatchClass::ZoneHandle(Z, PatchClass::New(klass, correct_script)); |
728 } | 686 } |
729 return klass; | 687 return klass; |
730 } | 688 } |
731 | 689 |
732 static int LowestFirst(const intptr_t* a, const intptr_t* b) { | |
733 return *a - *b; | |
734 } | |
735 | |
736 /** | |
737 * If index exists as sublist in list, sort the sublist from lowest to highest, | |
738 * then copy it, as Smis and without duplicates, | |
739 * to a new Array in Heap::kOld which is returned. | |
740 * Note that the source list is both sorted and de-duplicated as well, but will | |
741 * possibly contain duplicate and unsorted data at the end. | |
742 * Otherwise (when sublist doesn't exist in list) return new empty array. | |
743 */ | |
744 static RawArray* AsSortedDuplicateFreeArray( | |
745 intptr_t index, | |
746 MallocGrowableArray<MallocGrowableArray<intptr_t>*>* list) { | |
747 if ((index < list->length()) && (list->At(index)->length() > 0)) { | |
748 MallocGrowableArray<intptr_t>* source = list->At(index); | |
749 source->Sort(LowestFirst); | |
750 | |
751 intptr_t size = source->length(); | |
752 intptr_t last = 0; | |
753 for (intptr_t current = 1; current < size; ++current) { | |
754 if (source->At(last) != source->At(current)) { | |
755 (*source)[++last] = source->At(current); | |
756 } | |
757 } | |
758 Array& array_object = Array::Handle(); | |
759 array_object = Array::New(last + 1, Heap::kOld); | |
760 Smi& smi_value = Smi::Handle(); | |
761 for (intptr_t i = 0; i <= last; ++i) { | |
762 smi_value = Smi::New(source->At(i)); | |
763 array_object.SetAt(i, smi_value); | |
764 } | |
765 return array_object.raw(); | |
766 } else { | |
767 return Array::New(0); | |
768 } | |
769 } | |
770 | |
771 Script& KernelReader::ScriptAt(intptr_t index, StringIndex import_uri) { | 690 Script& KernelReader::ScriptAt(intptr_t index, StringIndex import_uri) { |
772 Script& script = Script::ZoneHandle(Z); | 691 Script& script = Script::ZoneHandle(Z); |
773 script ^= scripts_.At(index); | 692 script ^= scripts_.At(index); |
774 if (script.IsNull()) { | 693 if (script.IsNull()) { |
775 // Create script with correct uri(s). | 694 // Create script with correct uri(s). |
776 uint8_t* uri_buffer = program_->source_table().UriFor(index); | 695 dart::String& uri_string = builder_.SourceTableUriFor(index); |
777 intptr_t uri_size = program_->source_table().UriSizeFor(index); | |
778 dart::String& uri_string = H.DartString(uri_buffer, uri_size, Heap::kOld); | |
779 dart::String& import_uri_string = | 696 dart::String& import_uri_string = |
780 import_uri == -1 ? uri_string : H.DartString(import_uri, Heap::kOld); | 697 import_uri == -1 ? uri_string : H.DartString(import_uri, Heap::kOld); |
781 uint8_t* source_buffer = program_->source_table().SourceCodeFor(index); | 698 script = Script::New(import_uri_string, uri_string, |
782 intptr_t source_size = program_->source_table().SourceCodeSizeFor(index); | 699 String::Handle(String::null()), RawScript::kKernelTag); |
783 dart::String& source_code = | 700 script.set_kernel_data(program_->kernel_data()); |
784 H.DartString(source_buffer, source_size, Heap::kOld); | 701 script.set_kernel_data_size(program_->kernel_data_size()); |
785 script = Script::New(import_uri_string, uri_string, source_code, | 702 script.set_kernel_script_index(index); |
786 RawScript::kKernelTag); | |
787 script.set_kernel_data(program_->libraries()[0]->kernel_data()); | |
788 script.set_kernel_data_size(program_->libraries()[0]->kernel_data_size()); | |
789 script.set_kernel_string_offsets(H.string_offsets()); | 703 script.set_kernel_string_offsets(H.string_offsets()); |
790 script.set_kernel_string_data(H.string_data()); | 704 script.set_kernel_string_data(H.string_data()); |
791 script.set_kernel_canonical_names(H.canonical_names()); | 705 script.set_kernel_canonical_names(H.canonical_names()); |
792 scripts_.SetAt(index, script); | 706 scripts_.SetAt(index, script); |
793 | 707 |
794 // Create line_starts array for the script. | 708 script.set_line_starts(Array::Handle(Array::null())); |
795 intptr_t* line_starts = program_->source_table().LineStartsFor(index); | 709 script.set_debug_positions(Array::Handle(Array::null())); |
796 intptr_t line_count = program_->source_table().LineCountFor(index); | 710 script.set_yield_positions(Array::Handle(Array::null())); |
797 Array& array_object = Array::Handle(Z, Array::New(line_count, Heap::kOld)); | |
798 Smi& value = Smi::Handle(Z); | |
799 for (intptr_t i = 0; i < line_count; ++i) { | |
800 value = Smi::New(line_starts[i]); | |
801 array_object.SetAt(i, value); | |
802 } | |
803 script.set_line_starts(array_object); | |
804 | |
805 // Create tokens_seen array for the script. | |
806 array_object = | |
807 AsSortedDuplicateFreeArray(index, &program_->valid_token_positions); | |
808 script.set_debug_positions(array_object); | |
809 | |
810 // Create yield_positions array for the script. | |
811 array_object = | |
812 AsSortedDuplicateFreeArray(index, &program_->yield_token_positions); | |
813 script.set_yield_positions(array_object); | |
814 } | 711 } |
815 return script; | 712 return script; |
816 } | 713 } |
817 | 714 |
818 void KernelReader::GenerateFieldAccessors(const dart::Class& klass, | 715 void KernelReader::GenerateFieldAccessors(const dart::Class& klass, |
819 const dart::Field& field, | 716 const dart::Field& field, |
820 FieldHelper* field_helper, | 717 FieldHelper* field_helper, |
821 intptr_t field_offset) { | 718 intptr_t field_offset) { |
822 Tag tag = builder_.PeekTag(); | 719 Tag tag = builder_.PeekTag(); |
823 if (field_helper->IsStatic() && tag == kNothing) { | 720 if (field_helper->IsStatic() && tag == kNothing) { |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
900 setter.set_is_debuggable(false); | 797 setter.set_is_debuggable(false); |
901 SetupFieldAccessorFunction(klass, setter); | 798 SetupFieldAccessorFunction(klass, setter); |
902 } | 799 } |
903 } | 800 } |
904 | 801 |
905 | 802 |
906 void KernelReader::SetupFieldAccessorFunction(const dart::Class& klass, | 803 void KernelReader::SetupFieldAccessorFunction(const dart::Class& klass, |
907 const dart::Function& function) { | 804 const dart::Function& function) { |
908 bool is_setter = function.IsImplicitSetterFunction(); | 805 bool is_setter = function.IsImplicitSetterFunction(); |
909 bool is_method = !function.IsStaticFunction(); | 806 bool is_method = !function.IsStaticFunction(); |
910 intptr_t num_parameters = (is_method ? 1 : 0) + (is_setter ? 1 : 0); | 807 intptr_t parameter_count = (is_method ? 1 : 0) + (is_setter ? 1 : 0); |
911 | 808 |
912 function.SetNumOptionalParameters(0, false); | 809 function.SetNumOptionalParameters(0, false); |
913 function.set_num_fixed_parameters(num_parameters); | 810 function.set_num_fixed_parameters(parameter_count); |
914 function.set_parameter_types( | 811 function.set_parameter_types( |
915 Array::Handle(Z, Array::New(num_parameters, Heap::kOld))); | 812 Array::Handle(Z, Array::New(parameter_count, Heap::kOld))); |
916 function.set_parameter_names( | 813 function.set_parameter_names( |
917 Array::Handle(Z, Array::New(num_parameters, Heap::kOld))); | 814 Array::Handle(Z, Array::New(parameter_count, Heap::kOld))); |
918 | 815 |
919 intptr_t pos = 0; | 816 intptr_t pos = 0; |
920 if (is_method) { | 817 if (is_method) { |
921 function.SetParameterTypeAt(pos, T.ReceiverType(klass)); | 818 function.SetParameterTypeAt(pos, T.ReceiverType(klass)); |
922 function.SetParameterNameAt(pos, Symbols::This()); | 819 function.SetParameterNameAt(pos, Symbols::This()); |
923 pos++; | 820 pos++; |
924 } | 821 } |
925 if (is_setter) { | 822 if (is_setter) { |
926 function.SetParameterTypeAt(pos, AbstractType::dynamic_type()); | 823 function.SetParameterTypeAt(pos, AbstractType::dynamic_type()); |
927 function.SetParameterNameAt(pos, Symbols::Value()); | 824 function.SetParameterNameAt(pos, Symbols::Value()); |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1009 initializer_fun.set_is_debuggable(false); | 906 initializer_fun.set_is_debuggable(false); |
1010 initializer_fun.set_is_reflectable(false); | 907 initializer_fun.set_is_reflectable(false); |
1011 initializer_fun.set_is_inlinable(false); | 908 initializer_fun.set_is_inlinable(false); |
1012 return new (zone) ParsedFunction(thread, initializer_fun); | 909 return new (zone) ParsedFunction(thread, initializer_fun); |
1013 } | 910 } |
1014 | 911 |
1015 | 912 |
1016 } // namespace kernel | 913 } // namespace kernel |
1017 } // namespace dart | 914 } // namespace dart |
1018 #endif // !defined(DART_PRECOMPILED_RUNTIME) | 915 #endif // !defined(DART_PRECOMPILED_RUNTIME) |
OLD | NEW |