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 |