OLD | NEW |
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/kernel_binary_flowgraph.h" | 5 #include "vm/kernel_binary_flowgraph.h" |
6 | 6 |
7 #include "vm/longjump.h" | 7 #include "vm/longjump.h" |
8 #include "vm/object_store.h" | 8 #include "vm/object_store.h" |
9 | 9 |
10 #if !defined(DART_PRECOMPILED_RUNTIME) | 10 #if !defined(DART_PRECOMPILED_RUNTIME) |
11 | 11 |
12 namespace dart { | 12 namespace dart { |
13 namespace kernel { | 13 namespace kernel { |
14 | 14 |
15 #define Z (zone_) | 15 #define Z (zone_) |
16 #define H (translation_helper_) | 16 #define H (translation_helper_) |
17 #define T (type_translator_) | 17 #define T (type_translator_) |
18 #define I Isolate::Current() | 18 #define I Isolate::Current() |
19 | 19 |
| 20 static bool IsStaticInitializer(const Function& function, Zone* zone) { |
| 21 return (function.kind() == RawFunction::kImplicitStaticFinalGetter) && |
| 22 dart::String::Handle(zone, function.name()) |
| 23 .StartsWith(Symbols::InitPrefix()); |
| 24 } |
| 25 |
| 26 |
| 27 StreamingScopeBuilder::StreamingScopeBuilder(ParsedFunction* parsed_function, |
| 28 intptr_t kernel_offset, |
| 29 const uint8_t* buffer, |
| 30 intptr_t buffer_length) |
| 31 : result_(NULL), |
| 32 parsed_function_(parsed_function), |
| 33 kernel_offset_(kernel_offset), |
| 34 translation_helper_(Thread::Current()), |
| 35 zone_(translation_helper_.zone()), |
| 36 current_function_scope_(NULL), |
| 37 scope_(NULL), |
| 38 depth_(0), |
| 39 name_index_(0), |
| 40 needs_expr_temp_(false), |
| 41 builder_(new StreamingFlowGraphBuilder(&translation_helper_, |
| 42 zone_, |
| 43 buffer, |
| 44 buffer_length)), |
| 45 type_translator_(builder_, /*finalize=*/true) { |
| 46 Script& script = Script::Handle(Z, parsed_function->function().script()); |
| 47 H.SetStringOffsets(TypedData::Handle(Z, script.kernel_string_offsets())); |
| 48 H.SetStringData(TypedData::Handle(Z, script.kernel_string_data())); |
| 49 H.SetCanonicalNames(TypedData::Handle(Z, script.kernel_canonical_names())); |
| 50 type_translator_.active_class_ = &active_class_; |
| 51 } |
| 52 |
| 53 StreamingScopeBuilder::~StreamingScopeBuilder() { |
| 54 delete builder_; |
| 55 } |
| 56 |
| 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() { |
| 79 if (result_ != NULL) return result_; |
| 80 |
| 81 ASSERT(scope_ == NULL && depth_.loop_ == 0 && depth_.function_ == 0); |
| 82 result_ = new (Z) ScopeBuildingResult(); |
| 83 |
| 84 ParsedFunction* parsed_function = parsed_function_; |
| 85 const Function& function = parsed_function->function(); |
| 86 |
| 87 // Setup a [ActiveClassScope] and a [ActiveMemberScope] which will be used |
| 88 // e.g. for type translation. |
| 89 const dart::Class& klass = |
| 90 dart::Class::Handle(zone_, parsed_function_->function().Owner()); |
| 91 Function& outermost_function = Function::Handle(Z); |
| 92 intptr_t outermost_kernel_offset = -1; |
| 93 intptr_t parent_class_offset = -1; |
| 94 DiscoverEnclosingElements(Z, function, &outermost_function, |
| 95 &outermost_kernel_offset, &parent_class_offset); |
| 96 // Use [klass]/[kernel_class] as active class. Type parameters will get |
| 97 // resolved via [kernel_class] unless we are nested inside a static factory |
| 98 // in which case we will use [member]. |
| 99 intptr_t class_type_parameters = 0; |
| 100 intptr_t class_type_parameters_offset_start = -1; |
| 101 if (parent_class_offset > 0) { |
| 102 GetTypeParameterInfoForClass(parent_class_offset, &class_type_parameters, |
| 103 &class_type_parameters_offset_start); |
| 104 } |
| 105 ActiveClassScope active_class_scope(&active_class_, class_type_parameters, |
| 106 class_type_parameters_offset_start, |
| 107 &klass); |
| 108 |
| 109 bool member_is_procedure = false; |
| 110 bool is_factory_procedure = false; |
| 111 intptr_t member_type_parameters = 0; |
| 112 intptr_t member_type_parameters_offset_start = -1; |
| 113 GetTypeParameterInfoForPossibleProcedure( |
| 114 outermost_kernel_offset, &member_is_procedure, &is_factory_procedure, |
| 115 &member_type_parameters, &member_type_parameters_offset_start); |
| 116 |
| 117 ActiveMemberScope active_member(&active_class_, member_is_procedure, |
| 118 is_factory_procedure, member_type_parameters, |
| 119 member_type_parameters_offset_start); |
| 120 |
| 121 LocalScope* enclosing_scope = NULL; |
| 122 if (function.IsLocalFunction()) { |
| 123 enclosing_scope = LocalScope::RestoreOuterScope( |
| 124 ContextScope::Handle(Z, function.context_scope())); |
| 125 } |
| 126 current_function_scope_ = scope_ = new (Z) LocalScope(enclosing_scope, 0, 0); |
| 127 scope_->set_begin_token_pos(function.token_pos()); |
| 128 scope_->set_end_token_pos(function.end_token_pos()); |
| 129 |
| 130 LocalVariable* context_var = parsed_function->current_context_var(); |
| 131 context_var->set_is_forced_stack(); |
| 132 scope_->AddVariable(context_var); |
| 133 |
| 134 parsed_function->SetNodeSequence( |
| 135 new SequenceNode(TokenPosition::kNoSource, scope_)); |
| 136 |
| 137 intptr_t parent_offset = -1; |
| 138 builder_->SetOffset(kernel_offset_); |
| 139 |
| 140 switch (function.kind()) { |
| 141 case RawFunction::kClosureFunction: |
| 142 case RawFunction::kRegularFunction: |
| 143 case RawFunction::kGetterFunction: |
| 144 case RawFunction::kSetterFunction: |
| 145 case RawFunction::kConstructor: { |
| 146 const Tag tag = builder_->PeekTag(); |
| 147 if (tag == kProcedure) { |
| 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; |
| 166 ReadFunctionNodeUntilTypeParameters( |
| 167 &async_marker_word, |
| 168 &unused_word); // read first part of function node. |
| 169 current_function_async_marker_ = |
| 170 static_cast<FunctionNode::AsyncMarker>(async_marker_word); |
| 171 // NOTE: FunctionNode is not read entirely yet! It continues below the if. |
| 172 |
| 173 intptr_t pos = 0; |
| 174 if (function.IsClosureFunction()) { |
| 175 LocalVariable* variable = MakeVariable( |
| 176 TokenPosition::kNoSource, TokenPosition::kNoSource, |
| 177 Symbols::ClosureParameter(), AbstractType::dynamic_type()); |
| 178 variable->set_is_forced_stack(); |
| 179 scope_->InsertParameterAt(pos++, variable); |
| 180 } else if (!function.is_static()) { |
| 181 // We use [is_static] instead of [IsStaticFunction] because the latter |
| 182 // returns `false` for constructors. |
| 183 dart::Class& klass = dart::Class::Handle(Z, function.Owner()); |
| 184 Type& klass_type = H.GetCanonicalType(klass); |
| 185 LocalVariable* variable = |
| 186 MakeVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, |
| 187 Symbols::This(), klass_type); |
| 188 scope_->InsertParameterAt(pos++, variable); |
| 189 result_->this_variable = variable; |
| 190 |
| 191 // We visit instance field initializers because they might contain |
| 192 // [Let] expressions and we need to have a mapping. |
| 193 if (tag == kConstructor) { |
| 194 ASSERT(parent_offset >= 0); |
| 195 AlternativeReadingScope alt(builder_->reader_, parent_offset); |
| 196 ReadClassUntilFields(); // read first part of class. |
| 197 intptr_t list_length = |
| 198 builder_->ReadListLength(); // read fields list length. |
| 199 for (intptr_t i = 0; i < list_length; i++) { |
| 200 intptr_t field_offset = builder_->ReaderOffset(); |
| 201 TokenPosition position; |
| 202 TokenPosition end_position; |
| 203 word flags; |
| 204 ReadFieldUntilAnnotation(&position, &end_position, &flags, |
| 205 &unused_intptr); |
| 206 bool is_static = (flags & Field::kFlagStatic) == Field::kFlagStatic; |
| 207 builder_->SkipListOfExpressions(); // read annotations. |
| 208 builder_->SkipDartType(); // read type. |
| 209 Tag initializer_tag = builder_->ReadTag(); |
| 210 if (!is_static && initializer_tag == kSomething) { |
| 211 EnterScope(field_offset); |
| 212 VisitExpression(); // read initializer. |
| 213 ExitScope(position, end_position); |
| 214 } else if (initializer_tag == kSomething) { |
| 215 builder_->SkipExpression(); // read initializer. |
| 216 } |
| 217 } |
| 218 } |
| 219 } else if (function.IsFactory()) { |
| 220 LocalVariable* variable = MakeVariable( |
| 221 TokenPosition::kNoSource, TokenPosition::kNoSource, |
| 222 Symbols::TypeArgumentsParameter(), AbstractType::dynamic_type()); |
| 223 scope_->InsertParameterAt(pos++, variable); |
| 224 result_->type_arguments_variable = variable; |
| 225 } |
| 226 |
| 227 // Continue reading FunctionNode. |
| 228 builder_->SkipTypeParametersList(); // read type_parameters. |
| 229 builder_->ReadUInt(); // read required_parameter_count. |
| 230 AddPositionalAndNamedParameters( |
| 231 pos); // read positional_parameters and named_parameters. |
| 232 |
| 233 // We generate a syntethic body for implicit closure functions - which |
| 234 // will forward the call to the real function. |
| 235 // -> see BuildGraphOfImplicitClosureFunction |
| 236 if (!function.IsImplicitClosureFunction()) { |
| 237 builder_->SetOffset(kernel_offset_); |
| 238 first_body_token_position_ = TokenPosition::kNoSource; |
| 239 VisitNode(); |
| 240 |
| 241 // TODO(jensj): HACK: Push the begin token to after any parameters to |
| 242 // avoid crash when breaking on definition line of async method in |
| 243 // debugger. It seems that another scope needs to be added |
| 244 // in which captures are made, but I can't make that work. |
| 245 // This 'solution' doesn't crash, but I cannot see the parameters at |
| 246 // that particular breakpoint either. |
| 247 // Also push the end token to after the "}" to avoid crashing on |
| 248 // stepping past the last line (to the "}" character). |
| 249 if (first_body_token_position_.IsReal()) { |
| 250 scope_->set_begin_token_pos(first_body_token_position_); |
| 251 } |
| 252 if (scope_->end_token_pos().IsReal()) { |
| 253 scope_->set_end_token_pos(scope_->end_token_pos().Next()); |
| 254 } |
| 255 } |
| 256 break; |
| 257 } |
| 258 case RawFunction::kImplicitGetter: |
| 259 case RawFunction::kImplicitStaticFinalGetter: |
| 260 case RawFunction::kImplicitSetter: { |
| 261 ASSERT(builder_->PeekTag() == kField); |
| 262 if (IsStaticInitializer(function, Z)) { |
| 263 VisitNode(); |
| 264 break; |
| 265 } |
| 266 bool is_setter = function.IsImplicitSetterFunction(); |
| 267 bool is_method = !function.IsStaticFunction(); |
| 268 intptr_t pos = 0; |
| 269 if (is_method) { |
| 270 dart::Class& klass = dart::Class::Handle(Z, function.Owner()); |
| 271 Type& klass_type = H.GetCanonicalType(klass); |
| 272 LocalVariable* variable = |
| 273 MakeVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, |
| 274 Symbols::This(), klass_type); |
| 275 scope_->InsertParameterAt(pos++, variable); |
| 276 result_->this_variable = variable; |
| 277 } |
| 278 if (is_setter) { |
| 279 result_->setter_value = |
| 280 MakeVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, |
| 281 Symbols::Value(), AbstractType::dynamic_type()); |
| 282 scope_->InsertParameterAt(pos++, result_->setter_value); |
| 283 } |
| 284 break; |
| 285 } |
| 286 case RawFunction::kMethodExtractor: { |
| 287 // Add a receiver parameter. Though it is captured, we emit code to |
| 288 // explicitly copy it to a fixed offset in a freshly-allocated context |
| 289 // instead of using the generic code for regular functions. |
| 290 // Therefore, it isn't necessary to mark it as captured here. |
| 291 dart::Class& klass = dart::Class::Handle(Z, function.Owner()); |
| 292 Type& klass_type = H.GetCanonicalType(klass); |
| 293 LocalVariable* variable = |
| 294 MakeVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, |
| 295 Symbols::This(), klass_type); |
| 296 scope_->InsertParameterAt(0, variable); |
| 297 result_->this_variable = variable; |
| 298 break; |
| 299 } |
| 300 case RawFunction::kNoSuchMethodDispatcher: |
| 301 case RawFunction::kInvokeFieldDispatcher: |
| 302 for (intptr_t i = 0; i < function.NumParameters(); ++i) { |
| 303 LocalVariable* variable = MakeVariable( |
| 304 TokenPosition::kNoSource, TokenPosition::kNoSource, |
| 305 dart::String::ZoneHandle(Z, function.ParameterNameAt(i)), |
| 306 AbstractType::dynamic_type()); |
| 307 scope_->InsertParameterAt(i, variable); |
| 308 } |
| 309 break; |
| 310 case RawFunction::kSignatureFunction: |
| 311 case RawFunction::kIrregexpFunction: |
| 312 UNREACHABLE(); |
| 313 } |
| 314 if (needs_expr_temp_) { |
| 315 scope_->AddVariable(parsed_function_->EnsureExpressionTemp()); |
| 316 } |
| 317 parsed_function->AllocateVariables(); |
| 318 |
| 319 return result_; |
| 320 } |
| 321 |
| 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() { |
| 357 Tag tag = builder_->PeekTag(); |
| 358 switch (tag) { |
| 359 case kConstructor: |
| 360 VisitConstructor(); |
| 361 return; |
| 362 case kProcedure: |
| 363 VisitProcedure(); |
| 364 return; |
| 365 case kField: |
| 366 VisitField(); |
| 367 return; |
| 368 case kFunctionNode: |
| 369 VisitFunctionNode(); |
| 370 return; |
| 371 default: |
| 372 UNIMPLEMENTED(); |
| 373 return; |
| 374 } |
| 375 } |
| 376 |
| 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() { |
| 391 // Field initializers that come from non-static field declarations are |
| 392 // compiled as if they appear in the constructor initializer list. This is |
| 393 // important for closure-valued field initializers because the VM expects the |
| 394 // corresponding closure functions to appear as if they were nested inside the |
| 395 // constructor. |
| 396 intptr_t parent_offset = ReadConstructorUntilFunctionNode(); |
| 397 ASSERT(parent_offset >= 0); |
| 398 { |
| 399 AlternativeReadingScope alt(builder_->reader_, parent_offset); |
| 400 ReadClassUntilFields(); // read first part of class. |
| 401 |
| 402 intptr_t list_length = |
| 403 builder_->ReadListLength(); // read fields list length. |
| 404 for (intptr_t i = 0; i < list_length; i++) { |
| 405 word flags; |
| 406 ReadFieldUntilAnnotation(&unused_tokenposition, &unused_tokenposition, |
| 407 &flags, &unused_intptr); |
| 408 bool is_static = (flags & Field::kFlagStatic) == Field::kFlagStatic; |
| 409 builder_->SkipListOfExpressions(); // read annotations. |
| 410 builder_->SkipDartType(); // read type. |
| 411 Tag initializer_tag = builder_->ReadTag(); |
| 412 if (!is_static && initializer_tag == kSomething) { |
| 413 VisitExpression(); // read initializer. |
| 414 } else if (initializer_tag == kSomething) { |
| 415 builder_->SkipExpression(); // read initializer. |
| 416 } |
| 417 } |
| 418 } |
| 419 |
| 420 // Visit children (note that there's no reason to visit the name). |
| 421 VisitFunctionNode(); |
| 422 intptr_t list_length = |
| 423 builder_->ReadListLength(); // read initializers list length. |
| 424 for (intptr_t i = 0; i < list_length; i++) { |
| 425 VisitInitializer(); |
| 426 } |
| 427 } |
| 428 |
| 429 void StreamingScopeBuilder::VisitProcedure() { |
| 430 Tag function_node = ReadProcedureUntilFunctionNode( |
| 431 &unused_word, &unused_intptr); // read first part of procedure. |
| 432 if (function_node == kSomething) { |
| 433 VisitFunctionNode(); |
| 434 } |
| 435 } |
| 436 |
| 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() { |
| 455 ReadFieldUntilAnnotation(&unused_tokenposition, &unused_tokenposition, |
| 456 &unused_intptr, |
| 457 &unused_word); // read first part of field. |
| 458 builder_->SkipListOfExpressions(); // read annotations. |
| 459 VisitDartType(); // read type. |
| 460 Tag tag = builder_->ReadTag(); // read initializer (part 1). |
| 461 if (tag == kSomething) { |
| 462 VisitExpression(); // read initializer (part 2). |
| 463 } |
| 464 } |
| 465 |
| 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() { |
| 554 word async_marker_word; |
| 555 word dart_async_marker_word; |
| 556 ReadFunctionNodeUntilTypeParameters(&async_marker_word, |
| 557 &dart_async_marker_word); |
| 558 FunctionNode::AsyncMarker async_marker = |
| 559 static_cast<FunctionNode::AsyncMarker>(async_marker_word); |
| 560 FunctionNode::AsyncMarker dart_async_marker = |
| 561 static_cast<FunctionNode::AsyncMarker>(dart_async_marker_word); |
| 562 |
| 563 intptr_t list_length = |
| 564 builder_->ReadListLength(); // read type_parameters list length. |
| 565 for (intptr_t i = 0; i < list_length; ++i) { |
| 566 builder_->SkipStringReference(); // read ith name index. |
| 567 VisitDartType(); // read ith bound. |
| 568 } |
| 569 |
| 570 if (FLAG_causal_async_stacks && |
| 571 (dart_async_marker == FunctionNode::kAsync || |
| 572 dart_async_marker == FunctionNode::kAsyncStar)) { |
| 573 LocalVariable* asyncStackTraceVar = MakeVariable( |
| 574 TokenPosition::kNoSource, TokenPosition::kNoSource, |
| 575 Symbols::AsyncStackTraceVar(), AbstractType::dynamic_type()); |
| 576 scope_->AddVariable(asyncStackTraceVar); |
| 577 } |
| 578 |
| 579 if (async_marker == FunctionNode::kSyncYielding) { |
| 580 LocalScope* scope = parsed_function_->node_sequence()->scope(); |
| 581 intptr_t offset = parsed_function_->function().num_fixed_parameters(); |
| 582 for (intptr_t i = 0; |
| 583 i < parsed_function_->function().NumOptionalPositionalParameters(); |
| 584 i++) { |
| 585 scope->VariableAt(offset + i)->set_is_forced_stack(); |
| 586 } |
| 587 } |
| 588 |
| 589 // Read (but don't visit) the positional and named parameters, because they've |
| 590 // already been added to the scope. |
| 591 |
| 592 builder_->ReadUInt(); // read required_parameter_count. |
| 593 |
| 594 builder_->SkipListOfVariableDeclarations(); // read list of positionals. |
| 595 builder_->SkipListOfVariableDeclarations(); // read list of named. |
| 596 builder_->SkipDartType(); // read return type. |
| 597 |
| 598 if (builder_->ReadTag() == kSomething) { |
| 599 PositionScope scope(builder_->reader_); |
| 600 VisitStatement(); // Read body |
| 601 first_body_token_position_ = builder_->reader_->min_position(); |
| 602 } |
| 603 |
| 604 // Ensure that :await_jump_var, :await_ctx_var, :async_op and |
| 605 // :async_stack_trace are captured. |
| 606 if (async_marker == FunctionNode::kSyncYielding) { |
| 607 { |
| 608 LocalVariable* temp = NULL; |
| 609 LookupCapturedVariableByName( |
| 610 (depth_.function_ == 0) ? &result_->yield_jump_variable : &temp, |
| 611 Symbols::AwaitJumpVar()); |
| 612 } |
| 613 { |
| 614 LocalVariable* temp = NULL; |
| 615 LookupCapturedVariableByName( |
| 616 (depth_.function_ == 0) ? &result_->yield_context_variable : &temp, |
| 617 Symbols::AwaitContextVar()); |
| 618 } |
| 619 { |
| 620 LocalVariable* temp = |
| 621 scope_->LookupVariable(Symbols::AsyncOperation(), true); |
| 622 if (temp != NULL) { |
| 623 scope_->CaptureVariable(temp); |
| 624 } |
| 625 } |
| 626 if (FLAG_causal_async_stacks) { |
| 627 LocalVariable* temp = |
| 628 scope_->LookupVariable(Symbols::AsyncStackTraceVar(), true); |
| 629 if (temp != NULL) { |
| 630 scope_->CaptureVariable(temp); |
| 631 } |
| 632 } |
| 633 } |
| 634 } |
| 635 |
| 636 void StreamingScopeBuilder::VisitInitializer() { |
| 637 Tag tag = builder_->ReadTag(); |
| 638 switch (tag) { |
| 639 case kInvalidInitializer: |
| 640 return; |
| 641 case kFieldInitializer: |
| 642 builder_->SkipCanonicalNameReference(); // read field_reference. |
| 643 VisitExpression(); // read value. |
| 644 return; |
| 645 case kSuperInitializer: |
| 646 builder_->SkipCanonicalNameReference(); // read field_reference. |
| 647 VisitArguments(); // read arguments. |
| 648 return; |
| 649 case kRedirectingInitializer: |
| 650 builder_->SkipCanonicalNameReference(); // read field_reference. |
| 651 VisitArguments(); // read arguments. |
| 652 return; |
| 653 case kLocalInitializer: |
| 654 VisitVariableDeclaration(); // read variable. |
| 655 return; |
| 656 default: |
| 657 UNREACHABLE(); |
| 658 } |
| 659 } |
| 660 |
| 661 void StreamingScopeBuilder::VisitExpression() { |
| 662 uint8_t payload = 0; |
| 663 Tag tag = builder_->ReadTag(&payload); |
| 664 switch (tag) { |
| 665 case kInvalidExpression: |
| 666 return; |
| 667 case kVariableGet: { |
| 668 builder_->ReadPosition(); // read position. |
| 669 intptr_t variable_kernel_offset = |
| 670 builder_->ReadUInt(); // read kernel position. |
| 671 builder_->ReadUInt(); // read relative variable index. |
| 672 builder_->SkipOptionalDartType(); // read promoted type. |
| 673 LookupVariable(variable_kernel_offset); |
| 674 return; |
| 675 } |
| 676 case kSpecializedVariableGet: { |
| 677 builder_->ReadPosition(); // read position. |
| 678 intptr_t variable_kernel_offset = |
| 679 builder_->ReadUInt(); // read kernel position. |
| 680 LookupVariable(variable_kernel_offset); |
| 681 return; |
| 682 } |
| 683 case kVariableSet: { |
| 684 builder_->ReadPosition(); // read position. |
| 685 intptr_t variable_kernel_offset = |
| 686 builder_->ReadUInt(); // read kernel position. |
| 687 builder_->ReadUInt(); // read relative variable index. |
| 688 LookupVariable(variable_kernel_offset); |
| 689 VisitExpression(); // read expression. |
| 690 return; |
| 691 } |
| 692 case kSpecializedVariableSet: { |
| 693 builder_->ReadPosition(); // read position. |
| 694 intptr_t variable_kernel_offset = |
| 695 builder_->ReadUInt(); // read kernel position. |
| 696 LookupVariable(variable_kernel_offset); |
| 697 VisitExpression(); // read expression. |
| 698 return; |
| 699 } |
| 700 case kPropertyGet: |
| 701 builder_->ReadPosition(); // read position. |
| 702 VisitExpression(); // read receiver. |
| 703 builder_->SkipName(); // read name. |
| 704 // Read unused "interface_target_reference". |
| 705 builder_->SkipCanonicalNameReference(); |
| 706 return; |
| 707 case kPropertySet: |
| 708 builder_->ReadPosition(); // read position. |
| 709 VisitExpression(); // read receiver. |
| 710 builder_->SkipName(); // read name. |
| 711 VisitExpression(); // read value. |
| 712 // read unused "interface_target_reference". |
| 713 builder_->SkipCanonicalNameReference(); |
| 714 return; |
| 715 case kDirectPropertyGet: |
| 716 builder_->ReadPosition(); // read position. |
| 717 VisitExpression(); // read receiver. |
| 718 builder_->SkipCanonicalNameReference(); // read target_reference. |
| 719 return; |
| 720 case kDirectPropertySet: |
| 721 builder_->ReadPosition(); // read position. |
| 722 VisitExpression(); // read receiver. |
| 723 builder_->SkipCanonicalNameReference(); // read target_reference. |
| 724 VisitExpression(); // read value· |
| 725 return; |
| 726 case kStaticGet: |
| 727 builder_->ReadPosition(); // read position. |
| 728 builder_->SkipCanonicalNameReference(); // read target_reference. |
| 729 return; |
| 730 case kStaticSet: |
| 731 builder_->ReadPosition(); // read position. |
| 732 builder_->SkipCanonicalNameReference(); // read target_reference. |
| 733 VisitExpression(); // read expression. |
| 734 return; |
| 735 case kMethodInvocation: |
| 736 builder_->ReadPosition(); // read position. |
| 737 VisitExpression(); // read receiver. |
| 738 builder_->SkipName(); // read name. |
| 739 VisitArguments(); // read arguments. |
| 740 // read unused "interface_target_reference". |
| 741 builder_->SkipCanonicalNameReference(); |
| 742 return; |
| 743 case kDirectMethodInvocation: |
| 744 VisitExpression(); // read receiver. |
| 745 builder_->SkipCanonicalNameReference(); // read target_reference. |
| 746 VisitArguments(); // read arguments. |
| 747 return; |
| 748 case kStaticInvocation: |
| 749 case kConstStaticInvocation: |
| 750 builder_->ReadPosition(); // read position. |
| 751 builder_->SkipCanonicalNameReference(); // read procedure_reference. |
| 752 VisitArguments(); // read arguments. |
| 753 return; |
| 754 case kConstructorInvocation: |
| 755 case kConstConstructorInvocation: |
| 756 builder_->ReadPosition(); // read position. |
| 757 builder_->SkipCanonicalNameReference(); // read target_reference. |
| 758 VisitArguments(); // read arguments. |
| 759 return; |
| 760 case kNot: |
| 761 VisitExpression(); // read expression. |
| 762 return; |
| 763 case kLogicalExpression: |
| 764 needs_expr_temp_ = true; |
| 765 VisitExpression(); // read left. |
| 766 builder_->SkipBytes(1); // read operator. |
| 767 VisitExpression(); // read right. |
| 768 return; |
| 769 case kConditionalExpression: { |
| 770 needs_expr_temp_ = true; |
| 771 VisitExpression(); // read condition. |
| 772 VisitExpression(); // read then. |
| 773 VisitExpression(); // read otherwise. |
| 774 builder_->SkipOptionalDartType(); // read unused static type. |
| 775 return; |
| 776 } |
| 777 case kStringConcatenation: { |
| 778 builder_->ReadPosition(); // read position. |
| 779 intptr_t list_length = builder_->ReadListLength(); // read list length. |
| 780 for (intptr_t i = 0; i < list_length; ++i) { |
| 781 VisitExpression(); // read ith expression. |
| 782 } |
| 783 return; |
| 784 } |
| 785 case kIsExpression: |
| 786 builder_->ReadPosition(); // read position. |
| 787 VisitExpression(); // read operand. |
| 788 VisitDartType(); // read type. |
| 789 return; |
| 790 case kAsExpression: |
| 791 builder_->ReadPosition(); // read position. |
| 792 VisitExpression(); // read operand. |
| 793 VisitDartType(); // read type. |
| 794 return; |
| 795 case kSymbolLiteral: |
| 796 builder_->SkipStringReference(); // read index into string table. |
| 797 return; |
| 798 case kTypeLiteral: |
| 799 VisitDartType(); // read type. |
| 800 return; |
| 801 case kThisExpression: |
| 802 HandleSpecialLoad(&result_->this_variable, Symbols::This()); |
| 803 return; |
| 804 case kRethrow: |
| 805 builder_->ReadPosition(); // read position. |
| 806 return; |
| 807 case kThrow: |
| 808 builder_->ReadPosition(); // read position. |
| 809 VisitExpression(); // read expression. |
| 810 return; |
| 811 case kListLiteral: |
| 812 case kConstListLiteral: { |
| 813 builder_->ReadPosition(); // read position. |
| 814 VisitDartType(); // read type. |
| 815 intptr_t list_length = builder_->ReadListLength(); // read list length. |
| 816 for (intptr_t i = 0; i < list_length; ++i) { |
| 817 VisitExpression(); // read ith expression. |
| 818 } |
| 819 return; |
| 820 } |
| 821 case kMapLiteral: |
| 822 case kConstMapLiteral: { |
| 823 builder_->ReadPosition(); // read position. |
| 824 VisitDartType(); // read key type. |
| 825 VisitDartType(); // read value type. |
| 826 intptr_t list_length = builder_->ReadListLength(); // read list length. |
| 827 for (intptr_t i = 0; i < list_length; ++i) { |
| 828 VisitExpression(); // read ith key. |
| 829 VisitExpression(); // read ith value. |
| 830 } |
| 831 return; |
| 832 } |
| 833 case kFunctionExpression: { |
| 834 intptr_t offset = |
| 835 builder_->ReaderOffset() - 1; // -1 to include tag byte. |
| 836 HandleLocalFunction(offset); |
| 837 return; |
| 838 } |
| 839 case kLet: { |
| 840 PositionScope scope(builder_->reader_); |
| 841 intptr_t offset = |
| 842 builder_->ReaderOffset() - 1; // -1 to include tag byte. |
| 843 |
| 844 EnterScope(offset); |
| 845 |
| 846 VisitVariableDeclaration(); // read variable declaration. |
| 847 VisitExpression(); // read expression. |
| 848 |
| 849 ExitScope(builder_->reader_->min_position(), |
| 850 builder_->reader_->max_position()); |
| 851 return; |
| 852 } |
| 853 case kBigIntLiteral: |
| 854 builder_->SkipStringReference(); // read string reference. |
| 855 return; |
| 856 case kStringLiteral: |
| 857 builder_->SkipStringReference(); // read string reference. |
| 858 return; |
| 859 case kSpecialIntLiteral: |
| 860 return; |
| 861 case kNegativeIntLiteral: |
| 862 builder_->ReadUInt(); // read value. |
| 863 return; |
| 864 case kPositiveIntLiteral: |
| 865 builder_->ReadUInt(); // read value. |
| 866 return; |
| 867 case kDoubleLiteral: |
| 868 builder_->SkipStringReference(); // read index into string table. |
| 869 return; |
| 870 case kTrueLiteral: |
| 871 return; |
| 872 case kFalseLiteral: |
| 873 return; |
| 874 case kNullLiteral: |
| 875 return; |
| 876 default: |
| 877 UNREACHABLE(); |
| 878 } |
| 879 } |
| 880 |
| 881 void StreamingScopeBuilder::VisitStatement() { |
| 882 Tag tag = builder_->ReadTag(); // read tag. |
| 883 switch (tag) { |
| 884 case kInvalidStatement: |
| 885 return; |
| 886 case kExpressionStatement: |
| 887 VisitExpression(); // read expression. |
| 888 return; |
| 889 case kBlock: { |
| 890 PositionScope scope(builder_->reader_); |
| 891 intptr_t offset = |
| 892 builder_->ReaderOffset() - 1; // -1 to include tag byte. |
| 893 |
| 894 EnterScope(offset); |
| 895 |
| 896 intptr_t list_length = |
| 897 builder_->ReadListLength(); // read number of statements. |
| 898 for (intptr_t i = 0; i < list_length; ++i) { |
| 899 VisitStatement(); // read ith statement. |
| 900 } |
| 901 |
| 902 ExitScope(builder_->reader_->min_position(), |
| 903 builder_->reader_->max_position()); |
| 904 return; |
| 905 } |
| 906 case kEmptyStatement: |
| 907 return; |
| 908 case kAssertStatement: { |
| 909 if (I->asserts()) { |
| 910 VisitExpression(); // Read condition. |
| 911 Tag tag = builder_->ReadTag(); // read (first part of) message. |
| 912 if (tag == kSomething) { |
| 913 VisitExpression(); // read (rest of) message. |
| 914 } |
| 915 } else { |
| 916 builder_->SkipExpression(); // Read condition. |
| 917 Tag tag = builder_->ReadTag(); // read (first part of) message. |
| 918 if (tag == kSomething) { |
| 919 builder_->SkipExpression(); // read (rest of) message. |
| 920 } |
| 921 } |
| 922 return; |
| 923 } |
| 924 case kLabeledStatement: |
| 925 VisitStatement(); // read body. |
| 926 return; |
| 927 case kBreakStatement: |
| 928 builder_->ReadPosition(); // read position. |
| 929 builder_->ReadUInt(); // read target_index. |
| 930 return; |
| 931 case kWhileStatement: |
| 932 ++depth_.loop_; |
| 933 VisitExpression(); // read condition. |
| 934 VisitStatement(); // read body. |
| 935 --depth_.loop_; |
| 936 return; |
| 937 case kDoStatement: |
| 938 ++depth_.loop_; |
| 939 VisitStatement(); // read body. |
| 940 VisitExpression(); // read condition. |
| 941 --depth_.loop_; |
| 942 return; |
| 943 case kForStatement: { |
| 944 PositionScope scope(builder_->reader_); |
| 945 |
| 946 intptr_t offset = |
| 947 builder_->ReaderOffset() - 1; // -1 to include tag byte. |
| 948 |
| 949 EnterScope(offset); |
| 950 |
| 951 intptr_t list_length = |
| 952 builder_->ReadListLength(); // read number of variables. |
| 953 for (intptr_t i = 0; i < list_length; ++i) { |
| 954 VisitVariableDeclaration(); // read ith variable. |
| 955 } |
| 956 |
| 957 ++depth_.loop_; |
| 958 |
| 959 Tag tag = builder_->ReadTag(); // Read first part of condition. |
| 960 if (tag == kSomething) { |
| 961 VisitExpression(); // read rest of condition. |
| 962 } |
| 963 list_length = builder_->ReadListLength(); // read number of updates. |
| 964 for (intptr_t i = 0; i < list_length; ++i) { |
| 965 VisitExpression(); // read ith update. |
| 966 } |
| 967 VisitStatement(); // read body. |
| 968 |
| 969 --depth_.loop_; |
| 970 |
| 971 ExitScope(builder_->reader_->min_position(), |
| 972 builder_->reader_->max_position()); |
| 973 return; |
| 974 } |
| 975 case kForInStatement: |
| 976 case kAsyncForInStatement: { |
| 977 PositionScope scope(builder_->reader_); |
| 978 |
| 979 intptr_t start_offset = |
| 980 builder_->ReaderOffset() - 1; // -1 to include tag byte. |
| 981 |
| 982 TokenPosition position = builder_->ReadPosition(); // read position. |
| 983 |
| 984 // Notice the ordering: We skip the variable, read the iterable, go back, |
| 985 // re-read the variable, go forward to after having read the iterable. |
| 986 intptr_t offset = builder_->ReaderOffset(); |
| 987 builder_->SkipVariableDeclaration(); // read variable. |
| 988 VisitExpression(); // read iterable. |
| 989 |
| 990 ++depth_.for_in_; |
| 991 AddIteratorVariable(); |
| 992 ++depth_.loop_; |
| 993 EnterScope(start_offset); |
| 994 |
| 995 { |
| 996 AlternativeReadingScope alt(builder_->reader_, offset); |
| 997 VisitVariableDeclaration(); // read variable. |
| 998 } |
| 999 VisitStatement(); // read body. |
| 1000 |
| 1001 if (!position.IsReal()) { |
| 1002 position = builder_->reader_->min_position(); |
| 1003 } |
| 1004 // TODO(jensj): From kernel_binary.cc |
| 1005 // forinstmt->variable_->set_end_position(forinstmt->position_); |
| 1006 ExitScope(position, builder_->reader_->max_position()); |
| 1007 --depth_.loop_; |
| 1008 --depth_.for_in_; |
| 1009 return; |
| 1010 } |
| 1011 case kSwitchStatement: { |
| 1012 AddSwitchVariable(); |
| 1013 VisitExpression(); // read condition. |
| 1014 int num_cases = builder_->ReadListLength(); // read number of cases. |
| 1015 for (intptr_t i = 0; i < num_cases; ++i) { |
| 1016 int num_expressions = |
| 1017 builder_->ReadListLength(); // read number of expressions. |
| 1018 for (intptr_t j = 0; j < num_expressions; ++j) { |
| 1019 builder_->ReadPosition(); // read jth position. |
| 1020 VisitExpression(); // read jth expression. |
| 1021 } |
| 1022 builder_->ReadBool(); // read is_default. |
| 1023 VisitStatement(); // read body. |
| 1024 } |
| 1025 return; |
| 1026 } |
| 1027 case kContinueSwitchStatement: |
| 1028 builder_->ReadUInt(); // read target_index. |
| 1029 return; |
| 1030 case kIfStatement: |
| 1031 VisitExpression(); // read condition. |
| 1032 VisitStatement(); // read then. |
| 1033 VisitStatement(); // read otherwise. |
| 1034 return; |
| 1035 case kReturnStatement: { |
| 1036 if ((depth_.function_ == 0) && (depth_.finally_ > 0) && |
| 1037 (result_->finally_return_variable == NULL)) { |
| 1038 const dart::String& name = H.DartSymbol(":try_finally_return_value"); |
| 1039 LocalVariable* variable = |
| 1040 MakeVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, |
| 1041 name, AbstractType::dynamic_type()); |
| 1042 current_function_scope_->AddVariable(variable); |
| 1043 result_->finally_return_variable = variable; |
| 1044 } |
| 1045 |
| 1046 builder_->ReadPosition(); // read position |
| 1047 Tag tag = builder_->ReadTag(); // read (first part of) expression. |
| 1048 if (tag == kSomething) { |
| 1049 VisitExpression(); // read (rest of) expression. |
| 1050 } |
| 1051 return; |
| 1052 } |
| 1053 case kTryCatch: { |
| 1054 ++depth_.try_; |
| 1055 AddTryVariables(); |
| 1056 VisitStatement(); // read body. |
| 1057 --depth_.try_; |
| 1058 |
| 1059 ++depth_.catch_; |
| 1060 AddCatchVariables(); |
| 1061 |
| 1062 builder_->ReadBool(); // read any_catch_needs_stack_trace. |
| 1063 intptr_t num_catches = |
| 1064 builder_->ReadListLength(); // read number of catches. |
| 1065 for (intptr_t i = 0; i < num_catches; ++i) { |
| 1066 PositionScope scope(builder_->reader_); |
| 1067 intptr_t offset = builder_->ReaderOffset(); // Catch has no tag. |
| 1068 |
| 1069 EnterScope(offset); |
| 1070 |
| 1071 builder_->SkipDartType(); // read guard. |
| 1072 tag = builder_->ReadTag(); // read first part of exception. |
| 1073 if (tag == kSomething) { |
| 1074 VisitVariableDeclaration(); // read exception. |
| 1075 } |
| 1076 tag = builder_->ReadTag(); // read first part of stack trace. |
| 1077 if (tag == kSomething) { |
| 1078 VisitVariableDeclaration(); // read stack trace. |
| 1079 } |
| 1080 VisitStatement(); // read body. |
| 1081 |
| 1082 ExitScope(builder_->reader_->min_position(), |
| 1083 builder_->reader_->max_position()); |
| 1084 } |
| 1085 --depth_.catch_; |
| 1086 return; |
| 1087 } |
| 1088 case kTryFinally: { |
| 1089 ++depth_.try_; |
| 1090 ++depth_.finally_; |
| 1091 AddTryVariables(); |
| 1092 |
| 1093 VisitStatement(); // read body. |
| 1094 |
| 1095 --depth_.finally_; |
| 1096 --depth_.try_; |
| 1097 ++depth_.catch_; |
| 1098 AddCatchVariables(); |
| 1099 |
| 1100 VisitStatement(); // read finalizer. |
| 1101 |
| 1102 --depth_.catch_; |
| 1103 return; |
| 1104 } |
| 1105 case kYieldStatement: { |
| 1106 builder_->ReadPosition(); // read position. |
| 1107 word flags = builder_->ReadByte(); // read flags. |
| 1108 builder_->SkipExpression(); // read expression. |
| 1109 |
| 1110 ASSERT((flags & YieldStatement::kFlagNative) == |
| 1111 YieldStatement::kFlagNative); |
| 1112 if (depth_.function_ == 0) { |
| 1113 AddSwitchVariable(); |
| 1114 // Promote all currently visible local variables into the context. |
| 1115 // TODO(27590) CaptureLocalVariables promotes to many variables into |
| 1116 // the scope. Mark those variables as stack_local. |
| 1117 // TODO(27590) we don't need to promote those variables that are |
| 1118 // not used across yields. |
| 1119 scope_->CaptureLocalVariables(current_function_scope_); |
| 1120 } |
| 1121 return; |
| 1122 } |
| 1123 case kVariableDeclaration: |
| 1124 VisitVariableDeclaration(); // read variable declaration. |
| 1125 return; |
| 1126 case kFunctionDeclaration: { |
| 1127 intptr_t offset = |
| 1128 builder_->ReaderOffset() - 1; // -1 to include tag byte. |
| 1129 builder_->ReadPosition(); // read position. |
| 1130 VisitVariableDeclaration(); // read variable declaration. |
| 1131 HandleLocalFunction(offset); // read function node. |
| 1132 return; |
| 1133 } |
| 1134 default: |
| 1135 UNREACHABLE(); |
| 1136 } |
| 1137 } |
| 1138 |
| 1139 void StreamingScopeBuilder::VisitArguments() { |
| 1140 builder_->ReadUInt(); // read num_arguments. |
| 1141 |
| 1142 // Types |
| 1143 intptr_t list_length = builder_->ReadListLength(); // read list length. |
| 1144 for (intptr_t i = 0; i < list_length; ++i) { |
| 1145 VisitDartType(); // read ith type. |
| 1146 } |
| 1147 |
| 1148 // Positional. |
| 1149 list_length = builder_->ReadListLength(); // read list length. |
| 1150 for (intptr_t i = 0; i < list_length; ++i) { |
| 1151 VisitExpression(); // read ith positional. |
| 1152 } |
| 1153 |
| 1154 // Named. |
| 1155 list_length = builder_->ReadListLength(); // read list length. |
| 1156 for (intptr_t i = 0; i < list_length; ++i) { |
| 1157 builder_->SkipStringReference(); // read ith name index. |
| 1158 VisitExpression(); // read ith expression. |
| 1159 } |
| 1160 } |
| 1161 |
| 1162 void StreamingScopeBuilder::VisitVariableDeclaration() { |
| 1163 PositionScope scope(builder_->reader_); |
| 1164 |
| 1165 intptr_t kernel_offset_no_tag = builder_->ReaderOffset(); |
| 1166 TokenPosition position = builder_->ReadPosition(); // read position. |
| 1167 builder_->ReadPosition(); // read equals position. |
| 1168 word flags = builder_->ReadFlags(); // read flags. |
| 1169 bool is_final = (flags & VariableDeclaration::kFlagFinal) == |
| 1170 VariableDeclaration::kFlagFinal; |
| 1171 StringIndex name_index = builder_->ReadStringReference(); // read name index. |
| 1172 intptr_t offset_for_type = builder_->ReaderOffset(); |
| 1173 AbstractType& type = T.BuildVariableType(); // read type. |
| 1174 |
| 1175 // In case `declaration->IsConst()` the flow graph building will take care of |
| 1176 // evaluating the constant and setting it via |
| 1177 // `declaration->SetConstantValue()`. |
| 1178 const dart::String& name = (H.StringSize(name_index) == 0) |
| 1179 ? GenerateName(":var", name_index_++) |
| 1180 : H.DartSymbol(name_index); |
| 1181 // We also need to visit the type. |
| 1182 builder_->SetOffset(offset_for_type); |
| 1183 VisitDartType(); // read type. |
| 1184 |
| 1185 Tag tag = builder_->ReadTag(); // read (first part of) initializer. |
| 1186 if (tag == kSomething) { |
| 1187 VisitExpression(); // read (actual) initializer. |
| 1188 } |
| 1189 |
| 1190 // Go to next token position so it ends *after* the last potentially |
| 1191 // debuggable position in the initializer. |
| 1192 TokenPosition end_position = builder_->reader_->max_position(); |
| 1193 if (end_position.IsReal()) { |
| 1194 end_position.Next(); |
| 1195 } |
| 1196 LocalVariable* variable = MakeVariable(position, end_position, name, type); |
| 1197 if (is_final) { |
| 1198 variable->set_is_final(); |
| 1199 } |
| 1200 scope_->AddVariable(variable); |
| 1201 result_->locals.Insert(kernel_offset_no_tag, variable); |
| 1202 } |
| 1203 |
| 1204 void StreamingScopeBuilder::VisitDartType() { |
| 1205 Tag tag = builder_->ReadTag(); |
| 1206 switch (tag) { |
| 1207 case kInvalidType: |
| 1208 case kDynamicType: |
| 1209 case kVoidType: |
| 1210 case kBottomType: |
| 1211 // those contain nothing. |
| 1212 return; |
| 1213 case kInterfaceType: |
| 1214 VisitInterfaceType(false); |
| 1215 return; |
| 1216 case kSimpleInterfaceType: |
| 1217 VisitInterfaceType(true); |
| 1218 return; |
| 1219 case kFunctionType: |
| 1220 VisitFunctionType(false); |
| 1221 return; |
| 1222 case kSimpleFunctionType: |
| 1223 VisitFunctionType(true); |
| 1224 return; |
| 1225 case kTypeParameterType: |
| 1226 VisitTypeParameterType(); |
| 1227 return; |
| 1228 default: |
| 1229 UNREACHABLE(); |
| 1230 } |
| 1231 } |
| 1232 |
| 1233 void StreamingScopeBuilder::VisitInterfaceType(bool simple) { |
| 1234 builder_->ReadUInt(); // read klass_name. |
| 1235 if (!simple) { |
| 1236 intptr_t length = builder_->ReadListLength(); // read number of types. |
| 1237 for (intptr_t i = 0; i < length; ++i) { |
| 1238 VisitDartType(); // read the ith type. |
| 1239 } |
| 1240 } |
| 1241 } |
| 1242 |
| 1243 void StreamingScopeBuilder::VisitFunctionType(bool simple) { |
| 1244 if (!simple) { |
| 1245 intptr_t list_length = |
| 1246 builder_->ReadListLength(); // read type_parameters list length. |
| 1247 for (int i = 0; i < list_length; ++i) { |
| 1248 builder_->SkipStringReference(); // read string index (name). |
| 1249 VisitDartType(); // read dart type. |
| 1250 } |
| 1251 builder_->ReadUInt(); // read required parameter count. |
| 1252 builder_->ReadUInt(); // read total parameter count. |
| 1253 } |
| 1254 |
| 1255 const intptr_t positional_count = |
| 1256 builder_->ReadListLength(); // read positional_parameters list length. |
| 1257 for (intptr_t i = 0; i < positional_count; ++i) { |
| 1258 VisitDartType(); // read ith positional parameter. |
| 1259 } |
| 1260 |
| 1261 if (!simple) { |
| 1262 const intptr_t named_count = |
| 1263 builder_->ReadListLength(); // read named_parameters list length. |
| 1264 for (intptr_t i = 0; i < named_count; ++i) { |
| 1265 // read string reference (i.e. named_parameters[i].name). |
| 1266 builder_->SkipStringReference(); |
| 1267 VisitDartType(); // read named_parameters[i].type. |
| 1268 } |
| 1269 } |
| 1270 |
| 1271 VisitDartType(); // read return type. |
| 1272 } |
| 1273 |
| 1274 void StreamingScopeBuilder::VisitTypeParameterType() { |
| 1275 Function& function = Function::Handle(Z, parsed_function_->function().raw()); |
| 1276 while (function.IsClosureFunction()) { |
| 1277 function = function.parent_function(); |
| 1278 } |
| 1279 |
| 1280 if (function.IsFactory()) { |
| 1281 // The type argument vector is passed as the very first argument to the |
| 1282 // factory constructor function. |
| 1283 HandleSpecialLoad(&result_->type_arguments_variable, |
| 1284 Symbols::TypeArgumentsParameter()); |
| 1285 } else { |
| 1286 // The type argument vector is stored on the instance object. We therefore |
| 1287 // need to capture `this`. |
| 1288 HandleSpecialLoad(&result_->this_variable, Symbols::This()); |
| 1289 } |
| 1290 |
| 1291 builder_->ReadUInt(); // read index for parameter. |
| 1292 builder_->ReadUInt(); // read binary offset. |
| 1293 builder_->SkipOptionalDartType(); // read bound bound. |
| 1294 } |
| 1295 |
| 1296 void StreamingScopeBuilder::HandleLocalFunction(intptr_t parent_kernel_offset) { |
| 1297 // "Peek" ahead into the function node |
| 1298 intptr_t offset = builder_->ReaderOffset(); |
| 1299 |
| 1300 Tag tag = builder_->ReadTag(); // read tag. |
| 1301 ASSERT(tag == kFunctionNode); |
| 1302 TokenPosition position = builder_->ReadPosition(); // read position. |
| 1303 TokenPosition end_position = builder_->ReadPosition(); // read end position. |
| 1304 FunctionNode::AsyncMarker async_marker = |
| 1305 static_cast<FunctionNode::AsyncMarker>( |
| 1306 builder_->ReadByte()); // read async marker. |
| 1307 builder_->ReadByte(); // read dart async marker. |
| 1308 builder_->SkipTypeParametersList(); // read type_parameters. |
| 1309 |
| 1310 LocalScope* saved_function_scope = current_function_scope_; |
| 1311 FunctionNode::AsyncMarker saved_function_async_marker = |
| 1312 current_function_async_marker_; |
| 1313 StreamingScopeBuilder::DepthState saved_depth_state = depth_; |
| 1314 depth_ = DepthState(depth_.function_ + 1); |
| 1315 EnterScope(parent_kernel_offset); |
| 1316 current_function_scope_ = scope_; |
| 1317 current_function_async_marker_ = async_marker; |
| 1318 if (depth_.function_ == 1) { |
| 1319 FunctionScope function_scope = {offset, scope_}; |
| 1320 result_->function_scopes.Add(function_scope); |
| 1321 } |
| 1322 |
| 1323 builder_->ReadUInt(); // read required_parameter_count. |
| 1324 // read positional_parameters and named_parameters. |
| 1325 AddPositionalAndNamedParameters(); |
| 1326 |
| 1327 // "Peek" is now done. |
| 1328 builder_->SetOffset(offset); |
| 1329 |
| 1330 VisitFunctionNode(); // read function node. |
| 1331 |
| 1332 ExitScope(position, end_position); |
| 1333 depth_ = saved_depth_state; |
| 1334 current_function_scope_ = saved_function_scope; |
| 1335 current_function_async_marker_ = saved_function_async_marker; |
| 1336 } |
| 1337 |
| 1338 void StreamingScopeBuilder::EnterScope(intptr_t kernel_offset) { |
| 1339 scope_ = new (Z) LocalScope(scope_, depth_.function_, depth_.loop_); |
| 1340 ASSERT(kernel_offset >= 0); |
| 1341 result_->scopes.Insert(kernel_offset, scope_); |
| 1342 } |
| 1343 |
| 1344 |
| 1345 void StreamingScopeBuilder::ExitScope(TokenPosition start_position, |
| 1346 TokenPosition end_position) { |
| 1347 scope_->set_begin_token_pos(start_position); |
| 1348 scope_->set_end_token_pos(end_position); |
| 1349 scope_ = scope_->parent(); |
| 1350 } |
| 1351 |
| 1352 void StreamingScopeBuilder::AddPositionalAndNamedParameters(intptr_t pos) { |
| 1353 // List of positional. |
| 1354 intptr_t list_length = builder_->ReadListLength(); // read list length. |
| 1355 for (intptr_t i = 0; i < list_length; ++i) { |
| 1356 AddVariableDeclarationParameter(pos++); // read ith positional parameter. |
| 1357 } |
| 1358 |
| 1359 // List of named. |
| 1360 list_length = builder_->ReadListLength(); // read list length. |
| 1361 for (intptr_t i = 0; i < list_length; ++i) { |
| 1362 AddVariableDeclarationParameter(pos++); // read ith named parameter. |
| 1363 } |
| 1364 } |
| 1365 |
| 1366 void StreamingScopeBuilder::AddVariableDeclarationParameter(intptr_t pos) { |
| 1367 intptr_t kernel_offset = builder_->ReaderOffset(); // no tag. |
| 1368 TokenPosition position = builder_->ReadPosition(); // read position. |
| 1369 builder_->ReadPosition(); // read equals position. |
| 1370 word flags = builder_->ReadFlags(); // read flags. |
| 1371 bool is_final = (flags & VariableDeclaration::kFlagFinal) == |
| 1372 VariableDeclaration::kFlagFinal; |
| 1373 String& name = H.DartSymbol(builder_->ReadStringReference()); // read name. |
| 1374 AbstractType& type = T.BuildVariableType(); // read type. |
| 1375 |
| 1376 LocalVariable* variable = MakeVariable(position, position, name, type); |
| 1377 if (is_final) { |
| 1378 variable->set_is_final(); |
| 1379 } |
| 1380 if (variable->name().raw() == Symbols::IteratorParameter().raw()) { |
| 1381 variable->set_is_forced_stack(); |
| 1382 } |
| 1383 scope_->InsertParameterAt(pos, variable); |
| 1384 result_->locals.Insert(kernel_offset, variable); |
| 1385 |
| 1386 // The default value may contain 'let' bindings for which the constant |
| 1387 // evaluator needs scope bindings. |
| 1388 Tag tag = builder_->ReadTag(); |
| 1389 if (tag == kSomething) { |
| 1390 VisitExpression(); // read initializer. |
| 1391 } |
| 1392 } |
| 1393 |
| 1394 LocalVariable* StreamingScopeBuilder::MakeVariable( |
| 1395 TokenPosition declaration_pos, |
| 1396 TokenPosition token_pos, |
| 1397 const dart::String& name, |
| 1398 const AbstractType& type) { |
| 1399 return new (Z) LocalVariable(declaration_pos, token_pos, name, type); |
| 1400 } |
| 1401 |
| 1402 void StreamingScopeBuilder::AddExceptionVariable( |
| 1403 GrowableArray<LocalVariable*>* variables, |
| 1404 const char* prefix, |
| 1405 intptr_t nesting_depth) { |
| 1406 LocalVariable* v = NULL; |
| 1407 |
| 1408 // If we are inside a function with yield points then Kernel transformer |
| 1409 // could have lifted some of the auxiliary exception variables into the |
| 1410 // context to preserve them across yield points because they might |
| 1411 // be needed for rethrow. |
| 1412 // Check if it did and capture such variables instead of introducing |
| 1413 // new local ones. |
| 1414 // Note: function that wrap kSyncYielding function does not contain |
| 1415 // its own try/catches. |
| 1416 if (current_function_async_marker_ == FunctionNode::kSyncYielding) { |
| 1417 ASSERT(current_function_scope_->parent() != NULL); |
| 1418 v = current_function_scope_->parent()->LocalLookupVariable( |
| 1419 GenerateName(prefix, nesting_depth - 1)); |
| 1420 if (v != NULL) { |
| 1421 scope_->CaptureVariable(v); |
| 1422 } |
| 1423 } |
| 1424 |
| 1425 // No need to create variables for try/catch-statements inside |
| 1426 // nested functions. |
| 1427 if (depth_.function_ > 0) return; |
| 1428 if (variables->length() >= nesting_depth) return; |
| 1429 |
| 1430 // If variable was not lifted by the transformer introduce a new |
| 1431 // one into the current function scope. |
| 1432 if (v == NULL) { |
| 1433 v = MakeVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, |
| 1434 GenerateName(prefix, nesting_depth - 1), |
| 1435 AbstractType::dynamic_type()); |
| 1436 |
| 1437 // If transformer did not lift the variable then there is no need |
| 1438 // to lift it into the context when we encouter a YieldStatement. |
| 1439 v->set_is_forced_stack(); |
| 1440 current_function_scope_->AddVariable(v); |
| 1441 } |
| 1442 |
| 1443 variables->Add(v); |
| 1444 } |
| 1445 |
| 1446 void StreamingScopeBuilder::AddTryVariables() { |
| 1447 AddExceptionVariable(&result_->catch_context_variables, |
| 1448 ":saved_try_context_var", depth_.try_); |
| 1449 } |
| 1450 |
| 1451 |
| 1452 void StreamingScopeBuilder::AddCatchVariables() { |
| 1453 AddExceptionVariable(&result_->exception_variables, ":exception", |
| 1454 depth_.catch_); |
| 1455 AddExceptionVariable(&result_->stack_trace_variables, ":stack_trace", |
| 1456 depth_.catch_); |
| 1457 } |
| 1458 |
| 1459 |
| 1460 void StreamingScopeBuilder::AddIteratorVariable() { |
| 1461 if (depth_.function_ > 0) return; |
| 1462 if (result_->iterator_variables.length() >= depth_.for_in_) return; |
| 1463 |
| 1464 ASSERT(result_->iterator_variables.length() == depth_.for_in_ - 1); |
| 1465 LocalVariable* iterator = |
| 1466 MakeVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, |
| 1467 GenerateName(":iterator", depth_.for_in_ - 1), |
| 1468 AbstractType::dynamic_type()); |
| 1469 current_function_scope_->AddVariable(iterator); |
| 1470 result_->iterator_variables.Add(iterator); |
| 1471 } |
| 1472 |
| 1473 void StreamingScopeBuilder::AddSwitchVariable() { |
| 1474 if ((depth_.function_ == 0) && (result_->switch_variable == NULL)) { |
| 1475 LocalVariable* variable = |
| 1476 MakeVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, |
| 1477 Symbols::SwitchExpr(), AbstractType::dynamic_type()); |
| 1478 variable->set_is_forced_stack(); |
| 1479 current_function_scope_->AddVariable(variable); |
| 1480 result_->switch_variable = variable; |
| 1481 } |
| 1482 } |
| 1483 |
| 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) { |
| 1495 LocalVariable* variable = result_->locals.Lookup(declaration_binary_offest); |
| 1496 if (variable == NULL) { |
| 1497 // 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 |
| 1499 // 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. |
| 1501 ASSERT(current_function_scope_->parent() != NULL); |
| 1502 |
| 1503 StringIndex var_name = |
| 1504 GetNameFromVariableDeclaration(declaration_binary_offest); |
| 1505 |
| 1506 const dart::String& name = H.DartSymbol(var_name); |
| 1507 variable = current_function_scope_->parent()->LookupVariable(name, true); |
| 1508 ASSERT(variable != NULL); |
| 1509 result_->locals.Insert(declaration_binary_offest, variable); |
| 1510 } |
| 1511 |
| 1512 if (variable->owner()->function_level() < scope_->function_level()) { |
| 1513 // We call `LocalScope->CaptureVariable(variable)` in two scenarios for two |
| 1514 // different reasons: |
| 1515 // Scenario 1: |
| 1516 // We need to know which variables defined in this function |
| 1517 // are closed over by nested closures in order to ensure we will |
| 1518 // create a [Context] object of appropriate size and store captured |
| 1519 // variables there instead of the stack. |
| 1520 // Scenario 2: |
| 1521 // We need to find out which variables defined in enclosing functions |
| 1522 // are closed over by this function/closure or nested closures. This |
| 1523 // is necessary in order to build a fat flattened [ContextScope] |
| 1524 // object. |
| 1525 scope_->CaptureVariable(variable); |
| 1526 } else { |
| 1527 ASSERT(variable->owner()->function_level() == scope_->function_level()); |
| 1528 } |
| 1529 } |
| 1530 |
| 1531 const dart::String& StreamingScopeBuilder::GenerateName(const char* prefix, |
| 1532 intptr_t suffix) { |
| 1533 char name[64]; |
| 1534 OS::SNPrint(name, 64, "%s%" Pd "", prefix, suffix); |
| 1535 return H.DartSymbol(name); |
| 1536 } |
| 1537 |
| 1538 void StreamingScopeBuilder::HandleSpecialLoad(LocalVariable** variable, |
| 1539 const dart::String& symbol) { |
| 1540 if (current_function_scope_->parent() != NULL) { |
| 1541 // We are building the scope tree of a closure function and saw [node]. We |
| 1542 // lazily populate the variable using the parent function scope. |
| 1543 if (*variable == NULL) { |
| 1544 *variable = |
| 1545 current_function_scope_->parent()->LookupVariable(symbol, true); |
| 1546 ASSERT(*variable != NULL); |
| 1547 } |
| 1548 } |
| 1549 |
| 1550 if ((current_function_scope_->parent() != NULL) || |
| 1551 (scope_->function_level() > 0)) { |
| 1552 // Every scope we use the [variable] from needs to be notified of the usage |
| 1553 // in order to ensure that preserving the context scope on that particular |
| 1554 // use-site also includes the [variable]. |
| 1555 scope_->CaptureVariable(*variable); |
| 1556 } |
| 1557 } |
| 1558 |
| 1559 void StreamingScopeBuilder::LookupCapturedVariableByName( |
| 1560 LocalVariable** variable, |
| 1561 const dart::String& name) { |
| 1562 if (*variable == NULL) { |
| 1563 *variable = scope_->LookupVariable(name, true); |
| 1564 ASSERT(*variable != NULL); |
| 1565 scope_->CaptureVariable(*variable); |
| 1566 } |
| 1567 } |
20 | 1568 |
21 StreamingDartTypeTranslator::StreamingDartTypeTranslator( | 1569 StreamingDartTypeTranslator::StreamingDartTypeTranslator( |
22 StreamingFlowGraphBuilder* builder, | 1570 StreamingFlowGraphBuilder* builder, |
23 bool finalize) | 1571 bool finalize) |
24 : builder_(builder), | 1572 : builder_(builder), |
25 translation_helper_(builder->translation_helper_), | 1573 translation_helper_(builder->translation_helper_), |
26 active_class_(builder->active_class()), | 1574 active_class_(builder->active_class()), |
27 type_parameter_scope_(NULL), | 1575 type_parameter_scope_(NULL), |
28 zone_(translation_helper_.zone()), | 1576 zone_(translation_helper_.zone()), |
29 result_(AbstractType::Handle(translation_helper_.zone())), | 1577 result_(AbstractType::Handle(translation_helper_.zone())), |
30 finalize_(finalize) {} | 1578 finalize_(finalize) {} |
31 | 1579 |
32 | 1580 |
33 AbstractType& StreamingDartTypeTranslator::BuildType() { | 1581 AbstractType& StreamingDartTypeTranslator::BuildType() { |
34 BuildTypeInternal(); | 1582 BuildTypeInternal(); |
35 | 1583 |
36 // We return a new `ZoneHandle` here on purpose: The intermediate language | 1584 // We return a new `ZoneHandle` here on purpose: The intermediate language |
37 // instructions do not make a copy of the handle, so we do it. | 1585 // instructions do not make a copy of the handle, so we do it. |
38 return dart::AbstractType::ZoneHandle(Z, result_.raw()); | 1586 return dart::AbstractType::ZoneHandle(Z, result_.raw()); |
39 } | 1587 } |
40 | 1588 |
| 1589 AbstractType& StreamingDartTypeTranslator::BuildVariableType() { |
| 1590 AbstractType& abstract_type = BuildType(); |
| 1591 |
| 1592 // 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. |
| 1594 AbstractType& type = Type::ZoneHandle(Z); |
| 1595 |
| 1596 if (abstract_type.IsMalformed()) { |
| 1597 type = AbstractType::dynamic_type().raw(); |
| 1598 } else { |
| 1599 type = result_.raw(); |
| 1600 } |
| 1601 |
| 1602 return type; |
| 1603 } |
| 1604 |
41 void StreamingDartTypeTranslator::BuildTypeInternal() { | 1605 void StreamingDartTypeTranslator::BuildTypeInternal() { |
42 Tag tag = builder_->ReadTag(); | 1606 Tag tag = builder_->ReadTag(); |
43 switch (tag) { | 1607 switch (tag) { |
44 case kInvalidType: | 1608 case kInvalidType: |
45 result_ = ClassFinalizer::NewFinalizedMalformedType( | 1609 result_ = ClassFinalizer::NewFinalizedMalformedType( |
46 Error::Handle(Z), // No previous error. | 1610 Error::Handle(Z), // No previous error. |
47 dart::Script::Handle(Z, dart::Script::null()), | 1611 dart::Script::Handle(Z, dart::Script::null()), |
48 TokenPosition::kNoSource, "[InvalidType] in Kernel IR."); | 1612 TokenPosition::kNoSource, "[InvalidType] in Kernel IR."); |
49 break; | 1613 break; |
50 case kDynamicType: | 1614 case kDynamicType: |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
98 dart::Object::Handle(Z, H.LookupClassByKernelClass(klass_name)); | 1662 dart::Object::Handle(Z, H.LookupClassByKernelClass(klass_name)); |
99 result_ = Type::New(klass, type_arguments, TokenPosition::kNoSource); | 1663 result_ = Type::New(klass, type_arguments, TokenPosition::kNoSource); |
100 if (finalize_) { | 1664 if (finalize_) { |
101 ASSERT(active_class_->klass != NULL); | 1665 ASSERT(active_class_->klass != NULL); |
102 result_ = ClassFinalizer::FinalizeType(*active_class_->klass, result_); | 1666 result_ = ClassFinalizer::FinalizeType(*active_class_->klass, result_); |
103 } | 1667 } |
104 } | 1668 } |
105 | 1669 |
106 void StreamingDartTypeTranslator::BuildFunctionType(bool simple) { | 1670 void StreamingDartTypeTranslator::BuildFunctionType(bool simple) { |
107 intptr_t list_length = 0; | 1671 intptr_t list_length = 0; |
108 intptr_t* type_parameters = NULL; | 1672 intptr_t first_item_offest = -1; |
109 if (!simple) { | 1673 if (!simple) { |
110 list_length = | 1674 list_length = |
111 builder_->ReadListLength(); // read type_parameters list length | 1675 builder_->ReadListLength(); // read type_parameters list length |
112 type_parameters = new intptr_t[list_length]; | 1676 first_item_offest = builder_->ReaderOffset(); |
113 for (int i = 0; i < list_length; ++i) { | 1677 for (int i = 0; i < list_length; ++i) { |
114 type_parameters[i] = builder_->ReaderOffset(); | |
115 builder_->SkipStringReference(); // read string index (name). | 1678 builder_->SkipStringReference(); // read string index (name). |
116 builder_->SkipDartType(); // read dart type. | 1679 builder_->SkipDartType(); // read dart type. |
117 } | 1680 } |
118 } | 1681 } |
119 | 1682 |
120 // The spec describes in section "19.1 Static Types": | 1683 // The spec describes in section "19.1 Static Types": |
121 // | 1684 // |
122 // Any use of a malformed type gives rise to a static warning. A | 1685 // Any use of a malformed type gives rise to a static warning. A |
123 // malformed type is then interpreted as dynamic by the static type | 1686 // malformed type is then interpreted as dynamic by the static type |
124 // checker and the runtime unless explicitly specified otherwise. | 1687 // checker and the runtime unless explicitly specified otherwise. |
125 // | 1688 // |
126 // So we convert malformed return/parameter types to `dynamic`. | 1689 // So we convert malformed return/parameter types to `dynamic`. |
127 TypeParameterScope scope(this, type_parameters, list_length); | 1690 TypeParameterScope scope(this, first_item_offest, list_length); |
128 | 1691 |
129 Function& signature_function = Function::ZoneHandle( | 1692 Function& signature_function = Function::ZoneHandle( |
130 Z, Function::NewSignatureFunction(*active_class_->klass, | 1693 Z, Function::NewSignatureFunction(*active_class_->klass, |
131 TokenPosition::kNoSource)); | 1694 TokenPosition::kNoSource)); |
132 | 1695 |
133 intptr_t required_count; | 1696 intptr_t required_count; |
134 intptr_t all_count; | 1697 intptr_t all_count; |
135 intptr_t positional_count; | 1698 intptr_t positional_count; |
136 if (!simple) { | 1699 if (!simple) { |
137 required_count = builder_->ReadUInt(); // read required parameter count. | 1700 required_count = builder_->ReadUInt(); // read required parameter count. |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
198 signature_type ^= | 1761 signature_type ^= |
199 ClassFinalizer::FinalizeType(*active_class_->klass, signature_type); | 1762 ClassFinalizer::FinalizeType(*active_class_->klass, signature_type); |
200 // Do not refer to signature_function anymore, since it may have been | 1763 // Do not refer to signature_function anymore, since it may have been |
201 // replaced during canonicalization. | 1764 // replaced during canonicalization. |
202 signature_function = Function::null(); | 1765 signature_function = Function::null(); |
203 } | 1766 } |
204 | 1767 |
205 result_ = signature_type.raw(); | 1768 result_ = signature_type.raw(); |
206 } | 1769 } |
207 | 1770 |
208 static intptr_t FindTypeParameterIndex(intptr_t* parameters, | 1771 intptr_t StreamingDartTypeTranslator::FindTypeParameterIndex( |
209 intptr_t parameters_count, | 1772 intptr_t parameters_offset, |
210 intptr_t look_for) { | 1773 intptr_t parameters_count, |
| 1774 intptr_t look_for) { |
| 1775 AlternativeReadingScope alt(builder_->reader_, parameters_offset); |
211 for (intptr_t i = 0; i < parameters_count; ++i) { | 1776 for (intptr_t i = 0; i < parameters_count; ++i) { |
212 if (look_for == parameters[i]) { | 1777 if (look_for == builder_->ReaderOffset()) { |
213 return i; | 1778 return i; |
214 } | 1779 } |
| 1780 builder_->SkipStringReference(); // read string index (name). |
| 1781 builder_->SkipDartType(); // read dart type. |
215 } | 1782 } |
216 return -1; | 1783 return -1; |
217 } | 1784 } |
218 | |
219 static intptr_t FindTypeParameterIndex(List<TypeParameter>* parameters, | |
220 intptr_t look_for) { | |
221 for (intptr_t i = 0; i < parameters->length(); ++i) { | |
222 if (look_for == (*parameters)[i]->kernel_offset()) { | |
223 return i; | |
224 } | |
225 } | |
226 return -1; | |
227 } | |
228 | 1785 |
229 void StreamingDartTypeTranslator::BuildTypeParameterType() { | 1786 void StreamingDartTypeTranslator::BuildTypeParameterType() { |
230 builder_->ReadUInt(); // read parameter index. | 1787 builder_->ReadUInt(); // read parameter index. |
231 intptr_t binary_offset = builder_->ReadUInt(); // read binary offset. | 1788 intptr_t binary_offset = builder_->ReadUInt(); // read binary offset. |
232 builder_->SkipOptionalDartType(); // read bound. | 1789 builder_->SkipOptionalDartType(); // read bound. |
233 | 1790 |
234 if (binary_offset == 0) { | 1791 if (binary_offset == 0) { |
235 // TODO(jensj): This doesn't appear to actually happen. | 1792 // TODO(jensj): This doesn't appear to actually happen. |
236 UNIMPLEMENTED(); | 1793 UNIMPLEMENTED(); |
237 return; | 1794 return; |
238 } | 1795 } |
239 | 1796 |
240 for (TypeParameterScope* scope = type_parameter_scope_; scope != NULL; | 1797 for (TypeParameterScope* scope = type_parameter_scope_; scope != NULL; |
241 scope = scope->outer()) { | 1798 scope = scope->outer()) { |
242 const intptr_t index = FindTypeParameterIndex( | 1799 const intptr_t index = FindTypeParameterIndex( |
243 scope->parameters(), scope->parameters_count(), binary_offset); | 1800 scope->parameters_offset(), scope->parameters_count(), binary_offset); |
244 if (index >= 0) { | 1801 if (index >= 0) { |
245 result_ ^= dart::Type::DynamicType(); | 1802 result_ ^= dart::Type::DynamicType(); |
246 return; | 1803 return; |
247 } | 1804 } |
248 } | 1805 } |
249 | 1806 |
250 if ((active_class_->member != NULL) && active_class_->member->IsProcedure()) { | 1807 if (active_class_->member_is_procedure) { |
251 Procedure* procedure = Procedure::Cast(active_class_->member); | 1808 if (active_class_->member_type_parameters > 0) { |
252 if ((procedure->function() != NULL) && | |
253 (procedure->function()->type_parameters().length() > 0)) { | |
254 // | 1809 // |
255 // WARNING: This is a little hackish: | 1810 // WARNING: This is a little hackish: |
256 // | 1811 // |
257 // We have a static factory constructor. The kernel IR gives the factory | 1812 // We have a static factory constructor. The kernel IR gives the factory |
258 // constructor function it's own type parameters (which are equal in name | 1813 // constructor function it's own type parameters (which are equal in name |
259 // and number to the ones of the enclosing class). | 1814 // and number to the ones of the enclosing class). |
260 // I.e., | 1815 // I.e., |
261 // | 1816 // |
262 // class A<T> { | 1817 // class A<T> { |
263 // factory A.x() { return new B<T>(); } | 1818 // factory A.x() { return new B<T>(); } |
264 // } | 1819 // } |
265 // | 1820 // |
266 // is basically translated to this: | 1821 // is basically translated to this: |
267 // | 1822 // |
268 // class A<T> { | 1823 // class A<T> { |
269 // static A.x<T'>() { return new B<T'>(); } | 1824 // static A.x<T'>() { return new B<T'>(); } |
270 // } | 1825 // } |
271 // | 1826 // |
272 const intptr_t index = FindTypeParameterIndex( | 1827 const intptr_t index = FindTypeParameterIndex( |
273 &procedure->function()->type_parameters(), binary_offset); | 1828 active_class_->member_type_parameters_offset_start, |
| 1829 active_class_->member_type_parameters, binary_offset); |
274 if (index >= 0) { | 1830 if (index >= 0) { |
275 if (procedure->kind() == Procedure::kFactory) { | 1831 if (active_class_->member_is_factory_procedure) { |
276 // The index of the type parameter in [parameters] is | 1832 // The index of the type parameter in [parameters] is |
277 // the same index into the `klass->type_parameters()` array. | 1833 // the same index into the `klass->type_parameters()` array. |
278 result_ ^= dart::TypeArguments::Handle( | 1834 result_ ^= dart::TypeArguments::Handle( |
279 Z, active_class_->klass->type_parameters()) | 1835 Z, active_class_->klass->type_parameters()) |
280 .TypeAt(index); | 1836 .TypeAt(index); |
281 } else { | 1837 } else { |
282 result_ ^= dart::Type::DynamicType(); | 1838 result_ ^= dart::Type::DynamicType(); |
283 } | 1839 } |
284 return; | 1840 return; |
285 } | 1841 } |
286 } | 1842 } |
287 } | 1843 } |
288 | 1844 |
289 ASSERT(active_class_->kernel_class != NULL); | 1845 const intptr_t index = FindTypeParameterIndex( |
290 List<TypeParameter>* parameters = | 1846 active_class_->class_type_parameters_offset_start, |
291 &active_class_->kernel_class->type_parameters(); | 1847 active_class_->class_type_parameters, binary_offset); |
292 const intptr_t index = FindTypeParameterIndex(parameters, binary_offset); | |
293 if (index >= 0) { | 1848 if (index >= 0) { |
294 // The index of the type parameter in [parameters] is | 1849 // The index of the type parameter in [parameters] is |
295 // the same index into the `klass->type_parameters()` array. | 1850 // the same index into the `klass->type_parameters()` array. |
296 result_ ^= | 1851 result_ ^= |
297 dart::TypeArguments::Handle(Z, active_class_->klass->type_parameters()) | 1852 dart::TypeArguments::Handle(Z, active_class_->klass->type_parameters()) |
298 .TypeAt(index); | 1853 .TypeAt(index); |
299 return; | 1854 return; |
300 } | 1855 } |
301 | 1856 |
302 UNREACHABLE(); | 1857 UNREACHABLE(); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
341 intptr_t length) { | 1896 intptr_t length) { |
342 const TypeArguments& type_arguments = BuildTypeArguments(length); | 1897 const TypeArguments& type_arguments = BuildTypeArguments(length); |
343 if (type_arguments.IsNull()) return type_arguments; | 1898 if (type_arguments.IsNull()) return type_arguments; |
344 | 1899 |
345 // We make a temporary [Type] object and use `ClassFinalizer::FinalizeType` to | 1900 // We make a temporary [Type] object and use `ClassFinalizer::FinalizeType` to |
346 // finalize the argument types. | 1901 // finalize the argument types. |
347 // (This can for example make the [type_arguments] vector larger) | 1902 // (This can for example make the [type_arguments] vector larger) |
348 Type& type = Type::Handle( | 1903 Type& type = Type::Handle( |
349 Z, Type::New(receiver_class, type_arguments, TokenPosition::kNoSource)); | 1904 Z, Type::New(receiver_class, type_arguments, TokenPosition::kNoSource)); |
350 if (finalize_) { | 1905 if (finalize_) { |
351 type ^= | 1906 type ^= ClassFinalizer::FinalizeType(*active_class_->klass, type); |
352 ClassFinalizer::FinalizeType(*builder_->active_class()->klass, type); | |
353 } | 1907 } |
354 | 1908 |
355 const TypeArguments& instantiated_type_arguments = | 1909 const TypeArguments& instantiated_type_arguments = |
356 TypeArguments::ZoneHandle(Z, type.arguments()); | 1910 TypeArguments::ZoneHandle(Z, type.arguments()); |
357 return instantiated_type_arguments; | 1911 return instantiated_type_arguments; |
358 } | 1912 } |
359 | 1913 |
360 | 1914 |
361 const Type& StreamingDartTypeTranslator::ReceiverType( | 1915 const Type& StreamingDartTypeTranslator::ReceiverType( |
362 const dart::Class& klass) { | 1916 const dart::Class& klass) { |
(...skipping 17 matching lines...) Expand all Loading... |
380 | 1934 |
381 StreamingConstantEvaluator::StreamingConstantEvaluator( | 1935 StreamingConstantEvaluator::StreamingConstantEvaluator( |
382 StreamingFlowGraphBuilder* builder) | 1936 StreamingFlowGraphBuilder* builder) |
383 : builder_(builder), | 1937 : builder_(builder), |
384 isolate_(Isolate::Current()), | 1938 isolate_(Isolate::Current()), |
385 zone_(builder_->zone_), | 1939 zone_(builder_->zone_), |
386 translation_helper_(builder_->translation_helper_), | 1940 translation_helper_(builder_->translation_helper_), |
387 type_translator_(builder_->type_translator_), | 1941 type_translator_(builder_->type_translator_), |
388 script_(Script::Handle( | 1942 script_(Script::Handle( |
389 zone_, | 1943 zone_, |
390 builder == NULL ? Script::null() | 1944 // TODO(jensj): This was added to temporarily be able to let the scope |
391 : builder_->parsed_function()->function().script())), | 1945 // builder have a StreamingFlowGraphBuilder to get access to |
| 1946 // reading functions. |
| 1947 (builder == NULL || builder_->flow_graph_builder_ == NULL) |
| 1948 ? Script::null() |
| 1949 : builder_->parsed_function()->function().script())), |
392 result_(Instance::Handle(zone_)) {} | 1950 result_(Instance::Handle(zone_)) {} |
393 | 1951 |
394 | 1952 |
395 Instance& StreamingConstantEvaluator::EvaluateExpression(intptr_t offset, | 1953 Instance& StreamingConstantEvaluator::EvaluateExpression(intptr_t offset, |
396 bool reset_position) { | 1954 bool reset_position) { |
397 if (!GetCachedConstant(offset, &result_)) { | 1955 if (!GetCachedConstant(offset, &result_)) { |
398 intptr_t original_offset = builder_->ReaderOffset(); | 1956 intptr_t original_offset = builder_->ReaderOffset(); |
399 builder_->SetOffset(offset); | 1957 builder_->SetOffset(offset); |
400 uint8_t payload = 0; | 1958 uint8_t payload = 0; |
401 Tag tag = builder_->ReadTag(&payload); // read tag. | 1959 Tag tag = builder_->ReadTag(&payload); // read tag. |
(...skipping 867 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1269 return BuildIfStatement(); | 2827 return BuildIfStatement(); |
1270 case kReturnStatement: | 2828 case kReturnStatement: |
1271 return BuildReturnStatement(); | 2829 return BuildReturnStatement(); |
1272 case kTryCatch: | 2830 case kTryCatch: |
1273 return BuildTryCatch(); | 2831 return BuildTryCatch(); |
1274 case kTryFinally: | 2832 case kTryFinally: |
1275 return BuildTryFinally(); | 2833 return BuildTryFinally(); |
1276 case kYieldStatement: | 2834 case kYieldStatement: |
1277 return BuildYieldStatement(); | 2835 return BuildYieldStatement(); |
1278 case kVariableDeclaration: | 2836 case kVariableDeclaration: |
1279 return BuildVariableDeclaration(true); | 2837 return BuildVariableDeclaration(); |
1280 case kFunctionDeclaration: | 2838 case kFunctionDeclaration: |
1281 // TODO(jensj) | 2839 // TODO(jensj) |
1282 UNIMPLEMENTED(); | 2840 UNIMPLEMENTED(); |
1283 return Fragment(); | 2841 return Fragment(); |
1284 default: | 2842 default: |
1285 UNREACHABLE(); | 2843 UNREACHABLE(); |
1286 } | 2844 } |
1287 return Fragment(); | 2845 return Fragment(); |
1288 } | 2846 } |
1289 | 2847 |
(...skipping 15 matching lines...) Expand all Loading... |
1305 | 2863 |
1306 uint8_t StreamingFlowGraphBuilder::ReadByte() { | 2864 uint8_t StreamingFlowGraphBuilder::ReadByte() { |
1307 return reader_->ReadByte(); | 2865 return reader_->ReadByte(); |
1308 } | 2866 } |
1309 | 2867 |
1310 uint32_t StreamingFlowGraphBuilder::ReadUInt() { | 2868 uint32_t StreamingFlowGraphBuilder::ReadUInt() { |
1311 return reader_->ReadUInt(); | 2869 return reader_->ReadUInt(); |
1312 } | 2870 } |
1313 | 2871 |
1314 uint32_t StreamingFlowGraphBuilder::PeekUInt() { | 2872 uint32_t StreamingFlowGraphBuilder::PeekUInt() { |
1315 intptr_t offset = ReaderOffset(); | 2873 AlternativeReadingScope alt(reader_); |
1316 uint32_t result = reader_->ReadUInt(); | 2874 return reader_->ReadUInt(); |
1317 SetOffset(offset); | |
1318 return result; | |
1319 } | 2875 } |
1320 | 2876 |
1321 intptr_t StreamingFlowGraphBuilder::ReadListLength() { | 2877 intptr_t StreamingFlowGraphBuilder::ReadListLength() { |
1322 return reader_->ReadListLength(); | 2878 return reader_->ReadListLength(); |
1323 } | 2879 } |
1324 | 2880 |
1325 StringIndex StreamingFlowGraphBuilder::ReadStringReference() { | 2881 StringIndex StreamingFlowGraphBuilder::ReadStringReference() { |
1326 return StringIndex(ReadUInt()); | 2882 return StringIndex(ReadUInt()); |
1327 } | 2883 } |
1328 | 2884 |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1416 return; | 2972 return; |
1417 } | 2973 } |
1418 ASSERT(tag == kSomething); | 2974 ASSERT(tag == kSomething); |
1419 | 2975 |
1420 SkipDartType(); // read type. | 2976 SkipDartType(); // read type. |
1421 } | 2977 } |
1422 | 2978 |
1423 void StreamingFlowGraphBuilder::SkipInterfaceType(bool simple) { | 2979 void StreamingFlowGraphBuilder::SkipInterfaceType(bool simple) { |
1424 ReadUInt(); // read klass_name. | 2980 ReadUInt(); // read klass_name. |
1425 if (!simple) { | 2981 if (!simple) { |
1426 intptr_t length = ReadListLength(); // read number of types. | 2982 SkipListOfDartTypes(); // read list of types. |
1427 for (intptr_t i = 0; i < length; ++i) { | |
1428 SkipDartType(); // skip the ith type. | |
1429 } | |
1430 } | 2983 } |
1431 } | 2984 } |
1432 | 2985 |
1433 void StreamingFlowGraphBuilder::SkipFunctionType(bool simple) { | 2986 void StreamingFlowGraphBuilder::SkipFunctionType(bool simple) { |
1434 if (!simple) { | 2987 if (!simple) { |
1435 intptr_t list_length = | 2988 SkipTypeParametersList(); // read type_parameters. |
1436 ReadListLength(); // read type_parameters list length. | |
1437 for (int i = 0; i < list_length; ++i) { | |
1438 SkipStringReference(); // read string index (name). | |
1439 SkipDartType(); // read dart type. | |
1440 } | |
1441 ReadUInt(); // read required parameter count. | 2989 ReadUInt(); // read required parameter count. |
1442 ReadUInt(); // read total parameter count. | 2990 ReadUInt(); // read total parameter count. |
1443 } | 2991 } |
1444 | 2992 |
1445 const intptr_t positional_count = | 2993 SkipListOfDartTypes(); // read positional_parameters types. |
1446 ReadListLength(); // read positional_parameters list length. | |
1447 for (intptr_t i = 0; i < positional_count; ++i) { | |
1448 SkipDartType(); // read ith positional parameter. | |
1449 } | |
1450 | 2994 |
1451 if (!simple) { | 2995 if (!simple) { |
1452 const intptr_t named_count = | 2996 const intptr_t named_count = |
1453 ReadListLength(); // read named_parameters list length. | 2997 ReadListLength(); // read named_parameters list length. |
1454 for (intptr_t i = 0; i < named_count; ++i) { | 2998 for (intptr_t i = 0; i < named_count; ++i) { |
1455 // read string reference (i.e. named_parameters[i].name). | 2999 // read string reference (i.e. named_parameters[i].name). |
1456 SkipStringReference(); | 3000 SkipStringReference(); |
1457 SkipDartType(); // read named_parameters[i].type. | 3001 SkipDartType(); // read named_parameters[i].type. |
1458 } | 3002 } |
1459 } | 3003 } |
1460 | 3004 |
1461 SkipDartType(); // read return type. | 3005 SkipDartType(); // read return type. |
1462 } | 3006 } |
1463 | 3007 |
| 3008 void StreamingFlowGraphBuilder::SkipListOfExpressions() { |
| 3009 intptr_t list_length = ReadListLength(); // read list length. |
| 3010 for (intptr_t i = 0; i < list_length; ++i) { |
| 3011 SkipExpression(); // read ith expression. |
| 3012 } |
| 3013 } |
| 3014 |
| 3015 void StreamingFlowGraphBuilder::SkipListOfDartTypes() { |
| 3016 intptr_t list_length = ReadListLength(); // read list length. |
| 3017 for (intptr_t i = 0; i < list_length; ++i) { |
| 3018 SkipDartType(); // read ith type. |
| 3019 } |
| 3020 } |
| 3021 |
| 3022 void StreamingFlowGraphBuilder::SkipListOfVariableDeclarations() { |
| 3023 intptr_t list_length = ReadListLength(); // read list length. |
| 3024 for (intptr_t i = 0; i < list_length; ++i) { |
| 3025 SkipVariableDeclaration(); // read ith variable declaration. |
| 3026 } |
| 3027 } |
| 3028 |
| 3029 void StreamingFlowGraphBuilder::SkipTypeParametersList() { |
| 3030 intptr_t list_length = ReadListLength(); // read list length. |
| 3031 for (intptr_t i = 0; i < list_length; ++i) { |
| 3032 SkipStringReference(); // read ith name index. |
| 3033 SkipDartType(); // read ith bound. |
| 3034 } |
| 3035 } |
| 3036 |
1464 void StreamingFlowGraphBuilder::SkipExpression() { | 3037 void StreamingFlowGraphBuilder::SkipExpression() { |
1465 uint8_t payload = 0; | 3038 uint8_t payload = 0; |
1466 Tag tag = ReadTag(&payload); | 3039 Tag tag = ReadTag(&payload); |
1467 switch (tag) { | 3040 switch (tag) { |
1468 case kInvalidExpression: | 3041 case kInvalidExpression: |
1469 return; | 3042 return; |
1470 case kVariableGet: | 3043 case kVariableGet: |
1471 ReadPosition(); // read position. | 3044 ReadPosition(); // read position. |
1472 ReadUInt(); // read kernel position. | 3045 ReadUInt(); // read kernel position. |
1473 ReadUInt(); // read relative variable index. | 3046 ReadUInt(); // read relative variable index. |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1555 SkipExpression(); // read left. | 3128 SkipExpression(); // read left. |
1556 SkipBytes(1); // read operator. | 3129 SkipBytes(1); // read operator. |
1557 SkipExpression(); // read right. | 3130 SkipExpression(); // read right. |
1558 return; | 3131 return; |
1559 case kConditionalExpression: | 3132 case kConditionalExpression: |
1560 SkipExpression(); // read condition. | 3133 SkipExpression(); // read condition. |
1561 SkipExpression(); // read then. | 3134 SkipExpression(); // read then. |
1562 SkipExpression(); // read otherwise. | 3135 SkipExpression(); // read otherwise. |
1563 SkipOptionalDartType(); // read unused static type. | 3136 SkipOptionalDartType(); // read unused static type. |
1564 return; | 3137 return; |
1565 case kStringConcatenation: { | 3138 case kStringConcatenation: |
1566 ReadPosition(); // read position. | 3139 ReadPosition(); // read position. |
1567 intptr_t list_length = ReadListLength(); // read list length. | 3140 SkipListOfExpressions(); // read list of expressions. |
1568 for (intptr_t i = 0; i < list_length; ++i) { | |
1569 SkipExpression(); // read ith expression. | |
1570 } | |
1571 return; | 3141 return; |
1572 } | |
1573 case kIsExpression: | 3142 case kIsExpression: |
1574 ReadPosition(); // read position. | 3143 ReadPosition(); // read position. |
1575 SkipExpression(); // read operand. | 3144 SkipExpression(); // read operand. |
1576 SkipDartType(); // read type. | 3145 SkipDartType(); // read type. |
1577 return; | 3146 return; |
1578 case kAsExpression: | 3147 case kAsExpression: |
1579 ReadPosition(); // read position. | 3148 ReadPosition(); // read position. |
1580 SkipExpression(); // read operand. | 3149 SkipExpression(); // read operand. |
1581 SkipDartType(); // read type. | 3150 SkipDartType(); // read type. |
1582 return; | 3151 return; |
1583 case kSymbolLiteral: | 3152 case kSymbolLiteral: |
1584 SkipStringReference(); // read index into string table. | 3153 SkipStringReference(); // read index into string table. |
1585 return; | 3154 return; |
1586 case kTypeLiteral: | 3155 case kTypeLiteral: |
1587 SkipDartType(); // read type. | 3156 SkipDartType(); // read type. |
1588 return; | 3157 return; |
1589 case kThisExpression: | 3158 case kThisExpression: |
1590 return; | 3159 return; |
1591 case kRethrow: | 3160 case kRethrow: |
1592 ReadPosition(); // read position. | 3161 ReadPosition(); // read position. |
1593 return; | 3162 return; |
1594 case kThrow: | 3163 case kThrow: |
1595 ReadPosition(); // read position. | 3164 ReadPosition(); // read position. |
1596 SkipExpression(); // read expression. | 3165 SkipExpression(); // read expression. |
1597 return; | 3166 return; |
1598 case kListLiteral: | 3167 case kListLiteral: |
1599 case kConstListLiteral: { | 3168 case kConstListLiteral: |
1600 ReadPosition(); // read position. | 3169 ReadPosition(); // read position. |
1601 SkipDartType(); // read type. | 3170 SkipDartType(); // read type. |
1602 intptr_t list_length = ReadListLength(); // read list length. | 3171 SkipListOfExpressions(); // read list of expressions. |
1603 for (intptr_t i = 0; i < list_length; ++i) { | |
1604 SkipExpression(); // read ith expression. | |
1605 } | |
1606 return; | 3172 return; |
1607 } | |
1608 case kMapLiteral: | 3173 case kMapLiteral: |
1609 case kConstMapLiteral: { | 3174 case kConstMapLiteral: { |
1610 ReadPosition(); // read position. | 3175 ReadPosition(); // read position. |
1611 SkipDartType(); // read key type. | 3176 SkipDartType(); // read key type. |
1612 SkipDartType(); // read value type. | 3177 SkipDartType(); // read value type. |
1613 intptr_t list_length = ReadListLength(); // read list length. | 3178 intptr_t list_length = ReadListLength(); // read list length. |
1614 for (intptr_t i = 0; i < list_length; ++i) { | 3179 for (intptr_t i = 0; i < list_length; ++i) { |
1615 SkipExpression(); // read ith key. | 3180 SkipExpression(); // read ith key. |
1616 SkipExpression(); // read ith value. | 3181 SkipExpression(); // read ith value. |
1617 } | 3182 } |
1618 return; | 3183 return; |
1619 } | 3184 } |
1620 case kFunctionExpression: | 3185 case kFunctionExpression: |
1621 // TODO(jensj) | 3186 SkipFunctionNode(); // read function node. |
1622 UNIMPLEMENTED(); | |
1623 return; | 3187 return; |
1624 case kLet: | 3188 case kLet: |
1625 SkipVariableDeclaration(); // read variable declaration. | 3189 SkipVariableDeclaration(); // read variable declaration. |
1626 SkipExpression(); // read expression. | 3190 SkipExpression(); // read expression. |
1627 return; | 3191 return; |
1628 case kBigIntLiteral: | 3192 case kBigIntLiteral: |
1629 SkipStringReference(); // read string reference. | 3193 SkipStringReference(); // read string reference. |
1630 return; | 3194 return; |
1631 case kStringLiteral: | 3195 case kStringLiteral: |
1632 SkipStringReference(); // read string reference. | 3196 SkipStringReference(); // read string reference. |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1687 return; | 3251 return; |
1688 case kWhileStatement: | 3252 case kWhileStatement: |
1689 SkipExpression(); // read condition. | 3253 SkipExpression(); // read condition. |
1690 SkipStatement(); // read body. | 3254 SkipStatement(); // read body. |
1691 return; | 3255 return; |
1692 case kDoStatement: | 3256 case kDoStatement: |
1693 SkipStatement(); // read body. | 3257 SkipStatement(); // read body. |
1694 SkipExpression(); // read condition. | 3258 SkipExpression(); // read condition. |
1695 return; | 3259 return; |
1696 case kForStatement: { | 3260 case kForStatement: { |
1697 intptr_t list_length = ReadListLength(); // read number of variables. | 3261 SkipListOfVariableDeclarations(); // read variables. |
1698 for (intptr_t i = 0; i < list_length; ++i) { | |
1699 SkipVariableDeclaration(); // read ith variable. | |
1700 } | |
1701 Tag tag = ReadTag(); // Read first part of condition. | 3262 Tag tag = ReadTag(); // Read first part of condition. |
1702 if (tag == kSomething) { | 3263 if (tag == kSomething) { |
1703 SkipExpression(); // read rest of condition. | 3264 SkipExpression(); // read rest of condition. |
1704 } | 3265 } |
1705 list_length = ReadListLength(); // read number of updates. | 3266 SkipListOfExpressions(); // read updates. |
1706 for (intptr_t i = 0; i < list_length; ++i) { | |
1707 SkipExpression(); // read ith update. | |
1708 } | |
1709 SkipStatement(); // read body. | 3267 SkipStatement(); // read body. |
1710 return; | 3268 return; |
1711 } | 3269 } |
1712 case kForInStatement: | 3270 case kForInStatement: |
1713 case kAsyncForInStatement: | 3271 case kAsyncForInStatement: |
1714 ReadPosition(); // read position. | 3272 ReadPosition(); // read position. |
1715 SkipVariableDeclaration(); // read variable. | 3273 SkipVariableDeclaration(); // read variable. |
1716 SkipExpression(); // read iterable. | 3274 SkipExpression(); // read iterable. |
1717 SkipStatement(); // read body. | 3275 SkipStatement(); // read body. |
1718 return; | 3276 return; |
(...skipping 23 matching lines...) Expand all Loading... |
1742 ReadPosition(); // read position | 3300 ReadPosition(); // read position |
1743 Tag tag = ReadTag(); // read (first part of) expression. | 3301 Tag tag = ReadTag(); // read (first part of) expression. |
1744 if (tag == kSomething) { | 3302 if (tag == kSomething) { |
1745 SkipExpression(); // read (rest of) expression. | 3303 SkipExpression(); // read (rest of) expression. |
1746 } | 3304 } |
1747 return; | 3305 return; |
1748 } | 3306 } |
1749 case kTryCatch: { | 3307 case kTryCatch: { |
1750 SkipStatement(); // read body. | 3308 SkipStatement(); // read body. |
1751 ReadBool(); // read any_catch_needs_stack_trace. | 3309 ReadBool(); // read any_catch_needs_stack_trace. |
1752 intptr_t num_matches = ReadListLength(); // read number of catches. | 3310 intptr_t num_catches = ReadListLength(); // read number of catches. |
1753 for (intptr_t i = 0; i < num_matches; ++i) { | 3311 for (intptr_t i = 0; i < num_catches; ++i) { |
1754 SkipDartType(); // read guard. | 3312 SkipDartType(); // read guard. |
1755 tag = ReadTag(); // read first part of exception. | 3313 tag = ReadTag(); // read first part of exception. |
1756 if (tag == kSomething) { | 3314 if (tag == kSomething) { |
1757 SkipVariableDeclaration(); // read exception. | 3315 SkipVariableDeclaration(); // read exception. |
1758 } | 3316 } |
1759 tag = ReadTag(); // read first part of stack trace. | 3317 tag = ReadTag(); // read first part of stack trace. |
1760 if (tag == kSomething) { | 3318 if (tag == kSomething) { |
1761 SkipVariableDeclaration(); // read stack trace. | 3319 SkipVariableDeclaration(); // read stack trace. |
1762 } | 3320 } |
1763 SkipStatement(); // read body. | 3321 SkipStatement(); // read body. |
1764 } | 3322 } |
1765 return; | 3323 return; |
1766 } | 3324 } |
1767 case kTryFinally: | 3325 case kTryFinally: |
1768 SkipStatement(); // read body. | 3326 SkipStatement(); // read body. |
1769 SkipStatement(); // read finalizer. | 3327 SkipStatement(); // read finalizer. |
1770 return; | 3328 return; |
1771 case kYieldStatement: | 3329 case kYieldStatement: |
1772 ReadPosition(); // read position. | 3330 ReadPosition(); // read position. |
1773 ReadByte(); // read flags. | 3331 ReadByte(); // read flags. |
1774 SkipExpression(); // read expression. | 3332 SkipExpression(); // read expression. |
1775 return; | 3333 return; |
1776 case kVariableDeclaration: | 3334 case kVariableDeclaration: |
1777 SkipVariableDeclaration(); | 3335 SkipVariableDeclaration(); // read variable declaration. |
1778 return; | 3336 return; |
1779 case kFunctionDeclaration: | 3337 case kFunctionDeclaration: |
1780 // TODO(jensj) | 3338 ReadPosition(); // read position. |
1781 UNIMPLEMENTED(); | 3339 SkipVariableDeclaration(); // read variable. |
| 3340 SkipFunctionNode(); // read function node. |
1782 return; | 3341 return; |
1783 default: | 3342 default: |
1784 UNREACHABLE(); | 3343 UNREACHABLE(); |
1785 } | 3344 } |
1786 } | 3345 } |
1787 | 3346 |
| 3347 void StreamingFlowGraphBuilder::SkipFunctionNode() { |
| 3348 Tag tag = ReadTag(); // read tag. |
| 3349 ASSERT(tag == kFunctionNode); |
| 3350 |
| 3351 ReadPosition(); // read position. |
| 3352 ReadPosition(); // read end position. |
| 3353 ReadByte(); // read async marker. |
| 3354 ReadByte(); // read dart async marker. |
| 3355 SkipTypeParametersList(); // read type_parameters. |
| 3356 ReadUInt(); // read required_parameter_count. |
| 3357 |
| 3358 SkipListOfVariableDeclarations(); // read list of positionals. |
| 3359 SkipListOfVariableDeclarations(); // read list of named. |
| 3360 SkipDartType(); // read return type. |
| 3361 |
| 3362 if (ReadTag() == kSomething) { |
| 3363 SkipStatement(); // Read body |
| 3364 } |
| 3365 } |
| 3366 |
1788 void StreamingFlowGraphBuilder::SkipName() { | 3367 void StreamingFlowGraphBuilder::SkipName() { |
1789 StringIndex name_index = ReadStringReference(); // read name index. | 3368 StringIndex name_index = ReadStringReference(); // read name index. |
1790 if ((H.StringSize(name_index) >= 1) && H.CharacterAt(name_index, 0) == '_') { | 3369 if ((H.StringSize(name_index) >= 1) && H.CharacterAt(name_index, 0) == '_') { |
1791 SkipCanonicalNameReference(); // read library index. | 3370 SkipCanonicalNameReference(); // read library index. |
1792 } | 3371 } |
1793 } | 3372 } |
1794 | 3373 |
1795 void StreamingFlowGraphBuilder::SkipArguments() { | 3374 void StreamingFlowGraphBuilder::SkipArguments() { |
1796 ReadUInt(); // read argument count. | 3375 ReadUInt(); // read argument count. |
1797 | 3376 |
1798 // List of types. | 3377 SkipListOfDartTypes(); // read list of types. |
1799 intptr_t list_length = ReadListLength(); // read list length. | 3378 SkipListOfExpressions(); // read positionals. |
1800 for (intptr_t i = 0; i < list_length; ++i) { | |
1801 SkipDartType(); // read ith type. | |
1802 } | |
1803 | |
1804 // List of positional. | |
1805 list_length = ReadListLength(); // read list length. | |
1806 for (intptr_t i = 0; i < list_length; ++i) { | |
1807 SkipExpression(); // read ith expression. | |
1808 } | |
1809 | 3379 |
1810 // List of named. | 3380 // List of named. |
1811 list_length = ReadListLength(); // read list length. | 3381 intptr_t list_length = ReadListLength(); // read list length. |
1812 for (intptr_t i = 0; i < list_length; ++i) { | 3382 for (intptr_t i = 0; i < list_length; ++i) { |
1813 SkipStringReference(); // read ith name index. | 3383 SkipStringReference(); // read ith name index. |
1814 SkipExpression(); // read ith expression. | 3384 SkipExpression(); // read ith expression. |
1815 } | 3385 } |
1816 } | 3386 } |
1817 | 3387 |
1818 void StreamingFlowGraphBuilder::SkipVariableDeclaration() { | 3388 void StreamingFlowGraphBuilder::SkipVariableDeclaration() { |
1819 ReadPosition(); // read position. | 3389 ReadPosition(); // read position. |
1820 ReadPosition(); // read equals position. | 3390 ReadPosition(); // read equals position. |
1821 ReadFlags(); // read flags. | 3391 ReadFlags(); // read flags. |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1931 Value* StreamingFlowGraphBuilder::stack() { | 3501 Value* StreamingFlowGraphBuilder::stack() { |
1932 return flow_graph_builder_->stack_; | 3502 return flow_graph_builder_->stack_; |
1933 } | 3503 } |
1934 | 3504 |
1935 Value* StreamingFlowGraphBuilder::Pop() { | 3505 Value* StreamingFlowGraphBuilder::Pop() { |
1936 return flow_graph_builder_->Pop(); | 3506 return flow_graph_builder_->Pop(); |
1937 } | 3507 } |
1938 | 3508 |
1939 Tag StreamingFlowGraphBuilder::PeekArgumentsFirstPositionalTag() { | 3509 Tag StreamingFlowGraphBuilder::PeekArgumentsFirstPositionalTag() { |
1940 // read parts of arguments, then go back to before doing so. | 3510 // read parts of arguments, then go back to before doing so. |
1941 intptr_t offset = ReaderOffset(); | 3511 AlternativeReadingScope alt(reader_); |
1942 ReadUInt(); // read number of arguments. | 3512 ReadUInt(); // read number of arguments. |
1943 | 3513 |
1944 // List of types. | 3514 SkipListOfDartTypes(); // Read list of types. |
| 3515 |
| 3516 // List of positional. |
1945 intptr_t list_length = ReadListLength(); // read list length. | 3517 intptr_t list_length = ReadListLength(); // read list length. |
1946 for (intptr_t i = 0; i < list_length; ++i) { | 3518 for (intptr_t i = 0; i < list_length; ++i) { |
1947 SkipDartType(); // read ith type. | 3519 return ReadTag(); // read first tag. |
1948 } | |
1949 | |
1950 // List of positional. | |
1951 list_length = ReadListLength(); // read list length. | |
1952 for (intptr_t i = 0; i < list_length; ++i) { | |
1953 Tag tag = ReadTag(); // read first tag. | |
1954 SetOffset(offset); // reset offset. | |
1955 return tag; | |
1956 } | 3520 } |
1957 | 3521 |
1958 UNREACHABLE(); | 3522 UNREACHABLE(); |
1959 return kNothing; | 3523 return kNothing; |
1960 } | 3524 } |
1961 | 3525 |
1962 const TypeArguments& StreamingFlowGraphBuilder::PeekArgumentsInstantiatedType( | 3526 const TypeArguments& StreamingFlowGraphBuilder::PeekArgumentsInstantiatedType( |
1963 const dart::Class& klass) { | 3527 const dart::Class& klass) { |
1964 // read parts of arguments, then go back to before doing so. | 3528 // read parts of arguments, then go back to before doing so. |
1965 intptr_t offset = ReaderOffset(); | 3529 AlternativeReadingScope alt(reader_); |
1966 ReadUInt(); // read argument count. | 3530 ReadUInt(); // read argument count. |
1967 intptr_t list_length = ReadListLength(); // read types list length. | 3531 intptr_t list_length = ReadListLength(); // read types list length. |
1968 const TypeArguments& type_arguments = | 3532 return T.BuildInstantiatedTypeArguments(klass, list_length); // read types. |
1969 T.BuildInstantiatedTypeArguments(klass, list_length); // read types. | |
1970 SetOffset(offset); | |
1971 return type_arguments; | |
1972 } | 3533 } |
1973 | 3534 |
1974 intptr_t StreamingFlowGraphBuilder::PeekArgumentsCount() { | 3535 intptr_t StreamingFlowGraphBuilder::PeekArgumentsCount() { |
1975 return PeekUInt(); | 3536 return PeekUInt(); |
1976 } | 3537 } |
1977 | 3538 |
1978 intptr_t StreamingFlowGraphBuilder::PeekArgumentsTypeCount() { | 3539 intptr_t StreamingFlowGraphBuilder::PeekArgumentsTypeCount() { |
1979 intptr_t offset = ReaderOffset(); | 3540 AlternativeReadingScope alt(reader_); |
1980 ReadUInt(); // read arguments count. | 3541 ReadUInt(); // read arguments count. |
1981 intptr_t types_count = ReadListLength(); // read length of types list. | 3542 return ReadListLength(); // read length of types list. |
1982 SetOffset(offset); | |
1983 return types_count; | |
1984 } | 3543 } |
1985 | 3544 |
1986 void StreamingFlowGraphBuilder::SkipArgumentsBeforeActualArguments() { | 3545 void StreamingFlowGraphBuilder::SkipArgumentsBeforeActualArguments() { |
1987 ReadUInt(); // read arguments count. | 3546 ReadUInt(); // read arguments count. |
1988 intptr_t types_count = ReadListLength(); | 3547 SkipListOfDartTypes(); // read list of types. |
1989 for (intptr_t i = 0; i < types_count; ++i) { | |
1990 SkipDartType(); // read ith type. | |
1991 } | |
1992 } | 3548 } |
1993 | 3549 |
1994 LocalVariable* StreamingFlowGraphBuilder::LookupVariable( | 3550 LocalVariable* StreamingFlowGraphBuilder::LookupVariable( |
1995 intptr_t kernel_offset) { | 3551 intptr_t kernel_offset) { |
1996 return flow_graph_builder_->LookupVariable(kernel_offset); | 3552 return flow_graph_builder_->LookupVariable(kernel_offset); |
1997 } | 3553 } |
1998 | 3554 |
1999 LocalVariable* StreamingFlowGraphBuilder::MakeTemporary() { | 3555 LocalVariable* StreamingFlowGraphBuilder::MakeTemporary() { |
2000 return flow_graph_builder_->MakeTemporary(); | 3556 return flow_graph_builder_->MakeTemporary(); |
2001 } | 3557 } |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2171 | 3727 |
2172 Fragment StreamingFlowGraphBuilder::CloneContext() { | 3728 Fragment StreamingFlowGraphBuilder::CloneContext() { |
2173 return flow_graph_builder_->CloneContext(); | 3729 return flow_graph_builder_->CloneContext(); |
2174 } | 3730 } |
2175 | 3731 |
2176 Fragment StreamingFlowGraphBuilder::TranslateFinallyFinalizers( | 3732 Fragment StreamingFlowGraphBuilder::TranslateFinallyFinalizers( |
2177 TryFinallyBlock* outer_finally, | 3733 TryFinallyBlock* outer_finally, |
2178 intptr_t target_context_depth) { | 3734 intptr_t target_context_depth) { |
2179 // TranslateFinallyFinalizers can move the readers offset. | 3735 // TranslateFinallyFinalizers can move the readers offset. |
2180 // Save the current position and restore it afterwards. | 3736 // Save the current position and restore it afterwards. |
2181 intptr_t offset = ReaderOffset(); | 3737 AlternativeReadingScope alt(reader_); |
2182 Fragment result = flow_graph_builder_->TranslateFinallyFinalizers( | 3738 return flow_graph_builder_->TranslateFinallyFinalizers(outer_finally, |
2183 outer_finally, target_context_depth); | 3739 target_context_depth); |
2184 SetOffset(offset); | |
2185 return result; | |
2186 } | 3740 } |
2187 | 3741 |
2188 Fragment StreamingFlowGraphBuilder::BranchIfTrue( | 3742 Fragment StreamingFlowGraphBuilder::BranchIfTrue( |
2189 TargetEntryInstr** then_entry, | 3743 TargetEntryInstr** then_entry, |
2190 TargetEntryInstr** otherwise_entry, | 3744 TargetEntryInstr** otherwise_entry, |
2191 bool negate) { | 3745 bool negate) { |
2192 return flow_graph_builder_->BranchIfTrue(then_entry, otherwise_entry, negate); | 3746 return flow_graph_builder_->BranchIfTrue(then_entry, otherwise_entry, negate); |
2193 } | 3747 } |
2194 | 3748 |
2195 Fragment StreamingFlowGraphBuilder::BranchIfEqual( | 3749 Fragment StreamingFlowGraphBuilder::BranchIfEqual( |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2297 | 3851 |
2298 Fragment StreamingFlowGraphBuilder::BuildArguments(Array* argument_names, | 3852 Fragment StreamingFlowGraphBuilder::BuildArguments(Array* argument_names, |
2299 intptr_t* argument_count, | 3853 intptr_t* argument_count, |
2300 bool skip_push_arguments, | 3854 bool skip_push_arguments, |
2301 bool do_drop) { | 3855 bool do_drop) { |
2302 intptr_t dummy; | 3856 intptr_t dummy; |
2303 if (argument_count == NULL) argument_count = &dummy; | 3857 if (argument_count == NULL) argument_count = &dummy; |
2304 *argument_count = ReadUInt(); // read arguments count. | 3858 *argument_count = ReadUInt(); // read arguments count. |
2305 | 3859 |
2306 // List of types. | 3860 // List of types. |
2307 intptr_t list_length = ReadListLength(); // read type count. | 3861 SkipListOfDartTypes(); // read list of types. |
2308 for (intptr_t i = 0; i < list_length; ++i) { | |
2309 SkipDartType(); // read ith type. | |
2310 } | |
2311 | 3862 |
2312 return BuildArgumentsFromActualArguments(argument_names, skip_push_arguments, | 3863 return BuildArgumentsFromActualArguments(argument_names, skip_push_arguments, |
2313 do_drop); | 3864 do_drop); |
2314 } | 3865 } |
2315 | 3866 |
2316 Fragment StreamingFlowGraphBuilder::BuildArgumentsFromActualArguments( | 3867 Fragment StreamingFlowGraphBuilder::BuildArgumentsFromActualArguments( |
2317 Array* argument_names, | 3868 Array* argument_names, |
2318 bool skip_push_arguments, | 3869 bool skip_push_arguments, |
2319 bool do_drop) { | 3870 bool do_drop) { |
2320 Fragment instructions; | 3871 Fragment instructions; |
(...skipping 982 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3303 const Function& factory_method = Function::ZoneHandle( | 4854 const Function& factory_method = Function::ZoneHandle( |
3304 Z, map_class.LookupFactory( | 4855 Z, map_class.LookupFactory( |
3305 dart::Library::PrivateCoreLibName(Symbols::MapLiteralFactory()))); | 4856 dart::Library::PrivateCoreLibName(Symbols::MapLiteralFactory()))); |
3306 | 4857 |
3307 return instructions + StaticCall(position, factory_method, 2); | 4858 return instructions + StaticCall(position, factory_method, 2); |
3308 } | 4859 } |
3309 | 4860 |
3310 Fragment StreamingFlowGraphBuilder::BuildLet(TokenPosition* position) { | 4861 Fragment StreamingFlowGraphBuilder::BuildLet(TokenPosition* position) { |
3311 if (position != NULL) *position = TokenPosition::kNoSource; | 4862 if (position != NULL) *position = TokenPosition::kNoSource; |
3312 | 4863 |
3313 Fragment instructions = BuildVariableDeclaration(false); // read variable. | 4864 Fragment instructions = BuildVariableDeclaration(); // read variable. |
3314 instructions += BuildExpression(); // read body. | 4865 instructions += BuildExpression(); // read body. |
3315 return instructions; | 4866 return instructions; |
3316 } | 4867 } |
3317 | 4868 |
3318 | 4869 |
3319 Fragment StreamingFlowGraphBuilder::BuildBigIntLiteral( | 4870 Fragment StreamingFlowGraphBuilder::BuildBigIntLiteral( |
3320 TokenPosition* position) { | 4871 TokenPosition* position) { |
3321 if (position != NULL) *position = TokenPosition::kNoSource; | 4872 if (position != NULL) *position = TokenPosition::kNoSource; |
3322 | 4873 |
3323 const dart::String& value = | 4874 const dart::String& value = |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3401 | 4952 |
3402 return instructions; | 4953 return instructions; |
3403 } | 4954 } |
3404 | 4955 |
3405 Fragment StreamingFlowGraphBuilder::BuildEmptyStatement() { | 4956 Fragment StreamingFlowGraphBuilder::BuildEmptyStatement() { |
3406 return Fragment(); | 4957 return Fragment(); |
3407 } | 4958 } |
3408 | 4959 |
3409 Fragment StreamingFlowGraphBuilder::BuildAssertStatement() { | 4960 Fragment StreamingFlowGraphBuilder::BuildAssertStatement() { |
3410 if (!I->asserts()) { | 4961 if (!I->asserts()) { |
3411 intptr_t offset = ReaderOffset() - 1; // Include the tag. | 4962 SetOffset(ReaderOffset() - 1); // Include the tag. |
3412 SetOffset(offset); | 4963 SkipStatement(); // read this statement. |
3413 SkipStatement(); // read this statement. | |
3414 return Fragment(); | 4964 return Fragment(); |
3415 } | 4965 } |
3416 | 4966 |
3417 TargetEntryInstr* then; | 4967 TargetEntryInstr* then; |
3418 TargetEntryInstr* otherwise; | 4968 TargetEntryInstr* otherwise; |
3419 | 4969 |
3420 Fragment instructions; | 4970 Fragment instructions; |
3421 // Asserts can be of the following two kinds: | 4971 // Asserts can be of the following two kinds: |
3422 // | 4972 // |
3423 // * `assert(expr)` | 4973 // * `assert(expr)` |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3588 Fragment StreamingFlowGraphBuilder::BuildForStatement() { | 5138 Fragment StreamingFlowGraphBuilder::BuildForStatement() { |
3589 intptr_t offset = ReaderOffset() - 1; // Include the tag. | 5139 intptr_t offset = ReaderOffset() - 1; // Include the tag. |
3590 | 5140 |
3591 Fragment declarations; | 5141 Fragment declarations; |
3592 | 5142 |
3593 bool new_context = false; | 5143 bool new_context = false; |
3594 declarations += EnterScope(offset, &new_context); | 5144 declarations += EnterScope(offset, &new_context); |
3595 | 5145 |
3596 intptr_t list_length = ReadListLength(); // read number of variables. | 5146 intptr_t list_length = ReadListLength(); // read number of variables. |
3597 for (intptr_t i = 0; i < list_length; ++i) { | 5147 for (intptr_t i = 0; i < list_length; ++i) { |
3598 declarations += BuildVariableDeclaration(false); // read ith variable. | 5148 declarations += BuildVariableDeclaration(); // read ith variable. |
3599 } | 5149 } |
3600 | 5150 |
3601 loop_depth_inc(); | 5151 loop_depth_inc(); |
3602 bool negate = false; | 5152 bool negate = false; |
3603 Tag tag = ReadTag(); // Read first part of condition. | 5153 Tag tag = ReadTag(); // Read first part of condition. |
3604 Fragment condition = | 5154 Fragment condition = |
3605 tag == kNothing ? Constant(Bool::True()) | 5155 tag == kNothing ? Constant(Bool::True()) |
3606 : TranslateCondition(&negate); // read rest of condition. | 5156 : TranslateCondition(&negate); // read rest of condition. |
3607 TargetEntryInstr* body_entry; | 5157 TargetEntryInstr* body_entry; |
3608 TargetEntryInstr* loop_exit; | 5158 TargetEntryInstr* loop_exit; |
(...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4003 { | 5553 { |
4004 TryCatchBlock block(flow_graph_builder_, try_handler_index); | 5554 TryCatchBlock block(flow_graph_builder_, try_handler_index); |
4005 try_body += BuildStatement(); // read body. | 5555 try_body += BuildStatement(); // read body. |
4006 try_body += Goto(after_try); | 5556 try_body += Goto(after_try); |
4007 } | 5557 } |
4008 try_depth_dec(); | 5558 try_depth_dec(); |
4009 | 5559 |
4010 bool needs_stacktrace = ReadBool(); // read any_catch_needs_stack_trace | 5560 bool needs_stacktrace = ReadBool(); // read any_catch_needs_stack_trace |
4011 | 5561 |
4012 catch_depth_inc(); | 5562 catch_depth_inc(); |
4013 intptr_t num_matches = ReadListLength(); // read number of catches. | 5563 intptr_t num_catches = ReadListLength(); // read number of catches. |
4014 const Array& handler_types = | 5564 const Array& handler_types = |
4015 Array::ZoneHandle(Z, Array::New(num_matches, Heap::kOld)); | 5565 Array::ZoneHandle(Z, Array::New(num_catches, Heap::kOld)); |
4016 Fragment catch_body = | 5566 Fragment catch_body = |
4017 CatchBlockEntry(handler_types, try_handler_index, needs_stacktrace); | 5567 CatchBlockEntry(handler_types, try_handler_index, needs_stacktrace); |
4018 // Fill in the body of the catch. | 5568 // Fill in the body of the catch. |
4019 for (intptr_t i = 0; i < num_matches; ++i) { | 5569 for (intptr_t i = 0; i < num_catches; ++i) { |
4020 intptr_t catch_offset = ReaderOffset(); // Catch has no tag. | 5570 intptr_t catch_offset = ReaderOffset(); // Catch has no tag. |
4021 Tag tag = PeekTag(); // peek guard type. | 5571 Tag tag = PeekTag(); // peek guard type. |
4022 AbstractType* type_guard = NULL; | 5572 AbstractType* type_guard = NULL; |
4023 if (tag != kDynamicType) { | 5573 if (tag != kDynamicType) { |
4024 type_guard = &T.BuildType(); // read guard. | 5574 type_guard = &T.BuildType(); // read guard. |
4025 handler_types.SetAt(i, *type_guard); | 5575 handler_types.SetAt(i, *type_guard); |
4026 } else { | 5576 } else { |
4027 SkipDartType(); // read guard. | 5577 SkipDartType(); // read guard. |
4028 handler_types.SetAt(i, Object::dynamic_type()); | 5578 handler_types.SetAt(i, Object::dynamic_type()); |
4029 } | 5579 } |
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4266 rethrow += RethrowException(position, CatchClauseNode::kInvalidTryIndex); | 5816 rethrow += RethrowException(position, CatchClauseNode::kInvalidTryIndex); |
4267 Drop(); | 5817 Drop(); |
4268 | 5818 |
4269 | 5819 |
4270 continuation = Fragment(continuation.entry, no_error); | 5820 continuation = Fragment(continuation.entry, no_error); |
4271 } | 5821 } |
4272 | 5822 |
4273 return continuation; | 5823 return continuation; |
4274 } | 5824 } |
4275 | 5825 |
4276 Fragment StreamingFlowGraphBuilder::BuildVariableDeclaration(bool has_tag) { | 5826 Fragment StreamingFlowGraphBuilder::BuildVariableDeclaration() { |
4277 intptr_t kernel_position = ReaderOffset() - (has_tag ? 1 : 0); | 5827 intptr_t kernel_position_no_tag = ReaderOffset(); |
4278 LocalVariable* variable = LookupVariable(kernel_position); | 5828 LocalVariable* variable = LookupVariable(kernel_position_no_tag); |
4279 | 5829 |
4280 TokenPosition position = ReadPosition(); // read position. | 5830 TokenPosition position = ReadPosition(); // read position. |
4281 TokenPosition equals_position = ReadPosition(); // read equals position. | 5831 TokenPosition equals_position = ReadPosition(); // read equals position. |
4282 word flags = ReadFlags(); // read flags. | 5832 word flags = ReadFlags(); // read flags. |
4283 dart::String& name = H.DartSymbol(ReadStringReference()); // read name index. | 5833 dart::String& name = H.DartSymbol(ReadStringReference()); // read name index. |
4284 AbstractType& type = T.BuildType(); // read type. | 5834 AbstractType& type = T.BuildType(); // read type. |
4285 Tag tag = ReadTag(); // read (first part of) initializer. | 5835 Tag tag = ReadTag(); // read (first part of) initializer. |
4286 | 5836 |
4287 Fragment instructions; | 5837 Fragment instructions; |
4288 if (tag == kNothing) { | 5838 if (tag == kNothing) { |
(...skipping 22 matching lines...) Expand all Loading... |
4311 } | 5861 } |
4312 instructions += StoreLocal(position, variable); | 5862 instructions += StoreLocal(position, variable); |
4313 instructions += Drop(); | 5863 instructions += Drop(); |
4314 return instructions; | 5864 return instructions; |
4315 } | 5865 } |
4316 | 5866 |
4317 } // namespace kernel | 5867 } // namespace kernel |
4318 } // namespace dart | 5868 } // namespace dart |
4319 | 5869 |
4320 #endif // !defined(DART_PRECOMPILED_RUNTIME) | 5870 #endif // !defined(DART_PRECOMPILED_RUNTIME) |
OLD | NEW |