Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(16)

Side by Side Diff: runtime/vm/kernel_binary_flowgraph.cc

Issue 2901533002: [kernel] Stream everything. Replace .kernel_function with .kernel_offset (Closed)
Patch Set: Fixed assert issues; small refactorings. Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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_binary_flowgraph.h" 5 #include "vm/kernel_binary_flowgraph.h"
6 6
7 #include "vm/compiler.h"
7 #include "vm/longjump.h" 8 #include "vm/longjump.h"
8 #include "vm/object_store.h" 9 #include "vm/object_store.h"
9 10
10 #if !defined(DART_PRECOMPILED_RUNTIME) 11 #if !defined(DART_PRECOMPILED_RUNTIME)
11 12
12 namespace dart { 13 namespace dart {
13 namespace kernel { 14 namespace kernel {
14 15
15 #define Z (zone_) 16 #define Z (zone_)
16 #define H (translation_helper_) 17 #define H (translation_helper_)
(...skipping 30 matching lines...) Expand all
47 H.SetStringOffsets(TypedData::Handle(Z, script.kernel_string_offsets())); 48 H.SetStringOffsets(TypedData::Handle(Z, script.kernel_string_offsets()));
48 H.SetStringData(TypedData::Handle(Z, script.kernel_string_data())); 49 H.SetStringData(TypedData::Handle(Z, script.kernel_string_data()));
49 H.SetCanonicalNames(TypedData::Handle(Z, script.kernel_canonical_names())); 50 H.SetCanonicalNames(TypedData::Handle(Z, script.kernel_canonical_names()));
50 type_translator_.active_class_ = &active_class_; 51 type_translator_.active_class_ = &active_class_;
51 } 52 }
52 53
53 StreamingScopeBuilder::~StreamingScopeBuilder() { 54 StreamingScopeBuilder::~StreamingScopeBuilder() {
54 delete builder_; 55 delete builder_;
55 } 56 }
56 57
57 void StreamingScopeBuilder::DiscoverEnclosingElements(
58 Zone* zone,
59 const Function& function,
60 Function* outermost_function,
61 intptr_t* outermost_kernel_offset,
62 intptr_t* parent_class_offset) {
63 // Find out if there is an enclosing kernel class (which will be used to
64 // resolve type parameters).
65 *outermost_function = function.raw();
66 while (outermost_function->parent_function() != Object::null()) {
67 *outermost_function = outermost_function->parent_function();
68 }
69
70 if (outermost_function->kernel_function() != NULL) {
71 *outermost_kernel_offset =
72 static_cast<TreeNode*>(outermost_function->kernel_function())
73 ->kernel_offset();
74 *parent_class_offset = GetParentOffset(*outermost_kernel_offset);
75 }
76 }
77
78 ScopeBuildingResult* StreamingScopeBuilder::BuildScopes() { 58 ScopeBuildingResult* StreamingScopeBuilder::BuildScopes() {
79 if (result_ != NULL) return result_; 59 if (result_ != NULL) return result_;
80 60
81 ASSERT(scope_ == NULL && depth_.loop_ == 0 && depth_.function_ == 0); 61 ASSERT(scope_ == NULL && depth_.loop_ == 0 && depth_.function_ == 0);
82 result_ = new (Z) ScopeBuildingResult(); 62 result_ = new (Z) ScopeBuildingResult();
83 63
84 ParsedFunction* parsed_function = parsed_function_; 64 ParsedFunction* parsed_function = parsed_function_;
85 const Function& function = parsed_function->function(); 65 const Function& function = parsed_function->function();
86 66
87 // Setup a [ActiveClassScope] and a [ActiveMemberScope] which will be used 67 // Setup a [ActiveClassScope] and a [ActiveMemberScope] which will be used
88 // e.g. for type translation. 68 // e.g. for type translation.
89 const dart::Class& klass = 69 const dart::Class& klass =
90 dart::Class::Handle(zone_, parsed_function_->function().Owner()); 70 dart::Class::Handle(zone_, parsed_function_->function().Owner());
91 Function& outermost_function = Function::Handle(Z); 71 Function& outermost_function = Function::Handle(Z);
92 intptr_t outermost_kernel_offset = -1; 72 intptr_t outermost_kernel_offset = -1;
93 intptr_t parent_class_offset = -1; 73 intptr_t parent_class_offset = -1;
94 DiscoverEnclosingElements(Z, function, &outermost_function, 74 builder_->DiscoverEnclosingElements(Z, function, &outermost_function,
95 &outermost_kernel_offset, &parent_class_offset); 75 &outermost_kernel_offset,
76 &parent_class_offset);
96 // Use [klass]/[kernel_class] as active class. Type parameters will get 77 // Use [klass]/[kernel_class] as active class. Type parameters will get
97 // resolved via [kernel_class] unless we are nested inside a static factory 78 // resolved via [kernel_class] unless we are nested inside a static factory
98 // in which case we will use [member]. 79 // in which case we will use [member].
99 intptr_t class_type_parameters = 0; 80 intptr_t class_type_parameters = 0;
100 intptr_t class_type_parameters_offset_start = -1; 81 intptr_t class_type_parameters_offset_start = -1;
101 if (parent_class_offset > 0) { 82 if (parent_class_offset > 0) {
102 GetTypeParameterInfoForClass(parent_class_offset, &class_type_parameters, 83 builder_->GetTypeParameterInfoForClass(parent_class_offset,
103 &class_type_parameters_offset_start); 84 &class_type_parameters,
85 &class_type_parameters_offset_start);
104 } 86 }
105 ActiveClassScope active_class_scope(&active_class_, class_type_parameters, 87 ActiveClassScope active_class_scope(&active_class_, class_type_parameters,
106 class_type_parameters_offset_start, 88 class_type_parameters_offset_start,
107 &klass); 89 &klass);
108 90
109 bool member_is_procedure = false; 91 bool member_is_procedure = false;
110 bool is_factory_procedure = false; 92 bool is_factory_procedure = false;
111 intptr_t member_type_parameters = 0; 93 intptr_t member_type_parameters = 0;
112 intptr_t member_type_parameters_offset_start = -1; 94 intptr_t member_type_parameters_offset_start = -1;
113 GetTypeParameterInfoForPossibleProcedure( 95 builder_->GetTypeParameterInfoForPossibleProcedure(
114 outermost_kernel_offset, &member_is_procedure, &is_factory_procedure, 96 outermost_kernel_offset, &member_is_procedure, &is_factory_procedure,
115 &member_type_parameters, &member_type_parameters_offset_start); 97 &member_type_parameters, &member_type_parameters_offset_start);
116 98
117 ActiveMemberScope active_member(&active_class_, member_is_procedure, 99 ActiveMemberScope active_member(&active_class_, member_is_procedure,
118 is_factory_procedure, member_type_parameters, 100 is_factory_procedure, member_type_parameters,
119 member_type_parameters_offset_start); 101 member_type_parameters_offset_start);
120 102
121 LocalScope* enclosing_scope = NULL; 103 LocalScope* enclosing_scope = NULL;
122 if (function.IsLocalFunction()) { 104 if (function.IsLocalFunction()) {
123 enclosing_scope = LocalScope::RestoreOuterScope( 105 enclosing_scope = LocalScope::RestoreOuterScope(
(...skipping 13 matching lines...) Expand all
137 intptr_t parent_offset = -1; 119 intptr_t parent_offset = -1;
138 builder_->SetOffset(kernel_offset_); 120 builder_->SetOffset(kernel_offset_);
139 121
140 switch (function.kind()) { 122 switch (function.kind()) {
141 case RawFunction::kClosureFunction: 123 case RawFunction::kClosureFunction:
142 case RawFunction::kRegularFunction: 124 case RawFunction::kRegularFunction:
143 case RawFunction::kGetterFunction: 125 case RawFunction::kGetterFunction:
144 case RawFunction::kSetterFunction: 126 case RawFunction::kSetterFunction:
145 case RawFunction::kConstructor: { 127 case RawFunction::kConstructor: {
146 const Tag tag = builder_->PeekTag(); 128 const Tag tag = builder_->PeekTag();
147 if (tag == kProcedure) { 129 parent_offset = builder_->ReadUntilFunctionNode();
148 Tag has_function_node = ReadProcedureUntilFunctionNode(
149 &unused_word, &unused_intptr); // read first part of procedure.
150 if (has_function_node == kNothing) {
151 // Running a procedure without a function node doesn't make sense.
152 UNREACHABLE();
153 }
154 // Now at start of FunctionNode.
155 } else if (tag == kConstructor) {
156 // read first part of constructor.
157 parent_offset = ReadConstructorUntilFunctionNode();
158 // Now at start of FunctionNode.
159 // Notice that we also have a list of initializers after that!
160 } else if (tag == kFunctionNode) {
161 // Already at start of FunctionNode.
162 } else {
163 UNREACHABLE();
164 }
165 word async_marker_word; 130 word async_marker_word;
166 ReadFunctionNodeUntilTypeParameters( 131 builder_->ReadFunctionNodeUntilTypeParameters(
167 &async_marker_word, 132 &unused_tokenposition, &unused_tokenposition, &async_marker_word,
168 &unused_word); // read first part of function node. 133 &unused_word); // read first part of function node.
169 current_function_async_marker_ = 134 current_function_async_marker_ =
170 static_cast<FunctionNode::AsyncMarker>(async_marker_word); 135 static_cast<FunctionNode::AsyncMarker>(async_marker_word);
171 // NOTE: FunctionNode is not read entirely yet! It continues below the if. 136 // NOTE: FunctionNode is not read entirely yet! It continues below the if.
172 137
173 intptr_t pos = 0; 138 intptr_t pos = 0;
174 if (function.IsClosureFunction()) { 139 if (function.IsClosureFunction()) {
175 LocalVariable* variable = MakeVariable( 140 LocalVariable* variable = MakeVariable(
176 TokenPosition::kNoSource, TokenPosition::kNoSource, 141 TokenPosition::kNoSource, TokenPosition::kNoSource,
177 Symbols::ClosureParameter(), AbstractType::dynamic_type()); 142 Symbols::ClosureParameter(), AbstractType::dynamic_type());
178 variable->set_is_forced_stack(); 143 variable->set_is_forced_stack();
179 scope_->InsertParameterAt(pos++, variable); 144 scope_->InsertParameterAt(pos++, variable);
180 } else if (!function.is_static()) { 145 } else if (!function.is_static()) {
181 // We use [is_static] instead of [IsStaticFunction] because the latter 146 // We use [is_static] instead of [IsStaticFunction] because the latter
182 // returns `false` for constructors. 147 // returns `false` for constructors.
183 dart::Class& klass = dart::Class::Handle(Z, function.Owner()); 148 dart::Class& klass = dart::Class::Handle(Z, function.Owner());
184 Type& klass_type = H.GetCanonicalType(klass); 149 Type& klass_type = H.GetCanonicalType(klass);
185 LocalVariable* variable = 150 LocalVariable* variable =
186 MakeVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, 151 MakeVariable(TokenPosition::kNoSource, TokenPosition::kNoSource,
187 Symbols::This(), klass_type); 152 Symbols::This(), klass_type);
188 scope_->InsertParameterAt(pos++, variable); 153 scope_->InsertParameterAt(pos++, variable);
189 result_->this_variable = variable; 154 result_->this_variable = variable;
190 155
191 // We visit instance field initializers because they might contain 156 // We visit instance field initializers because they might contain
192 // [Let] expressions and we need to have a mapping. 157 // [Let] expressions and we need to have a mapping.
193 if (tag == kConstructor) { 158 if (tag == kConstructor) {
194 ASSERT(parent_offset >= 0); 159 ASSERT(parent_offset >= 0);
195 AlternativeReadingScope alt(builder_->reader_, parent_offset); 160 AlternativeReadingScope alt(builder_->reader_, parent_offset);
196 ReadClassUntilFields(); // read first part of class. 161 builder_->ReadClassUntilFields(); // read first part of class.
197 intptr_t list_length = 162 intptr_t list_length =
198 builder_->ReadListLength(); // read fields list length. 163 builder_->ReadListLength(); // read fields list length.
199 for (intptr_t i = 0; i < list_length; i++) { 164 for (intptr_t i = 0; i < list_length; i++) {
200 intptr_t field_offset = builder_->ReaderOffset(); 165 intptr_t field_offset = builder_->ReaderOffset();
201 TokenPosition position; 166 TokenPosition position;
202 TokenPosition end_position; 167 TokenPosition end_position;
203 word flags; 168 word flags;
204 ReadFieldUntilAnnotation(&position, &end_position, &flags, 169 builder_->ReadFieldUntilAnnotation(&unused_nameindex, &position,
205 &unused_intptr); 170 &end_position, &flags,
171 &unused_intptr);
206 bool is_static = (flags & Field::kFlagStatic) == Field::kFlagStatic; 172 bool is_static = (flags & Field::kFlagStatic) == Field::kFlagStatic;
207 builder_->SkipListOfExpressions(); // read annotations. 173 builder_->SkipListOfExpressions(); // read annotations.
208 builder_->SkipDartType(); // read type. 174 builder_->SkipDartType(); // read type.
209 Tag initializer_tag = builder_->ReadTag(); 175 Tag initializer_tag =
176 builder_->ReadTag(); // read first part of initializer.
210 if (!is_static && initializer_tag == kSomething) { 177 if (!is_static && initializer_tag == kSomething) {
211 EnterScope(field_offset); 178 EnterScope(field_offset);
212 VisitExpression(); // read initializer. 179 VisitExpression(); // read initializer.
213 ExitScope(position, end_position); 180 ExitScope(position, end_position);
214 } else if (initializer_tag == kSomething) { 181 } else if (initializer_tag == kSomething) {
215 builder_->SkipExpression(); // read initializer. 182 builder_->SkipExpression(); // read initializer.
216 } 183 }
217 } 184 }
218 } 185 }
219 } else if (function.IsFactory()) { 186 } else if (function.IsFactory()) {
220 LocalVariable* variable = MakeVariable( 187 LocalVariable* variable = MakeVariable(
221 TokenPosition::kNoSource, TokenPosition::kNoSource, 188 TokenPosition::kNoSource, TokenPosition::kNoSource,
222 Symbols::TypeArgumentsParameter(), AbstractType::dynamic_type()); 189 Symbols::TypeArgumentsParameter(), AbstractType::dynamic_type());
223 scope_->InsertParameterAt(pos++, variable); 190 scope_->InsertParameterAt(pos++, variable);
224 result_->type_arguments_variable = variable; 191 result_->type_arguments_variable = variable;
225 } 192 }
226 193
227 // Continue reading FunctionNode. 194 // Continue reading FunctionNode.
228 builder_->SkipTypeParametersList(); // read type_parameters. 195 builder_->SkipTypeParametersList(); // read type_parameters.
229 builder_->ReadUInt(); // read required_parameter_count. 196 builder_->ReadUInt(); // read required_parameter_count.
197 builder_->ReadUInt(); // read total parameter count.
230 AddPositionalAndNamedParameters( 198 AddPositionalAndNamedParameters(
231 pos); // read positional_parameters and named_parameters. 199 pos); // read positional_parameters and named_parameters.
232 200
233 // We generate a syntethic body for implicit closure functions - which 201 // We generate a syntethic body for implicit closure functions - which
234 // will forward the call to the real function. 202 // will forward the call to the real function.
235 // -> see BuildGraphOfImplicitClosureFunction 203 // -> see BuildGraphOfImplicitClosureFunction
236 if (!function.IsImplicitClosureFunction()) { 204 if (!function.IsImplicitClosureFunction()) {
237 builder_->SetOffset(kernel_offset_); 205 builder_->SetOffset(kernel_offset_);
238 first_body_token_position_ = TokenPosition::kNoSource; 206 first_body_token_position_ = TokenPosition::kNoSource;
239 VisitNode(); 207 VisitNode();
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
312 UNREACHABLE(); 280 UNREACHABLE();
313 } 281 }
314 if (needs_expr_temp_) { 282 if (needs_expr_temp_) {
315 scope_->AddVariable(parsed_function_->EnsureExpressionTemp()); 283 scope_->AddVariable(parsed_function_->EnsureExpressionTemp());
316 } 284 }
317 parsed_function->AllocateVariables(); 285 parsed_function->AllocateVariables();
318 286
319 return result_; 287 return result_;
320 } 288 }
321 289
322 intptr_t StreamingScopeBuilder::GetParentOffset(intptr_t offset) {
323 AlternativeReadingScope alt(builder_->reader_, offset);
324
325 Tag tag = builder_->PeekTag();
326 intptr_t parent_offset = -1;
327 switch (tag) {
328 case kConstructor:
329 return ReadConstructorUntilFunctionNode();
330 case kProcedure:
331 ReadProcedureUntilFunctionNode(
332 &unused_word, &parent_offset); // read first part of procedure.
333 return parent_offset;
334 case kField:
335 ReadFieldUntilAnnotation(&unused_tokenposition, &unused_tokenposition,
336 &unused_word, &parent_offset);
337 return parent_offset;
338 default:
339 UNIMPLEMENTED();
340 return -1;
341 }
342 }
343
344 void StreamingScopeBuilder::GetTypeParameterInfoForClass(
345 intptr_t class_offset,
346 intptr_t* type_paremeter_counts,
347 intptr_t* type_paremeter_offset) {
348 AlternativeReadingScope alt(builder_->reader_, class_offset);
349
350 ReadClassUntilTypeParameters();
351 *type_paremeter_counts =
352 builder_->ReadListLength(); // read type_parameters list length.
353 *type_paremeter_offset = builder_->ReaderOffset();
354 }
355
356 void StreamingScopeBuilder::VisitNode() { 290 void StreamingScopeBuilder::VisitNode() {
357 Tag tag = builder_->PeekTag(); 291 Tag tag = builder_->PeekTag();
358 switch (tag) { 292 switch (tag) {
359 case kConstructor: 293 case kConstructor:
360 VisitConstructor(); 294 VisitConstructor();
361 return; 295 return;
362 case kProcedure: 296 case kProcedure:
363 VisitProcedure(); 297 VisitProcedure();
364 return; 298 return;
365 case kField: 299 case kField:
366 VisitField(); 300 VisitField();
367 return; 301 return;
368 case kFunctionNode: 302 case kFunctionNode:
369 VisitFunctionNode(); 303 VisitFunctionNode();
370 return; 304 return;
371 default: 305 default:
372 UNIMPLEMENTED(); 306 UNIMPLEMENTED();
373 return; 307 return;
374 } 308 }
375 } 309 }
376 310
377 intptr_t StreamingScopeBuilder::ReadConstructorUntilFunctionNode() {
378 Tag tag = builder_->ReadTag();
379 ASSERT(tag == kConstructor);
380 builder_->SkipCanonicalNameReference(); // read canonical name reference.
381 builder_->ReadPosition(); // read position.
382 builder_->ReadPosition(); // read end position.
383 builder_->ReadFlags(); // read flags.
384 intptr_t parent_offset = builder_->ReadUInt(); // parent class binary offset.
385 builder_->SkipName(); // read name.
386 builder_->SkipListOfExpressions(); // read annotations.
387 return parent_offset;
388 }
389
390 void StreamingScopeBuilder::VisitConstructor() { 311 void StreamingScopeBuilder::VisitConstructor() {
391 // Field initializers that come from non-static field declarations are 312 // Field initializers that come from non-static field declarations are
392 // compiled as if they appear in the constructor initializer list. This is 313 // compiled as if they appear in the constructor initializer list. This is
393 // important for closure-valued field initializers because the VM expects the 314 // important for closure-valued field initializers because the VM expects the
394 // corresponding closure functions to appear as if they were nested inside the 315 // corresponding closure functions to appear as if they were nested inside the
395 // constructor. 316 // constructor.
396 intptr_t parent_offset = ReadConstructorUntilFunctionNode(); 317 intptr_t parent_offset = builder_->ReadConstructorUntilFunctionNode();
397 ASSERT(parent_offset >= 0); 318 ASSERT(parent_offset >= 0);
398 { 319 {
399 AlternativeReadingScope alt(builder_->reader_, parent_offset); 320 AlternativeReadingScope alt(builder_->reader_, parent_offset);
400 ReadClassUntilFields(); // read first part of class. 321 builder_->ReadClassUntilFields(); // read first part of class.
401 322
402 intptr_t list_length = 323 intptr_t list_length =
403 builder_->ReadListLength(); // read fields list length. 324 builder_->ReadListLength(); // read fields list length.
404 for (intptr_t i = 0; i < list_length; i++) { 325 for (intptr_t i = 0; i < list_length; i++) {
405 word flags; 326 word flags;
406 ReadFieldUntilAnnotation(&unused_tokenposition, &unused_tokenposition, 327 builder_->ReadFieldUntilAnnotation(
407 &flags, &unused_intptr); 328 &unused_nameindex, &unused_tokenposition, &unused_tokenposition,
329 &flags, &unused_intptr);
408 bool is_static = (flags & Field::kFlagStatic) == Field::kFlagStatic; 330 bool is_static = (flags & Field::kFlagStatic) == Field::kFlagStatic;
409 builder_->SkipListOfExpressions(); // read annotations. 331 builder_->SkipListOfExpressions(); // read annotations.
410 builder_->SkipDartType(); // read type. 332 builder_->SkipDartType(); // read type.
411 Tag initializer_tag = builder_->ReadTag(); 333 Tag initializer_tag = builder_->ReadTag();
412 if (!is_static && initializer_tag == kSomething) { 334 if (!is_static && initializer_tag == kSomething) {
413 VisitExpression(); // read initializer. 335 VisitExpression(); // read initializer.
414 } else if (initializer_tag == kSomething) { 336 } else if (initializer_tag == kSomething) {
415 builder_->SkipExpression(); // read initializer. 337 builder_->SkipExpression(); // read initializer.
416 } 338 }
417 } 339 }
418 } 340 }
419 341
420 // Visit children (note that there's no reason to visit the name). 342 // Visit children (note that there's no reason to visit the name).
421 VisitFunctionNode(); 343 VisitFunctionNode();
422 intptr_t list_length = 344 intptr_t list_length =
423 builder_->ReadListLength(); // read initializers list length. 345 builder_->ReadListLength(); // read initializers list length.
424 for (intptr_t i = 0; i < list_length; i++) { 346 for (intptr_t i = 0; i < list_length; i++) {
425 VisitInitializer(); 347 VisitInitializer();
426 } 348 }
427 } 349 }
428 350
429 void StreamingScopeBuilder::VisitProcedure() { 351 void StreamingScopeBuilder::VisitProcedure() {
430 Tag function_node = ReadProcedureUntilFunctionNode( 352 Tag function_node = builder_->ReadProcedureUntilFunctionNode(
431 &unused_word, &unused_intptr); // read first part of procedure. 353 &unused_word, &unused_intptr); // read first part of procedure.
432 if (function_node == kSomething) { 354 if (function_node == kSomething) {
433 VisitFunctionNode(); 355 VisitFunctionNode();
434 } 356 }
435 } 357 }
436 358
437 void StreamingScopeBuilder::ReadFieldUntilAnnotation(
438 TokenPosition* position,
439 TokenPosition* end_position,
440 word* flags,
441 intptr_t* parent_offset) {
442 Tag tag = builder_->ReadTag();
443 ASSERT(tag == kField);
444
445 builder_->SkipCanonicalNameReference(); // read canonical_name.
446 *position = builder_->ReadPosition(); // read position.
447 *end_position = builder_->ReadPosition(); // read end position.
448 *flags = builder_->ReadFlags(); // read flags.
449 *parent_offset = builder_->ReadUInt(); // read parent class binary offset.
450 builder_->SkipName(); // read name.
451 builder_->ReadUInt(); // source_uri_index.
452 }
453
454 void StreamingScopeBuilder::VisitField() { 359 void StreamingScopeBuilder::VisitField() {
455 ReadFieldUntilAnnotation(&unused_tokenposition, &unused_tokenposition, 360 builder_->ReadFieldUntilAnnotation(
456 &unused_intptr, 361 &unused_nameindex, &unused_tokenposition, &unused_tokenposition,
457 &unused_word); // read first part of field. 362 &unused_intptr, &unused_word); // read first part of field.
458 builder_->SkipListOfExpressions(); // read annotations. 363 builder_->SkipListOfExpressions(); // read annotations.
459 VisitDartType(); // read type. 364 VisitDartType(); // read type.
460 Tag tag = builder_->ReadTag(); // read initializer (part 1). 365 Tag tag = builder_->ReadTag(); // read initializer (part 1).
461 if (tag == kSomething) { 366 if (tag == kSomething) {
462 VisitExpression(); // read initializer (part 2). 367 VisitExpression(); // read initializer (part 2).
463 } 368 }
464 } 369 }
465 370
466 Tag StreamingScopeBuilder::ReadProcedureUntilFunctionNode(
467 word* kind,
468 intptr_t* parent_offset) {
469 Tag tag = builder_->ReadTag(); // read tag.
470 ASSERT(tag == kProcedure);
471 builder_->SkipCanonicalNameReference(); // read canonical name reference.
472 builder_->ReadPosition(); // read position.
473 builder_->ReadPosition(); // read end position.
474 *kind = builder_->ReadByte(); // read kind.
475 builder_->ReadFlags(); // read flags.
476 *parent_offset = builder_->ReadUInt(); // read parent class binary offset.
477 builder_->SkipName(); // read name,
478 builder_->ReadUInt(); // read source_uri_index.
479 builder_->SkipListOfExpressions(); // read annotations.
480 return builder_->ReadTag(); // read tag for optional function node.
481 }
482
483 void StreamingScopeBuilder::GetTypeParameterInfoForPossibleProcedure(
484 intptr_t outermost_kernel_offset,
485 bool* member_is_procedure,
486 bool* is_factory_procedure,
487 intptr_t* member_type_parameters,
488 intptr_t* member_type_parameters_offset_start) {
489 if (outermost_kernel_offset >= 0) {
490 AlternativeReadingScope alt(builder_->reader_, outermost_kernel_offset);
491 Tag tag = builder_->PeekTag();
492 if (tag == kProcedure) {
493 *member_is_procedure = true;
494
495 word kind;
496 tag = ReadProcedureUntilFunctionNode(
497 &kind, &unused_intptr); // read first part of procedure.
498 *is_factory_procedure =
499 static_cast<Procedure::ProcedureKind>(kind) == Procedure::kFactory;
500
501 if (tag == kSomething) {
502 ReadFunctionNodeUntilTypeParameters(
503 &unused_word, &unused_word); // read first part of function node.
504
505 intptr_t list_length =
506 builder_->ReadListLength(); // read type_parameters list length.
507 if (list_length > 0) {
508 *member_type_parameters = list_length;
509 *member_type_parameters_offset_start = builder_->ReaderOffset();
510 }
511 }
512 }
513 }
514 }
515
516 void StreamingScopeBuilder::ReadClassUntilTypeParameters() {
517 Tag class_tag = builder_->ReadTag();
518 ASSERT(class_tag == kClass);
519 builder_->SkipCanonicalNameReference(); // read canonical_name.
520 builder_->ReadPosition(); // read position.
521 builder_->ReadBool(); // read is_abstract.
522 builder_->SkipStringReference(); // read name index.
523 builder_->ReadUInt(); // read source_uri_index.
524 builder_->SkipListOfExpressions(); // read annotations.
525 }
526
527 void StreamingScopeBuilder::ReadClassUntilFields() {
528 ReadClassUntilTypeParameters();
529 builder_->SkipTypeParametersList(); // read type_parameters.
530 Tag type_tag = builder_->ReadTag(); // read type (part 1).
531 if (type_tag == kSomething) {
532 builder_->SkipDartType(); // read type (part 2).
533 }
534 type_tag = builder_->ReadTag(); // read Mixed-in type (part 1).
535 if (type_tag == kSomething) {
536 builder_->SkipDartType(); // read Mixed-in type (part 2).
537 }
538 builder_->SkipListOfDartTypes(); // read implemented_classes.
539 }
540
541 void StreamingScopeBuilder::ReadFunctionNodeUntilTypeParameters(
542 word* async_marker,
543 word* dart_async_marker) {
544 Tag tag = builder_->ReadTag(); // read tag.
545 ASSERT(tag == kFunctionNode);
546
547 builder_->ReadPosition(); // read position.
548 builder_->ReadPosition(); // read end position.
549 *async_marker = builder_->ReadByte(); // read async marker.
550 *dart_async_marker = builder_->ReadByte(); // read dart async marker.
551 }
552
553 void StreamingScopeBuilder::VisitFunctionNode() { 371 void StreamingScopeBuilder::VisitFunctionNode() {
554 word async_marker_word; 372 word async_marker_word;
555 word dart_async_marker_word; 373 word dart_async_marker_word;
556 ReadFunctionNodeUntilTypeParameters(&async_marker_word, 374 builder_->ReadFunctionNodeUntilTypeParameters(
557 &dart_async_marker_word); 375 &unused_tokenposition, &unused_tokenposition, &async_marker_word,
376 &dart_async_marker_word);
558 FunctionNode::AsyncMarker async_marker = 377 FunctionNode::AsyncMarker async_marker =
559 static_cast<FunctionNode::AsyncMarker>(async_marker_word); 378 static_cast<FunctionNode::AsyncMarker>(async_marker_word);
560 FunctionNode::AsyncMarker dart_async_marker = 379 FunctionNode::AsyncMarker dart_async_marker =
561 static_cast<FunctionNode::AsyncMarker>(dart_async_marker_word); 380 static_cast<FunctionNode::AsyncMarker>(dart_async_marker_word);
562 381
563 intptr_t list_length = 382 intptr_t list_length =
564 builder_->ReadListLength(); // read type_parameters list length. 383 builder_->ReadListLength(); // read type_parameters list length.
565 for (intptr_t i = 0; i < list_length; ++i) { 384 for (intptr_t i = 0; i < list_length; ++i) {
566 builder_->SkipStringReference(); // read ith name index. 385 builder_->SkipStringReference(); // read ith name index.
567 VisitDartType(); // read ith bound. 386 VisitDartType(); // read ith bound.
(...skipping 15 matching lines...) Expand all
583 i < parsed_function_->function().NumOptionalPositionalParameters(); 402 i < parsed_function_->function().NumOptionalPositionalParameters();
584 i++) { 403 i++) {
585 scope->VariableAt(offset + i)->set_is_forced_stack(); 404 scope->VariableAt(offset + i)->set_is_forced_stack();
586 } 405 }
587 } 406 }
588 407
589 // Read (but don't visit) the positional and named parameters, because they've 408 // Read (but don't visit) the positional and named parameters, because they've
590 // already been added to the scope. 409 // already been added to the scope.
591 410
592 builder_->ReadUInt(); // read required_parameter_count. 411 builder_->ReadUInt(); // read required_parameter_count.
412 builder_->ReadUInt(); // read total parameter count.
593 413
594 builder_->SkipListOfVariableDeclarations(); // read list of positionals. 414 builder_->SkipListOfVariableDeclarations(); // read list of positionals.
595 builder_->SkipListOfVariableDeclarations(); // read list of named. 415 builder_->SkipListOfVariableDeclarations(); // read list of named.
596 builder_->SkipDartType(); // read return type. 416 builder_->SkipDartType(); // read return type.
597 417
598 if (builder_->ReadTag() == kSomething) { 418 if (builder_->ReadTag() == kSomething) {
599 PositionScope scope(builder_->reader_); 419 PositionScope scope(builder_->reader_);
600 VisitStatement(); // Read body 420 VisitStatement(); // Read body
601 first_body_token_position_ = builder_->reader_->min_position(); 421 first_body_token_position_ = builder_->reader_->min_position();
602 } 422 }
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
636 void StreamingScopeBuilder::VisitInitializer() { 456 void StreamingScopeBuilder::VisitInitializer() {
637 Tag tag = builder_->ReadTag(); 457 Tag tag = builder_->ReadTag();
638 switch (tag) { 458 switch (tag) {
639 case kInvalidInitializer: 459 case kInvalidInitializer:
640 return; 460 return;
641 case kFieldInitializer: 461 case kFieldInitializer:
642 builder_->SkipCanonicalNameReference(); // read field_reference. 462 builder_->SkipCanonicalNameReference(); // read field_reference.
643 VisitExpression(); // read value. 463 VisitExpression(); // read value.
644 return; 464 return;
645 case kSuperInitializer: 465 case kSuperInitializer:
646 builder_->SkipCanonicalNameReference(); // read field_reference. 466 builder_->SkipCanonicalNameReference(); // read target_reference.
647 VisitArguments(); // read arguments. 467 VisitArguments(); // read arguments.
648 return; 468 return;
649 case kRedirectingInitializer: 469 case kRedirectingInitializer:
650 builder_->SkipCanonicalNameReference(); // read field_reference. 470 builder_->SkipCanonicalNameReference(); // read target_reference.
651 VisitArguments(); // read arguments. 471 VisitArguments(); // read arguments.
652 return; 472 return;
653 case kLocalInitializer: 473 case kLocalInitializer:
654 VisitVariableDeclaration(); // read variable. 474 VisitVariableDeclaration(); // read variable.
655 return; 475 return;
656 default: 476 default:
657 UNREACHABLE(); 477 UNREACHABLE();
658 } 478 }
659 } 479 }
660 480
(...skipping 653 matching lines...) Expand 10 before | Expand all | Expand 10 after
1314 depth_ = DepthState(depth_.function_ + 1); 1134 depth_ = DepthState(depth_.function_ + 1);
1315 EnterScope(parent_kernel_offset); 1135 EnterScope(parent_kernel_offset);
1316 current_function_scope_ = scope_; 1136 current_function_scope_ = scope_;
1317 current_function_async_marker_ = async_marker; 1137 current_function_async_marker_ = async_marker;
1318 if (depth_.function_ == 1) { 1138 if (depth_.function_ == 1) {
1319 FunctionScope function_scope = {offset, scope_}; 1139 FunctionScope function_scope = {offset, scope_};
1320 result_->function_scopes.Add(function_scope); 1140 result_->function_scopes.Add(function_scope);
1321 } 1141 }
1322 1142
1323 builder_->ReadUInt(); // read required_parameter_count. 1143 builder_->ReadUInt(); // read required_parameter_count.
1144 builder_->ReadUInt(); // read total parameter count.
1324 // read positional_parameters and named_parameters. 1145 // read positional_parameters and named_parameters.
1325 AddPositionalAndNamedParameters(); 1146 AddPositionalAndNamedParameters();
1326 1147
1327 // "Peek" is now done. 1148 // "Peek" is now done.
1328 builder_->SetOffset(offset); 1149 builder_->SetOffset(offset);
1329 1150
1330 VisitFunctionNode(); // read function node. 1151 VisitFunctionNode(); // read function node.
1331 1152
1332 ExitScope(position, end_position); 1153 ExitScope(position, end_position);
1333 depth_ = saved_depth_state; 1154 depth_ = saved_depth_state;
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
1474 if ((depth_.function_ == 0) && (result_->switch_variable == NULL)) { 1295 if ((depth_.function_ == 0) && (result_->switch_variable == NULL)) {
1475 LocalVariable* variable = 1296 LocalVariable* variable =
1476 MakeVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, 1297 MakeVariable(TokenPosition::kNoSource, TokenPosition::kNoSource,
1477 Symbols::SwitchExpr(), AbstractType::dynamic_type()); 1298 Symbols::SwitchExpr(), AbstractType::dynamic_type());
1478 variable->set_is_forced_stack(); 1299 variable->set_is_forced_stack();
1479 current_function_scope_->AddVariable(variable); 1300 current_function_scope_->AddVariable(variable);
1480 result_->switch_variable = variable; 1301 result_->switch_variable = variable;
1481 } 1302 }
1482 } 1303 }
1483 1304
1484 StringIndex StreamingScopeBuilder::GetNameFromVariableDeclaration(
1485 intptr_t kernel_offset) {
1486 // Temporarily go to the variable declaration, read the name.
1487 AlternativeReadingScope alt(builder_->reader_, kernel_offset);
1488 builder_->ReadPosition(); // read position.
1489 builder_->ReadPosition(); // read equals position.
1490 builder_->ReadFlags(); // read flags.
1491 return builder_->ReadStringReference(); // read name index.
1492 }
1493
1494 void StreamingScopeBuilder::LookupVariable(intptr_t declaration_binary_offest) { 1305 void StreamingScopeBuilder::LookupVariable(intptr_t declaration_binary_offest) {
1495 LocalVariable* variable = result_->locals.Lookup(declaration_binary_offest); 1306 LocalVariable* variable = result_->locals.Lookup(declaration_binary_offest);
1496 if (variable == NULL) { 1307 if (variable == NULL) {
1497 // We have not seen a declaration of the variable, so it must be the 1308 // We have not seen a declaration of the variable, so it must be the
1498 // case that we are compiling a nested function and the variable is 1309 // case that we are compiling a nested function and the variable is
1499 // declared in an outer scope. In that case, look it up in the scope by 1310 // declared in an outer scope. In that case, look it up in the scope by
1500 // name and add it to the variable map to simplify later lookup. 1311 // name and add it to the variable map to simplify later lookup.
1501 ASSERT(current_function_scope_->parent() != NULL); 1312 ASSERT(current_function_scope_->parent() != NULL);
1502 1313
1503 StringIndex var_name = 1314 StringIndex var_name =
1504 GetNameFromVariableDeclaration(declaration_binary_offest); 1315 builder_->GetNameFromVariableDeclaration(declaration_binary_offest);
1505 1316
1506 const dart::String& name = H.DartSymbol(var_name); 1317 const dart::String& name = H.DartSymbol(var_name);
1507 variable = current_function_scope_->parent()->LookupVariable(name, true); 1318 variable = current_function_scope_->parent()->LookupVariable(name, true);
1508 ASSERT(variable != NULL); 1319 ASSERT(variable != NULL);
1509 result_->locals.Insert(declaration_binary_offest, variable); 1320 result_->locals.Insert(declaration_binary_offest, variable);
1510 } 1321 }
1511 1322
1512 if (variable->owner()->function_level() < scope_->function_level()) { 1323 if (variable->owner()->function_level() < scope_->function_level()) {
1513 // We call `LocalScope->CaptureVariable(variable)` in two scenarios for two 1324 // We call `LocalScope->CaptureVariable(variable)` in two scenarios for two
1514 // different reasons: 1325 // different reasons:
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1579 1390
1580 1391
1581 AbstractType& StreamingDartTypeTranslator::BuildType() { 1392 AbstractType& StreamingDartTypeTranslator::BuildType() {
1582 BuildTypeInternal(); 1393 BuildTypeInternal();
1583 1394
1584 // We return a new `ZoneHandle` here on purpose: The intermediate language 1395 // We return a new `ZoneHandle` here on purpose: The intermediate language
1585 // instructions do not make a copy of the handle, so we do it. 1396 // instructions do not make a copy of the handle, so we do it.
1586 return dart::AbstractType::ZoneHandle(Z, result_.raw()); 1397 return dart::AbstractType::ZoneHandle(Z, result_.raw());
1587 } 1398 }
1588 1399
1400 AbstractType& StreamingDartTypeTranslator::BuildTypeWithoutFinalization() {
1401 bool saved_finalize = finalize_;
1402 finalize_ = false;
1403 BuildTypeInternal();
1404 finalize_ = saved_finalize;
1405
1406 // We return a new `ZoneHandle` here on purpose: The intermediate language
1407 // instructions do not make a copy of the handle, so we do it.
1408 return dart::AbstractType::ZoneHandle(Z, result_.raw());
1409 }
1410
1589 AbstractType& StreamingDartTypeTranslator::BuildVariableType() { 1411 AbstractType& StreamingDartTypeTranslator::BuildVariableType() {
1590 AbstractType& abstract_type = BuildType(); 1412 AbstractType& abstract_type = BuildType();
1591 1413
1592 // We return a new `ZoneHandle` here on purpose: The intermediate language 1414 // We return a new `ZoneHandle` here on purpose: The intermediate language
1593 // instructions do not make a copy of the handle, so we do it. 1415 // instructions do not make a copy of the handle, so we do it.
1594 AbstractType& type = Type::ZoneHandle(Z); 1416 AbstractType& type = Type::ZoneHandle(Z);
1595 1417
1596 if (abstract_type.IsMalformed()) { 1418 if (abstract_type.IsMalformed()) {
1597 type = AbstractType::dynamic_type().raw(); 1419 type = AbstractType::dynamic_type().raw();
1598 } else { 1420 } else {
(...skipping 579 matching lines...) Expand 10 before | Expand all | Expand 10 after
2178 } else { 2000 } else {
2179 result_ = field.StaticValue(); 2001 result_ = field.StaticValue();
2180 } 2002 }
2181 } else if (H.IsProcedure(target)) { 2003 } else if (H.IsProcedure(target)) {
2182 const Function& function = 2004 const Function& function =
2183 Function::ZoneHandle(Z, H.LookupStaticMethodByKernelProcedure(target)); 2005 Function::ZoneHandle(Z, H.LookupStaticMethodByKernelProcedure(target));
2184 2006
2185 if (H.IsMethod(target)) { 2007 if (H.IsMethod(target)) {
2186 Function& closure_function = 2008 Function& closure_function =
2187 Function::ZoneHandle(Z, function.ImplicitClosureFunction()); 2009 Function::ZoneHandle(Z, function.ImplicitClosureFunction());
2188 closure_function.set_kernel_function(function.kernel_function());
2189 result_ = closure_function.ImplicitStaticClosure(); 2010 result_ = closure_function.ImplicitStaticClosure();
2190 result_ = H.Canonicalize(result_); 2011 result_ = H.Canonicalize(result_);
2191 } else if (H.IsGetter(target)) { 2012 } else if (H.IsGetter(target)) {
2192 UNIMPLEMENTED(); 2013 UNIMPLEMENTED();
2193 } else { 2014 } else {
2194 UNIMPLEMENTED(); 2015 UNIMPLEMENTED();
2195 } 2016 }
2196 } 2017 }
2197 } 2018 }
2198 2019
(...skipping 425 matching lines...) Expand 10 before | Expand all | Expand 10 after
2624 } 2445 }
2625 2446
2626 bool StreamingConstantEvaluator::EvaluateBooleanExpressionHere() { 2447 bool StreamingConstantEvaluator::EvaluateBooleanExpressionHere() {
2627 EvaluateExpression(builder_->ReaderOffset(), false); 2448 EvaluateExpression(builder_->ReaderOffset(), false);
2628 AssertBoolInCheckedMode(); 2449 AssertBoolInCheckedMode();
2629 return result_.raw() == Bool::True().raw(); 2450 return result_.raw() == Bool::True().raw();
2630 } 2451 }
2631 2452
2632 bool StreamingConstantEvaluator::GetCachedConstant(intptr_t kernel_offset, 2453 bool StreamingConstantEvaluator::GetCachedConstant(intptr_t kernel_offset,
2633 Instance* value) { 2454 Instance* value) {
2634 if (builder_ == NULL) return false; 2455 if (builder_ == NULL || builder_->flow_graph_builder_ == NULL) return false;
2635 2456
2636 const Function& function = builder_->parsed_function()->function(); 2457 const Function& function = builder_->parsed_function()->function();
2637 if (function.kind() == RawFunction::kImplicitStaticFinalGetter) { 2458 if (function.kind() == RawFunction::kImplicitStaticFinalGetter) {
2638 // Don't cache constants in initializer expressions. They get 2459 // Don't cache constants in initializer expressions. They get
2639 // evaluated only once. 2460 // evaluated only once.
2640 return false; 2461 return false;
2641 } 2462 }
2642 2463
2643 bool is_present = false; 2464 bool is_present = false;
2644 ASSERT(!script_.InVMHeap()); 2465 ASSERT(!script_.InVMHeap());
(...skipping 10 matching lines...) Expand all
2655 ++H.thread()->compiler_stats()->num_const_cache_hits; 2476 ++H.thread()->compiler_stats()->num_const_cache_hits;
2656 } 2477 }
2657 return is_present; 2478 return is_present;
2658 } 2479 }
2659 2480
2660 2481
2661 void StreamingConstantEvaluator::CacheConstantValue(intptr_t kernel_offset, 2482 void StreamingConstantEvaluator::CacheConstantValue(intptr_t kernel_offset,
2662 const Instance& value) { 2483 const Instance& value) {
2663 ASSERT(Thread::Current()->IsMutatorThread()); 2484 ASSERT(Thread::Current()->IsMutatorThread());
2664 2485
2665 if (builder_ == NULL) return; 2486 if (builder_ == NULL || builder_->flow_graph_builder_ == NULL) return;
2666 2487
2667 const Function& function = builder_->parsed_function()->function(); 2488 const Function& function = builder_->parsed_function()->function();
2668 if (function.kind() == RawFunction::kImplicitStaticFinalGetter) { 2489 if (function.kind() == RawFunction::kImplicitStaticFinalGetter) {
2669 // Don't cache constants in initializer expressions. They get 2490 // Don't cache constants in initializer expressions. They get
2670 // evaluated only once. 2491 // evaluated only once.
2671 return; 2492 return;
2672 } 2493 }
2673 const intptr_t kInitialConstMapSize = 16; 2494 const intptr_t kInitialConstMapSize = 16;
2674 ASSERT(!script_.InVMHeap()); 2495 ASSERT(!script_.InVMHeap());
2675 if (script_.compile_time_constants() == Array::null()) { 2496 if (script_.compile_time_constants() == Array::null()) {
2676 const Array& array = Array::Handle( 2497 const Array& array = Array::Handle(
2677 HashTables::New<KernelConstantsMap>(kInitialConstMapSize, Heap::kNew)); 2498 HashTables::New<KernelConstantsMap>(kInitialConstMapSize, Heap::kNew));
2678 script_.set_compile_time_constants(array); 2499 script_.set_compile_time_constants(array);
2679 } 2500 }
2680 KernelConstantsMap constants(script_.compile_time_constants()); 2501 KernelConstantsMap constants(script_.compile_time_constants());
2681 constants.InsertNewOrGetValue(kernel_offset, value); 2502 constants.InsertNewOrGetValue(kernel_offset, value);
2682 script_.set_compile_time_constants(constants.Release()); 2503 script_.set_compile_time_constants(constants.Release());
2683 } 2504 }
2684 2505
2685 2506 void StreamingFlowGraphBuilder::DiscoverEnclosingElements(
2686 Fragment StreamingFlowGraphBuilder::BuildExpressionAt(intptr_t kernel_offset) { 2507 Zone* zone,
2508 const Function& function,
2509 Function* outermost_function,
2510 intptr_t* outermost_kernel_offset,
2511 intptr_t* parent_class_offset) {
2512 // Find out if there is an enclosing kernel class (which will be used to
2513 // resolve type parameters).
2514 *outermost_function = function.raw();
2515 while (outermost_function->parent_function() != Object::null()) {
2516 *outermost_function = outermost_function->parent_function();
2517 }
2518
2519 if (outermost_function->kernel_offset() > 0) {
2520 *outermost_kernel_offset = outermost_function->kernel_offset();
2521 *parent_class_offset = GetParentOffset(*outermost_kernel_offset);
2522 }
2523 }
2524
2525 intptr_t StreamingFlowGraphBuilder::GetParentOffset(intptr_t offset) {
2526 AlternativeReadingScope alt(reader_, offset);
2527
2528 Tag tag = PeekTag();
2529 intptr_t parent_offset = -1;
2530 switch (tag) {
2531 case kConstructor:
2532 return ReadConstructorUntilFunctionNode();
2533 case kProcedure:
2534 ReadProcedureUntilFunctionNode(
2535 &unused_word, &parent_offset); // read first part of procedure.
2536 return parent_offset;
2537 case kField:
2538 ReadFieldUntilAnnotation(&unused_nameindex, &unused_tokenposition,
2539 &unused_tokenposition, &unused_word,
2540 &parent_offset);
2541 return parent_offset;
2542 default:
2543 UNIMPLEMENTED();
2544 return -1;
2545 }
2546 }
2547
2548 void StreamingFlowGraphBuilder::GetTypeParameterInfoForClass(
2549 intptr_t class_offset,
2550 intptr_t* type_paremeter_counts,
2551 intptr_t* type_paremeter_offset) {
2552 AlternativeReadingScope alt(reader_, class_offset);
2553
2554 ReadClassUntilTypeParameters();
2555 *type_paremeter_counts =
2556 ReadListLength(); // read type_parameters list length.
2557 *type_paremeter_offset = ReaderOffset();
2558 }
2559
2560 void StreamingFlowGraphBuilder::ReadClassUntilFields() {
2561 ReadClassUntilTypeParameters();
2562 SkipTypeParametersList(); // read type_parameters.
2563 Tag type_tag = ReadTag(); // read type (part 1).
2564 if (type_tag == kSomething) {
2565 SkipDartType(); // read type (part 2).
2566 }
2567 type_tag = ReadTag(); // read Mixed-in type (part 1).
2568 if (type_tag == kSomething) {
2569 SkipDartType(); // read Mixed-in type (part 2).
2570 }
2571 SkipListOfDartTypes(); // read implemented_classes.
2572 }
2573
2574 void StreamingFlowGraphBuilder::ReadClassUntilTypeParameters() {
2575 Tag class_tag = ReadTag();
2576 ASSERT(class_tag == kClass);
2577 SkipCanonicalNameReference(); // read canonical_name.
2578 ReadPosition(); // read position.
2579 ReadBool(); // read is_abstract.
2580 SkipStringReference(); // read name index.
2581 ReadUInt(); // read source_uri_index.
2582 SkipListOfExpressions(); // read annotations.
2583 }
2584
2585 intptr_t StreamingFlowGraphBuilder::ReadConstructorUntilFunctionNode() {
2586 Tag tag = ReadTag();
2587 ASSERT(tag == kConstructor);
2588 SkipCanonicalNameReference(); // read canonical name reference.
2589 ReadPosition(); // read position.
2590 ReadPosition(); // read end position.
2591 ReadFlags(); // read flags.
2592 intptr_t parent_offset = ReadUInt(); // parent class binary offset.
2593 SkipName(); // read name.
2594 SkipListOfExpressions(); // read annotations.
2595 return parent_offset;
2596 }
2597
2598 Tag StreamingFlowGraphBuilder::ReadProcedureUntilFunctionNode(
2599 word* kind,
2600 intptr_t* parent_offset) {
2601 Tag tag = ReadTag(); // read tag.
2602 ASSERT(tag == kProcedure);
2603 SkipCanonicalNameReference(); // read canonical name reference.
2604 ReadPosition(); // read position.
2605 ReadPosition(); // read end position.
2606 *kind = ReadByte(); // read kind.
2607 ReadFlags(); // read flags.
2608 *parent_offset = ReadUInt(); // read parent class binary offset.
2609 SkipName(); // read name,
2610 ReadUInt(); // read source_uri_index.
2611 SkipListOfExpressions(); // read annotations.
2612 return ReadTag(); // read tag for optional function node.
2613 }
2614
2615 void StreamingFlowGraphBuilder::ReadFieldUntilAnnotation(
2616 NameIndex* canonical_name,
2617 TokenPosition* position,
2618 TokenPosition* end_position,
2619 word* flags,
2620 intptr_t* parent_offset) {
2621 Tag tag = ReadTag();
2622 ASSERT(tag == kField);
2623
2624 *canonical_name = ReadCanonicalNameReference(); // read canonical_name.
2625 *position = ReadPosition(); // read position.
2626 *end_position = ReadPosition(); // read end position.
2627 *flags = ReadFlags(); // read flags.
2628 *parent_offset = ReadUInt(); // read parent class binary offset.
2629 SkipName(); // read name.
2630 ReadUInt(); // source_uri_index.
2631 }
2632
2633 void StreamingFlowGraphBuilder::GetTypeParameterInfoForPossibleProcedure(
2634 intptr_t outermost_kernel_offset,
2635 bool* member_is_procedure,
2636 bool* is_factory_procedure,
2637 intptr_t* member_type_parameters,
2638 intptr_t* member_type_parameters_offset_start) {
2639 if (outermost_kernel_offset >= 0) {
2640 AlternativeReadingScope alt(reader_, outermost_kernel_offset);
2641 Tag tag = PeekTag();
2642 if (tag == kProcedure) {
2643 *member_is_procedure = true;
2644
2645 word kind;
2646 tag = ReadProcedureUntilFunctionNode(
2647 &kind, &unused_intptr); // read first part of procedure.
2648 *is_factory_procedure =
2649 static_cast<Procedure::ProcedureKind>(kind) == Procedure::kFactory;
2650
2651 if (tag == kSomething) {
2652 ReadFunctionNodeUntilTypeParameters(
2653 &unused_tokenposition, &unused_tokenposition, &unused_word,
2654 &unused_word); // read first part of function node.
2655
2656 intptr_t list_length =
2657 ReadListLength(); // read type_parameters list length.
2658 if (list_length > 0) {
2659 *member_type_parameters = list_length;
2660 *member_type_parameters_offset_start = ReaderOffset();
2661 }
2662 }
2663 }
2664 }
2665 }
2666
2667 void StreamingFlowGraphBuilder::ReadFunctionNodeUntilTypeParameters(
2668 TokenPosition* position,
2669 TokenPosition* end_position,
2670 word* async_marker,
2671 word* dart_async_marker) {
2672 Tag tag = ReadTag(); // read tag.
2673 ASSERT(tag == kFunctionNode);
2674
2675 *position = ReadPosition(); // read position.
2676 *end_position = ReadPosition(); // read end position.
2677 *async_marker = ReadByte(); // read async marker.
2678 *dart_async_marker = ReadByte(); // read dart async marker.
2679 }
2680
2681 intptr_t StreamingFlowGraphBuilder::ReadUntilFunctionNode() {
2682 const Tag tag = PeekTag();
2683 if (tag == kProcedure) {
2684 Tag has_function_node = ReadProcedureUntilFunctionNode(
2685 &unused_word, &unused_intptr); // read first part of procedure.
2686 if (has_function_node == kNothing) {
2687 // Running a procedure without a function node doesn't make sense.
2688 UNREACHABLE();
2689 }
2690 return -1;
2691 // Now at start of FunctionNode.
2692 } else if (tag == kConstructor) {
2693 // read first part of constructor.
2694 return ReadConstructorUntilFunctionNode();
2695 // Now at start of FunctionNode.
2696 // Notice that we also have a list of initializers after that!
2697 } else if (tag == kFunctionNode) {
2698 // Already at start of FunctionNode.
2699 } else {
2700 UNREACHABLE();
2701 }
2702 return -1;
2703 }
2704
2705 StringIndex StreamingFlowGraphBuilder::GetNameFromVariableDeclaration(
2706 intptr_t kernel_offset) {
2707 // Temporarily go to the variable declaration, read the name.
2708 AlternativeReadingScope alt(reader_, kernel_offset);
2709 ReadPosition(); // read position.
2710 ReadPosition(); // read equals position.
2711 ReadFlags(); // read flags.
2712 return ReadStringReference(); // read name index.
2713 }
2714
2715 FlowGraph* StreamingFlowGraphBuilder::BuildGraphOfStaticFieldInitializer() {
2716 TokenPosition position;
2717 TokenPosition end_position;
2718 word flags;
2719 ReadFieldUntilAnnotation(&unused_nameindex, &position, &end_position, &flags,
2720 &unused_intptr);
2721 bool is_static = (flags & Field::kFlagStatic) == Field::kFlagStatic;
2722 bool is_const = (flags & Field::kFlagConst) == Field::kFlagConst;
2723 ASSERT(is_static);
2724
2725 SkipListOfExpressions(); // read annotations.
2726 SkipDartType(); // read type.
2727 Tag initializer_tag = ReadTag(); // read first part of initializer.
2728 if (initializer_tag != kSomething) {
2729 UNREACHABLE();
2730 }
2731
2732 TargetEntryInstr* normal_entry = flow_graph_builder_->BuildTargetEntry();
2733 flow_graph_builder_->graph_entry_ = new (Z) GraphEntryInstr(
2734 *parsed_function(), normal_entry, Compiler::kNoOSRDeoptId);
2735
2736 Fragment body(normal_entry);
2737 body += flow_graph_builder_->CheckStackOverflowInPrologue();
2738 if (is_const) {
2739 // this will (potentially) read the initializer, but reset the position.
2740 body += Constant(constant_evaluator_.EvaluateExpression(ReaderOffset()));
2741 SkipExpression(); // read the initializer.
2742 } else {
2743 body += BuildExpression(); // read initializer.
2744 }
2745 body += Return(TokenPosition::kNoSource);
2746
2747 return new (Z)
2748 FlowGraph(*parsed_function(), flow_graph_builder_->graph_entry_,
2749 flow_graph_builder_->next_block_id_ - 1);
2750 }
2751
2752 FlowGraph* StreamingFlowGraphBuilder::BuildGraphOfFieldAccessor(
2753 LocalVariable* setter_value) {
2754 NameIndex canonical_name;
2755 ReadFieldUntilAnnotation(&canonical_name, &unused_tokenposition,
2756 &unused_tokenposition, &unused_word, &unused_intptr);
2757 SkipListOfExpressions(); // read annotations.
2758 SkipDartType(); // read type.
2759 Tag initializer_tag = ReadTag(); // read first part of initializer.
2760
2761 const Function& function = parsed_function()->function();
2762
2763 bool is_setter = function.IsImplicitSetterFunction();
2764 bool is_method = !function.IsStaticFunction();
2765 dart::Field& field =
2766 dart::Field::ZoneHandle(Z, H.LookupFieldByKernelField(canonical_name));
2767
2768 TargetEntryInstr* normal_entry = flow_graph_builder_->BuildTargetEntry();
2769 flow_graph_builder_->graph_entry_ = new (Z) GraphEntryInstr(
2770 *parsed_function(), normal_entry, Compiler::kNoOSRDeoptId);
2771
2772 Fragment body(normal_entry);
2773 if (is_setter) {
2774 if (is_method) {
2775 body += LoadLocal(scopes()->this_variable);
2776 body += LoadLocal(setter_value);
2777 body += flow_graph_builder_->StoreInstanceFieldGuarded(field, false);
2778 } else {
2779 body += LoadLocal(setter_value);
2780 body += StoreStaticField(TokenPosition::kNoSource, field);
2781 }
2782 body += NullConstant();
2783 } else if (is_method) {
2784 body += LoadLocal(scopes()->this_variable);
2785 body += flow_graph_builder_->LoadField(field);
2786 } else if (field.is_const()) {
2787 // If the parser needs to know the value of an uninitialized constant field
2788 // it will set the value to the transition sentinel (used to detect circular
2789 // initialization) and then call the implicit getter. Thus, the getter
2790 // cannot contain the InitStaticField instruction that normal static getters
2791 // contain because it would detect spurious circular initialization when it
2792 // checks for the transition sentinel.
2793 ASSERT(initializer_tag == kSomething);
2794 // this will (potentially) read the initializer, but reset the position.
2795 body += Constant(constant_evaluator_.EvaluateExpression(ReaderOffset()));
2796 SkipExpression(); // read the initializer.
2797 } else {
2798 // The field always has an initializer because static fields without
2799 // initializers are initialized eagerly and do not have implicit getters.
2800 ASSERT(field.has_initializer());
2801 body += Constant(field);
2802 body += flow_graph_builder_->InitStaticField(field);
2803 body += Constant(field);
2804 body += LoadStaticField();
2805 }
2806 body += Return(TokenPosition::kNoSource);
2807
2808 return new (Z)
2809 FlowGraph(*parsed_function(), flow_graph_builder_->graph_entry_,
2810 flow_graph_builder_->next_block_id_ - 1);
2811 }
2812
2813 void StreamingFlowGraphBuilder::SetupDefaultParameterValues() {
2814 intptr_t num_optional_parameters =
2815 parsed_function()->function().NumOptionalParameters();
2816 if (num_optional_parameters > 0) {
2817 ZoneGrowableArray<const Instance*>* default_values =
2818 new ZoneGrowableArray<const Instance*>(Z, num_optional_parameters);
2819
2820 AlternativeReadingScope alt(reader_);
2821 ReadFunctionNodeUntilTypeParameters(
2822 &unused_tokenposition, &unused_tokenposition, &unused_word,
2823 &unused_word); // read first part of function node.
2824 SkipTypeParametersList(); // read type_parameters.
2825 intptr_t required = ReadUInt(); // read required_parameter_count.
2826 ReadUInt(); // read total parameter count.
2827
2828 if (parsed_function()->function().HasOptionalNamedParameters()) {
2829 // List of positional.
2830 intptr_t list_length = ReadListLength(); // read list length.
2831 for (intptr_t i = 0; i < list_length; ++i) {
2832 SkipVariableDeclaration(); // read ith variable declaration.
2833 }
2834
2835 // List of named.
2836 list_length = ReadListLength(); // read list length.
2837 ASSERT(num_optional_parameters == list_length);
2838 ASSERT(!parsed_function()->function().HasOptionalPositionalParameters());
2839 for (intptr_t i = 0; i < list_length; ++i) {
2840 Instance* default_value;
2841
2842 // Read ith variable declaration
2843 ReadPosition(); // read position.
2844 ReadPosition(); // read equals position.
2845 ReadFlags(); // read flags.
2846 SkipStringReference(); // read name index.
2847 SkipDartType(); // read type.
2848 Tag tag = ReadTag(); // read (first part of) initializer.
2849 if (tag == kSomething) {
2850 // this will (potentially) read the initializer,
2851 // but reset the position.
2852 default_value =
2853 &constant_evaluator_.EvaluateExpression(ReaderOffset());
2854 SkipExpression(); // read (actual) initializer.
2855 } else {
2856 default_value = &Instance::ZoneHandle(Z, Instance::null());
2857 }
2858 default_values->Add(default_value);
2859 }
2860 } else {
2861 // List of positional.
2862 intptr_t list_length = ReadListLength(); // read list length.
2863 ASSERT(list_length == required + num_optional_parameters);
2864 ASSERT(parsed_function()->function().HasOptionalPositionalParameters());
2865 for (intptr_t i = 0; i < required; ++i) {
2866 SkipVariableDeclaration(); // read ith variable declaration.
2867 }
2868 for (intptr_t i = 0; i < num_optional_parameters; ++i) {
2869 Instance* default_value;
2870
2871 // Read ith variable declaration
2872 ReadPosition(); // read position.
2873 ReadPosition(); // read equals position.
2874 ReadFlags(); // read flags.
2875 SkipStringReference(); // read name index.
2876 SkipDartType(); // read type.
2877 Tag tag = ReadTag(); // read (first part of) initializer.
2878 if (tag == kSomething) {
2879 // this will (potentially) read the initializer,
2880 // but reset the position.
2881 default_value =
2882 &constant_evaluator_.EvaluateExpression(ReaderOffset());
2883 SkipExpression(); // read (actual) initializer.
2884 } else {
2885 default_value = &Instance::ZoneHandle(Z, Instance::null());
2886 }
2887 default_values->Add(default_value);
2888 }
2889
2890 // List of named.
2891 list_length = ReadListLength(); // read list length.
2892 ASSERT(list_length == 0);
2893 }
2894 parsed_function()->set_default_parameter_values(default_values);
2895 }
2896 }
2897
2898 Fragment StreamingFlowGraphBuilder::BuildFieldInitializer(
2899 NameIndex canonical_name) {
2900 dart::Field& field =
2901 dart::Field::ZoneHandle(Z, H.LookupFieldByKernelField(canonical_name));
2902 if (PeekTag() == kNullLiteral) {
2903 SkipExpression(); // read past the null literal.
2904 field.RecordStore(Object::null_object());
2905 return Fragment();
2906 }
2907
2908 Fragment instructions;
2909 instructions += LoadLocal(scopes()->this_variable);
2910 instructions += BuildExpression();
2911 instructions += flow_graph_builder_->StoreInstanceFieldGuarded(field, true);
2912 return instructions;
2913 }
2914
2915 Fragment StreamingFlowGraphBuilder::BuildInitializers(
2916 intptr_t constructor_class_parent_offset) {
2917 Fragment instructions;
2918
2919 // These come from:
2920 // class A {
2921 // var x = (expr);
2922 // }
2923 {
2924 AlternativeReadingScope alt(reader_, constructor_class_parent_offset);
2925 ReadClassUntilFields(); // read first part of class.
2926 intptr_t list_length = ReadListLength(); // read fields list length.
2927
2928 for (intptr_t i = 0; i < list_length; ++i) {
2929 intptr_t field_offset = ReaderOffset();
2930 NameIndex canonical_name;
2931 TokenPosition position;
2932 TokenPosition end_position;
2933 word flags;
2934 ReadFieldUntilAnnotation(&canonical_name, &position, &end_position,
2935 &flags, &unused_intptr);
2936 bool is_static = (flags & Field::kFlagStatic) == Field::kFlagStatic;
2937 SkipListOfExpressions(); // read annotations.
2938 SkipDartType(); // read type.
2939 Tag initializer_tag = ReadTag(); // read first part of initializer.
2940 if (!is_static && initializer_tag == kSomething) {
2941 EnterScope(field_offset);
2942 instructions +=
2943 BuildFieldInitializer(canonical_name); // read initializer.
2944 ExitScope(field_offset);
2945 } else if (initializer_tag == kSomething) {
2946 SkipExpression(); // read initializer.
2947 }
2948 }
2949 }
2950
2951 // These to come from:
2952 // class A {
2953 // var x;
2954 // var y;
2955 // A(this.x) : super(expr), y = (expr);
2956 // }
2957 {
2958 AlternativeReadingScope alt(reader_);
2959 SkipFunctionNode(); // read constructors function node.
2960
2961 intptr_t list_length = ReadListLength(); // read initializers list length.
2962 for (intptr_t i = 0; i < list_length; ++i) {
2963 Tag tag = ReadTag();
2964 switch (tag) {
2965 case kInvalidInitializer:
2966 UNIMPLEMENTED();
2967 return Fragment();
2968 case kFieldInitializer: {
2969 NameIndex canonical_name =
2970 ReadCanonicalNameReference(); // read field_reference.
2971 instructions += BuildFieldInitializer(canonical_name); // read value.
2972 break;
2973 }
2974 case kSuperInitializer: {
2975 NameIndex canonical_target =
2976 ReadCanonicalNameReference(); // read target_reference.
2977
2978 instructions += LoadLocal(scopes()->this_variable);
2979 instructions += PushArgument();
2980
2981 // TODO(jensj): ASSERT(init->arguments()->types().length() == 0);
2982 Array& argument_names = Array::ZoneHandle(Z);
2983 intptr_t argument_count;
2984 instructions += BuildArguments(&argument_names,
2985 &argument_count); // read arguments.
2986 argument_count += 1;
2987
2988 const Function& target = Function::ZoneHandle(
2989 Z, H.LookupConstructorByKernelConstructor(canonical_target));
2990 instructions += StaticCall(TokenPosition::kNoSource, target,
2991 argument_count, argument_names);
2992 instructions += Drop();
2993 break;
2994 }
2995 case kRedirectingInitializer: {
2996 NameIndex canonical_target =
2997 ReadCanonicalNameReference(); // read target_reference.
2998
2999 instructions += LoadLocal(scopes()->this_variable);
3000 instructions += PushArgument();
3001
3002 // TODO(jensj): ASSERT(init->arguments()->types().length() == 0);
3003 Array& argument_names = Array::ZoneHandle(Z);
3004 intptr_t argument_count;
3005 instructions += BuildArguments(&argument_names,
3006 &argument_count); // read arguments.
3007 argument_count += 1;
3008
3009 const Function& target = Function::ZoneHandle(
3010 Z, H.LookupConstructorByKernelConstructor(canonical_target));
3011 instructions += StaticCall(TokenPosition::kNoSource, target,
3012 argument_count, argument_names);
3013 instructions += Drop();
3014 break;
3015 }
3016 case kLocalInitializer: {
3017 // The other initializers following this one might read the variable.
3018 // This is used e.g. for evaluating the arguments to a super call
3019 // first, run normal field initializers next and then make the actual
3020 // super call:
3021 //
3022 // The frontend converts
3023 //
3024 // class A {
3025 // var x;
3026 // A(a, b) : super(a + b), x = 2*b {}
3027 // }
3028 //
3029 // to
3030 //
3031 // class A {
3032 // var x;
3033 // A(a, b) : tmp = a + b, x = 2*b, super(tmp) {}
3034 // }
3035 //
3036 // (This is strictly speaking not what one should do in terms of the
3037 // specification but that is how it is currently implemented.)
3038 LocalVariable* variable = LookupVariable(ReaderOffset());
3039
3040 // Variable declaration
3041 ReadPosition(); // read position.
3042 ReadPosition(); // read equals position.
3043 word flags = ReadFlags(); // read flags.
3044 ASSERT((flags & VariableDeclaration::kFlagConst) !=
3045 VariableDeclaration::kFlagConst);
3046 SkipStringReference(); // read name index.
3047 SkipDartType(); // read type.
3048 Tag tag = ReadTag(); // read (first part of) initializer.
3049 if (tag != kSomething) {
3050 UNREACHABLE();
3051 }
3052
3053 instructions += BuildExpression(); // read initializer.
3054 instructions += StoreLocal(TokenPosition::kNoSource, variable);
3055 instructions += Drop();
3056 break;
3057 }
3058 default:
3059 UNREACHABLE();
3060 }
3061 }
3062 }
3063 return instructions;
3064 }
3065
3066 FlowGraph* StreamingFlowGraphBuilder::BuildGraphOfImplicitClosureFunction(
3067 const Function& function) {
3068 const Function& target = Function::ZoneHandle(Z, function.parent_function());
3069
3070 TargetEntryInstr* normal_entry = flow_graph_builder_->BuildTargetEntry();
3071 flow_graph_builder_->graph_entry_ = new (Z) GraphEntryInstr(
3072 *parsed_function(), normal_entry, Compiler::kNoOSRDeoptId);
3073 SetupDefaultParameterValues();
3074
3075 Fragment body(normal_entry);
3076 body += flow_graph_builder_->CheckStackOverflowInPrologue();
3077
3078 // Load all the arguments.
3079 if (!target.is_static()) {
3080 // The context has a fixed shape: a single variable which is the
3081 // closed-over receiver.
3082 body += LoadLocal(parsed_function()->current_context_var());
3083 body += flow_graph_builder_->LoadField(Context::variable_offset(0));
3084 body += PushArgument();
3085 }
3086
3087 TokenPosition end_position;
3088 ReadFunctionNodeUntilTypeParameters(
3089 &unused_tokenposition, &end_position, &unused_word,
3090 &unused_word); // read first part of function node.
3091 SkipTypeParametersList(); // read type parameter list.
3092 ReadUInt(); // read required_parameter_count.
3093 ReadUInt(); // read total parameter count.
3094
3095 // Positional.
3096 intptr_t positional_argument_count = ReadListLength();
3097 for (intptr_t i = 0; i < positional_argument_count; ++i) {
3098 body += LoadLocal(LookupVariable(ReaderOffset())); // ith variable offset.
3099 body += PushArgument();
3100 SkipVariableDeclaration(); // read ith variable.
3101 }
3102
3103 // Named.
3104 intptr_t named_argument_count = ReadListLength();
3105 Array& argument_names = Array::ZoneHandle(Z);
3106 if (named_argument_count > 0) {
3107 argument_names = Array::New(named_argument_count);
3108 for (intptr_t i = 0; i < named_argument_count; ++i) {
3109 body +=
3110 LoadLocal(LookupVariable(ReaderOffset())); // ith variable offset.
3111 body += PushArgument();
3112 argument_names.SetAt(
3113 i, H.DartSymbol(GetNameFromVariableDeclaration(ReaderOffset())));
3114 SkipVariableDeclaration(); // read ith variable.
3115 }
3116 }
3117
3118 // Forward them to the target.
3119 intptr_t argument_count = positional_argument_count + named_argument_count;
3120 if (!target.is_static()) ++argument_count;
3121 body += StaticCall(TokenPosition::kNoSource, target, argument_count,
3122 argument_names);
3123
3124 // Return the result.
3125 body += Return(end_position);
3126
3127 return new (Z)
3128 FlowGraph(*parsed_function(), flow_graph_builder_->graph_entry_,
3129 flow_graph_builder_->next_block_id_ - 1);
3130 }
3131
3132 static bool IsGetMainClosure(const String& name) {
3133 if (name.Length() < 16) return false;
3134 const char* cstr = "_getMainClosure@";
3135 for (intptr_t i = 0; i < 16; ++i) {
3136 if (name.CharAt(i) != cstr[i]) return false;
3137 }
3138 return true;
3139 }
3140
3141 FlowGraph* StreamingFlowGraphBuilder::BuildGraphOfFunction(
3142 bool is_in_builtin_library_toplevel,
3143 intptr_t constructor_class_parent_offset) {
3144 const Function& dart_function = parsed_function()->function();
3145 TargetEntryInstr* normal_entry = flow_graph_builder_->BuildTargetEntry();
3146 flow_graph_builder_->graph_entry_ = new (Z) GraphEntryInstr(
3147 *parsed_function(), normal_entry, flow_graph_builder_->osr_id_);
3148
3149 SetupDefaultParameterValues();
3150
3151 Fragment body;
3152 if (!dart_function.is_native())
3153 body += flow_graph_builder_->CheckStackOverflowInPrologue();
3154 intptr_t context_size =
3155 parsed_function()->node_sequence()->scope()->num_context_variables();
3156 if (context_size > 0) {
3157 body += flow_graph_builder_->PushContext(context_size);
3158 LocalVariable* context = MakeTemporary();
3159
3160 // Copy captured parameters from the stack into the context.
3161 LocalScope* scope = parsed_function()->node_sequence()->scope();
3162 intptr_t parameter_count = dart_function.NumParameters();
3163 intptr_t parameter_index = parsed_function()->first_parameter_index();
3164 for (intptr_t i = 0; i < parameter_count; ++i, --parameter_index) {
3165 LocalVariable* variable = scope->VariableAt(i);
3166 if (variable->is_captured()) {
3167 // There is no LocalVariable describing the on-stack parameter so
3168 // create one directly and use the same type.
3169 LocalVariable* parameter = new (Z)
3170 LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource,
3171 Symbols::TempParam(), variable->type());
3172 parameter->set_index(parameter_index);
3173 // Mark the stack variable so it will be ignored by the code for
3174 // try/catch.
3175 parameter->set_is_captured_parameter(true);
3176
3177 // Copy the parameter from the stack to the context. Overwrite it
3178 // with a null constant on the stack so the original value is
3179 // eligible for garbage collection.
3180 body += LoadLocal(context);
3181 body += LoadLocal(parameter);
3182 body += flow_graph_builder_->StoreInstanceField(
3183 TokenPosition::kNoSource,
3184 Context::variable_offset(variable->index()));
3185 body += NullConstant();
3186 body += StoreLocal(TokenPosition::kNoSource, parameter);
3187 body += Drop();
3188 }
3189 }
3190 body += Drop(); // The context.
3191 }
3192 if (constructor_class_parent_offset > 0) {
3193 // TODO(27590): Currently the [VariableDeclaration]s from the
3194 // initializers will be visible inside the entire body of the constructor.
3195 // We should make a separate scope for them.
3196 body += BuildInitializers(constructor_class_parent_offset);
3197 }
3198
3199 TokenPosition position;
3200 ReadFunctionNodeUntilTypeParameters(
3201 &position, &unused_tokenposition, &unused_word,
3202 &unused_word); // read first part of function node.
3203 SkipTypeParametersList(); // read type parameter list.
3204 ReadUInt(); // read required_parameter_count.
3205 ReadUInt(); // read total parameter count
3206 intptr_t first_parameter_offset = -1;
3207 {
3208 AlternativeReadingScope alt(reader_);
3209 intptr_t list_length = ReadListLength(); // read number of positionals.
3210 if (list_length > 0) {
3211 first_parameter_offset = ReaderOffset();
3212 }
3213 }
3214 // Current position: About to read list of positionals.
3215
3216 // The specification defines the result of `a == b` to be:
3217 //
3218 // a) if either side is `null` then the result is `identical(a, b)`.
3219 // b) else the result is `a.operator==(b)`
3220 //
3221 // For user-defined implementations of `operator==` we need therefore
3222 // implement the handling of a).
3223 //
3224 // The default `operator==` implementation in `Object` is implemented in terms
3225 // of identical (which we assume here!) which means that case a) is actually
3226 // included in b). So we just use the normal implementation in the body.
3227 if ((dart_function.NumParameters() == 2) &&
3228 (dart_function.name() == Symbols::EqualOperator().raw()) &&
3229 (dart_function.Owner() != I->object_store()->object_class())) {
3230 LocalVariable* parameter = LookupVariable(first_parameter_offset);
3231
3232 TargetEntryInstr* null_entry;
3233 TargetEntryInstr* non_null_entry;
3234
3235 body += LoadLocal(parameter);
3236 body += BranchIfNull(&null_entry, &non_null_entry);
3237
3238 // The argument was `null` and the receiver is not the null class (we only
3239 // go into this branch for user-defined == operators) so we can return
3240 // false.
3241 Fragment null_fragment(null_entry);
3242 null_fragment += Constant(Bool::False());
3243 null_fragment += Return(dart_function.end_token_pos());
3244
3245 body = Fragment(body.entry, non_null_entry);
3246 }
3247
3248 // If we run in checked mode, we have to check the type of the passed
3249 // arguments.
3250 if (I->type_checks()) {
3251 // Positional.
3252 intptr_t list_length = ReadListLength();
3253 for (intptr_t i = 0; i < list_length; ++i) {
3254 body +=
3255 LoadLocal(LookupVariable(ReaderOffset())); // ith variable offset.
3256 body += CheckVariableTypeInCheckedMode(ReaderOffset());
3257 body += Drop();
3258 SkipVariableDeclaration(); // read ith variable.
3259 }
3260
3261 // Named.
3262 list_length = ReadListLength();
3263 for (intptr_t i = 0; i < list_length; ++i) {
3264 body +=
3265 LoadLocal(LookupVariable(ReaderOffset())); // ith variable offset.
3266 body += CheckVariableTypeInCheckedMode(ReaderOffset());
3267 body += Drop();
3268 SkipVariableDeclaration(); // read ith variable.
3269 }
3270 } else {
3271 // Still skip past the parameters.
3272 SkipListOfVariableDeclarations(); // read list of positionals.
3273 SkipListOfVariableDeclarations(); // read list of named.
3274 }
3275
3276 SkipDartType(); // read return type.
3277
3278 if (FLAG_causal_async_stacks &&
3279 (dart_function.IsAsyncFunction() || dart_function.IsAsyncGenerator())) {
3280 LocalScope* scope = parsed_function()->node_sequence()->scope();
3281 // :async_stack_trace = _asyncStackTraceHelper(:async_op);
3282 const dart::Library& async_lib =
3283 dart::Library::Handle(dart::Library::AsyncLibrary());
3284 const Function& target = Function::ZoneHandle(
3285 Z,
3286 async_lib.LookupFunctionAllowPrivate(Symbols::AsyncStackTraceHelper()));
3287 ASSERT(!target.IsNull());
3288
3289 // TODO(johnmccutchan): Why does this have the null value?
3290 LocalVariable* async_op =
3291 scope->child()->LookupVariable(Symbols::AsyncOperation(), false);
3292 ASSERT(async_op != NULL);
3293 ASSERT(async_op->is_captured());
3294 body += LoadLocal(async_op);
3295 body += PushArgument();
3296 body += StaticCall(TokenPosition::kNoSource, target, 1);
3297 LocalVariable* async_stack_trace_var =
3298 scope->LookupVariable(Symbols::AsyncStackTraceVar(), false);
3299 ASSERT(async_stack_trace_var != NULL);
3300 body += StoreLocal(TokenPosition::kNoSource, async_stack_trace_var);
3301 body += Drop();
3302 }
3303
3304 bool has_body = ReadTag() == kSomething; // read first part of body.
3305
3306 if (dart_function.is_native()) {
3307 body += flow_graph_builder_->NativeFunctionBody(first_parameter_offset,
3308 dart_function);
3309 } else if (has_body) {
3310 if (is_in_builtin_library_toplevel &&
3311 IsGetMainClosure(dart::String::Handle(Z, dart_function.name()))) {
3312 body += BuildGetMainClosure();
3313 } else {
3314 body += BuildStatement(); // read body.
3315 }
3316 }
3317 if (body.is_open()) {
3318 body += NullConstant();
3319 body += Return(dart_function.end_token_pos());
3320 }
3321
3322 // If functions body contains any yield points build switch statement that
3323 // selects a continuation point based on the value of :await_jump_var.
3324 if (!yield_continuations().is_empty()) {
3325 // The code we are building will be executed right after we enter
3326 // the function and before any nested contexts are allocated.
3327 // Reset current context_depth_ to match this.
3328 const intptr_t current_context_depth = flow_graph_builder_->context_depth_;
3329 flow_graph_builder_->context_depth_ =
3330 scopes()->yield_jump_variable->owner()->context_level();
3331
3332 // Prepend an entry corresponding to normal entry to the function.
3333 yield_continuations().InsertAt(
3334 0, YieldContinuation(new (Z) DropTempsInstr(0, NULL),
3335 CatchClauseNode::kInvalidTryIndex));
3336 yield_continuations()[0].entry->LinkTo(body.entry);
3337
3338 // Build a switch statement.
3339 Fragment dispatch;
3340
3341 // Load :await_jump_var into a temporary.
3342 dispatch += LoadLocal(scopes()->yield_jump_variable);
3343 dispatch += StoreLocal(TokenPosition::kNoSource, scopes()->switch_variable);
3344 dispatch += Drop();
3345
3346 BlockEntryInstr* block = NULL;
3347 for (intptr_t i = 0; i < yield_continuations().length(); i++) {
3348 if (i == 1) {
3349 // This is not a normal entry but a resumption. Restore
3350 // :current_context_var from :await_ctx_var.
3351 // Note: after this point context_depth_ does not match current context
3352 // depth so we should not access any local variables anymore.
3353 dispatch += LoadLocal(scopes()->yield_context_variable);
3354 dispatch += StoreLocal(TokenPosition::kNoSource,
3355 parsed_function()->current_context_var());
3356 dispatch += Drop();
3357 }
3358 if (i == (yield_continuations().length() - 1)) {
3359 // We reached the last possility, no need to build more ifs.
3360 // Continue to the last continuation.
3361 // Note: continuations start with nop DropTemps instruction
3362 // which acts like an anchor, so we need to skip it.
3363 block->set_try_index(yield_continuations()[i].try_index);
3364 dispatch <<= yield_continuations()[i].entry->next();
3365 break;
3366 }
3367
3368 // Build comparison:
3369 //
3370 // if (:await_ctx_var == i) {
3371 // -> yield_continuations()[i]
3372 // } else ...
3373 //
3374 TargetEntryInstr* then;
3375 TargetEntryInstr* otherwise;
3376 dispatch += LoadLocal(scopes()->switch_variable);
3377 dispatch += IntConstant(i);
3378 dispatch += flow_graph_builder_->BranchIfStrictEqual(&then, &otherwise);
3379
3380 // True branch is linked to appropriate continuation point.
3381 // Note: continuations start with nop DropTemps instruction
3382 // which acts like an anchor, so we need to skip it.
3383 then->LinkTo(yield_continuations()[i].entry->next());
3384 then->set_try_index(yield_continuations()[i].try_index);
3385 // False branch will contain the next comparison.
3386 dispatch = Fragment(dispatch.entry, otherwise);
3387 block = otherwise;
3388 }
3389 body = dispatch;
3390
3391 flow_graph_builder_->context_depth_ = current_context_depth;
3392 }
3393
3394 if (FLAG_causal_async_stacks &&
3395 (dart_function.IsAsyncClosure() || dart_function.IsAsyncGenClosure())) {
3396 // The code we are building will be executed right after we enter
3397 // the function and before any nested contexts are allocated.
3398 // Reset current context_depth_ to match this.
3399 const intptr_t current_context_depth = flow_graph_builder_->context_depth_;
3400 flow_graph_builder_->context_depth_ =
3401 scopes()->yield_jump_variable->owner()->context_level();
3402
3403 Fragment instructions;
3404 LocalScope* scope = parsed_function()->node_sequence()->scope();
3405
3406 const Function& target = Function::ZoneHandle(
3407 Z, I->object_store()->async_set_thread_stack_trace());
3408 ASSERT(!target.IsNull());
3409
3410 // Fetch and load :async_stack_trace
3411 LocalVariable* async_stack_trace_var =
3412 scope->LookupVariable(Symbols::AsyncStackTraceVar(), false);
3413 ASSERT((async_stack_trace_var != NULL) &&
3414 async_stack_trace_var->is_captured());
3415 instructions += LoadLocal(async_stack_trace_var);
3416 instructions += PushArgument();
3417
3418 // Call _asyncSetThreadStackTrace
3419 instructions += StaticCall(TokenPosition::kNoSource, target, 1);
3420 instructions += Drop();
3421
3422 body = instructions + body;
3423 flow_graph_builder_->context_depth_ = current_context_depth;
3424 }
3425
3426 if (NeedsDebugStepCheck(dart_function, position)) {
3427 // If a switch was added above: Start the switch by injecting a debuggable
3428 // safepoint so stepping over an await works.
3429 // If not, still start the body with a debuggable safepoint to ensure
3430 // breaking on a method always happens, even if there are no
3431 // assignments/calls/runtimecalls in the first basic block.
3432 // Place this check at the last parameter to ensure parameters
3433 // are in scope in the debugger at method entry.
3434 const int num_params = dart_function.NumParameters();
3435 TokenPosition check_pos = TokenPosition::kNoSource;
3436 if (num_params > 0) {
3437 LocalScope* scope = parsed_function()->node_sequence()->scope();
3438 const LocalVariable& parameter = *scope->VariableAt(num_params - 1);
3439 check_pos = parameter.token_pos();
3440 }
3441 if (!check_pos.IsDebugPause()) {
3442 // No parameters or synthetic parameters.
3443 check_pos = position;
3444 ASSERT(check_pos.IsDebugPause());
3445 }
3446 body = DebugStepCheck(check_pos) + body;
3447 }
3448
3449 normal_entry->LinkTo(body.entry);
3450
3451 // When compiling for OSR, use a depth first search to prune instructions
3452 // unreachable from the OSR entry. Catch entries are always considered
3453 // reachable, even if they become unreachable after OSR.
3454 if (flow_graph_builder_->osr_id_ != Compiler::kNoOSRDeoptId) {
3455 BitVector* block_marks =
3456 new (Z) BitVector(Z, flow_graph_builder_->next_block_id_);
3457 bool found = flow_graph_builder_->graph_entry_->PruneUnreachable(
3458 flow_graph_builder_->graph_entry_, NULL, flow_graph_builder_->osr_id_,
3459 block_marks);
3460 ASSERT(found);
3461 }
3462 return new (Z)
3463 FlowGraph(*parsed_function(), flow_graph_builder_->graph_entry_,
3464 flow_graph_builder_->next_block_id_ - 1);
3465 }
3466
3467 Fragment StreamingFlowGraphBuilder::BuildGetMainClosure() {
3468 // _getMainClosure in dart:_builtin. Compile that one specially here.
3469 const dart::Library& builtin =
3470 dart::Library::Handle(Z, I->object_store()->builtin_library());
3471 const Object& main =
3472 Object::Handle(Z, builtin.LookupObjectAllowPrivate(dart::String::Handle(
3473 Z, dart::String::New("main"))));
3474 if (main.IsField()) {
3475 UNIMPLEMENTED();
3476 } else if (main.IsFunction()) {
3477 const Function& function = Function::Cast(main);
3478 if (function.kind() == RawFunction::kRegularFunction) {
3479 const Function& closure_function =
3480 Function::Handle(Z, function.ImplicitClosureFunction());
3481 const Instance& closure =
3482 Instance::ZoneHandle(Z, closure_function.ImplicitStaticClosure());
3483 return Constant(closure) + Return(TokenPosition::kNoSource);
3484 } else {
3485 UNIMPLEMENTED();
3486 }
3487 } else {
3488 UNIMPLEMENTED();
3489 }
3490 return Fragment();
3491 }
3492
3493 FlowGraph* StreamingFlowGraphBuilder::BuildGraph(intptr_t kernel_offset) {
3494 const Function& function = parsed_function()->function();
3495
3496 // Setup a [ActiveClassScope] and a [ActiveMemberScope] which will be used
3497 // e.g. for type translation.
3498 const dart::Class& klass =
3499 dart::Class::Handle(zone_, parsed_function()->function().Owner());
3500 bool is_in_builtin_library_toplevel =
3501 klass.library() == I->object_store()->builtin_library() &&
3502 klass.IsTopLevel();
3503
3504 Function& outermost_function = Function::Handle(Z);
3505 intptr_t outermost_kernel_offset = -1;
3506 intptr_t parent_class_offset = -1;
3507 DiscoverEnclosingElements(Z, function, &outermost_function,
3508 &outermost_kernel_offset, &parent_class_offset);
3509 // Use [klass]/[kernel_class] as active class. Type parameters will get
3510 // resolved via [kernel_class] unless we are nested inside a static factory
3511 // in which case we will use [member].
3512 intptr_t class_type_parameters = 0;
3513 intptr_t class_type_parameters_offset_start = -1;
3514 if (parent_class_offset > 0) {
3515 GetTypeParameterInfoForClass(parent_class_offset, &class_type_parameters,
3516 &class_type_parameters_offset_start);
3517 }
3518
3519 ActiveClassScope active_class_scope(active_class(), class_type_parameters,
3520 class_type_parameters_offset_start,
3521 &klass);
3522
3523 bool member_is_procedure = false;
3524 bool is_factory_procedure = false;
3525 intptr_t member_type_parameters = 0;
3526 intptr_t member_type_parameters_offset_start = -1;
3527 GetTypeParameterInfoForPossibleProcedure(
3528 outermost_kernel_offset, &member_is_procedure, &is_factory_procedure,
3529 &member_type_parameters, &member_type_parameters_offset_start);
3530
3531 ActiveMemberScope active_member(active_class(), member_is_procedure,
3532 is_factory_procedure, member_type_parameters,
3533 member_type_parameters_offset_start);
3534
3535 // The IR builder will create its own local variables and scopes, and it
3536 // will not need an AST. The code generator will assume that there is a
3537 // local variable stack slot allocated for the current context and (I
3538 // think) that the runtime will expect it to be at a fixed offset which
3539 // requires allocating an unused expression temporary variable.
3540 set_scopes(parsed_function()->EnsureKernelScopes());
3541
2687 SetOffset(kernel_offset); 3542 SetOffset(kernel_offset);
2688 return BuildExpression(); // read expression. 3543
2689 } 3544 switch (function.kind()) {
3545 case RawFunction::kClosureFunction:
3546 case RawFunction::kRegularFunction:
3547 case RawFunction::kGetterFunction:
3548 case RawFunction::kSetterFunction: {
3549 ReadUntilFunctionNode(); // read until function node.
3550 return function.IsImplicitClosureFunction()
3551 ? BuildGraphOfImplicitClosureFunction(function)
3552 : BuildGraphOfFunction(is_in_builtin_library_toplevel);
3553 }
3554 case RawFunction::kConstructor: {
3555 bool is_factory = function.IsFactory();
3556 if (is_factory) {
3557 ReadUntilFunctionNode(); // read until function node.
3558 return BuildGraphOfFunction(is_in_builtin_library_toplevel);
3559 } else {
3560 // Constructor: Pass offset to parent class.
3561 return BuildGraphOfFunction(
3562 is_in_builtin_library_toplevel,
3563 ReadUntilFunctionNode()); // read until function node.
3564 }
3565 }
3566 case RawFunction::kImplicitGetter:
3567 case RawFunction::kImplicitStaticFinalGetter:
3568 case RawFunction::kImplicitSetter: {
3569 return IsStaticInitializer(function, Z)
3570 ? BuildGraphOfStaticFieldInitializer()
3571 : BuildGraphOfFieldAccessor(scopes()->setter_value);
3572 }
3573 case RawFunction::kMethodExtractor:
3574 return flow_graph_builder_->BuildGraphOfMethodExtractor(function);
3575 case RawFunction::kNoSuchMethodDispatcher:
3576 return flow_graph_builder_->BuildGraphOfNoSuchMethodDispatcher(function);
3577 case RawFunction::kInvokeFieldDispatcher:
3578 return flow_graph_builder_->BuildGraphOfInvokeFieldDispatcher(function);
3579 case RawFunction::kSignatureFunction:
3580 case RawFunction::kIrregexpFunction:
3581 break;
3582 }
3583 UNREACHABLE();
3584 return NULL;
3585 }
3586
2690 3587
2691 Fragment StreamingFlowGraphBuilder::BuildStatementAt(intptr_t kernel_offset) { 3588 Fragment StreamingFlowGraphBuilder::BuildStatementAt(intptr_t kernel_offset) {
2692 SetOffset(kernel_offset); 3589 SetOffset(kernel_offset);
2693 return BuildStatement(); // read statement. 3590 return BuildStatement(); // read statement.
2694 } 3591 }
2695 3592
2696 Fragment StreamingFlowGraphBuilder::BuildExpression(TokenPosition* position) { 3593 Fragment StreamingFlowGraphBuilder::BuildExpression(TokenPosition* position) {
2697 uint8_t payload = 0; 3594 uint8_t payload = 0;
2698 Tag tag = ReadTag(&payload); // read tag. 3595 Tag tag = ReadTag(&payload); // read tag.
2699 switch (tag) { 3596 switch (tag) {
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
2755 return BuildThrow(position); 3652 return BuildThrow(position);
2756 case kListLiteral: 3653 case kListLiteral:
2757 return BuildListLiteral(false, position); 3654 return BuildListLiteral(false, position);
2758 case kConstListLiteral: 3655 case kConstListLiteral:
2759 return BuildListLiteral(true, position); 3656 return BuildListLiteral(true, position);
2760 case kMapLiteral: 3657 case kMapLiteral:
2761 return BuildMapLiteral(false, position); 3658 return BuildMapLiteral(false, position);
2762 case kConstMapLiteral: 3659 case kConstMapLiteral:
2763 return BuildMapLiteral(true, position); 3660 return BuildMapLiteral(true, position);
2764 case kFunctionExpression: 3661 case kFunctionExpression:
2765 // TODO(jensj) 3662 return BuildFunctionExpression();
2766 UNIMPLEMENTED();
2767 return Fragment();
2768 case kLet: 3663 case kLet:
2769 return BuildLet(position); 3664 return BuildLet(position);
2770 case kBigIntLiteral: 3665 case kBigIntLiteral:
2771 return BuildBigIntLiteral(position); 3666 return BuildBigIntLiteral(position);
2772 case kStringLiteral: 3667 case kStringLiteral:
2773 return BuildStringLiteral(position); 3668 return BuildStringLiteral(position);
2774 case kSpecialIntLiteral: 3669 case kSpecialIntLiteral:
2775 return BuildIntLiteral(payload, position); 3670 return BuildIntLiteral(payload, position);
2776 case kNegativeIntLiteral: 3671 case kNegativeIntLiteral:
2777 return BuildIntLiteral(true, position); 3672 return BuildIntLiteral(true, position);
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
2829 return BuildReturnStatement(); 3724 return BuildReturnStatement();
2830 case kTryCatch: 3725 case kTryCatch:
2831 return BuildTryCatch(); 3726 return BuildTryCatch();
2832 case kTryFinally: 3727 case kTryFinally:
2833 return BuildTryFinally(); 3728 return BuildTryFinally();
2834 case kYieldStatement: 3729 case kYieldStatement:
2835 return BuildYieldStatement(); 3730 return BuildYieldStatement();
2836 case kVariableDeclaration: 3731 case kVariableDeclaration:
2837 return BuildVariableDeclaration(); 3732 return BuildVariableDeclaration();
2838 case kFunctionDeclaration: 3733 case kFunctionDeclaration:
2839 // TODO(jensj) 3734 return BuildFunctionDeclaration();
2840 UNIMPLEMENTED();
2841 return Fragment();
2842 default: 3735 default:
2843 UNREACHABLE(); 3736 UNREACHABLE();
2844 } 3737 }
2845 return Fragment(); 3738 return Fragment();
2846 } 3739 }
2847 3740
2848 intptr_t StreamingFlowGraphBuilder::ReaderOffset() { 3741 intptr_t StreamingFlowGraphBuilder::ReaderOffset() {
2849 return reader_->offset(); 3742 return reader_->offset();
2850 } 3743 }
2851 3744
(...skipping 495 matching lines...) Expand 10 before | Expand all | Expand 10 after
3347 void StreamingFlowGraphBuilder::SkipFunctionNode() { 4240 void StreamingFlowGraphBuilder::SkipFunctionNode() {
3348 Tag tag = ReadTag(); // read tag. 4241 Tag tag = ReadTag(); // read tag.
3349 ASSERT(tag == kFunctionNode); 4242 ASSERT(tag == kFunctionNode);
3350 4243
3351 ReadPosition(); // read position. 4244 ReadPosition(); // read position.
3352 ReadPosition(); // read end position. 4245 ReadPosition(); // read end position.
3353 ReadByte(); // read async marker. 4246 ReadByte(); // read async marker.
3354 ReadByte(); // read dart async marker. 4247 ReadByte(); // read dart async marker.
3355 SkipTypeParametersList(); // read type_parameters. 4248 SkipTypeParametersList(); // read type_parameters.
3356 ReadUInt(); // read required_parameter_count. 4249 ReadUInt(); // read required_parameter_count.
4250 ReadUInt(); // read total parameter count.
3357 4251
3358 SkipListOfVariableDeclarations(); // read list of positionals. 4252 SkipListOfVariableDeclarations(); // read list of positionals.
3359 SkipListOfVariableDeclarations(); // read list of named. 4253 SkipListOfVariableDeclarations(); // read list of named.
3360 SkipDartType(); // read return type. 4254 SkipDartType(); // read return type.
3361 4255
3362 if (ReadTag() == kSomething) { 4256 if (ReadTag() == kSomething) {
3363 SkipStatement(); // Read body 4257 SkipStatement(); // Read body
3364 } 4258 }
3365 } 4259 }
3366 4260
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
3470 } 4364 }
3471 4365
3472 ActiveClass* StreamingFlowGraphBuilder::active_class() { 4366 ActiveClass* StreamingFlowGraphBuilder::active_class() {
3473 return &flow_graph_builder_->active_class_; 4367 return &flow_graph_builder_->active_class_;
3474 } 4368 }
3475 4369
3476 ScopeBuildingResult* StreamingFlowGraphBuilder::scopes() { 4370 ScopeBuildingResult* StreamingFlowGraphBuilder::scopes() {
3477 return flow_graph_builder_->scopes_; 4371 return flow_graph_builder_->scopes_;
3478 } 4372 }
3479 4373
4374 void StreamingFlowGraphBuilder::set_scopes(ScopeBuildingResult* scope) {
4375 flow_graph_builder_->scopes_ = scope;
4376 }
4377
3480 ParsedFunction* StreamingFlowGraphBuilder::parsed_function() { 4378 ParsedFunction* StreamingFlowGraphBuilder::parsed_function() {
3481 return flow_graph_builder_->parsed_function_; 4379 return flow_graph_builder_->parsed_function_;
3482 } 4380 }
3483 4381
3484 TryFinallyBlock* StreamingFlowGraphBuilder::try_finally_block() { 4382 TryFinallyBlock* StreamingFlowGraphBuilder::try_finally_block() {
3485 return flow_graph_builder_->try_finally_block_; 4383 return flow_graph_builder_->try_finally_block_;
3486 } 4384 }
3487 4385
3488 SwitchBlock* StreamingFlowGraphBuilder::switch_block() { 4386 SwitchBlock* StreamingFlowGraphBuilder::switch_block() {
3489 return flow_graph_builder_->switch_block_; 4387 return flow_graph_builder_->switch_block_;
(...skipping 1361 matching lines...) Expand 10 before | Expand all | Expand 10 after
4851 5749
4852 const dart::Class& map_class = 5750 const dart::Class& map_class =
4853 dart::Class::Handle(Z, dart::Library::LookupCoreClass(Symbols::Map())); 5751 dart::Class::Handle(Z, dart::Library::LookupCoreClass(Symbols::Map()));
4854 const Function& factory_method = Function::ZoneHandle( 5752 const Function& factory_method = Function::ZoneHandle(
4855 Z, map_class.LookupFactory( 5753 Z, map_class.LookupFactory(
4856 dart::Library::PrivateCoreLibName(Symbols::MapLiteralFactory()))); 5754 dart::Library::PrivateCoreLibName(Symbols::MapLiteralFactory())));
4857 5755
4858 return instructions + StaticCall(position, factory_method, 2); 5756 return instructions + StaticCall(position, factory_method, 2);
4859 } 5757 }
4860 5758
5759 Fragment StreamingFlowGraphBuilder::BuildFunctionExpression() {
5760 intptr_t offset = ReaderOffset() - 1; // -1 to include tag byte.
5761 return BuildFunctionNode(offset, TokenPosition::kNoSource, false, -1);
5762 }
5763
4861 Fragment StreamingFlowGraphBuilder::BuildLet(TokenPosition* position) { 5764 Fragment StreamingFlowGraphBuilder::BuildLet(TokenPosition* position) {
4862 if (position != NULL) *position = TokenPosition::kNoSource; 5765 if (position != NULL) *position = TokenPosition::kNoSource;
4863 5766
4864 Fragment instructions = BuildVariableDeclaration(); // read variable. 5767 Fragment instructions = BuildVariableDeclaration(); // read variable.
4865 instructions += BuildExpression(); // read body. 5768 instructions += BuildExpression(); // read body.
4866 return instructions; 5769 return instructions;
4867 } 5770 }
4868 5771
4869 5772
4870 Fragment StreamingFlowGraphBuilder::BuildBigIntLiteral( 5773 Fragment StreamingFlowGraphBuilder::BuildBigIntLiteral(
(...skipping 986 matching lines...) Expand 10 before | Expand all | Expand 10 after
5857 // use the position of the identifier. 6760 // use the position of the identifier.
5858 TokenPosition debug_position = Utils::Maximum(position, equals_position); 6761 TokenPosition debug_position = Utils::Maximum(position, equals_position);
5859 if (NeedsDebugStepCheck(stack(), debug_position)) { 6762 if (NeedsDebugStepCheck(stack(), debug_position)) {
5860 instructions = DebugStepCheck(debug_position) + instructions; 6763 instructions = DebugStepCheck(debug_position) + instructions;
5861 } 6764 }
5862 instructions += StoreLocal(position, variable); 6765 instructions += StoreLocal(position, variable);
5863 instructions += Drop(); 6766 instructions += Drop();
5864 return instructions; 6767 return instructions;
5865 } 6768 }
5866 6769
6770 Fragment StreamingFlowGraphBuilder::BuildFunctionDeclaration() {
6771 intptr_t offset = ReaderOffset() - 1; // -1 to include tag byte.
6772 TokenPosition position = ReadPosition(); // read position.
6773 intptr_t variable_offeset = ReaderOffset();
6774 SkipVariableDeclaration(); // read variable declaration.
6775
6776 Fragment instructions = DebugStepCheck(position);
6777 instructions += BuildFunctionNode(offset, position, true, variable_offeset);
6778 instructions += StoreLocal(position, LookupVariable(variable_offeset));
6779 instructions += Drop();
6780 return instructions;
6781 }
6782
6783 Fragment StreamingFlowGraphBuilder::BuildFunctionNode(
6784 intptr_t parent_kernel_offset,
6785 TokenPosition parent_position,
6786 bool declaration,
6787 intptr_t variable_offeset) {
6788 intptr_t offset = ReaderOffset();
6789
6790 TokenPosition position;
6791 TokenPosition end_position;
6792 word async_marker_word;
6793 word dart_async_marker_word;
6794 ReadFunctionNodeUntilTypeParameters(
6795 &position, &end_position, &async_marker_word,
6796 &dart_async_marker_word); // read first part of function node.
6797 FunctionNode::AsyncMarker async_marker =
6798 static_cast<FunctionNode::AsyncMarker>(async_marker_word);
6799 FunctionNode::AsyncMarker dart_async_marker =
6800 static_cast<FunctionNode::AsyncMarker>(dart_async_marker_word);
6801
6802 if (declaration) {
6803 position = parent_position;
6804 }
6805 if (!position.IsReal()) {
6806 // Positions has to be unique in regards to the parent.
6807 // A non-real at this point is probably -1, we cannot blindly use that
6808 // as others might use it too. Create a new dummy non-real TokenPosition.
6809 position = TokenPosition(offset).ToSynthetic();
6810 }
6811
6812 SkipTypeParametersList(); // read type parameters.
6813
6814 // The VM has a per-isolate table of functions indexed by the enclosing
6815 // function and token position.
6816 Function& function = Function::ZoneHandle(Z);
6817 bool read_rest_of_function_node = false;
6818
6819 // NOTE: This is not TokenPosition in the general sense!
6820 function = I->LookupClosureFunction(parsed_function()->function(), position);
6821 if (function.IsNull()) {
6822 for (intptr_t i = 0; i < scopes()->function_scopes.length(); ++i) {
6823 if (scopes()->function_scopes[i].kernel_offset != offset) {
6824 continue;
6825 }
6826
6827 const dart::String* name;
6828 if (!declaration) {
6829 name = &Symbols::AnonymousClosure();
6830 } else {
6831 name = &H.DartSymbol(GetNameFromVariableDeclaration(variable_offeset));
6832 }
6833 // NOTE: This is not TokenPosition in the general sense!
6834 function = Function::NewClosureFunction(
6835 *name, parsed_function()->function(), position);
6836
6837 function.set_is_debuggable(dart_async_marker == FunctionNode::kSync);
6838 switch (dart_async_marker) {
6839 case FunctionNode::kSyncStar:
6840 function.set_modifier(RawFunction::kSyncGen);
6841 break;
6842 case FunctionNode::kAsync:
6843 function.set_modifier(RawFunction::kAsync);
6844 function.set_is_inlinable(!FLAG_causal_async_stacks);
6845 break;
6846 case FunctionNode::kAsyncStar:
6847 function.set_modifier(RawFunction::kAsyncGen);
6848 function.set_is_inlinable(!FLAG_causal_async_stacks);
6849 break;
6850 default:
6851 // no special modifier
6852 break;
6853 }
6854 function.set_is_generated_body(async_marker ==
6855 FunctionNode::kSyncYielding);
6856 if (function.IsAsyncClosure() || function.IsAsyncGenClosure()) {
6857 function.set_is_inlinable(!FLAG_causal_async_stacks);
6858 }
6859
6860 function.set_end_token_pos(end_position);
6861 LocalScope* scope = scopes()->function_scopes[i].scope;
6862 const ContextScope& context_scope = ContextScope::Handle(
6863 Z, scope->PreserveOuterScope(flow_graph_builder_->context_depth_));
6864 function.set_context_scope(context_scope);
6865 function.set_kernel_offset(offset);
6866 // Read rest of function node.
6867 SetupFunctionParameters(dart::Class::Handle(Z), function,
6868 false, // is_method
6869 true); // is_closure
6870 read_rest_of_function_node = true;
6871 // Finalize function type.
6872 Type& signature_type = Type::Handle(Z, function.SignatureType());
6873 signature_type ^=
6874 ClassFinalizer::FinalizeType(*active_class()->klass, signature_type);
6875 function.SetSignatureType(signature_type);
6876
6877 I->AddClosureFunction(function);
6878 break;
6879 }
6880 }
6881
6882 if (!read_rest_of_function_node) {
6883 ReadUInt(); // read required_parameter_count.
6884 ReadUInt(); // read total parameter count.
6885 SkipListOfVariableDeclarations(); // read list of positionals.
6886 SkipListOfVariableDeclarations(); // read list of named.
6887 SkipDartType(); // read return type.
6888 if (ReadTag() == kSomething) { // read first part of body.
6889 SkipStatement(); // read body.
6890 }
6891 }
6892
6893 const dart::Class& closure_class =
6894 dart::Class::ZoneHandle(Z, I->object_store()->closure_class());
6895 ASSERT(!closure_class.IsNull());
6896 Fragment instructions =
6897 flow_graph_builder_->AllocateObject(closure_class, function);
6898 LocalVariable* closure = MakeTemporary();
6899
6900 // TODO(27590): Generic closures need type arguments.
6901
6902 // Store the function and the context in the closure.
6903 instructions += LoadLocal(closure);
6904 instructions += Constant(function);
6905 instructions += flow_graph_builder_->StoreInstanceField(
6906 TokenPosition::kNoSource, Closure::function_offset());
6907
6908 instructions += LoadLocal(closure);
6909 instructions += LoadLocal(parsed_function()->current_context_var());
6910 instructions += flow_graph_builder_->StoreInstanceField(
6911 TokenPosition::kNoSource, Closure::context_offset());
6912
6913 return instructions;
6914 }
6915
6916
6917 void StreamingFlowGraphBuilder::SetupFunctionParameters(
6918 const dart::Class& klass,
6919 const dart::Function& function,
6920 bool is_method,
6921 bool is_closure) {
6922 ASSERT(!(is_method && is_closure));
6923 bool is_factory = function.IsFactory();
6924 intptr_t extra_parameters = (is_method || is_closure || is_factory) ? 1 : 0;
6925
6926 intptr_t required_parameter_count =
6927 ReadUInt(); // read required_parameter_count.
6928 intptr_t total_parameter_count = ReadUInt(); // read total parameter count.
6929 intptr_t positional_parameters_count = ReadListLength(); // read list length.
6930 intptr_t named_parameters_count =
6931 total_parameter_count - positional_parameters_count;
6932
6933 function.set_num_fixed_parameters(extra_parameters +
6934 required_parameter_count);
6935 if (named_parameters_count > 0) {
6936 function.SetNumOptionalParameters(named_parameters_count, false);
6937 } else {
6938 function.SetNumOptionalParameters(
6939 positional_parameters_count - required_parameter_count, true);
6940 }
6941 intptr_t num_parameters = extra_parameters + total_parameter_count;
6942 function.set_parameter_types(
6943 Array::Handle(Z, Array::New(num_parameters, Heap::kOld)));
6944 function.set_parameter_names(
6945 Array::Handle(Z, Array::New(num_parameters, Heap::kOld)));
6946 intptr_t pos = 0;
6947 if (is_method) {
6948 ASSERT(!klass.IsNull());
6949 function.SetParameterTypeAt(pos, H.GetCanonicalType(klass));
6950 function.SetParameterNameAt(pos, Symbols::This());
6951 pos++;
6952 } else if (is_closure) {
6953 function.SetParameterTypeAt(pos, AbstractType::dynamic_type());
6954 function.SetParameterNameAt(pos, Symbols::ClosureParameter());
6955 pos++;
6956 } else if (is_factory) {
6957 function.SetParameterTypeAt(pos, AbstractType::dynamic_type());
6958 function.SetParameterNameAt(pos, Symbols::TypeArgumentsParameter());
6959 pos++;
6960 }
6961
6962 for (intptr_t i = 0; i < positional_parameters_count; ++i, ++pos) {
6963 // Read ith variable declaration.
6964 ReadPosition(); // read position.
6965 ReadPosition(); // read equals position.
6966 ReadFlags(); // read flags.
6967 StringIndex name = ReadStringReference(); // read name index.
6968 const AbstractType& type = T.BuildTypeWithoutFinalization(); // read type.
6969 Tag tag = ReadTag(); // read (first part of) initializer.
6970 if (tag == kSomething) {
6971 SkipExpression(); // read (actual) initializer.
6972 }
6973
6974 function.SetParameterTypeAt(
6975 pos, type.IsMalformed() ? Type::dynamic_type() : type);
6976 function.SetParameterNameAt(pos, H.DartSymbol(name));
6977 }
6978
6979 intptr_t named_parameters_count_check =
6980 ReadListLength(); // read list length.
6981 ASSERT(named_parameters_count_check == named_parameters_count);
6982 for (intptr_t i = 0; i < named_parameters_count; ++i, ++pos) {
6983 // Read ith variable declaration.
6984 ReadPosition(); // read position.
6985 ReadPosition(); // read equals position.
6986 ReadFlags(); // read flags.
6987 StringIndex name = ReadStringReference(); // read name index.
6988 const AbstractType& type = T.BuildTypeWithoutFinalization(); // read type.
6989 Tag tag = ReadTag(); // read (first part of) initializer.
6990 if (tag == kSomething) {
6991 SkipExpression(); // read (actual) initializer.
6992 }
6993
6994 function.SetParameterTypeAt(
6995 pos, type.IsMalformed() ? Type::dynamic_type() : type);
6996 function.SetParameterNameAt(pos, H.DartSymbol(name));
6997 }
6998
6999 // The result type for generative constructors has already been set.
7000 if (!function.IsGenerativeConstructor()) {
7001 const AbstractType& return_type =
7002 T.BuildTypeWithoutFinalization(); // read return type.
7003 function.set_result_type(return_type.IsMalformed() ? Type::dynamic_type()
7004 : return_type);
7005 } else {
7006 SkipDartType(); // read return type.
7007 }
7008
7009 if (ReadTag() == kSomething) { // read first part of body.
7010 SkipStatement(); // read body.
7011 }
7012 }
7013
7014 RawObject* StreamingFlowGraphBuilder::BuildParameterDescriptor(
7015 intptr_t kernel_offset) {
7016 SetOffset(kernel_offset);
7017 ReadUntilFunctionNode(); // read until function node.
7018 ReadFunctionNodeUntilTypeParameters(
7019 &unused_tokenposition, &unused_tokenposition, &unused_word,
7020 &unused_word); // read first part of function node.
7021 SkipTypeParametersList(); // read type_parameters.
7022
7023 ReadUInt(); // read required_parameter_count.
7024 intptr_t param_count = ReadUInt(); // read total parameter count.
7025 intptr_t positional_count = ReadListLength(); // read list length.
7026 intptr_t named_parameters_count = param_count - positional_count;
7027
7028 const Array& param_descriptor = Array::Handle(
7029 Array::New(param_count * Parser::kParameterEntrySize, Heap::kOld));
7030 for (intptr_t i = 0; i < param_count; ++i) {
7031 const intptr_t entry_start = i * Parser::kParameterEntrySize;
7032
7033 if (i == positional_count) {
7034 intptr_t named_parameters_count_check =
7035 ReadListLength(); // read list length.
7036 ASSERT(named_parameters_count_check == named_parameters_count);
7037 }
7038
7039 // Read ith variable declaration.
7040 ReadPosition(); // read position.
7041 ReadPosition(); // read equals position.
7042 word flags = ReadFlags(); // read flags.
7043 bool is_final = (flags & VariableDeclaration::kFlagFinal) ==
7044 VariableDeclaration::kFlagFinal;
7045 param_descriptor.SetAt(entry_start + Parser::kParameterIsFinalOffset,
7046 is_final ? Bool::True() : Bool::False());
7047
7048 SkipStringReference(); // read name index.
7049 SkipDartType(); // read type.
7050 Tag tag = ReadTag(); // read (first part of) initializer.
7051 if (tag == kSomething) {
7052 // this will (potentially) read the initializer, but reset the position.
7053 Instance& constant =
7054 constant_evaluator_.EvaluateExpression(ReaderOffset());
7055 SkipExpression(); // read (actual) initializer.
7056 param_descriptor.SetAt(entry_start + Parser::kParameterDefaultValueOffset,
7057 constant);
7058 } else {
7059 param_descriptor.SetAt(entry_start + Parser::kParameterDefaultValueOffset,
7060 Object::null_instance());
7061 }
7062
7063 param_descriptor.SetAt(entry_start + Parser::kParameterMetadataOffset,
7064 /* Issue(28434): Missing parameter metadata. */
7065 Object::null_instance());
7066 }
7067 return param_descriptor.raw();
7068 }
7069
7070 RawObject* StreamingFlowGraphBuilder::EvaluateMetadata(intptr_t kernel_offset) {
7071 SetOffset(kernel_offset);
7072 const Tag tag = PeekTag();
7073
7074 if (tag == kClass) {
7075 Tag tag = ReadTag(); // read tag.
7076 ASSERT(tag == kClass);
7077 SkipCanonicalNameReference(); // read canonical name reference.
7078 ReadPosition(); // read position.
7079 ReadByte(); // read is_abstract
7080 SkipStringReference(); // read name_index.
7081 ReadUInt(); // read source_uri_index.
7082 // SkipListOfExpressions(); // read annotations.
7083 } else if (tag == kProcedure) {
7084 Tag tag = ReadTag(); // read tag.
7085 ASSERT(tag == kProcedure);
7086 SkipCanonicalNameReference(); // read canonical name reference.
7087 ReadPosition(); // read position.
7088 ReadPosition(); // read end position.
7089 ReadByte(); // read kind.
7090 ReadFlags(); // read flags.
7091 ReadUInt(); // read parent class binary offset.
7092 SkipName(); // read name,
7093 ReadUInt(); // read source_uri_index.
7094 // SkipListOfExpressions(); // read annotations.
7095 } else if (tag == kField) {
7096 ReadFieldUntilAnnotation(&unused_nameindex, &unused_tokenposition,
7097 &unused_tokenposition, &unused_word,
7098 &unused_intptr);
7099 // SkipListOfExpressions(); // read annotations.
7100 } else if (tag == kConstructor) {
7101 Tag tag = ReadTag();
7102 ASSERT(tag == kConstructor);
7103 SkipCanonicalNameReference(); // read canonical name reference.
7104 ReadPosition(); // read position.
7105 ReadPosition(); // read end position.
7106 ReadFlags(); // read flags.
7107 ReadUInt(); // parent class binary offset.
7108 SkipName(); // read name.
7109 // SkipListOfExpressions(); // read annotations.
7110 } else {
7111 FATAL("No support for metadata on this type of kernel node\n");
7112 }
7113
7114 intptr_t list_length = ReadListLength(); // read list length.
7115 const Array& metadata_values = Array::Handle(Z, Array::New(list_length));
7116 for (intptr_t i = 0; i < list_length; ++i) {
7117 // this will (potentially) read the expression, but reset the position.
7118 Instance& value = constant_evaluator_.EvaluateExpression(ReaderOffset());
7119 SkipExpression(); // read (actual) initializer.
7120 metadata_values.SetAt(i, value);
7121 }
7122
7123 return metadata_values.raw();
7124 }
7125
5867 } // namespace kernel 7126 } // namespace kernel
5868 } // namespace dart 7127 } // namespace dart
5869 7128
5870 #endif // !defined(DART_PRECOMPILED_RUNTIME) 7129 #endif // !defined(DART_PRECOMPILED_RUNTIME)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698