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

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

Issue 2901533002: [kernel] Stream everything. Replace .kernel_function with .kernel_offset (Closed)
Patch Set: Fix for bad merge 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
« no previous file with comments | « runtime/vm/kernel_binary_flowgraph.h ('k') | runtime/vm/kernel_reader.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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.
196 builder_->ReadUInt(); // read total parameter count.
229 builder_->ReadUInt(); // read required_parameter_count. 197 builder_->ReadUInt(); // read required_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;
(...skipping 73 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 14 matching lines...) Expand all
582 for (intptr_t i = 0; 401 for (intptr_t i = 0;
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
411 builder_->ReadUInt(); // read total parameter count.
592 builder_->ReadUInt(); // read required_parameter_count. 412 builder_->ReadUInt(); // read required_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();
(...skipping 34 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 652 matching lines...) Expand 10 before | Expand all | Expand 10 after
1313 StreamingScopeBuilder::DepthState saved_depth_state = depth_; 1133 StreamingScopeBuilder::DepthState saved_depth_state = depth_;
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
1143 builder_->ReadUInt(); // read total parameter count.
1323 builder_->ReadUInt(); // read required_parameter_count. 1144 builder_->ReadUInt(); // read required_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);
(...skipping 141 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 583 matching lines...) Expand 10 before | Expand all | Expand 10 after
2182 } else { 2004 } else {
2183 result_ = field.StaticValue(); 2005 result_ = field.StaticValue();
2184 } 2006 }
2185 } else if (H.IsProcedure(target)) { 2007 } else if (H.IsProcedure(target)) {
2186 const Function& function = 2008 const Function& function =
2187 Function::ZoneHandle(Z, H.LookupStaticMethodByKernelProcedure(target)); 2009 Function::ZoneHandle(Z, H.LookupStaticMethodByKernelProcedure(target));
2188 2010
2189 if (H.IsMethod(target)) { 2011 if (H.IsMethod(target)) {
2190 Function& closure_function = 2012 Function& closure_function =
2191 Function::ZoneHandle(Z, function.ImplicitClosureFunction()); 2013 Function::ZoneHandle(Z, function.ImplicitClosureFunction());
2192 closure_function.set_kernel_function(function.kernel_function());
2193 result_ = closure_function.ImplicitStaticClosure(); 2014 result_ = closure_function.ImplicitStaticClosure();
2194 result_ = H.Canonicalize(result_); 2015 result_ = H.Canonicalize(result_);
2195 } else if (H.IsGetter(target)) { 2016 } else if (H.IsGetter(target)) {
2196 UNIMPLEMENTED(); 2017 UNIMPLEMENTED();
2197 } else { 2018 } else {
2198 UNIMPLEMENTED(); 2019 UNIMPLEMENTED();
2199 } 2020 }
2200 } 2021 }
2201 } 2022 }
2202 2023
(...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after
2632 } 2453 }
2633 2454
2634 bool StreamingConstantEvaluator::EvaluateBooleanExpressionHere() { 2455 bool StreamingConstantEvaluator::EvaluateBooleanExpressionHere() {
2635 EvaluateExpression(builder_->ReaderOffset(), false); 2456 EvaluateExpression(builder_->ReaderOffset(), false);
2636 AssertBoolInCheckedMode(); 2457 AssertBoolInCheckedMode();
2637 return result_.raw() == Bool::True().raw(); 2458 return result_.raw() == Bool::True().raw();
2638 } 2459 }
2639 2460
2640 bool StreamingConstantEvaluator::GetCachedConstant(intptr_t kernel_offset, 2461 bool StreamingConstantEvaluator::GetCachedConstant(intptr_t kernel_offset,
2641 Instance* value) { 2462 Instance* value) {
2642 if (builder_ == NULL) return false; 2463 if (builder_ == NULL || builder_->flow_graph_builder_ == NULL) return false;
2643 2464
2644 const Function& function = builder_->parsed_function()->function(); 2465 const Function& function = builder_->parsed_function()->function();
2645 if (function.kind() == RawFunction::kImplicitStaticFinalGetter) { 2466 if (function.kind() == RawFunction::kImplicitStaticFinalGetter) {
2646 // Don't cache constants in initializer expressions. They get 2467 // Don't cache constants in initializer expressions. They get
2647 // evaluated only once. 2468 // evaluated only once.
2648 return false; 2469 return false;
2649 } 2470 }
2650 2471
2651 bool is_present = false; 2472 bool is_present = false;
2652 ASSERT(!script_.InVMHeap()); 2473 ASSERT(!script_.InVMHeap());
(...skipping 10 matching lines...) Expand all
2663 ++H.thread()->compiler_stats()->num_const_cache_hits; 2484 ++H.thread()->compiler_stats()->num_const_cache_hits;
2664 } 2485 }
2665 return is_present; 2486 return is_present;
2666 } 2487 }
2667 2488
2668 2489
2669 void StreamingConstantEvaluator::CacheConstantValue(intptr_t kernel_offset, 2490 void StreamingConstantEvaluator::CacheConstantValue(intptr_t kernel_offset,
2670 const Instance& value) { 2491 const Instance& value) {
2671 ASSERT(Thread::Current()->IsMutatorThread()); 2492 ASSERT(Thread::Current()->IsMutatorThread());
2672 2493
2673 if (builder_ == NULL) return; 2494 if (builder_ == NULL || builder_->flow_graph_builder_ == NULL) return;
2674 2495
2675 const Function& function = builder_->parsed_function()->function(); 2496 const Function& function = builder_->parsed_function()->function();
2676 if (function.kind() == RawFunction::kImplicitStaticFinalGetter) { 2497 if (function.kind() == RawFunction::kImplicitStaticFinalGetter) {
2677 // Don't cache constants in initializer expressions. They get 2498 // Don't cache constants in initializer expressions. They get
2678 // evaluated only once. 2499 // evaluated only once.
2679 return; 2500 return;
2680 } 2501 }
2681 const intptr_t kInitialConstMapSize = 16; 2502 const intptr_t kInitialConstMapSize = 16;
2682 ASSERT(!script_.InVMHeap()); 2503 ASSERT(!script_.InVMHeap());
2683 if (script_.compile_time_constants() == Array::null()) { 2504 if (script_.compile_time_constants() == Array::null()) {
2684 const Array& array = Array::Handle( 2505 const Array& array = Array::Handle(
2685 HashTables::New<KernelConstantsMap>(kInitialConstMapSize, Heap::kNew)); 2506 HashTables::New<KernelConstantsMap>(kInitialConstMapSize, Heap::kNew));
2686 script_.set_compile_time_constants(array); 2507 script_.set_compile_time_constants(array);
2687 } 2508 }
2688 KernelConstantsMap constants(script_.compile_time_constants()); 2509 KernelConstantsMap constants(script_.compile_time_constants());
2689 constants.InsertNewOrGetValue(kernel_offset, value); 2510 constants.InsertNewOrGetValue(kernel_offset, value);
2690 script_.set_compile_time_constants(constants.Release()); 2511 script_.set_compile_time_constants(constants.Release());
2691 } 2512 }
2692 2513
2693 2514 void StreamingFlowGraphBuilder::DiscoverEnclosingElements(
2694 Fragment StreamingFlowGraphBuilder::BuildExpressionAt(intptr_t kernel_offset) { 2515 Zone* zone,
2516 const Function& function,
2517 Function* outermost_function,
2518 intptr_t* outermost_kernel_offset,
2519 intptr_t* parent_class_offset) {
2520 // Find out if there is an enclosing kernel class (which will be used to
2521 // resolve type parameters).
2522 *outermost_function = function.raw();
2523 while (outermost_function->parent_function() != Object::null()) {
2524 *outermost_function = outermost_function->parent_function();
2525 }
2526
2527 if (outermost_function->kernel_offset() > 0) {
2528 *outermost_kernel_offset = outermost_function->kernel_offset();
2529 *parent_class_offset = GetParentOffset(*outermost_kernel_offset);
2530 }
2531 }
2532
2533 intptr_t StreamingFlowGraphBuilder::GetParentOffset(intptr_t offset) {
2534 AlternativeReadingScope alt(reader_, offset);
2535
2536 Tag tag = PeekTag();
2537 intptr_t parent_offset = -1;
2538 switch (tag) {
2539 case kConstructor:
2540 return ReadConstructorUntilFunctionNode();
2541 case kProcedure:
2542 ReadProcedureUntilFunctionNode(
2543 &unused_word, &parent_offset); // read first part of procedure.
2544 return parent_offset;
2545 case kField:
2546 ReadFieldUntilAnnotation(&unused_nameindex, &unused_tokenposition,
2547 &unused_tokenposition, &unused_word,
2548 &parent_offset);
2549 return parent_offset;
2550 default:
2551 UNIMPLEMENTED();
2552 return -1;
2553 }
2554 }
2555
2556 void StreamingFlowGraphBuilder::GetTypeParameterInfoForClass(
2557 intptr_t class_offset,
2558 intptr_t* type_paremeter_counts,
2559 intptr_t* type_paremeter_offset) {
2560 AlternativeReadingScope alt(reader_, class_offset);
2561
2562 ReadClassUntilTypeParameters();
2563 *type_paremeter_counts =
2564 ReadListLength(); // read type_parameters list length.
2565 *type_paremeter_offset = ReaderOffset();
2566 }
2567
2568 void StreamingFlowGraphBuilder::ReadClassUntilFields() {
2569 ReadClassUntilTypeParameters();
2570 SkipTypeParametersList(); // read type_parameters.
2571 Tag type_tag = ReadTag(); // read type (part 1).
2572 if (type_tag == kSomething) {
2573 SkipDartType(); // read type (part 2).
2574 }
2575 type_tag = ReadTag(); // read Mixed-in type (part 1).
2576 if (type_tag == kSomething) {
2577 SkipDartType(); // read Mixed-in type (part 2).
2578 }
2579 SkipListOfDartTypes(); // read implemented_classes.
2580 }
2581
2582 void StreamingFlowGraphBuilder::ReadClassUntilTypeParameters() {
2583 Tag class_tag = ReadTag();
2584 ASSERT(class_tag == kClass);
2585 SkipCanonicalNameReference(); // read canonical_name.
2586 ReadPosition(); // read position.
2587 ReadBool(); // read is_abstract.
2588 SkipStringReference(); // read name index.
2589 ReadUInt(); // read source_uri_index.
2590 SkipListOfExpressions(); // read annotations.
2591 }
2592
2593 intptr_t StreamingFlowGraphBuilder::ReadConstructorUntilFunctionNode() {
2594 Tag tag = ReadTag();
2595 ASSERT(tag == kConstructor);
2596 SkipCanonicalNameReference(); // read canonical name reference.
2597 ReadPosition(); // read position.
2598 ReadPosition(); // read end position.
2599 ReadFlags(); // read flags.
2600 intptr_t parent_offset = ReadUInt(); // parent class binary offset.
2601 SkipName(); // read name.
2602 SkipListOfExpressions(); // read annotations.
2603 return parent_offset;
2604 }
2605
2606 Tag StreamingFlowGraphBuilder::ReadProcedureUntilFunctionNode(
2607 word* kind,
2608 intptr_t* parent_offset) {
2609 Tag tag = ReadTag(); // read tag.
2610 ASSERT(tag == kProcedure);
2611 SkipCanonicalNameReference(); // read canonical name reference.
2612 ReadPosition(); // read position.
2613 ReadPosition(); // read end position.
2614 *kind = ReadByte(); // read kind.
2615 ReadFlags(); // read flags.
2616 *parent_offset = ReadUInt(); // read parent class binary offset.
2617 SkipName(); // read name,
2618 ReadUInt(); // read source_uri_index.
2619 SkipListOfExpressions(); // read annotations.
2620 return ReadTag(); // read tag for optional function node.
2621 }
2622
2623 void StreamingFlowGraphBuilder::ReadFieldUntilAnnotation(
2624 NameIndex* canonical_name,
2625 TokenPosition* position,
2626 TokenPosition* end_position,
2627 word* flags,
2628 intptr_t* parent_offset) {
2629 Tag tag = ReadTag();
2630 ASSERT(tag == kField);
2631
2632 *canonical_name = ReadCanonicalNameReference(); // read canonical_name.
2633 *position = ReadPosition(); // read position.
2634 *end_position = ReadPosition(); // read end position.
2635 *flags = ReadFlags(); // read flags.
2636 *parent_offset = ReadUInt(); // read parent class binary offset.
2637 SkipName(); // read name.
2638 ReadUInt(); // source_uri_index.
2639 }
2640
2641 void StreamingFlowGraphBuilder::GetTypeParameterInfoForPossibleProcedure(
2642 intptr_t outermost_kernel_offset,
2643 bool* member_is_procedure,
2644 bool* is_factory_procedure,
2645 intptr_t* member_type_parameters,
2646 intptr_t* member_type_parameters_offset_start) {
2647 if (outermost_kernel_offset >= 0) {
2648 AlternativeReadingScope alt(reader_, outermost_kernel_offset);
2649 Tag tag = PeekTag();
2650 if (tag == kProcedure) {
2651 *member_is_procedure = true;
2652
2653 word kind;
2654 tag = ReadProcedureUntilFunctionNode(
2655 &kind, &unused_intptr); // read first part of procedure.
2656 *is_factory_procedure =
2657 static_cast<Procedure::ProcedureKind>(kind) == Procedure::kFactory;
2658
2659 if (tag == kSomething) {
2660 ReadFunctionNodeUntilTypeParameters(
2661 &unused_tokenposition, &unused_tokenposition, &unused_word,
2662 &unused_word); // read first part of function node.
2663
2664 intptr_t list_length =
2665 ReadListLength(); // read type_parameters list length.
2666 if (list_length > 0) {
2667 *member_type_parameters = list_length;
2668 *member_type_parameters_offset_start = ReaderOffset();
2669 }
2670 }
2671 }
2672 }
2673 }
2674
2675 void StreamingFlowGraphBuilder::ReadFunctionNodeUntilTypeParameters(
2676 TokenPosition* position,
2677 TokenPosition* end_position,
2678 word* async_marker,
2679 word* dart_async_marker) {
2680 Tag tag = ReadTag(); // read tag.
2681 ASSERT(tag == kFunctionNode);
2682
2683 *position = ReadPosition(); // read position.
2684 *end_position = ReadPosition(); // read end position.
2685 *async_marker = ReadByte(); // read async marker.
2686 *dart_async_marker = ReadByte(); // read dart async marker.
2687 }
2688
2689 intptr_t StreamingFlowGraphBuilder::ReadUntilFunctionNode() {
2690 const Tag tag = PeekTag();
2691 if (tag == kProcedure) {
2692 Tag has_function_node = ReadProcedureUntilFunctionNode(
2693 &unused_word, &unused_intptr); // read first part of procedure.
2694 if (has_function_node == kNothing) {
2695 // Running a procedure without a function node doesn't make sense.
2696 UNREACHABLE();
2697 }
2698 return -1;
2699 // Now at start of FunctionNode.
2700 } else if (tag == kConstructor) {
2701 // read first part of constructor.
2702 return ReadConstructorUntilFunctionNode();
2703 // Now at start of FunctionNode.
2704 // Notice that we also have a list of initializers after that!
2705 } else if (tag == kFunctionNode) {
2706 // Already at start of FunctionNode.
2707 } else {
2708 UNREACHABLE();
2709 }
2710 return -1;
2711 }
2712
2713 StringIndex StreamingFlowGraphBuilder::GetNameFromVariableDeclaration(
2714 intptr_t kernel_offset) {
2715 // Temporarily go to the variable declaration, read the name.
2716 AlternativeReadingScope alt(reader_, kernel_offset);
2717 ReadPosition(); // read position.
2718 ReadPosition(); // read equals position.
2719 ReadFlags(); // read flags.
2720 return ReadStringReference(); // read name index.
2721 }
2722
2723 FlowGraph* StreamingFlowGraphBuilder::BuildGraphOfStaticFieldInitializer() {
2724 TokenPosition position;
2725 TokenPosition end_position;
2726 word flags;
2727 ReadFieldUntilAnnotation(&unused_nameindex, &position, &end_position, &flags,
2728 &unused_intptr);
2729 bool is_static = (flags & Field::kFlagStatic) == Field::kFlagStatic;
2730 bool is_const = (flags & Field::kFlagConst) == Field::kFlagConst;
2731 ASSERT(is_static);
2732
2733 SkipListOfExpressions(); // read annotations.
2734 SkipDartType(); // read type.
2735 Tag initializer_tag = ReadTag(); // read first part of initializer.
2736 if (initializer_tag != kSomething) {
2737 UNREACHABLE();
2738 }
2739
2740 TargetEntryInstr* normal_entry = flow_graph_builder_->BuildTargetEntry();
2741 flow_graph_builder_->graph_entry_ = new (Z) GraphEntryInstr(
2742 *parsed_function(), normal_entry, Compiler::kNoOSRDeoptId);
2743
2744 Fragment body(normal_entry);
2745 body += flow_graph_builder_->CheckStackOverflowInPrologue();
2746 if (is_const) {
2747 // this will (potentially) read the initializer, but reset the position.
2748 body += Constant(constant_evaluator_.EvaluateExpression(ReaderOffset()));
2749 SkipExpression(); // read the initializer.
2750 } else {
2751 body += BuildExpression(); // read initializer.
2752 }
2753 body += Return(TokenPosition::kNoSource);
2754
2755 return new (Z)
2756 FlowGraph(*parsed_function(), flow_graph_builder_->graph_entry_,
2757 flow_graph_builder_->next_block_id_ - 1);
2758 }
2759
2760 FlowGraph* StreamingFlowGraphBuilder::BuildGraphOfFieldAccessor(
2761 LocalVariable* setter_value) {
2762 NameIndex canonical_name;
2763 ReadFieldUntilAnnotation(&canonical_name, &unused_tokenposition,
2764 &unused_tokenposition, &unused_word, &unused_intptr);
2765 SkipListOfExpressions(); // read annotations.
2766 SkipDartType(); // read type.
2767 Tag initializer_tag = ReadTag(); // read first part of initializer.
2768
2769 const Function& function = parsed_function()->function();
2770
2771 bool is_setter = function.IsImplicitSetterFunction();
2772 bool is_method = !function.IsStaticFunction();
2773 dart::Field& field =
2774 dart::Field::ZoneHandle(Z, H.LookupFieldByKernelField(canonical_name));
2775
2776 TargetEntryInstr* normal_entry = flow_graph_builder_->BuildTargetEntry();
2777 flow_graph_builder_->graph_entry_ = new (Z) GraphEntryInstr(
2778 *parsed_function(), normal_entry, Compiler::kNoOSRDeoptId);
2779
2780 Fragment body(normal_entry);
2781 if (is_setter) {
2782 if (is_method) {
2783 body += LoadLocal(scopes()->this_variable);
2784 body += LoadLocal(setter_value);
2785 body += flow_graph_builder_->StoreInstanceFieldGuarded(field, false);
2786 } else {
2787 body += LoadLocal(setter_value);
2788 body += StoreStaticField(TokenPosition::kNoSource, field);
2789 }
2790 body += NullConstant();
2791 } else if (is_method) {
2792 body += LoadLocal(scopes()->this_variable);
2793 body += flow_graph_builder_->LoadField(field);
2794 } else if (field.is_const()) {
2795 // If the parser needs to know the value of an uninitialized constant field
2796 // it will set the value to the transition sentinel (used to detect circular
2797 // initialization) and then call the implicit getter. Thus, the getter
2798 // cannot contain the InitStaticField instruction that normal static getters
2799 // contain because it would detect spurious circular initialization when it
2800 // checks for the transition sentinel.
2801 ASSERT(initializer_tag == kSomething);
2802 // this will (potentially) read the initializer, but reset the position.
2803 body += Constant(constant_evaluator_.EvaluateExpression(ReaderOffset()));
2804 SkipExpression(); // read the initializer.
2805 } else {
2806 // The field always has an initializer because static fields without
2807 // initializers are initialized eagerly and do not have implicit getters.
2808 ASSERT(field.has_initializer());
2809 body += Constant(field);
2810 body += flow_graph_builder_->InitStaticField(field);
2811 body += Constant(field);
2812 body += LoadStaticField();
2813 }
2814 body += Return(TokenPosition::kNoSource);
2815
2816 return new (Z)
2817 FlowGraph(*parsed_function(), flow_graph_builder_->graph_entry_,
2818 flow_graph_builder_->next_block_id_ - 1);
2819 }
2820
2821 void StreamingFlowGraphBuilder::SetupDefaultParameterValues() {
2822 intptr_t num_optional_parameters =
2823 parsed_function()->function().NumOptionalParameters();
2824 if (num_optional_parameters > 0) {
2825 ZoneGrowableArray<const Instance*>* default_values =
2826 new ZoneGrowableArray<const Instance*>(Z, num_optional_parameters);
2827
2828 AlternativeReadingScope alt(reader_);
2829 ReadFunctionNodeUntilTypeParameters(
2830 &unused_tokenposition, &unused_tokenposition, &unused_word,
2831 &unused_word); // read first part of function node.
2832 SkipTypeParametersList(); // read type_parameters.
2833 ReadUInt(); // read total parameter count.
2834 intptr_t required = ReadUInt(); // read required_parameter_count.
2835
2836 if (parsed_function()->function().HasOptionalNamedParameters()) {
2837 // List of positional.
2838 intptr_t list_length = ReadListLength(); // read list length.
2839 for (intptr_t i = 0; i < list_length; ++i) {
2840 SkipVariableDeclaration(); // read ith variable declaration.
2841 }
2842
2843 // List of named.
2844 list_length = ReadListLength(); // read list length.
2845 ASSERT(num_optional_parameters == list_length);
2846 ASSERT(!parsed_function()->function().HasOptionalPositionalParameters());
2847 for (intptr_t i = 0; i < list_length; ++i) {
2848 Instance* default_value;
2849
2850 // Read ith variable declaration
2851 ReadPosition(); // read position.
2852 ReadPosition(); // read equals position.
2853 ReadFlags(); // read flags.
2854 SkipStringReference(); // read name index.
2855 SkipDartType(); // read type.
2856 Tag tag = ReadTag(); // read (first part of) initializer.
2857 if (tag == kSomething) {
2858 // this will (potentially) read the initializer,
2859 // but reset the position.
2860 default_value =
2861 &constant_evaluator_.EvaluateExpression(ReaderOffset());
2862 SkipExpression(); // read (actual) initializer.
2863 } else {
2864 default_value = &Instance::ZoneHandle(Z, Instance::null());
2865 }
2866 default_values->Add(default_value);
2867 }
2868 } else {
2869 // List of positional.
2870 intptr_t list_length = ReadListLength(); // read list length.
2871 ASSERT(list_length == required + num_optional_parameters);
2872 ASSERT(parsed_function()->function().HasOptionalPositionalParameters());
2873 for (intptr_t i = 0; i < required; ++i) {
2874 SkipVariableDeclaration(); // read ith variable declaration.
2875 }
2876 for (intptr_t i = 0; i < num_optional_parameters; ++i) {
2877 Instance* default_value;
2878
2879 // Read ith variable declaration
2880 ReadPosition(); // read position.
2881 ReadPosition(); // read equals position.
2882 ReadFlags(); // read flags.
2883 SkipStringReference(); // read name index.
2884 SkipDartType(); // read type.
2885 Tag tag = ReadTag(); // read (first part of) initializer.
2886 if (tag == kSomething) {
2887 // this will (potentially) read the initializer,
2888 // but reset the position.
2889 default_value =
2890 &constant_evaluator_.EvaluateExpression(ReaderOffset());
2891 SkipExpression(); // read (actual) initializer.
2892 } else {
2893 default_value = &Instance::ZoneHandle(Z, Instance::null());
2894 }
2895 default_values->Add(default_value);
2896 }
2897
2898 // List of named.
2899 list_length = ReadListLength(); // read list length.
2900 ASSERT(list_length == 0);
2901 }
2902 parsed_function()->set_default_parameter_values(default_values);
2903 }
2904 }
2905
2906 Fragment StreamingFlowGraphBuilder::BuildFieldInitializer(
2907 NameIndex canonical_name) {
2908 dart::Field& field =
2909 dart::Field::ZoneHandle(Z, H.LookupFieldByKernelField(canonical_name));
2910 if (PeekTag() == kNullLiteral) {
2911 SkipExpression(); // read past the null literal.
2912 field.RecordStore(Object::null_object());
2913 return Fragment();
2914 }
2915
2916 Fragment instructions;
2917 instructions += LoadLocal(scopes()->this_variable);
2918 instructions += BuildExpression();
2919 instructions += flow_graph_builder_->StoreInstanceFieldGuarded(field, true);
2920 return instructions;
2921 }
2922
2923 Fragment StreamingFlowGraphBuilder::BuildInitializers(
2924 intptr_t constructor_class_parent_offset) {
2925 Fragment instructions;
2926
2927 // These come from:
2928 // class A {
2929 // var x = (expr);
2930 // }
2931 {
2932 AlternativeReadingScope alt(reader_, constructor_class_parent_offset);
2933 ReadClassUntilFields(); // read first part of class.
2934 intptr_t list_length = ReadListLength(); // read fields list length.
2935
2936 for (intptr_t i = 0; i < list_length; ++i) {
2937 intptr_t field_offset = ReaderOffset();
2938 NameIndex canonical_name;
2939 TokenPosition position;
2940 TokenPosition end_position;
2941 word flags;
2942 ReadFieldUntilAnnotation(&canonical_name, &position, &end_position,
2943 &flags, &unused_intptr);
2944 bool is_static = (flags & Field::kFlagStatic) == Field::kFlagStatic;
2945 SkipListOfExpressions(); // read annotations.
2946 SkipDartType(); // read type.
2947 Tag initializer_tag = ReadTag(); // read first part of initializer.
2948 if (!is_static && initializer_tag == kSomething) {
2949 EnterScope(field_offset);
2950 instructions +=
2951 BuildFieldInitializer(canonical_name); // read initializer.
2952 ExitScope(field_offset);
2953 } else if (initializer_tag == kSomething) {
2954 SkipExpression(); // read initializer.
2955 }
2956 }
2957 }
2958
2959 // These to come from:
2960 // class A {
2961 // var x;
2962 // var y;
2963 // A(this.x) : super(expr), y = (expr);
2964 // }
2965 {
2966 AlternativeReadingScope alt(reader_);
2967 SkipFunctionNode(); // read constructors function node.
2968
2969 intptr_t list_length = ReadListLength(); // read initializers list length.
2970 for (intptr_t i = 0; i < list_length; ++i) {
2971 Tag tag = ReadTag();
2972 switch (tag) {
2973 case kInvalidInitializer:
2974 UNIMPLEMENTED();
2975 return Fragment();
2976 case kFieldInitializer: {
2977 NameIndex canonical_name =
2978 ReadCanonicalNameReference(); // read field_reference.
2979 instructions += BuildFieldInitializer(canonical_name); // read value.
2980 break;
2981 }
2982 case kSuperInitializer: {
2983 NameIndex canonical_target =
2984 ReadCanonicalNameReference(); // read target_reference.
2985
2986 instructions += LoadLocal(scopes()->this_variable);
2987 instructions += PushArgument();
2988
2989 // TODO(jensj): ASSERT(init->arguments()->types().length() == 0);
2990 Array& argument_names = Array::ZoneHandle(Z);
2991 intptr_t argument_count;
2992 instructions += BuildArguments(&argument_names,
2993 &argument_count); // read arguments.
2994 argument_count += 1;
2995
2996 const Function& target = Function::ZoneHandle(
2997 Z, H.LookupConstructorByKernelConstructor(canonical_target));
2998 instructions += StaticCall(TokenPosition::kNoSource, target,
2999 argument_count, argument_names);
3000 instructions += Drop();
3001 break;
3002 }
3003 case kRedirectingInitializer: {
3004 NameIndex canonical_target =
3005 ReadCanonicalNameReference(); // read target_reference.
3006
3007 instructions += LoadLocal(scopes()->this_variable);
3008 instructions += PushArgument();
3009
3010 // TODO(jensj): ASSERT(init->arguments()->types().length() == 0);
3011 Array& argument_names = Array::ZoneHandle(Z);
3012 intptr_t argument_count;
3013 instructions += BuildArguments(&argument_names,
3014 &argument_count); // read arguments.
3015 argument_count += 1;
3016
3017 const Function& target = Function::ZoneHandle(
3018 Z, H.LookupConstructorByKernelConstructor(canonical_target));
3019 instructions += StaticCall(TokenPosition::kNoSource, target,
3020 argument_count, argument_names);
3021 instructions += Drop();
3022 break;
3023 }
3024 case kLocalInitializer: {
3025 // The other initializers following this one might read the variable.
3026 // This is used e.g. for evaluating the arguments to a super call
3027 // first, run normal field initializers next and then make the actual
3028 // super call:
3029 //
3030 // The frontend converts
3031 //
3032 // class A {
3033 // var x;
3034 // A(a, b) : super(a + b), x = 2*b {}
3035 // }
3036 //
3037 // to
3038 //
3039 // class A {
3040 // var x;
3041 // A(a, b) : tmp = a + b, x = 2*b, super(tmp) {}
3042 // }
3043 //
3044 // (This is strictly speaking not what one should do in terms of the
3045 // specification but that is how it is currently implemented.)
3046 LocalVariable* variable = LookupVariable(ReaderOffset());
3047
3048 // Variable declaration
3049 ReadPosition(); // read position.
3050 ReadPosition(); // read equals position.
3051 word flags = ReadFlags(); // read flags.
3052 ASSERT((flags & VariableDeclaration::kFlagConst) !=
3053 VariableDeclaration::kFlagConst);
3054 SkipStringReference(); // read name index.
3055 SkipDartType(); // read type.
3056 Tag tag = ReadTag(); // read (first part of) initializer.
3057 if (tag != kSomething) {
3058 UNREACHABLE();
3059 }
3060
3061 instructions += BuildExpression(); // read initializer.
3062 instructions += StoreLocal(TokenPosition::kNoSource, variable);
3063 instructions += Drop();
3064 break;
3065 }
3066 default:
3067 UNREACHABLE();
3068 }
3069 }
3070 }
3071 return instructions;
3072 }
3073
3074 FlowGraph* StreamingFlowGraphBuilder::BuildGraphOfImplicitClosureFunction(
3075 const Function& function) {
3076 const Function& target = Function::ZoneHandle(Z, function.parent_function());
3077
3078 TargetEntryInstr* normal_entry = flow_graph_builder_->BuildTargetEntry();
3079 flow_graph_builder_->graph_entry_ = new (Z) GraphEntryInstr(
3080 *parsed_function(), normal_entry, Compiler::kNoOSRDeoptId);
3081 SetupDefaultParameterValues();
3082
3083 Fragment body(normal_entry);
3084 body += flow_graph_builder_->CheckStackOverflowInPrologue();
3085
3086 // Load all the arguments.
3087 if (!target.is_static()) {
3088 // The context has a fixed shape: a single variable which is the
3089 // closed-over receiver.
3090 body += LoadLocal(parsed_function()->current_context_var());
3091 body += flow_graph_builder_->LoadField(Context::variable_offset(0));
3092 body += PushArgument();
3093 }
3094
3095 TokenPosition end_position;
3096 ReadFunctionNodeUntilTypeParameters(
3097 &unused_tokenposition, &end_position, &unused_word,
3098 &unused_word); // read first part of function node.
3099 SkipTypeParametersList(); // read type parameter list.
3100 ReadUInt(); // read total parameter count.
3101 ReadUInt(); // read required_parameter_count.
3102
3103 // Positional.
3104 intptr_t positional_argument_count = ReadListLength();
3105 for (intptr_t i = 0; i < positional_argument_count; ++i) {
3106 body += LoadLocal(LookupVariable(ReaderOffset())); // ith variable offset.
3107 body += PushArgument();
3108 SkipVariableDeclaration(); // read ith variable.
3109 }
3110
3111 // Named.
3112 intptr_t named_argument_count = ReadListLength();
3113 Array& argument_names = Array::ZoneHandle(Z);
3114 if (named_argument_count > 0) {
3115 argument_names = Array::New(named_argument_count);
3116 for (intptr_t i = 0; i < named_argument_count; ++i) {
3117 body +=
3118 LoadLocal(LookupVariable(ReaderOffset())); // ith variable offset.
3119 body += PushArgument();
3120 argument_names.SetAt(
3121 i, H.DartSymbol(GetNameFromVariableDeclaration(ReaderOffset())));
3122 SkipVariableDeclaration(); // read ith variable.
3123 }
3124 }
3125
3126 // Forward them to the target.
3127 intptr_t argument_count = positional_argument_count + named_argument_count;
3128 if (!target.is_static()) ++argument_count;
3129 body += StaticCall(TokenPosition::kNoSource, target, argument_count,
3130 argument_names);
3131
3132 // Return the result.
3133 body += Return(end_position);
3134
3135 return new (Z)
3136 FlowGraph(*parsed_function(), flow_graph_builder_->graph_entry_,
3137 flow_graph_builder_->next_block_id_ - 1);
3138 }
3139
3140 static bool IsGetMainClosure(const String& name) {
3141 if (name.Length() < 16) return false;
3142 const char* cstr = "_getMainClosure@";
3143 for (intptr_t i = 0; i < 16; ++i) {
3144 if (name.CharAt(i) != cstr[i]) return false;
3145 }
3146 return true;
3147 }
3148
3149 FlowGraph* StreamingFlowGraphBuilder::BuildGraphOfFunction(
3150 bool is_in_builtin_library_toplevel,
3151 intptr_t constructor_class_parent_offset) {
3152 const Function& dart_function = parsed_function()->function();
3153 TargetEntryInstr* normal_entry = flow_graph_builder_->BuildTargetEntry();
3154 flow_graph_builder_->graph_entry_ = new (Z) GraphEntryInstr(
3155 *parsed_function(), normal_entry, flow_graph_builder_->osr_id_);
3156
3157 SetupDefaultParameterValues();
3158
3159 Fragment body;
3160 if (!dart_function.is_native())
3161 body += flow_graph_builder_->CheckStackOverflowInPrologue();
3162 intptr_t context_size =
3163 parsed_function()->node_sequence()->scope()->num_context_variables();
3164 if (context_size > 0) {
3165 body += flow_graph_builder_->PushContext(context_size);
3166 LocalVariable* context = MakeTemporary();
3167
3168 // Copy captured parameters from the stack into the context.
3169 LocalScope* scope = parsed_function()->node_sequence()->scope();
3170 intptr_t parameter_count = dart_function.NumParameters();
3171 intptr_t parameter_index = parsed_function()->first_parameter_index();
3172 for (intptr_t i = 0; i < parameter_count; ++i, --parameter_index) {
3173 LocalVariable* variable = scope->VariableAt(i);
3174 if (variable->is_captured()) {
3175 // There is no LocalVariable describing the on-stack parameter so
3176 // create one directly and use the same type.
3177 LocalVariable* parameter = new (Z)
3178 LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource,
3179 Symbols::TempParam(), variable->type());
3180 parameter->set_index(parameter_index);
3181 // Mark the stack variable so it will be ignored by the code for
3182 // try/catch.
3183 parameter->set_is_captured_parameter(true);
3184
3185 // Copy the parameter from the stack to the context. Overwrite it
3186 // with a null constant on the stack so the original value is
3187 // eligible for garbage collection.
3188 body += LoadLocal(context);
3189 body += LoadLocal(parameter);
3190 body += flow_graph_builder_->StoreInstanceField(
3191 TokenPosition::kNoSource,
3192 Context::variable_offset(variable->index()));
3193 body += NullConstant();
3194 body += StoreLocal(TokenPosition::kNoSource, parameter);
3195 body += Drop();
3196 }
3197 }
3198 body += Drop(); // The context.
3199 }
3200 if (constructor_class_parent_offset > 0) {
3201 // TODO(27590): Currently the [VariableDeclaration]s from the
3202 // initializers will be visible inside the entire body of the constructor.
3203 // We should make a separate scope for them.
3204 body += BuildInitializers(constructor_class_parent_offset);
3205 }
3206
3207 TokenPosition position;
3208 ReadFunctionNodeUntilTypeParameters(
3209 &position, &unused_tokenposition, &unused_word,
3210 &unused_word); // read first part of function node.
3211 SkipTypeParametersList(); // read type parameter list.
3212 ReadUInt(); // read total parameter count
3213 ReadUInt(); // read required_parameter_count.
3214 intptr_t first_parameter_offset = -1;
3215 {
3216 AlternativeReadingScope alt(reader_);
3217 intptr_t list_length = ReadListLength(); // read number of positionals.
3218 if (list_length > 0) {
3219 first_parameter_offset = ReaderOffset();
3220 }
3221 }
3222 // Current position: About to read list of positionals.
3223
3224 // The specification defines the result of `a == b` to be:
3225 //
3226 // a) if either side is `null` then the result is `identical(a, b)`.
3227 // b) else the result is `a.operator==(b)`
3228 //
3229 // For user-defined implementations of `operator==` we need therefore
3230 // implement the handling of a).
3231 //
3232 // The default `operator==` implementation in `Object` is implemented in terms
3233 // of identical (which we assume here!) which means that case a) is actually
3234 // included in b). So we just use the normal implementation in the body.
3235 if ((dart_function.NumParameters() == 2) &&
3236 (dart_function.name() == Symbols::EqualOperator().raw()) &&
3237 (dart_function.Owner() != I->object_store()->object_class())) {
3238 LocalVariable* parameter = LookupVariable(first_parameter_offset);
3239
3240 TargetEntryInstr* null_entry;
3241 TargetEntryInstr* non_null_entry;
3242
3243 body += LoadLocal(parameter);
3244 body += BranchIfNull(&null_entry, &non_null_entry);
3245
3246 // The argument was `null` and the receiver is not the null class (we only
3247 // go into this branch for user-defined == operators) so we can return
3248 // false.
3249 Fragment null_fragment(null_entry);
3250 null_fragment += Constant(Bool::False());
3251 null_fragment += Return(dart_function.end_token_pos());
3252
3253 body = Fragment(body.entry, non_null_entry);
3254 }
3255
3256 // If we run in checked mode, we have to check the type of the passed
3257 // arguments.
3258 if (I->type_checks()) {
3259 // Positional.
3260 intptr_t list_length = ReadListLength();
3261 for (intptr_t i = 0; i < list_length; ++i) {
3262 body +=
3263 LoadLocal(LookupVariable(ReaderOffset())); // ith variable offset.
3264 body += CheckVariableTypeInCheckedMode(ReaderOffset());
3265 body += Drop();
3266 SkipVariableDeclaration(); // read ith variable.
3267 }
3268
3269 // Named.
3270 list_length = ReadListLength();
3271 for (intptr_t i = 0; i < list_length; ++i) {
3272 body +=
3273 LoadLocal(LookupVariable(ReaderOffset())); // ith variable offset.
3274 body += CheckVariableTypeInCheckedMode(ReaderOffset());
3275 body += Drop();
3276 SkipVariableDeclaration(); // read ith variable.
3277 }
3278 } else {
3279 // Still skip past the parameters.
3280 SkipListOfVariableDeclarations(); // read list of positionals.
3281 SkipListOfVariableDeclarations(); // read list of named.
3282 }
3283
3284 SkipDartType(); // read return type.
3285
3286 if (FLAG_causal_async_stacks &&
3287 (dart_function.IsAsyncFunction() || dart_function.IsAsyncGenerator())) {
3288 LocalScope* scope = parsed_function()->node_sequence()->scope();
3289 // :async_stack_trace = _asyncStackTraceHelper(:async_op);
3290 const dart::Library& async_lib =
3291 dart::Library::Handle(dart::Library::AsyncLibrary());
3292 const Function& target = Function::ZoneHandle(
3293 Z,
3294 async_lib.LookupFunctionAllowPrivate(Symbols::AsyncStackTraceHelper()));
3295 ASSERT(!target.IsNull());
3296
3297 // TODO(johnmccutchan): Why does this have the null value?
3298 LocalVariable* async_op =
3299 scope->child()->LookupVariable(Symbols::AsyncOperation(), false);
3300 ASSERT(async_op != NULL);
3301 ASSERT(async_op->is_captured());
3302 body += LoadLocal(async_op);
3303 body += PushArgument();
3304 body += StaticCall(TokenPosition::kNoSource, target, 1);
3305 LocalVariable* async_stack_trace_var =
3306 scope->LookupVariable(Symbols::AsyncStackTraceVar(), false);
3307 ASSERT(async_stack_trace_var != NULL);
3308 body += StoreLocal(TokenPosition::kNoSource, async_stack_trace_var);
3309 body += Drop();
3310 }
3311
3312 bool has_body = ReadTag() == kSomething; // read first part of body.
3313
3314 if (dart_function.is_native()) {
3315 body += flow_graph_builder_->NativeFunctionBody(first_parameter_offset,
3316 dart_function);
3317 } else if (has_body) {
3318 if (is_in_builtin_library_toplevel &&
3319 IsGetMainClosure(dart::String::Handle(Z, dart_function.name()))) {
3320 body += BuildGetMainClosure();
3321 } else {
3322 body += BuildStatement(); // read body.
3323 }
3324 }
3325 if (body.is_open()) {
3326 body += NullConstant();
3327 body += Return(dart_function.end_token_pos());
3328 }
3329
3330 // If functions body contains any yield points build switch statement that
3331 // selects a continuation point based on the value of :await_jump_var.
3332 if (!yield_continuations().is_empty()) {
3333 // The code we are building will be executed right after we enter
3334 // the function and before any nested contexts are allocated.
3335 // Reset current context_depth_ to match this.
3336 const intptr_t current_context_depth = flow_graph_builder_->context_depth_;
3337 flow_graph_builder_->context_depth_ =
3338 scopes()->yield_jump_variable->owner()->context_level();
3339
3340 // Prepend an entry corresponding to normal entry to the function.
3341 yield_continuations().InsertAt(
3342 0, YieldContinuation(new (Z) DropTempsInstr(0, NULL),
3343 CatchClauseNode::kInvalidTryIndex));
3344 yield_continuations()[0].entry->LinkTo(body.entry);
3345
3346 // Build a switch statement.
3347 Fragment dispatch;
3348
3349 // Load :await_jump_var into a temporary.
3350 dispatch += LoadLocal(scopes()->yield_jump_variable);
3351 dispatch += StoreLocal(TokenPosition::kNoSource, scopes()->switch_variable);
3352 dispatch += Drop();
3353
3354 BlockEntryInstr* block = NULL;
3355 for (intptr_t i = 0; i < yield_continuations().length(); i++) {
3356 if (i == 1) {
3357 // This is not a normal entry but a resumption. Restore
3358 // :current_context_var from :await_ctx_var.
3359 // Note: after this point context_depth_ does not match current context
3360 // depth so we should not access any local variables anymore.
3361 dispatch += LoadLocal(scopes()->yield_context_variable);
3362 dispatch += StoreLocal(TokenPosition::kNoSource,
3363 parsed_function()->current_context_var());
3364 dispatch += Drop();
3365 }
3366 if (i == (yield_continuations().length() - 1)) {
3367 // We reached the last possility, no need to build more ifs.
3368 // Continue to the last continuation.
3369 // Note: continuations start with nop DropTemps instruction
3370 // which acts like an anchor, so we need to skip it.
3371 block->set_try_index(yield_continuations()[i].try_index);
3372 dispatch <<= yield_continuations()[i].entry->next();
3373 break;
3374 }
3375
3376 // Build comparison:
3377 //
3378 // if (:await_ctx_var == i) {
3379 // -> yield_continuations()[i]
3380 // } else ...
3381 //
3382 TargetEntryInstr* then;
3383 TargetEntryInstr* otherwise;
3384 dispatch += LoadLocal(scopes()->switch_variable);
3385 dispatch += IntConstant(i);
3386 dispatch += flow_graph_builder_->BranchIfStrictEqual(&then, &otherwise);
3387
3388 // True branch is linked to appropriate continuation point.
3389 // Note: continuations start with nop DropTemps instruction
3390 // which acts like an anchor, so we need to skip it.
3391 then->LinkTo(yield_continuations()[i].entry->next());
3392 then->set_try_index(yield_continuations()[i].try_index);
3393 // False branch will contain the next comparison.
3394 dispatch = Fragment(dispatch.entry, otherwise);
3395 block = otherwise;
3396 }
3397 body = dispatch;
3398
3399 flow_graph_builder_->context_depth_ = current_context_depth;
3400 }
3401
3402 if (FLAG_causal_async_stacks &&
3403 (dart_function.IsAsyncClosure() || dart_function.IsAsyncGenClosure())) {
3404 // The code we are building will be executed right after we enter
3405 // the function and before any nested contexts are allocated.
3406 // Reset current context_depth_ to match this.
3407 const intptr_t current_context_depth = flow_graph_builder_->context_depth_;
3408 flow_graph_builder_->context_depth_ =
3409 scopes()->yield_jump_variable->owner()->context_level();
3410
3411 Fragment instructions;
3412 LocalScope* scope = parsed_function()->node_sequence()->scope();
3413
3414 const Function& target = Function::ZoneHandle(
3415 Z, I->object_store()->async_set_thread_stack_trace());
3416 ASSERT(!target.IsNull());
3417
3418 // Fetch and load :async_stack_trace
3419 LocalVariable* async_stack_trace_var =
3420 scope->LookupVariable(Symbols::AsyncStackTraceVar(), false);
3421 ASSERT((async_stack_trace_var != NULL) &&
3422 async_stack_trace_var->is_captured());
3423 instructions += LoadLocal(async_stack_trace_var);
3424 instructions += PushArgument();
3425
3426 // Call _asyncSetThreadStackTrace
3427 instructions += StaticCall(TokenPosition::kNoSource, target, 1);
3428 instructions += Drop();
3429
3430 // TODO(29737): This sequence should be generated in order.
3431 body = instructions + body;
3432 flow_graph_builder_->context_depth_ = current_context_depth;
3433 }
3434
3435 if (NeedsDebugStepCheck(dart_function, position)) {
3436 const intptr_t current_context_depth = flow_graph_builder_->context_depth_;
3437 flow_graph_builder_->context_depth_ = 0;
3438
3439 // If a switch was added above: Start the switch by injecting a debuggable
3440 // safepoint so stepping over an await works.
3441 // If not, still start the body with a debuggable safepoint to ensure
3442 // breaking on a method always happens, even if there are no
3443 // assignments/calls/runtimecalls in the first basic block.
3444 // Place this check at the last parameter to ensure parameters
3445 // are in scope in the debugger at method entry.
3446 const int num_params = dart_function.NumParameters();
3447 TokenPosition check_pos = TokenPosition::kNoSource;
3448 if (num_params > 0) {
3449 LocalScope* scope = parsed_function()->node_sequence()->scope();
3450 const LocalVariable& parameter = *scope->VariableAt(num_params - 1);
3451 check_pos = parameter.token_pos();
3452 }
3453 if (!check_pos.IsDebugPause()) {
3454 // No parameters or synthetic parameters.
3455 check_pos = position;
3456 ASSERT(check_pos.IsDebugPause());
3457 }
3458
3459 // TODO(29737): This sequence should be generated in order.
3460 body = DebugStepCheck(check_pos) + body;
3461 flow_graph_builder_->context_depth_ = current_context_depth;
3462 }
3463
3464 normal_entry->LinkTo(body.entry);
3465
3466 // When compiling for OSR, use a depth first search to prune instructions
3467 // unreachable from the OSR entry. Catch entries are always considered
3468 // reachable, even if they become unreachable after OSR.
3469 if (flow_graph_builder_->osr_id_ != Compiler::kNoOSRDeoptId) {
3470 BitVector* block_marks =
3471 new (Z) BitVector(Z, flow_graph_builder_->next_block_id_);
3472 bool found = flow_graph_builder_->graph_entry_->PruneUnreachable(
3473 flow_graph_builder_->graph_entry_, NULL, flow_graph_builder_->osr_id_,
3474 block_marks);
3475 ASSERT(found);
3476 }
3477 return new (Z)
3478 FlowGraph(*parsed_function(), flow_graph_builder_->graph_entry_,
3479 flow_graph_builder_->next_block_id_ - 1);
3480 }
3481
3482 Fragment StreamingFlowGraphBuilder::BuildGetMainClosure() {
3483 // _getMainClosure in dart:_builtin. Compile that one specially here.
3484 const dart::Library& builtin =
3485 dart::Library::Handle(Z, I->object_store()->builtin_library());
3486 const Object& main =
3487 Object::Handle(Z, builtin.LookupObjectAllowPrivate(dart::String::Handle(
3488 Z, dart::String::New("main"))));
3489 if (main.IsField()) {
3490 UNIMPLEMENTED();
3491 } else if (main.IsFunction()) {
3492 const Function& function = Function::Cast(main);
3493 if (function.kind() == RawFunction::kRegularFunction) {
3494 const Function& closure_function =
3495 Function::Handle(Z, function.ImplicitClosureFunction());
3496 const Instance& closure =
3497 Instance::ZoneHandle(Z, closure_function.ImplicitStaticClosure());
3498 return Constant(closure) + Return(TokenPosition::kNoSource);
3499 } else {
3500 UNIMPLEMENTED();
3501 }
3502 } else {
3503 UNIMPLEMENTED();
3504 }
3505 return Fragment();
3506 }
3507
3508 FlowGraph* StreamingFlowGraphBuilder::BuildGraph(intptr_t kernel_offset) {
3509 const Function& function = parsed_function()->function();
3510
3511 // Setup a [ActiveClassScope] and a [ActiveMemberScope] which will be used
3512 // e.g. for type translation.
3513 const dart::Class& klass =
3514 dart::Class::Handle(zone_, parsed_function()->function().Owner());
3515 bool is_in_builtin_library_toplevel =
3516 klass.library() == I->object_store()->builtin_library() &&
3517 klass.IsTopLevel();
3518
3519 Function& outermost_function = Function::Handle(Z);
3520 intptr_t outermost_kernel_offset = -1;
3521 intptr_t parent_class_offset = -1;
3522 DiscoverEnclosingElements(Z, function, &outermost_function,
3523 &outermost_kernel_offset, &parent_class_offset);
3524 // Use [klass]/[kernel_class] as active class. Type parameters will get
3525 // resolved via [kernel_class] unless we are nested inside a static factory
3526 // in which case we will use [member].
3527 intptr_t class_type_parameters = 0;
3528 intptr_t class_type_parameters_offset_start = -1;
3529 if (parent_class_offset > 0) {
3530 GetTypeParameterInfoForClass(parent_class_offset, &class_type_parameters,
3531 &class_type_parameters_offset_start);
3532 }
3533
3534 ActiveClassScope active_class_scope(active_class(), class_type_parameters,
3535 class_type_parameters_offset_start,
3536 &klass);
3537
3538 bool member_is_procedure = false;
3539 bool is_factory_procedure = false;
3540 intptr_t member_type_parameters = 0;
3541 intptr_t member_type_parameters_offset_start = -1;
3542 GetTypeParameterInfoForPossibleProcedure(
3543 outermost_kernel_offset, &member_is_procedure, &is_factory_procedure,
3544 &member_type_parameters, &member_type_parameters_offset_start);
3545
3546 ActiveMemberScope active_member(active_class(), member_is_procedure,
3547 is_factory_procedure, member_type_parameters,
3548 member_type_parameters_offset_start);
3549
3550 // The IR builder will create its own local variables and scopes, and it
3551 // will not need an AST. The code generator will assume that there is a
3552 // local variable stack slot allocated for the current context and (I
3553 // think) that the runtime will expect it to be at a fixed offset which
3554 // requires allocating an unused expression temporary variable.
3555 set_scopes(parsed_function()->EnsureKernelScopes());
3556
2695 SetOffset(kernel_offset); 3557 SetOffset(kernel_offset);
2696 return BuildExpression(); // read expression. 3558
2697 } 3559 switch (function.kind()) {
3560 case RawFunction::kClosureFunction:
3561 case RawFunction::kRegularFunction:
3562 case RawFunction::kGetterFunction:
3563 case RawFunction::kSetterFunction: {
3564 ReadUntilFunctionNode(); // read until function node.
3565 return function.IsImplicitClosureFunction()
3566 ? BuildGraphOfImplicitClosureFunction(function)
3567 : BuildGraphOfFunction(is_in_builtin_library_toplevel);
3568 }
3569 case RawFunction::kConstructor: {
3570 bool is_factory = function.IsFactory();
3571 if (is_factory) {
3572 ReadUntilFunctionNode(); // read until function node.
3573 return BuildGraphOfFunction(is_in_builtin_library_toplevel);
3574 } else {
3575 // Constructor: Pass offset to parent class.
3576 return BuildGraphOfFunction(
3577 is_in_builtin_library_toplevel,
3578 ReadUntilFunctionNode()); // read until function node.
3579 }
3580 }
3581 case RawFunction::kImplicitGetter:
3582 case RawFunction::kImplicitStaticFinalGetter:
3583 case RawFunction::kImplicitSetter: {
3584 return IsStaticInitializer(function, Z)
3585 ? BuildGraphOfStaticFieldInitializer()
3586 : BuildGraphOfFieldAccessor(scopes()->setter_value);
3587 }
3588 case RawFunction::kMethodExtractor:
3589 return flow_graph_builder_->BuildGraphOfMethodExtractor(function);
3590 case RawFunction::kNoSuchMethodDispatcher:
3591 return flow_graph_builder_->BuildGraphOfNoSuchMethodDispatcher(function);
3592 case RawFunction::kInvokeFieldDispatcher:
3593 return flow_graph_builder_->BuildGraphOfInvokeFieldDispatcher(function);
3594 case RawFunction::kSignatureFunction:
3595 case RawFunction::kIrregexpFunction:
3596 break;
3597 }
3598 UNREACHABLE();
3599 return NULL;
3600 }
3601
2698 3602
2699 Fragment StreamingFlowGraphBuilder::BuildStatementAt(intptr_t kernel_offset) { 3603 Fragment StreamingFlowGraphBuilder::BuildStatementAt(intptr_t kernel_offset) {
2700 SetOffset(kernel_offset); 3604 SetOffset(kernel_offset);
2701 return BuildStatement(); // read statement. 3605 return BuildStatement(); // read statement.
2702 } 3606 }
2703 3607
2704 Fragment StreamingFlowGraphBuilder::BuildExpression(TokenPosition* position) { 3608 Fragment StreamingFlowGraphBuilder::BuildExpression(TokenPosition* position) {
2705 uint8_t payload = 0; 3609 uint8_t payload = 0;
2706 Tag tag = ReadTag(&payload); // read tag. 3610 Tag tag = ReadTag(&payload); // read tag.
2707 switch (tag) { 3611 switch (tag) {
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
2763 return BuildThrow(position); 3667 return BuildThrow(position);
2764 case kListLiteral: 3668 case kListLiteral:
2765 return BuildListLiteral(false, position); 3669 return BuildListLiteral(false, position);
2766 case kConstListLiteral: 3670 case kConstListLiteral:
2767 return BuildListLiteral(true, position); 3671 return BuildListLiteral(true, position);
2768 case kMapLiteral: 3672 case kMapLiteral:
2769 return BuildMapLiteral(false, position); 3673 return BuildMapLiteral(false, position);
2770 case kConstMapLiteral: 3674 case kConstMapLiteral:
2771 return BuildMapLiteral(true, position); 3675 return BuildMapLiteral(true, position);
2772 case kFunctionExpression: 3676 case kFunctionExpression:
2773 // TODO(jensj) 3677 return BuildFunctionExpression();
2774 UNIMPLEMENTED();
2775 return Fragment();
2776 case kLet: 3678 case kLet:
2777 return BuildLet(position); 3679 return BuildLet(position);
2778 case kBigIntLiteral: 3680 case kBigIntLiteral:
2779 return BuildBigIntLiteral(position); 3681 return BuildBigIntLiteral(position);
2780 case kStringLiteral: 3682 case kStringLiteral:
2781 return BuildStringLiteral(position); 3683 return BuildStringLiteral(position);
2782 case kSpecialIntLiteral: 3684 case kSpecialIntLiteral:
2783 return BuildIntLiteral(payload, position); 3685 return BuildIntLiteral(payload, position);
2784 case kNegativeIntLiteral: 3686 case kNegativeIntLiteral:
2785 return BuildIntLiteral(true, position); 3687 return BuildIntLiteral(true, position);
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
2837 return BuildReturnStatement(); 3739 return BuildReturnStatement();
2838 case kTryCatch: 3740 case kTryCatch:
2839 return BuildTryCatch(); 3741 return BuildTryCatch();
2840 case kTryFinally: 3742 case kTryFinally:
2841 return BuildTryFinally(); 3743 return BuildTryFinally();
2842 case kYieldStatement: 3744 case kYieldStatement:
2843 return BuildYieldStatement(); 3745 return BuildYieldStatement();
2844 case kVariableDeclaration: 3746 case kVariableDeclaration:
2845 return BuildVariableDeclaration(); 3747 return BuildVariableDeclaration();
2846 case kFunctionDeclaration: 3748 case kFunctionDeclaration:
2847 // TODO(jensj) 3749 return BuildFunctionDeclaration();
2848 UNIMPLEMENTED();
2849 return Fragment();
2850 default: 3750 default:
2851 UNREACHABLE(); 3751 UNREACHABLE();
2852 } 3752 }
2853 return Fragment(); 3753 return Fragment();
2854 } 3754 }
2855 3755
2856 intptr_t StreamingFlowGraphBuilder::ReaderOffset() { 3756 intptr_t StreamingFlowGraphBuilder::ReaderOffset() {
2857 return reader_->offset(); 3757 return reader_->offset();
2858 } 3758 }
2859 3759
(...skipping 494 matching lines...) Expand 10 before | Expand all | Expand 10 after
3354 4254
3355 void StreamingFlowGraphBuilder::SkipFunctionNode() { 4255 void StreamingFlowGraphBuilder::SkipFunctionNode() {
3356 Tag tag = ReadTag(); // read tag. 4256 Tag tag = ReadTag(); // read tag.
3357 ASSERT(tag == kFunctionNode); 4257 ASSERT(tag == kFunctionNode);
3358 4258
3359 ReadPosition(); // read position. 4259 ReadPosition(); // read position.
3360 ReadPosition(); // read end position. 4260 ReadPosition(); // read end position.
3361 ReadByte(); // read async marker. 4261 ReadByte(); // read async marker.
3362 ReadByte(); // read dart async marker. 4262 ReadByte(); // read dart async marker.
3363 SkipTypeParametersList(); // read type_parameters. 4263 SkipTypeParametersList(); // read type_parameters.
4264 ReadUInt(); // read total parameter count.
3364 ReadUInt(); // read required_parameter_count. 4265 ReadUInt(); // read required_parameter_count.
3365 4266
3366 SkipListOfVariableDeclarations(); // read list of positionals. 4267 SkipListOfVariableDeclarations(); // read list of positionals.
3367 SkipListOfVariableDeclarations(); // read list of named. 4268 SkipListOfVariableDeclarations(); // read list of named.
3368 SkipDartType(); // read return type. 4269 SkipDartType(); // read return type.
3369 4270
3370 if (ReadTag() == kSomething) { 4271 if (ReadTag() == kSomething) {
3371 SkipStatement(); // Read body 4272 SkipStatement(); // Read body
3372 } 4273 }
3373 } 4274 }
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
3478 } 4379 }
3479 4380
3480 ActiveClass* StreamingFlowGraphBuilder::active_class() { 4381 ActiveClass* StreamingFlowGraphBuilder::active_class() {
3481 return &flow_graph_builder_->active_class_; 4382 return &flow_graph_builder_->active_class_;
3482 } 4383 }
3483 4384
3484 ScopeBuildingResult* StreamingFlowGraphBuilder::scopes() { 4385 ScopeBuildingResult* StreamingFlowGraphBuilder::scopes() {
3485 return flow_graph_builder_->scopes_; 4386 return flow_graph_builder_->scopes_;
3486 } 4387 }
3487 4388
4389 void StreamingFlowGraphBuilder::set_scopes(ScopeBuildingResult* scope) {
4390 flow_graph_builder_->scopes_ = scope;
4391 }
4392
3488 ParsedFunction* StreamingFlowGraphBuilder::parsed_function() { 4393 ParsedFunction* StreamingFlowGraphBuilder::parsed_function() {
3489 return flow_graph_builder_->parsed_function_; 4394 return flow_graph_builder_->parsed_function_;
3490 } 4395 }
3491 4396
3492 TryFinallyBlock* StreamingFlowGraphBuilder::try_finally_block() { 4397 TryFinallyBlock* StreamingFlowGraphBuilder::try_finally_block() {
3493 return flow_graph_builder_->try_finally_block_; 4398 return flow_graph_builder_->try_finally_block_;
3494 } 4399 }
3495 4400
3496 SwitchBlock* StreamingFlowGraphBuilder::switch_block() { 4401 SwitchBlock* StreamingFlowGraphBuilder::switch_block() {
3497 return flow_graph_builder_->switch_block_; 4402 return flow_graph_builder_->switch_block_;
(...skipping 1363 matching lines...) Expand 10 before | Expand all | Expand 10 after
4861 5766
4862 const dart::Class& map_class = 5767 const dart::Class& map_class =
4863 dart::Class::Handle(Z, dart::Library::LookupCoreClass(Symbols::Map())); 5768 dart::Class::Handle(Z, dart::Library::LookupCoreClass(Symbols::Map()));
4864 const Function& factory_method = Function::ZoneHandle( 5769 const Function& factory_method = Function::ZoneHandle(
4865 Z, map_class.LookupFactory( 5770 Z, map_class.LookupFactory(
4866 dart::Library::PrivateCoreLibName(Symbols::MapLiteralFactory()))); 5771 dart::Library::PrivateCoreLibName(Symbols::MapLiteralFactory())));
4867 5772
4868 return instructions + StaticCall(position, factory_method, 2); 5773 return instructions + StaticCall(position, factory_method, 2);
4869 } 5774 }
4870 5775
5776 Fragment StreamingFlowGraphBuilder::BuildFunctionExpression() {
5777 intptr_t offset = ReaderOffset() - 1; // -1 to include tag byte.
5778 return BuildFunctionNode(offset, TokenPosition::kNoSource, false, -1);
5779 }
5780
4871 Fragment StreamingFlowGraphBuilder::BuildLet(TokenPosition* position) { 5781 Fragment StreamingFlowGraphBuilder::BuildLet(TokenPosition* position) {
4872 if (position != NULL) *position = TokenPosition::kNoSource; 5782 if (position != NULL) *position = TokenPosition::kNoSource;
4873 5783
4874 Fragment instructions = BuildVariableDeclaration(); // read variable. 5784 Fragment instructions = BuildVariableDeclaration(); // read variable.
4875 instructions += BuildExpression(); // read body. 5785 instructions += BuildExpression(); // read body.
4876 return instructions; 5786 return instructions;
4877 } 5787 }
4878 5788
4879 5789
4880 Fragment StreamingFlowGraphBuilder::BuildBigIntLiteral( 5790 Fragment StreamingFlowGraphBuilder::BuildBigIntLiteral(
(...skipping 987 matching lines...) Expand 10 before | Expand all | Expand 10 after
5868 // use the position of the identifier. 6778 // use the position of the identifier.
5869 TokenPosition debug_position = Utils::Maximum(position, equals_position); 6779 TokenPosition debug_position = Utils::Maximum(position, equals_position);
5870 if (NeedsDebugStepCheck(stack(), debug_position)) { 6780 if (NeedsDebugStepCheck(stack(), debug_position)) {
5871 instructions = DebugStepCheck(debug_position) + instructions; 6781 instructions = DebugStepCheck(debug_position) + instructions;
5872 } 6782 }
5873 instructions += StoreLocal(position, variable); 6783 instructions += StoreLocal(position, variable);
5874 instructions += Drop(); 6784 instructions += Drop();
5875 return instructions; 6785 return instructions;
5876 } 6786 }
5877 6787
6788 Fragment StreamingFlowGraphBuilder::BuildFunctionDeclaration() {
6789 intptr_t offset = ReaderOffset() - 1; // -1 to include tag byte.
6790 TokenPosition position = ReadPosition(); // read position.
6791 intptr_t variable_offeset = ReaderOffset();
6792 SkipVariableDeclaration(); // read variable declaration.
6793
6794 Fragment instructions = DebugStepCheck(position);
6795 instructions += BuildFunctionNode(offset, position, true, variable_offeset);
6796 instructions += StoreLocal(position, LookupVariable(variable_offeset));
6797 instructions += Drop();
6798 return instructions;
6799 }
6800
6801 Fragment StreamingFlowGraphBuilder::BuildFunctionNode(
6802 intptr_t parent_kernel_offset,
6803 TokenPosition parent_position,
6804 bool declaration,
6805 intptr_t variable_offeset) {
6806 intptr_t offset = ReaderOffset();
6807
6808 TokenPosition position;
6809 TokenPosition end_position;
6810 word async_marker_word;
6811 word dart_async_marker_word;
6812 ReadFunctionNodeUntilTypeParameters(
6813 &position, &end_position, &async_marker_word,
6814 &dart_async_marker_word); // read first part of function node.
6815 FunctionNode::AsyncMarker async_marker =
6816 static_cast<FunctionNode::AsyncMarker>(async_marker_word);
6817 FunctionNode::AsyncMarker dart_async_marker =
6818 static_cast<FunctionNode::AsyncMarker>(dart_async_marker_word);
6819
6820 if (declaration) {
6821 position = parent_position;
6822 }
6823 if (!position.IsReal()) {
6824 // Positions has to be unique in regards to the parent.
6825 // A non-real at this point is probably -1, we cannot blindly use that
6826 // as others might use it too. Create a new dummy non-real TokenPosition.
6827 position = TokenPosition(offset).ToSynthetic();
6828 }
6829
6830 SkipTypeParametersList(); // read type parameters.
6831
6832 // The VM has a per-isolate table of functions indexed by the enclosing
6833 // function and token position.
6834 Function& function = Function::ZoneHandle(Z);
6835 bool read_rest_of_function_node = false;
6836
6837 // NOTE: This is not TokenPosition in the general sense!
6838 function = I->LookupClosureFunction(parsed_function()->function(), position);
6839 if (function.IsNull()) {
6840 for (intptr_t i = 0; i < scopes()->function_scopes.length(); ++i) {
6841 if (scopes()->function_scopes[i].kernel_offset != offset) {
6842 continue;
6843 }
6844
6845 const dart::String* name;
6846 if (!declaration) {
6847 name = &Symbols::AnonymousClosure();
6848 } else {
6849 name = &H.DartSymbol(GetNameFromVariableDeclaration(variable_offeset));
6850 }
6851 // NOTE: This is not TokenPosition in the general sense!
6852 function = Function::NewClosureFunction(
6853 *name, parsed_function()->function(), position);
6854
6855 function.set_is_debuggable(dart_async_marker == FunctionNode::kSync);
6856 switch (dart_async_marker) {
6857 case FunctionNode::kSyncStar:
6858 function.set_modifier(RawFunction::kSyncGen);
6859 break;
6860 case FunctionNode::kAsync:
6861 function.set_modifier(RawFunction::kAsync);
6862 function.set_is_inlinable(!FLAG_causal_async_stacks);
6863 break;
6864 case FunctionNode::kAsyncStar:
6865 function.set_modifier(RawFunction::kAsyncGen);
6866 function.set_is_inlinable(!FLAG_causal_async_stacks);
6867 break;
6868 default:
6869 // no special modifier
6870 break;
6871 }
6872 function.set_is_generated_body(async_marker ==
6873 FunctionNode::kSyncYielding);
6874 if (function.IsAsyncClosure() || function.IsAsyncGenClosure()) {
6875 function.set_is_inlinable(!FLAG_causal_async_stacks);
6876 }
6877
6878 function.set_end_token_pos(end_position);
6879 LocalScope* scope = scopes()->function_scopes[i].scope;
6880 const ContextScope& context_scope = ContextScope::Handle(
6881 Z, scope->PreserveOuterScope(flow_graph_builder_->context_depth_));
6882 function.set_context_scope(context_scope);
6883 function.set_kernel_offset(offset);
6884 // Read rest of function node.
6885 SetupFunctionParameters(dart::Class::Handle(Z), function,
6886 false, // is_method
6887 true); // is_closure
6888 read_rest_of_function_node = true;
6889 // Finalize function type.
6890 Type& signature_type = Type::Handle(Z, function.SignatureType());
6891 signature_type ^=
6892 ClassFinalizer::FinalizeType(*active_class()->klass, signature_type);
6893 function.SetSignatureType(signature_type);
6894
6895 I->AddClosureFunction(function);
6896 break;
6897 }
6898 }
6899
6900 if (!read_rest_of_function_node) {
6901 ReadUInt(); // read total parameter count.
6902 ReadUInt(); // read required_parameter_count.
6903 SkipListOfVariableDeclarations(); // read list of positionals.
6904 SkipListOfVariableDeclarations(); // read list of named.
6905 SkipDartType(); // read return type.
6906 if (ReadTag() == kSomething) { // read first part of body.
6907 SkipStatement(); // read body.
6908 }
6909 }
6910
6911 const dart::Class& closure_class =
6912 dart::Class::ZoneHandle(Z, I->object_store()->closure_class());
6913 ASSERT(!closure_class.IsNull());
6914 Fragment instructions =
6915 flow_graph_builder_->AllocateObject(closure_class, function);
6916 LocalVariable* closure = MakeTemporary();
6917
6918 // The function signature can have uninstantiated class type parameters.
6919 //
6920 // TODO(regis): Also handle the case of a function signature that has
6921 // uninstantiated function type parameters.
6922 if (!function.HasInstantiatedSignature(kCurrentClass)) {
6923 instructions += LoadLocal(closure);
6924 instructions += LoadInstantiatorTypeArguments();
6925 instructions += flow_graph_builder_->StoreInstanceField(
6926 TokenPosition::kNoSource,
6927 Closure::instantiator_type_arguments_offset());
6928 }
6929
6930 // Store the function and the context in the closure.
6931 instructions += LoadLocal(closure);
6932 instructions += Constant(function);
6933 instructions += flow_graph_builder_->StoreInstanceField(
6934 TokenPosition::kNoSource, Closure::function_offset());
6935
6936 instructions += LoadLocal(closure);
6937 instructions += LoadLocal(parsed_function()->current_context_var());
6938 instructions += flow_graph_builder_->StoreInstanceField(
6939 TokenPosition::kNoSource, Closure::context_offset());
6940
6941 return instructions;
6942 }
6943
6944
6945 void StreamingFlowGraphBuilder::SetupFunctionParameters(
6946 const dart::Class& klass,
6947 const dart::Function& function,
6948 bool is_method,
6949 bool is_closure) {
6950 ASSERT(!(is_method && is_closure));
6951 bool is_factory = function.IsFactory();
6952 intptr_t extra_parameters = (is_method || is_closure || is_factory) ? 1 : 0;
6953
6954 intptr_t total_parameter_count = ReadUInt(); // read total parameter count.
6955 intptr_t required_parameter_count =
6956 ReadUInt(); // read required_parameter_count.
6957 intptr_t positional_parameters_count = ReadListLength(); // read list length.
6958 intptr_t named_parameters_count =
6959 total_parameter_count - positional_parameters_count;
6960
6961 function.set_num_fixed_parameters(extra_parameters +
6962 required_parameter_count);
6963 if (named_parameters_count > 0) {
6964 function.SetNumOptionalParameters(named_parameters_count, false);
6965 } else {
6966 function.SetNumOptionalParameters(
6967 positional_parameters_count - required_parameter_count, true);
6968 }
6969 intptr_t num_parameters = extra_parameters + total_parameter_count;
6970 function.set_parameter_types(
6971 Array::Handle(Z, Array::New(num_parameters, Heap::kOld)));
6972 function.set_parameter_names(
6973 Array::Handle(Z, Array::New(num_parameters, Heap::kOld)));
6974 intptr_t pos = 0;
6975 if (is_method) {
6976 ASSERT(!klass.IsNull());
6977 function.SetParameterTypeAt(pos, H.GetCanonicalType(klass));
6978 function.SetParameterNameAt(pos, Symbols::This());
6979 pos++;
6980 } else if (is_closure) {
6981 function.SetParameterTypeAt(pos, AbstractType::dynamic_type());
6982 function.SetParameterNameAt(pos, Symbols::ClosureParameter());
6983 pos++;
6984 } else if (is_factory) {
6985 function.SetParameterTypeAt(pos, AbstractType::dynamic_type());
6986 function.SetParameterNameAt(pos, Symbols::TypeArgumentsParameter());
6987 pos++;
6988 }
6989
6990 for (intptr_t i = 0; i < positional_parameters_count; ++i, ++pos) {
6991 // Read ith variable declaration.
6992 ReadPosition(); // read position.
6993 ReadPosition(); // read equals position.
6994 ReadFlags(); // read flags.
6995 StringIndex name = ReadStringReference(); // read name index.
6996 const AbstractType& type = T.BuildTypeWithoutFinalization(); // read type.
6997 Tag tag = ReadTag(); // read (first part of) initializer.
6998 if (tag == kSomething) {
6999 SkipExpression(); // read (actual) initializer.
7000 }
7001
7002 function.SetParameterTypeAt(
7003 pos, type.IsMalformed() ? Type::dynamic_type() : type);
7004 function.SetParameterNameAt(pos, H.DartSymbol(name));
7005 }
7006
7007 intptr_t named_parameters_count_check =
7008 ReadListLength(); // read list length.
7009 ASSERT(named_parameters_count_check == named_parameters_count);
7010 for (intptr_t i = 0; i < named_parameters_count; ++i, ++pos) {
7011 // Read ith variable declaration.
7012 ReadPosition(); // read position.
7013 ReadPosition(); // read equals position.
7014 ReadFlags(); // read flags.
7015 StringIndex name = ReadStringReference(); // read name index.
7016 const AbstractType& type = T.BuildTypeWithoutFinalization(); // read type.
7017 Tag tag = ReadTag(); // read (first part of) initializer.
7018 if (tag == kSomething) {
7019 SkipExpression(); // read (actual) initializer.
7020 }
7021
7022 function.SetParameterTypeAt(
7023 pos, type.IsMalformed() ? Type::dynamic_type() : type);
7024 function.SetParameterNameAt(pos, H.DartSymbol(name));
7025 }
7026
7027 // The result type for generative constructors has already been set.
7028 if (!function.IsGenerativeConstructor()) {
7029 const AbstractType& return_type =
7030 T.BuildTypeWithoutFinalization(); // read return type.
7031 function.set_result_type(return_type.IsMalformed() ? Type::dynamic_type()
7032 : return_type);
7033 } else {
7034 SkipDartType(); // read return type.
7035 }
7036
7037 if (ReadTag() == kSomething) { // read first part of body.
7038 SkipStatement(); // read body.
7039 }
7040 }
7041
7042 RawObject* StreamingFlowGraphBuilder::BuildParameterDescriptor(
7043 intptr_t kernel_offset) {
7044 SetOffset(kernel_offset);
7045 ReadUntilFunctionNode(); // read until function node.
7046 ReadFunctionNodeUntilTypeParameters(
7047 &unused_tokenposition, &unused_tokenposition, &unused_word,
7048 &unused_word); // read first part of function node.
7049 SkipTypeParametersList(); // read type_parameters.
7050
7051 intptr_t param_count = ReadUInt(); // read total parameter count.
7052 ReadUInt(); // read required_parameter_count.
7053 intptr_t positional_count = ReadListLength(); // read list length.
7054 intptr_t named_parameters_count = param_count - positional_count;
7055
7056 const Array& param_descriptor = Array::Handle(
7057 Array::New(param_count * Parser::kParameterEntrySize, Heap::kOld));
7058 for (intptr_t i = 0; i < param_count; ++i) {
7059 const intptr_t entry_start = i * Parser::kParameterEntrySize;
7060
7061 if (i == positional_count) {
7062 intptr_t named_parameters_count_check =
7063 ReadListLength(); // read list length.
7064 ASSERT(named_parameters_count_check == named_parameters_count);
7065 }
7066
7067 // Read ith variable declaration.
7068 ReadPosition(); // read position.
7069 ReadPosition(); // read equals position.
7070 word flags = ReadFlags(); // read flags.
7071 bool is_final = (flags & VariableDeclaration::kFlagFinal) ==
7072 VariableDeclaration::kFlagFinal;
7073 param_descriptor.SetAt(entry_start + Parser::kParameterIsFinalOffset,
7074 is_final ? Bool::True() : Bool::False());
7075
7076 SkipStringReference(); // read name index.
7077 SkipDartType(); // read type.
7078 Tag tag = ReadTag(); // read (first part of) initializer.
7079 if (tag == kSomething) {
7080 // this will (potentially) read the initializer, but reset the position.
7081 Instance& constant =
7082 constant_evaluator_.EvaluateExpression(ReaderOffset());
7083 SkipExpression(); // read (actual) initializer.
7084 param_descriptor.SetAt(entry_start + Parser::kParameterDefaultValueOffset,
7085 constant);
7086 } else {
7087 param_descriptor.SetAt(entry_start + Parser::kParameterDefaultValueOffset,
7088 Object::null_instance());
7089 }
7090
7091 param_descriptor.SetAt(entry_start + Parser::kParameterMetadataOffset,
7092 /* Issue(28434): Missing parameter metadata. */
7093 Object::null_instance());
7094 }
7095 return param_descriptor.raw();
7096 }
7097
7098 RawObject* StreamingFlowGraphBuilder::EvaluateMetadata(intptr_t kernel_offset) {
7099 SetOffset(kernel_offset);
7100 const Tag tag = PeekTag();
7101
7102 if (tag == kClass) {
7103 Tag tag = ReadTag(); // read tag.
7104 ASSERT(tag == kClass);
7105 SkipCanonicalNameReference(); // read canonical name reference.
7106 ReadPosition(); // read position.
7107 ReadByte(); // read is_abstract
7108 SkipStringReference(); // read name_index.
7109 ReadUInt(); // read source_uri_index.
7110 // SkipListOfExpressions(); // read annotations.
7111 } else if (tag == kProcedure) {
7112 Tag tag = ReadTag(); // read tag.
7113 ASSERT(tag == kProcedure);
7114 SkipCanonicalNameReference(); // read canonical name reference.
7115 ReadPosition(); // read position.
7116 ReadPosition(); // read end position.
7117 ReadByte(); // read kind.
7118 ReadFlags(); // read flags.
7119 ReadUInt(); // read parent class binary offset.
7120 SkipName(); // read name,
7121 ReadUInt(); // read source_uri_index.
7122 // SkipListOfExpressions(); // read annotations.
7123 } else if (tag == kField) {
7124 ReadFieldUntilAnnotation(&unused_nameindex, &unused_tokenposition,
7125 &unused_tokenposition, &unused_word,
7126 &unused_intptr);
7127 // SkipListOfExpressions(); // read annotations.
7128 } else if (tag == kConstructor) {
7129 Tag tag = ReadTag();
7130 ASSERT(tag == kConstructor);
7131 SkipCanonicalNameReference(); // read canonical name reference.
7132 ReadPosition(); // read position.
7133 ReadPosition(); // read end position.
7134 ReadFlags(); // read flags.
7135 ReadUInt(); // parent class binary offset.
7136 SkipName(); // read name.
7137 // SkipListOfExpressions(); // read annotations.
7138 } else {
7139 FATAL("No support for metadata on this type of kernel node\n");
7140 }
7141
7142 intptr_t list_length = ReadListLength(); // read list length.
7143 const Array& metadata_values = Array::Handle(Z, Array::New(list_length));
7144 for (intptr_t i = 0; i < list_length; ++i) {
7145 // this will (potentially) read the expression, but reset the position.
7146 Instance& value = constant_evaluator_.EvaluateExpression(ReaderOffset());
7147 SkipExpression(); // read (actual) initializer.
7148 metadata_values.SetAt(i, value);
7149 }
7150
7151 return metadata_values.raw();
7152 }
7153
5878 } // namespace kernel 7154 } // namespace kernel
5879 } // namespace dart 7155 } // namespace dart
5880 7156
5881 #endif // !defined(DART_PRECOMPILED_RUNTIME) 7157 #endif // !defined(DART_PRECOMPILED_RUNTIME)
OLDNEW
« no previous file with comments | « runtime/vm/kernel_binary_flowgraph.h ('k') | runtime/vm/kernel_reader.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698