Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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/flow_graph_builder.h" | 5 #include "vm/flow_graph_builder.h" |
| 6 | 6 |
| 7 #include "vm/ast_printer.h" | 7 #include "vm/ast_printer.h" |
| 8 #include "vm/code_descriptors.h" | |
| 8 #include "vm/dart_entry.h" | 9 #include "vm/dart_entry.h" |
| 9 #include "vm/flags.h" | 10 #include "vm/flags.h" |
| 10 #include "vm/intermediate_language.h" | 11 #include "vm/intermediate_language.h" |
| 11 #include "vm/longjump.h" | 12 #include "vm/longjump.h" |
| 12 #include "vm/object_store.h" | 13 #include "vm/object_store.h" |
| 13 #include "vm/os.h" | 14 #include "vm/os.h" |
| 14 #include "vm/parser.h" | 15 #include "vm/parser.h" |
| 15 #include "vm/resolver.h" | 16 #include "vm/resolver.h" |
| 16 #include "vm/stub_code.h" | 17 #include "vm/stub_code.h" |
| 17 | 18 |
| 18 namespace dart { | 19 namespace dart { |
| 19 | 20 |
| 20 DEFINE_FLAG(bool, print_flow_graph, false, "Print the IR flow graph."); | 21 DEFINE_FLAG(bool, print_flow_graph, false, "Print the IR flow graph."); |
| 21 DECLARE_FLAG(bool, enable_type_checks); | 22 DECLARE_FLAG(bool, enable_type_checks); |
| 22 DECLARE_FLAG(bool, print_ast); | 23 DECLARE_FLAG(bool, print_ast); |
| 23 | 24 |
| 25 | |
| 26 FlowGraphBuilder::FlowGraphBuilder(const ParsedFunction& parsed_function) | |
| 27 : parsed_function_(parsed_function), | |
| 28 preorder_block_entries_(), | |
| 29 postorder_block_entries_(), | |
| 30 context_level_(0), | |
| 31 last_used_try_index_(CatchClauseNode::kInvalidTryIndex), | |
| 32 try_index_(CatchClauseNode::kInvalidTryIndex), | |
| 33 catch_entries_() {} | |
| 34 | |
| 35 | |
| 36 void FlowGraphBuilder::AddCatchEntry(intptr_t try_index, Instruction* entry) { | |
| 37 catch_entries_.Add(entry); | |
| 38 } | |
| 39 | |
| 40 | |
| 24 void EffectGraphVisitor::Append(const EffectGraphVisitor& other_fragment) { | 41 void EffectGraphVisitor::Append(const EffectGraphVisitor& other_fragment) { |
| 25 ASSERT(is_open()); | 42 ASSERT(is_open()); |
| 26 if (other_fragment.is_empty()) return; | 43 if (other_fragment.is_empty()) return; |
| 27 if (is_empty()) { | 44 if (is_empty()) { |
| 28 entry_ = other_fragment.entry(); | 45 entry_ = other_fragment.entry(); |
| 29 exit_ = other_fragment.exit(); | 46 exit_ = other_fragment.exit(); |
| 30 } else { | 47 } else { |
| 31 exit()->SetSuccessor(other_fragment.entry()); | 48 exit()->SetSuccessor(other_fragment.entry()); |
| 32 exit_ = other_fragment.exit(); | 49 exit_ = other_fragment.exit(); |
| 33 } | 50 } |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 110 join->SetSuccessor(test_fragment.entry()); | 127 join->SetSuccessor(test_fragment.entry()); |
| 111 body_exit->SetSuccessor(join); | 128 body_exit->SetSuccessor(join); |
| 112 } | 129 } |
| 113 | 130 |
| 114 // 3. Set the exit to the graph to be the false successor of the test, a | 131 // 3. Set the exit to the graph to be the false successor of the test, a |
| 115 // fresh target node | 132 // fresh target node |
| 116 exit_ = *test_fragment.false_successor_address() = new TargetEntryInstr(); | 133 exit_ = *test_fragment.false_successor_address() = new TargetEntryInstr(); |
| 117 } | 134 } |
| 118 | 135 |
| 119 | 136 |
| 137 // Stores current context into the 'variable' | |
| 138 void EffectGraphVisitor::BuildStoreContext(const LocalVariable& variable, | |
| 139 intptr_t start_index) { | |
| 140 AddInstruction(new BindInstr(start_index, new CurrentContextComp())); | |
| 141 StoreLocalComp* store_context = new StoreLocalComp( | |
| 142 variable, | |
| 143 new TempVal(start_index), | |
| 144 owner()->context_level()); | |
| 145 AddInstruction(new DoInstr(store_context)); | |
| 146 } | |
| 147 | |
| 148 | |
| 149 // Loads context saved in 'context_variable' into the current context. | |
| 150 void EffectGraphVisitor::BuildLoadContext( | |
| 151 const LocalVariable& context_variable, intptr_t start_index) { | |
|
regis
2012/04/10 22:58:24
Should you also call the variable in BuildStoreCon
srdjan
2012/04/10 23:11:58
-> variable
| |
| 152 LoadLocalComp* load_saved_context = | |
| 153 new LoadLocalComp(context_variable, owner()->context_level()); | |
| 154 AddInstruction(new BindInstr(start_index, load_saved_context)); | |
| 155 StoreContextComp* store_context = | |
| 156 new StoreContextComp(new TempVal(start_index)); | |
| 157 AddInstruction(new DoInstr(store_context)); | |
| 158 } | |
| 159 | |
| 160 | |
| 161 | |
| 120 void TestGraphVisitor::ReturnValue(Value* value) { | 162 void TestGraphVisitor::ReturnValue(Value* value) { |
| 121 BranchInstr* branch = new BranchInstr(value); | 163 BranchInstr* branch = new BranchInstr(value); |
| 122 AddInstruction(branch); | 164 AddInstruction(branch); |
| 123 CloseFragment(); | 165 CloseFragment(); |
| 124 true_successor_address_ = branch->true_successor_address(); | 166 true_successor_address_ = branch->true_successor_address(); |
| 125 false_successor_address_ = branch->false_successor_address(); | 167 false_successor_address_ = branch->false_successor_address(); |
| 126 } | 168 } |
| 127 | 169 |
| 128 | 170 |
| 129 void ArgumentGraphVisitor::ReturnValue(Value* value) { | 171 void ArgumentGraphVisitor::ReturnValue(Value* value) { |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 171 new AssertAssignableComp(return_value, type); | 213 new AssertAssignableComp(return_value, type); |
| 172 AddInstruction(new BindInstr(temp_index(), assert)); | 214 AddInstruction(new BindInstr(temp_index(), assert)); |
| 173 return_value = new TempVal(temp_index()); | 215 return_value = new TempVal(temp_index()); |
| 174 } | 216 } |
| 175 } | 217 } |
| 176 | 218 |
| 177 intptr_t current_context_level = owner()->context_level(); | 219 intptr_t current_context_level = owner()->context_level(); |
| 178 ASSERT(current_context_level >= 0); | 220 ASSERT(current_context_level >= 0); |
| 179 if (owner()->parsed_function().saved_context_var() != NULL) { | 221 if (owner()->parsed_function().saved_context_var() != NULL) { |
| 180 // CTX on entry was saved, but not linked as context parent. | 222 // CTX on entry was saved, but not linked as context parent. |
| 181 LoadLocalComp* load_comp = | 223 BuildLoadContext(*owner()->parsed_function().saved_context_var(), 0); |
| 182 new LoadLocalComp(*owner()->parsed_function().saved_context_var(), 0); | |
| 183 AddInstruction(new BindInstr(temp_index(), load_comp)); | |
| 184 TempVal* local_value = new TempVal(temp_index()); | |
| 185 StoreContextComp* store_context = new StoreContextComp(local_value); | |
| 186 AddInstruction(new DoInstr(store_context)); | |
| 187 } else { | 224 } else { |
| 188 while (current_context_level-- > 0) { | 225 while (current_context_level-- > 0) { |
| 189 UnchainContext(); | 226 UnchainContext(); |
| 190 } | 227 } |
| 191 } | 228 } |
| 192 | 229 |
| 193 | 230 |
| 194 AddInstruction(new ReturnInstr(return_value, node->token_index())); | 231 AddInstruction(new ReturnInstr(return_value, node->token_index())); |
| 195 CloseFragment(); | 232 CloseFragment(); |
| 196 } | 233 } |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 251 ArgumentGraphVisitor for_left_value(owner(), temp_index()); | 288 ArgumentGraphVisitor for_left_value(owner(), temp_index()); |
| 252 node->left()->Visit(&for_left_value); | 289 node->left()->Visit(&for_left_value); |
| 253 Append(for_left_value); | 290 Append(for_left_value); |
| 254 ArgumentGraphVisitor for_right_value(owner(), for_left_value.temp_index()); | 291 ArgumentGraphVisitor for_right_value(owner(), for_left_value.temp_index()); |
| 255 node->right()->Visit(&for_right_value); | 292 node->right()->Visit(&for_right_value); |
| 256 Append(for_right_value); | 293 Append(for_right_value); |
| 257 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2); | 294 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2); |
| 258 arguments->Add(for_left_value.value()); | 295 arguments->Add(for_left_value.value()); |
| 259 arguments->Add(for_right_value.value()); | 296 arguments->Add(for_right_value.value()); |
| 260 const String& name = String::ZoneHandle(String::NewSymbol(node->Name())); | 297 const String& name = String::ZoneHandle(String::NewSymbol(node->Name())); |
| 261 InstanceCallComp* call = | 298 InstanceCallComp* call = new InstanceCallComp(node->id(), |
| 262 new InstanceCallComp(node->id(), node->token_index(), name, | 299 node->token_index(), |
| 263 arguments, Array::ZoneHandle(), 2); | 300 owner()->try_index(), |
| 301 name, | |
| 302 arguments, | |
| 303 Array::ZoneHandle(), | |
| 304 2); | |
| 264 ReturnComputation(call); | 305 ReturnComputation(call); |
| 265 } | 306 } |
| 266 | 307 |
| 267 | 308 |
| 268 // Special handling for AND/OR. | 309 // Special handling for AND/OR. |
| 269 void ValueGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) { | 310 void ValueGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) { |
| 270 // Operators "&&" and "||" cannot be overloaded therefore do not call | 311 // Operators "&&" and "||" cannot be overloaded therefore do not call |
| 271 // operator. | 312 // operator. |
| 272 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { | 313 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { |
| 273 // Implement short-circuit logic: do not evaluate right if evaluation | 314 // Implement short-circuit logic: do not evaluate right if evaluation |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 370 CompiletimeStringInterpolation(interpol_func, literals); | 411 CompiletimeStringInterpolation(interpol_func, literals); |
| 371 return; | 412 return; |
| 372 } | 413 } |
| 373 // Runtime string interpolation. | 414 // Runtime string interpolation. |
| 374 ZoneGrowableArray<Value*>* values = new ZoneGrowableArray<Value*>(); | 415 ZoneGrowableArray<Value*>* values = new ZoneGrowableArray<Value*>(); |
| 375 ArgumentListNode* interpol_arg = new ArgumentListNode(node->token_index()); | 416 ArgumentListNode* interpol_arg = new ArgumentListNode(node->token_index()); |
| 376 interpol_arg->Add(node->values()); | 417 interpol_arg->Add(node->values()); |
| 377 TranslateArgumentList(*interpol_arg, temp_index(), values); | 418 TranslateArgumentList(*interpol_arg, temp_index(), values); |
| 378 StaticCallComp* call = | 419 StaticCallComp* call = |
| 379 new StaticCallComp(node->token_index(), | 420 new StaticCallComp(node->token_index(), |
| 421 owner()->try_index(), | |
| 380 interpol_func, | 422 interpol_func, |
| 381 interpol_arg->names(), | 423 interpol_arg->names(), |
| 382 values); | 424 values); |
| 383 ReturnComputation(call); | 425 ReturnComputation(call); |
| 384 } | 426 } |
| 385 | 427 |
| 386 | 428 |
| 387 // <Expression> :: Comparison { kind: Token::Kind | 429 // <Expression> :: Comparison { kind: Token::Kind |
| 388 // left: <Expression> | 430 // left: <Expression> |
| 389 // right: <Expression> } | 431 // right: <Expression> } |
| 390 void EffectGraphVisitor::VisitComparisonNode(ComparisonNode* node) { | 432 void EffectGraphVisitor::VisitComparisonNode(ComparisonNode* node) { |
| 391 if (Token::IsInstanceofOperator(node->kind())) { | 433 if (Token::IsInstanceofOperator(node->kind())) { |
| 392 ArgumentGraphVisitor for_left_value(owner(), temp_index()); | 434 ArgumentGraphVisitor for_left_value(owner(), temp_index()); |
| 393 node->left()->Visit(&for_left_value); | 435 node->left()->Visit(&for_left_value); |
| 394 Append(for_left_value); | 436 Append(for_left_value); |
| 395 InstanceOfComp* instance_of = new InstanceOfComp( | 437 InstanceOfComp* instance_of = new InstanceOfComp( |
| 396 node->id(), | 438 node->id(), |
| 397 node->token_index(), | 439 node->token_index(), |
| 440 owner()->try_index(), | |
| 398 for_left_value.value(), | 441 for_left_value.value(), |
| 399 node->right()->AsTypeNode()->type(), | 442 node->right()->AsTypeNode()->type(), |
| 400 (node->kind() == Token::kISNOT)); | 443 (node->kind() == Token::kISNOT)); |
| 401 ReturnComputation(instance_of); | 444 ReturnComputation(instance_of); |
| 402 return; | 445 return; |
| 403 } | 446 } |
| 404 if ((node->kind() == Token::kEQ_STRICT) || | 447 if ((node->kind() == Token::kEQ_STRICT) || |
| 405 (node->kind() == Token::kNE_STRICT)) { | 448 (node->kind() == Token::kNE_STRICT)) { |
| 406 ValueGraphVisitor for_left_value(owner(), temp_index()); | 449 ValueGraphVisitor for_left_value(owner(), temp_index()); |
| 407 node->left()->Visit(&for_left_value); | 450 node->left()->Visit(&for_left_value); |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 421 ArgumentGraphVisitor for_right_value(owner(), for_left_value.temp_index()); | 464 ArgumentGraphVisitor for_right_value(owner(), for_left_value.temp_index()); |
| 422 node->right()->Visit(&for_right_value); | 465 node->right()->Visit(&for_right_value); |
| 423 Append(for_right_value); | 466 Append(for_right_value); |
| 424 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2); | 467 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2); |
| 425 arguments->Add(for_left_value.value()); | 468 arguments->Add(for_left_value.value()); |
| 426 arguments->Add(for_right_value.value()); | 469 arguments->Add(for_right_value.value()); |
| 427 // 'kNE' is not overloadable, must implement as kEQ and negation. | 470 // 'kNE' is not overloadable, must implement as kEQ and negation. |
| 428 // Boolean negation '!' cannot be overloaded neither. | 471 // Boolean negation '!' cannot be overloaded neither. |
| 429 if (node->kind() == Token::kNE) { | 472 if (node->kind() == Token::kNE) { |
| 430 const String& name = String::ZoneHandle(String::NewSymbol("==")); | 473 const String& name = String::ZoneHandle(String::NewSymbol("==")); |
| 431 InstanceCallComp* call_equal = | 474 InstanceCallComp* call_equal = new InstanceCallComp( |
| 432 new InstanceCallComp(node->id(), node->token_index(), name, | 475 node->id(), node->token_index(), owner()->try_index(), name, |
| 433 arguments, Array::ZoneHandle(), 2); | 476 arguments, Array::ZoneHandle(), 2); |
| 434 AddInstruction(new BindInstr(temp_index(), call_equal)); | 477 AddInstruction(new BindInstr(temp_index(), call_equal)); |
| 435 Value* eq_result = new TempVal(temp_index()); | 478 Value* eq_result = new TempVal(temp_index()); |
| 436 if (FLAG_enable_type_checks) { | 479 if (FLAG_enable_type_checks) { |
| 437 Bailout("GenerateConditionTypeCheck in kNE"); | 480 Bailout("GenerateConditionTypeCheck in kNE"); |
| 438 } | 481 } |
| 439 BooleanNegateComp* negate = new BooleanNegateComp(eq_result); | 482 BooleanNegateComp* negate = new BooleanNegateComp(eq_result); |
| 440 ReturnComputation(negate); | 483 ReturnComputation(negate); |
| 441 } else { | 484 } else { |
| 442 const String& name = String::ZoneHandle(String::NewSymbol(node->Name())); | 485 const String& name = String::ZoneHandle(String::NewSymbol(node->Name())); |
| 443 InstanceCallComp* call = | 486 InstanceCallComp* call = new InstanceCallComp( |
| 444 new InstanceCallComp(node->id(), node->token_index(), name, | 487 node->id(), node->token_index(), owner()->try_index(), name, |
| 445 arguments, Array::ZoneHandle(), 2); | 488 arguments, Array::ZoneHandle(), 2); |
| 446 ReturnComputation(call); | 489 ReturnComputation(call); |
| 447 } | 490 } |
| 448 } | 491 } |
| 449 | 492 |
| 450 | 493 |
| 451 void EffectGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) { | 494 void EffectGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) { |
| 452 // "!" cannot be overloaded, therefore do not call operator. | 495 // "!" cannot be overloaded, therefore do not call operator. |
| 453 if (node->kind() == Token::kNOT) { | 496 if (node->kind() == Token::kNOT) { |
| 454 ValueGraphVisitor for_value(owner(), temp_index()); | 497 ValueGraphVisitor for_value(owner(), temp_index()); |
| 455 node->operand()->Visit(&for_value); | 498 node->operand()->Visit(&for_value); |
| 456 Append(for_value); | 499 Append(for_value); |
| 457 if (FLAG_enable_type_checks) { | 500 if (FLAG_enable_type_checks) { |
| 458 Bailout("GenerateConditionTypeCheck in kNOT"); | 501 Bailout("GenerateConditionTypeCheck in kNOT"); |
| 459 } | 502 } |
| 460 BooleanNegateComp* negate = new BooleanNegateComp(for_value.value()); | 503 BooleanNegateComp* negate = new BooleanNegateComp(for_value.value()); |
| 461 ReturnComputation(negate); | 504 ReturnComputation(negate); |
| 462 return; | 505 return; |
| 463 } | 506 } |
| 464 ArgumentGraphVisitor for_value(owner(), temp_index()); | 507 ArgumentGraphVisitor for_value(owner(), temp_index()); |
| 465 node->operand()->Visit(&for_value); | 508 node->operand()->Visit(&for_value); |
| 466 Append(for_value); | 509 Append(for_value); |
| 467 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(1); | 510 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(1); |
| 468 arguments->Add(for_value.value()); | 511 arguments->Add(for_value.value()); |
| 469 const String& name = | 512 const String& name = |
| 470 String::ZoneHandle(String::NewSymbol((node->kind() == Token::kSUB) | 513 String::ZoneHandle(String::NewSymbol((node->kind() == Token::kSUB) |
| 471 ? Token::Str(Token::kNEGATE) | 514 ? Token::Str(Token::kNEGATE) |
| 472 : node->Name())); | 515 : node->Name())); |
| 473 InstanceCallComp* call = | 516 InstanceCallComp* call = new InstanceCallComp( |
| 474 new InstanceCallComp(node->id(), node->token_index(), name, | 517 node->id(), node->token_index(), owner()->try_index(), name, |
| 475 arguments, Array::ZoneHandle(), 1); | 518 arguments, Array::ZoneHandle(), 1); |
| 476 ReturnComputation(call); | 519 ReturnComputation(call); |
| 477 } | 520 } |
| 478 | 521 |
| 479 | 522 |
| 480 void EffectGraphVisitor::VisitIncrOpLocalNode(IncrOpLocalNode* node) { | 523 void EffectGraphVisitor::VisitIncrOpLocalNode(IncrOpLocalNode* node) { |
| 481 ASSERT((node->kind() == Token::kINCR) || (node->kind() == Token::kDECR)); | 524 ASSERT((node->kind() == Token::kINCR) || (node->kind() == Token::kDECR)); |
| 482 // In an effect context, treat postincrement as if it were preincrement | 525 // In an effect context, treat postincrement as if it were preincrement |
| 483 // because its value is not needed. | 526 // because its value is not needed. |
| 484 | 527 |
| 485 // 1. Load the value. | 528 // 1. Load the value. |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 534 const int next_index = for_receiver.temp_index(); | 577 const int next_index = for_receiver.temp_index(); |
| 535 ASSERT(next_index == start_index + 1); | 578 ASSERT(next_index == start_index + 1); |
| 536 AddInstruction(new PickTempInstr(next_index, start_index)); | 579 AddInstruction(new PickTempInstr(next_index, start_index)); |
| 537 | 580 |
| 538 // Load the value. | 581 // Load the value. |
| 539 // t_n+1 <- InstanceCall(get:name, t_n+1) | 582 // t_n+1 <- InstanceCall(get:name, t_n+1) |
| 540 const String& getter_name = | 583 const String& getter_name = |
| 541 String::ZoneHandle(Field::GetterSymbol(node->field_name())); | 584 String::ZoneHandle(Field::GetterSymbol(node->field_name())); |
| 542 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(1); | 585 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(1); |
| 543 arguments->Add(new TempVal(next_index)); | 586 arguments->Add(new TempVal(next_index)); |
| 544 InstanceCallComp* load = | 587 InstanceCallComp* load = new InstanceCallComp( |
| 545 new InstanceCallComp(node->getter_id(), node->token_index(), getter_name, | 588 node->getter_id(), node->token_index(), owner()->try_index(), |
| 546 arguments, Array::ZoneHandle(), 1); | 589 getter_name, arguments, Array::ZoneHandle(), 1); |
| 547 AddInstruction(new BindInstr(next_index, load)); | 590 AddInstruction(new BindInstr(next_index, load)); |
| 548 | 591 |
| 549 return next_index; | 592 return next_index; |
| 550 } | 593 } |
| 551 | 594 |
| 552 | 595 |
| 553 void EffectGraphVisitor::BuildIncrOpIncrement(Token::Kind kind, | 596 void EffectGraphVisitor::BuildIncrOpIncrement(Token::Kind kind, |
| 554 intptr_t node_id, | 597 intptr_t node_id, |
| 555 intptr_t token_index, | 598 intptr_t token_index, |
| 556 intptr_t start_index) { | 599 intptr_t start_index) { |
| 557 ASSERT((kind == Token::kINCR) || (kind == Token::kDECR)); | 600 ASSERT((kind == Token::kINCR) || (kind == Token::kDECR)); |
| 558 // Assumed that t_n-1 (where n is start_index) is the field value. | 601 // Assumed that t_n-1 (where n is start_index) is the field value. |
| 559 // t_n <- #1 | 602 // t_n <- #1 |
| 560 // t_n-1 <- InstanceCall(op, t_n-1, t_n) | 603 // t_n-1 <- InstanceCall(op, t_n-1, t_n) |
| 561 const Smi& one = Smi::ZoneHandle(Smi::New(1)); | 604 const Smi& one = Smi::ZoneHandle(Smi::New(1)); |
| 562 AddInstruction(new BindInstr(start_index, new ConstantVal(one))); | 605 AddInstruction(new BindInstr(start_index, new ConstantVal(one))); |
| 563 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2); | 606 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2); |
| 564 arguments->Add(new TempVal(start_index - 1)); | 607 arguments->Add(new TempVal(start_index - 1)); |
| 565 arguments->Add(new TempVal(start_index)); | 608 arguments->Add(new TempVal(start_index)); |
| 566 const String& op_name = | 609 const String& op_name = |
| 567 String::ZoneHandle(String::NewSymbol((kind == Token::kINCR) ? "+" : "-")); | 610 String::ZoneHandle(String::NewSymbol((kind == Token::kINCR) ? "+" : "-")); |
| 568 InstanceCallComp* add = | 611 InstanceCallComp* add = new InstanceCallComp( |
| 569 new InstanceCallComp(node_id, token_index, op_name, | 612 node_id, token_index, owner()->try_index(), op_name, |
| 570 arguments, Array::ZoneHandle(), 2); | 613 arguments, Array::ZoneHandle(), 2); |
| 571 AddInstruction(new BindInstr(start_index - 1, add)); | 614 AddInstruction(new BindInstr(start_index - 1, add)); |
| 572 } | 615 } |
| 573 | 616 |
| 574 | 617 |
| 575 void EffectGraphVisitor::VisitIncrOpInstanceFieldNode( | 618 void EffectGraphVisitor::VisitIncrOpInstanceFieldNode( |
| 576 IncrOpInstanceFieldNode* node) { | 619 IncrOpInstanceFieldNode* node) { |
| 577 ASSERT((node->kind() == Token::kINCR) || (node->kind() == Token::kDECR)); | 620 ASSERT((node->kind() == Token::kINCR) || (node->kind() == Token::kDECR)); |
| 578 // In an effect context, treat postincrement as if it were preincrement | 621 // In an effect context, treat postincrement as if it were preincrement |
| 579 // because its value is not needed. | 622 // because its value is not needed. |
| 580 | 623 |
| 581 // 1. Load the value. | 624 // 1. Load the value. |
| 582 const int value_index = BuildIncrOpFieldLoad(node, temp_index()); | 625 const int value_index = BuildIncrOpFieldLoad(node, temp_index()); |
| 583 // 2. Increment. | 626 // 2. Increment. |
| 584 BuildIncrOpIncrement(node->kind(), node->operator_id(), node->token_index(), | 627 BuildIncrOpIncrement(node->kind(), node->operator_id(), node->token_index(), |
| 585 value_index + 1); | 628 value_index + 1); |
| 586 // 3. Perform the store, returning the stored value. | 629 // 3. Perform the store, returning the stored value. |
| 587 InstanceSetterComp* store = | 630 InstanceSetterComp* store = |
| 588 new InstanceSetterComp(node->setter_id(), node->token_index(), | 631 new InstanceSetterComp(node->setter_id(), |
| 632 node->token_index(), | |
| 633 owner()->try_index(), | |
| 589 node->field_name(), | 634 node->field_name(), |
| 590 new TempVal(value_index - 1), | 635 new TempVal(value_index - 1), |
| 591 new TempVal(value_index)); | 636 new TempVal(value_index)); |
| 592 ReturnComputation(store); | 637 ReturnComputation(store); |
| 593 } | 638 } |
| 594 | 639 |
| 595 | 640 |
| 596 void ValueGraphVisitor::VisitIncrOpInstanceFieldNode( | 641 void ValueGraphVisitor::VisitIncrOpInstanceFieldNode( |
| 597 IncrOpInstanceFieldNode* node) { | 642 IncrOpInstanceFieldNode* node) { |
| 598 ASSERT((node->kind() == Token::kINCR) || (node->kind() == Token::kDECR)); | 643 ASSERT((node->kind() == Token::kINCR) || (node->kind() == Token::kDECR)); |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 613 AddInstruction(new TuckTempInstr(temp_index(), value_index)); | 658 AddInstruction(new TuckTempInstr(temp_index(), value_index)); |
| 614 // 4. Increment. | 659 // 4. Increment. |
| 615 BuildIncrOpIncrement(node->kind(), node->operator_id(), node->token_index(), | 660 BuildIncrOpIncrement(node->kind(), node->operator_id(), node->token_index(), |
| 616 value_index + 1); | 661 value_index + 1); |
| 617 // 5. Perform the store and return the original value. | 662 // 5. Perform the store and return the original value. |
| 618 const String& setter_name = | 663 const String& setter_name = |
| 619 String::ZoneHandle(Field::SetterSymbol(node->field_name())); | 664 String::ZoneHandle(Field::SetterSymbol(node->field_name())); |
| 620 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2); | 665 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2); |
| 621 arguments->Add(new TempVal(value_index - 1)); | 666 arguments->Add(new TempVal(value_index - 1)); |
| 622 arguments->Add(new TempVal(value_index)); | 667 arguments->Add(new TempVal(value_index)); |
| 623 InstanceCallComp* store = | 668 InstanceCallComp* store = new InstanceCallComp( |
| 624 new InstanceCallComp(node->setter_id(), node->token_index(), | 669 node->setter_id(), node->token_index(), owner()->try_index(), |
| 625 setter_name, arguments, Array::ZoneHandle(), 1); | 670 setter_name, arguments, Array::ZoneHandle(), 1); |
| 626 AddInstruction(new DoInstr(store)); | 671 AddInstruction(new DoInstr(store)); |
| 627 ReturnValue(new TempVal(AllocateTempIndex())); | 672 ReturnValue(new TempVal(AllocateTempIndex())); |
| 628 } | 673 } |
| 629 | 674 |
| 630 | 675 |
| 631 int EffectGraphVisitor::BuildIncrOpIndexedLoad(IncrOpIndexedNode* node, | 676 int EffectGraphVisitor::BuildIncrOpIndexedLoad(IncrOpIndexedNode* node, |
| 632 intptr_t start_index) { | 677 intptr_t start_index) { |
| 633 // Evaluate the receiver and index. | 678 // Evaluate the receiver and index. |
| 634 // t_n <- ... receiver ... | 679 // t_n <- ... receiver ... |
| 635 // t_n+1 <- ... index ... | 680 // t_n+1 <- ... index ... |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 647 // t_n+3 <- Pick(t_n+1) | 692 // t_n+3 <- Pick(t_n+1) |
| 648 // t_n+2 <- InstanceCall([], t_n+2, t_n+3) | 693 // t_n+2 <- InstanceCall([], t_n+2, t_n+3) |
| 649 const int next_index = start_index + 2; | 694 const int next_index = start_index + 2; |
| 650 AddInstruction(new PickTempInstr(next_index, start_index)); | 695 AddInstruction(new PickTempInstr(next_index, start_index)); |
| 651 AddInstruction(new PickTempInstr(next_index + 1, start_index + 1)); | 696 AddInstruction(new PickTempInstr(next_index + 1, start_index + 1)); |
| 652 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2); | 697 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2); |
| 653 arguments->Add(new TempVal(next_index)); | 698 arguments->Add(new TempVal(next_index)); |
| 654 arguments->Add(new TempVal(next_index + 1)); | 699 arguments->Add(new TempVal(next_index + 1)); |
| 655 const String& load_name = | 700 const String& load_name = |
| 656 String::ZoneHandle(String::NewSymbol(Token::Str(Token::kINDEX))); | 701 String::ZoneHandle(String::NewSymbol(Token::Str(Token::kINDEX))); |
| 657 InstanceCallComp* load = | 702 InstanceCallComp* load = new InstanceCallComp( |
| 658 new InstanceCallComp(node->load_id(), node->token_index(), load_name, | 703 node->load_id(), node->token_index(), owner()->try_index(), |
| 659 arguments, Array::ZoneHandle(), 1); | 704 load_name, arguments, Array::ZoneHandle(), 1); |
| 660 AddInstruction(new BindInstr(next_index, load)); | 705 AddInstruction(new BindInstr(next_index, load)); |
| 661 return next_index; | 706 return next_index; |
| 662 } | 707 } |
| 663 | 708 |
| 664 | 709 |
| 665 void EffectGraphVisitor::VisitIncrOpIndexedNode(IncrOpIndexedNode* node) { | 710 void EffectGraphVisitor::VisitIncrOpIndexedNode(IncrOpIndexedNode* node) { |
| 666 ASSERT((node->kind() == Token::kINCR) || (node->kind() == Token::kDECR)); | 711 ASSERT((node->kind() == Token::kINCR) || (node->kind() == Token::kDECR)); |
| 667 // In an effect context, treat postincrement as if it were preincrement | 712 // In an effect context, treat postincrement as if it were preincrement |
| 668 // because its value is not needed. | 713 // because its value is not needed. |
| 669 | 714 |
| 670 // 1. Load the value. | 715 // 1. Load the value. |
| 671 const int value_index = BuildIncrOpIndexedLoad(node, temp_index()); | 716 const int value_index = BuildIncrOpIndexedLoad(node, temp_index()); |
| 672 // 2. Increment. | 717 // 2. Increment. |
| 673 BuildIncrOpIncrement(node->kind(), node->operator_id(), node->token_index(), | 718 BuildIncrOpIncrement(node->kind(), node->operator_id(), node->token_index(), |
| 674 value_index + 1); | 719 value_index + 1); |
| 675 // 3. Perform the store, returning the stored value. | 720 // 3. Perform the store, returning the stored value. |
| 676 StoreIndexedComp* store = new StoreIndexedComp(node->store_id(), | 721 StoreIndexedComp* store = new StoreIndexedComp(node->store_id(), |
| 677 node->token_index(), | 722 node->token_index(), |
| 723 owner()->try_index(), | |
| 678 new TempVal(value_index - 2), | 724 new TempVal(value_index - 2), |
| 679 new TempVal(value_index - 1), | 725 new TempVal(value_index - 1), |
| 680 new TempVal(value_index)); | 726 new TempVal(value_index)); |
| 681 ReturnComputation(store); | 727 ReturnComputation(store); |
| 682 } | 728 } |
| 683 | 729 |
| 684 | 730 |
| 685 void ValueGraphVisitor::VisitIncrOpIndexedNode(IncrOpIndexedNode* node) { | 731 void ValueGraphVisitor::VisitIncrOpIndexedNode(IncrOpIndexedNode* node) { |
| 686 ASSERT((node->kind() == Token::kINCR) || (node->kind() == Token::kDECR)); | 732 ASSERT((node->kind() == Token::kINCR) || (node->kind() == Token::kDECR)); |
| 687 if (node->prefix()) { | 733 if (node->prefix()) { |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 702 // 4. Increment. | 748 // 4. Increment. |
| 703 BuildIncrOpIncrement(node->kind(), node->operator_id(), node->token_index(), | 749 BuildIncrOpIncrement(node->kind(), node->operator_id(), node->token_index(), |
| 704 value_index + 1); | 750 value_index + 1); |
| 705 // 5. Perform the store and return the original value. | 751 // 5. Perform the store and return the original value. |
| 706 const String& store_name = | 752 const String& store_name = |
| 707 String::ZoneHandle(String::NewSymbol(Token::Str(Token::kASSIGN_INDEX))); | 753 String::ZoneHandle(String::NewSymbol(Token::Str(Token::kASSIGN_INDEX))); |
| 708 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(3); | 754 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(3); |
| 709 arguments->Add(new TempVal(value_index - 2)); | 755 arguments->Add(new TempVal(value_index - 2)); |
| 710 arguments->Add(new TempVal(value_index - 1)); | 756 arguments->Add(new TempVal(value_index - 1)); |
| 711 arguments->Add(new TempVal(value_index)); | 757 arguments->Add(new TempVal(value_index)); |
| 712 InstanceCallComp* store = | 758 InstanceCallComp* store = new InstanceCallComp( |
| 713 new InstanceCallComp(node->store_id(), node->token_index(), store_name, | 759 node->store_id(), node->token_index(), owner()->try_index(), |
| 714 arguments, Array::ZoneHandle(), 1); | 760 store_name, arguments, Array::ZoneHandle(), 1); |
| 715 AddInstruction(new DoInstr(store)); | 761 AddInstruction(new DoInstr(store)); |
| 716 ReturnValue(new TempVal(AllocateTempIndex())); | 762 ReturnValue(new TempVal(AllocateTempIndex())); |
| 717 } | 763 } |
| 718 | 764 |
| 719 | 765 |
| 720 void EffectGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) { | 766 void EffectGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) { |
| 721 TestGraphVisitor for_test(owner(), temp_index()); | 767 TestGraphVisitor for_test(owner(), temp_index()); |
| 722 node->condition()->Visit(&for_test); | 768 node->condition()->Visit(&for_test); |
| 723 | 769 |
| 724 // Translate the subexpressions for their effects. | 770 // Translate the subexpressions for their effects. |
| (...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1149 ZoneGrowableArray<Value*>* values = | 1195 ZoneGrowableArray<Value*>* values = |
| 1150 new ZoneGrowableArray<Value*>(node->length()); | 1196 new ZoneGrowableArray<Value*>(node->length()); |
| 1151 int index = temp_index(); | 1197 int index = temp_index(); |
| 1152 for (int i = 0; i < node->length(); ++i) { | 1198 for (int i = 0; i < node->length(); ++i) { |
| 1153 ValueGraphVisitor for_value(owner(), index); | 1199 ValueGraphVisitor for_value(owner(), index); |
| 1154 node->ElementAt(i)->Visit(&for_value); | 1200 node->ElementAt(i)->Visit(&for_value); |
| 1155 Append(for_value); | 1201 Append(for_value); |
| 1156 values->Add(for_value.value()); | 1202 values->Add(for_value.value()); |
| 1157 index = for_value.temp_index(); | 1203 index = for_value.temp_index(); |
| 1158 } | 1204 } |
| 1159 CreateArrayComp* create = new CreateArrayComp(node, values); | 1205 CreateArrayComp* create = new CreateArrayComp(node, |
| 1206 owner()->try_index(), | |
| 1207 values); | |
| 1160 ReturnComputation(create); | 1208 ReturnComputation(create); |
| 1161 } | 1209 } |
| 1162 | 1210 |
| 1163 | 1211 |
| 1164 void EffectGraphVisitor::VisitClosureNode(ClosureNode* node) { | 1212 void EffectGraphVisitor::VisitClosureNode(ClosureNode* node) { |
| 1165 const Function& function = node->function(); | 1213 const Function& function = node->function(); |
| 1166 | 1214 |
| 1167 int next_index = temp_index(); | 1215 int next_index = temp_index(); |
| 1168 if (function.IsNonImplicitClosureFunction()) { | 1216 if (function.IsNonImplicitClosureFunction()) { |
| 1169 const ContextScope& context_scope = ContextScope::ZoneHandle( | 1217 const ContextScope& context_scope = ContextScope::ZoneHandle( |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 1187 const Class& cls = Class::Handle(function.signature_class()); | 1235 const Class& cls = Class::Handle(function.signature_class()); |
| 1188 ASSERT(!cls.IsNull()); | 1236 ASSERT(!cls.IsNull()); |
| 1189 const bool requires_type_arguments = cls.HasTypeArguments(); | 1237 const bool requires_type_arguments = cls.HasTypeArguments(); |
| 1190 Value* type_arguments = NULL; | 1238 Value* type_arguments = NULL; |
| 1191 if (requires_type_arguments) { | 1239 if (requires_type_arguments) { |
| 1192 ASSERT(!function.IsImplicitStaticClosureFunction()); | 1240 ASSERT(!function.IsImplicitStaticClosureFunction()); |
| 1193 type_arguments = | 1241 type_arguments = |
| 1194 BuildInstantiatorTypeArguments(node->token_index(), temp_index()); | 1242 BuildInstantiatorTypeArguments(node->token_index(), temp_index()); |
| 1195 } | 1243 } |
| 1196 | 1244 |
| 1197 CreateClosureComp* create = new CreateClosureComp(node, type_arguments); | 1245 CreateClosureComp* create = |
| 1246 new CreateClosureComp(node, owner()->try_index(), type_arguments); | |
| 1198 ReturnComputation(create); | 1247 ReturnComputation(create); |
| 1199 } | 1248 } |
| 1200 | 1249 |
| 1201 | 1250 |
| 1202 void EffectGraphVisitor::TranslateArgumentList( | 1251 void EffectGraphVisitor::TranslateArgumentList( |
| 1203 const ArgumentListNode& node, | 1252 const ArgumentListNode& node, |
| 1204 intptr_t next_temp_index, | 1253 intptr_t next_temp_index, |
| 1205 ZoneGrowableArray<Value*>* values) { | 1254 ZoneGrowableArray<Value*>* values) { |
| 1206 for (intptr_t i = 0; i < node.length(); ++i) { | 1255 for (intptr_t i = 0; i < node.length(); ++i) { |
| 1207 ArgumentGraphVisitor for_argument(owner(), next_temp_index); | 1256 ArgumentGraphVisitor for_argument(owner(), next_temp_index); |
| 1208 node.NodeAt(i)->Visit(&for_argument); | 1257 node.NodeAt(i)->Visit(&for_argument); |
| 1209 Append(for_argument); | 1258 Append(for_argument); |
| 1210 next_temp_index = for_argument.temp_index(); | 1259 next_temp_index = for_argument.temp_index(); |
| 1211 values->Add(for_argument.value()); | 1260 values->Add(for_argument.value()); |
| 1212 } | 1261 } |
| 1213 } | 1262 } |
| 1214 | 1263 |
| 1215 void EffectGraphVisitor::VisitInstanceCallNode(InstanceCallNode* node) { | 1264 void EffectGraphVisitor::VisitInstanceCallNode(InstanceCallNode* node) { |
| 1216 ArgumentListNode* arguments = node->arguments(); | 1265 ArgumentListNode* arguments = node->arguments(); |
| 1217 int length = arguments->length(); | 1266 int length = arguments->length(); |
| 1218 ZoneGrowableArray<Value*>* values = new ZoneGrowableArray<Value*>(length + 1); | 1267 ZoneGrowableArray<Value*>* values = new ZoneGrowableArray<Value*>(length + 1); |
| 1219 | 1268 |
| 1220 ArgumentGraphVisitor for_receiver(owner(), temp_index()); | 1269 ArgumentGraphVisitor for_receiver(owner(), temp_index()); |
| 1221 node->receiver()->Visit(&for_receiver); | 1270 node->receiver()->Visit(&for_receiver); |
| 1222 Append(for_receiver); | 1271 Append(for_receiver); |
| 1223 values->Add(for_receiver.value()); | 1272 values->Add(for_receiver.value()); |
| 1224 | 1273 |
| 1225 TranslateArgumentList(*arguments, for_receiver.temp_index(), values); | 1274 TranslateArgumentList(*arguments, for_receiver.temp_index(), values); |
| 1226 InstanceCallComp* call = | 1275 InstanceCallComp* call = new InstanceCallComp( |
| 1227 new InstanceCallComp(node->id(), node->token_index(), | 1276 node->id(), node->token_index(), owner()->try_index(), |
| 1228 node->function_name(), values, | 1277 node->function_name(), values, |
| 1229 arguments->names(), 1); | 1278 arguments->names(), 1); |
| 1230 ReturnComputation(call); | 1279 ReturnComputation(call); |
| 1231 } | 1280 } |
| 1232 | 1281 |
| 1233 | 1282 |
| 1234 // <Expression> ::= StaticCall { function: Function | 1283 // <Expression> ::= StaticCall { function: Function |
| 1235 // arguments: <ArgumentList> } | 1284 // arguments: <ArgumentList> } |
| 1236 void EffectGraphVisitor::VisitStaticCallNode(StaticCallNode* node) { | 1285 void EffectGraphVisitor::VisitStaticCallNode(StaticCallNode* node) { |
| 1237 int length = node->arguments()->length(); | 1286 int length = node->arguments()->length(); |
| 1238 ZoneGrowableArray<Value*>* values = new ZoneGrowableArray<Value*>(length); | 1287 ZoneGrowableArray<Value*>* values = new ZoneGrowableArray<Value*>(length); |
| 1239 TranslateArgumentList(*node->arguments(), temp_index(), values); | 1288 TranslateArgumentList(*node->arguments(), temp_index(), values); |
| 1240 StaticCallComp* call = | 1289 StaticCallComp* call = |
| 1241 new StaticCallComp(node->token_index(), | 1290 new StaticCallComp(node->token_index(), |
| 1291 owner()->try_index(), | |
| 1242 node->function(), | 1292 node->function(), |
| 1243 node->arguments()->names(), | 1293 node->arguments()->names(), |
| 1244 values); | 1294 values); |
| 1245 ReturnComputation(call); | 1295 ReturnComputation(call); |
| 1246 } | 1296 } |
| 1247 | 1297 |
| 1248 | 1298 |
| 1249 void EffectGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { | 1299 void EffectGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { |
| 1250 // Context is saved around the call, it's treated as an extra operand | 1300 // Context is saved around the call, it's treated as an extra operand |
| 1251 // consumed by the call (but not an argument). | 1301 // consumed by the call (but not an argument). |
| 1252 AddInstruction(new BindInstr(temp_index(), new CurrentContextComp())); | 1302 AddInstruction(new BindInstr(temp_index(), new CurrentContextComp())); |
| 1253 | 1303 |
| 1254 ArgumentGraphVisitor for_closure(owner(), temp_index() + 1); | 1304 ArgumentGraphVisitor for_closure(owner(), temp_index() + 1); |
| 1255 node->closure()->Visit(&for_closure); | 1305 node->closure()->Visit(&for_closure); |
| 1256 Append(for_closure); | 1306 Append(for_closure); |
| 1257 | 1307 |
| 1258 ZoneGrowableArray<Value*>* arguments = | 1308 ZoneGrowableArray<Value*>* arguments = |
| 1259 new ZoneGrowableArray<Value*>(node->arguments()->length()); | 1309 new ZoneGrowableArray<Value*>(node->arguments()->length()); |
| 1260 arguments->Add(for_closure.value()); | 1310 arguments->Add(for_closure.value()); |
| 1261 TranslateArgumentList(*node->arguments(), temp_index() + 2, arguments); | 1311 TranslateArgumentList(*node->arguments(), temp_index() + 2, arguments); |
| 1262 // First operand is the saved context, consumed by the call. | 1312 // First operand is the saved context, consumed by the call. |
| 1263 ClosureCallComp* call = | 1313 ClosureCallComp* call = new ClosureCallComp(node, |
| 1264 new ClosureCallComp(node, new TempVal(temp_index()), arguments); | 1314 owner()->try_index(), |
| 1315 new TempVal(temp_index()), | |
| 1316 arguments); | |
| 1265 ReturnComputation(call); | 1317 ReturnComputation(call); |
| 1266 } | 1318 } |
| 1267 | 1319 |
| 1268 | 1320 |
| 1269 void EffectGraphVisitor::VisitCloneContextNode(CloneContextNode* node) { | 1321 void EffectGraphVisitor::VisitCloneContextNode(CloneContextNode* node) { |
| 1270 AddInstruction(new BindInstr(temp_index(), new CurrentContextComp())); | 1322 AddInstruction(new BindInstr(temp_index(), new CurrentContextComp())); |
| 1271 TempVal* ctx = new TempVal(temp_index()); | 1323 TempVal* ctx = new TempVal(temp_index()); |
| 1272 AddInstruction(new BindInstr(temp_index(), | 1324 AddInstruction(new BindInstr(temp_index(), |
| 1273 new CloneContextComp(node->id(), node->token_index(), ctx))); | 1325 new CloneContextComp(node->id(), |
| 1326 node->token_index(), | |
| 1327 owner()->try_index(), | |
| 1328 ctx))); | |
| 1274 TempVal* cloned_ctx = new TempVal(temp_index()); | 1329 TempVal* cloned_ctx = new TempVal(temp_index()); |
| 1275 ReturnComputation(new StoreContextComp(cloned_ctx)); | 1330 ReturnComputation(new StoreContextComp(cloned_ctx)); |
| 1276 } | 1331 } |
| 1277 | 1332 |
| 1278 | 1333 |
| 1279 TempVal* EffectGraphVisitor::BuildObjectAllocation(ConstructorCallNode* node, | 1334 TempVal* EffectGraphVisitor::BuildObjectAllocation(ConstructorCallNode* node, |
| 1280 int start_index) { | 1335 int start_index) { |
| 1281 const Class& cls = Class::ZoneHandle(node->constructor().owner()); | 1336 const Class& cls = Class::ZoneHandle(node->constructor().owner()); |
| 1282 const bool requires_type_arguments = cls.HasTypeArguments(); | 1337 const bool requires_type_arguments = cls.HasTypeArguments(); |
| 1283 | 1338 |
| 1284 ZoneGrowableArray<Value*>* allocate_arguments = | 1339 ZoneGrowableArray<Value*>* allocate_arguments = |
| 1285 new ZoneGrowableArray<Value*>(); | 1340 new ZoneGrowableArray<Value*>(); |
| 1286 if (requires_type_arguments) { | 1341 if (requires_type_arguments) { |
| 1287 BuildConstructorTypeArguments(node, start_index, allocate_arguments); | 1342 BuildConstructorTypeArguments(node, start_index, allocate_arguments); |
| 1288 } | 1343 } |
| 1289 AllocateObjectComp* alloc_comp = | 1344 AllocateObjectComp* alloc_comp = |
| 1290 new AllocateObjectComp(node, allocate_arguments); | 1345 new AllocateObjectComp(node, |
| 1346 owner()->try_index(), | |
| 1347 allocate_arguments); | |
| 1291 AddInstruction(new BindInstr(start_index, alloc_comp)); | 1348 AddInstruction(new BindInstr(start_index, alloc_comp)); |
| 1292 return new TempVal(start_index); | 1349 return new TempVal(start_index); |
| 1293 } | 1350 } |
| 1294 | 1351 |
| 1295 | 1352 |
| 1296 void EffectGraphVisitor::BuildConstructorCall(ConstructorCallNode* node, | 1353 void EffectGraphVisitor::BuildConstructorCall(ConstructorCallNode* node, |
| 1297 int start_index, | 1354 int start_index, |
| 1298 Value* alloc_value) { | 1355 Value* alloc_value) { |
| 1299 ZoneGrowableArray<Value*>* values = new ZoneGrowableArray<Value*>(); | 1356 ZoneGrowableArray<Value*>* values = new ZoneGrowableArray<Value*>(); |
| 1300 values->Add(alloc_value); | 1357 values->Add(alloc_value); |
| 1301 const Smi& ctor_arg = Smi::ZoneHandle(Smi::New(Function::kCtorPhaseAll)); | 1358 const Smi& ctor_arg = Smi::ZoneHandle(Smi::New(Function::kCtorPhaseAll)); |
| 1302 TempVal* ctor_arg_value = new TempVal(start_index); | 1359 TempVal* ctor_arg_value = new TempVal(start_index); |
| 1303 AddInstruction( | 1360 AddInstruction( |
| 1304 new BindInstr(ctor_arg_value->index(), new ConstantVal(ctor_arg))); | 1361 new BindInstr(ctor_arg_value->index(), new ConstantVal(ctor_arg))); |
| 1305 values->Add(ctor_arg_value); | 1362 values->Add(ctor_arg_value); |
| 1306 TranslateArgumentList(*node->arguments(), start_index + 1, values); | 1363 TranslateArgumentList(*node->arguments(), start_index + 1, values); |
| 1307 StaticCallComp* call = | 1364 StaticCallComp* call = |
| 1308 new StaticCallComp(node->token_index(), | 1365 new StaticCallComp(node->token_index(), |
| 1366 owner()->try_index(), | |
| 1309 node->constructor(), | 1367 node->constructor(), |
| 1310 node->arguments()->names(), | 1368 node->arguments()->names(), |
| 1311 values); | 1369 values); |
| 1312 AddInstruction(new DoInstr(call)); | 1370 AddInstruction(new DoInstr(call)); |
| 1313 } | 1371 } |
| 1314 | 1372 |
| 1315 | 1373 |
| 1316 void EffectGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) { | 1374 void EffectGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) { |
| 1317 if (node->constructor().IsFactory()) { | 1375 if (node->constructor().IsFactory()) { |
| 1318 ZoneGrowableArray<Value*>* factory_arguments = | 1376 ZoneGrowableArray<Value*>* factory_arguments = |
| 1319 new ZoneGrowableArray<Value*>(); | 1377 new ZoneGrowableArray<Value*>(); |
| 1320 factory_arguments->Add(BuildFactoryTypeArguments(node, temp_index())); | 1378 factory_arguments->Add(BuildFactoryTypeArguments(node, temp_index())); |
| 1321 ASSERT(factory_arguments->length() == 1); | 1379 ASSERT(factory_arguments->length() == 1); |
| 1322 TranslateArgumentList(*node->arguments(), | 1380 TranslateArgumentList(*node->arguments(), |
| 1323 temp_index() + 1, | 1381 temp_index() + 1, |
| 1324 factory_arguments); | 1382 factory_arguments); |
| 1325 StaticCallComp* call = | 1383 StaticCallComp* call = |
| 1326 new StaticCallComp(node->token_index(), | 1384 new StaticCallComp(node->token_index(), |
| 1385 owner()->try_index(), | |
| 1327 node->constructor(), | 1386 node->constructor(), |
| 1328 node->arguments()->names(), | 1387 node->arguments()->names(), |
| 1329 factory_arguments); | 1388 factory_arguments); |
| 1330 ReturnComputation(call); | 1389 ReturnComputation(call); |
| 1331 return; | 1390 return; |
| 1332 } | 1391 } |
| 1333 // t_n contains the allocated and initialized object. | 1392 // t_n contains the allocated and initialized object. |
| 1334 // t_n <- AllocateObject(class) | 1393 // t_n <- AllocateObject(class) |
| 1335 // t_n+1 <- ctor-arg | 1394 // t_n+1 <- ctor-arg |
| 1336 // t_n+2... <- constructor arguments start here | 1395 // t_n+2... <- constructor arguments start here |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1392 if (node->type_arguments().IsNull() || | 1451 if (node->type_arguments().IsNull() || |
| 1393 node->type_arguments().IsInstantiated()) { | 1452 node->type_arguments().IsInstantiated()) { |
| 1394 AddInstruction( | 1453 AddInstruction( |
| 1395 new BindInstr(start_index, new ConstantVal(node->type_arguments()))); | 1454 new BindInstr(start_index, new ConstantVal(node->type_arguments()))); |
| 1396 return new TempVal(start_index); | 1455 return new TempVal(start_index); |
| 1397 } | 1456 } |
| 1398 // The type arguments are uninstantiated. | 1457 // The type arguments are uninstantiated. |
| 1399 Value* instantiator_value = | 1458 Value* instantiator_value = |
| 1400 BuildInstantiatorTypeArguments(node->token_index(), start_index); | 1459 BuildInstantiatorTypeArguments(node->token_index(), start_index); |
| 1401 ExtractFactoryTypeArgumentsComp* extract = | 1460 ExtractFactoryTypeArgumentsComp* extract = |
| 1402 new ExtractFactoryTypeArgumentsComp(node, instantiator_value); | 1461 new ExtractFactoryTypeArgumentsComp(node, |
| 1462 owner()->try_index(), | |
| 1463 instantiator_value); | |
| 1403 AddInstruction(new BindInstr(start_index, extract)); | 1464 AddInstruction(new BindInstr(start_index, extract)); |
| 1404 return new TempVal(start_index); | 1465 return new TempVal(start_index); |
| 1405 } | 1466 } |
| 1406 | 1467 |
| 1407 | 1468 |
| 1408 void EffectGraphVisitor::BuildConstructorTypeArguments( | 1469 void EffectGraphVisitor::BuildConstructorTypeArguments( |
| 1409 ConstructorCallNode* node, | 1470 ConstructorCallNode* node, |
| 1410 intptr_t start_index, | 1471 intptr_t start_index, |
| 1411 ZoneGrowableArray<Value*>* args) { | 1472 ZoneGrowableArray<Value*>* args) { |
| 1412 const Class& cls = Class::ZoneHandle(node->constructor().owner()); | 1473 const Class& cls = Class::ZoneHandle(node->constructor().owner()); |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1475 | 1536 |
| 1476 | 1537 |
| 1477 void EffectGraphVisitor::VisitInstanceGetterNode(InstanceGetterNode* node) { | 1538 void EffectGraphVisitor::VisitInstanceGetterNode(InstanceGetterNode* node) { |
| 1478 ArgumentGraphVisitor for_receiver(owner(), temp_index()); | 1539 ArgumentGraphVisitor for_receiver(owner(), temp_index()); |
| 1479 node->receiver()->Visit(&for_receiver); | 1540 node->receiver()->Visit(&for_receiver); |
| 1480 Append(for_receiver); | 1541 Append(for_receiver); |
| 1481 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(1); | 1542 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(1); |
| 1482 arguments->Add(for_receiver.value()); | 1543 arguments->Add(for_receiver.value()); |
| 1483 const String& name = | 1544 const String& name = |
| 1484 String::ZoneHandle(Field::GetterSymbol(node->field_name())); | 1545 String::ZoneHandle(Field::GetterSymbol(node->field_name())); |
| 1485 InstanceCallComp* call = | 1546 InstanceCallComp* call = new InstanceCallComp( |
| 1486 new InstanceCallComp(node->id(), node->token_index(), name, | 1547 node->id(), node->token_index(), owner()->try_index(), name, |
| 1487 arguments, Array::ZoneHandle(), 1); | 1548 arguments, Array::ZoneHandle(), 1); |
| 1488 ReturnComputation(call); | 1549 ReturnComputation(call); |
| 1489 } | 1550 } |
| 1490 | 1551 |
| 1491 | 1552 |
| 1492 void EffectGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) { | 1553 void EffectGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) { |
| 1493 ArgumentGraphVisitor for_receiver(owner(), temp_index()); | 1554 ArgumentGraphVisitor for_receiver(owner(), temp_index()); |
| 1494 node->receiver()->Visit(&for_receiver); | 1555 node->receiver()->Visit(&for_receiver); |
| 1495 Append(for_receiver); | 1556 Append(for_receiver); |
| 1496 ArgumentGraphVisitor for_value(owner(), for_receiver.temp_index()); | 1557 ArgumentGraphVisitor for_value(owner(), for_receiver.temp_index()); |
| 1497 node->value()->Visit(&for_value); | 1558 node->value()->Visit(&for_value); |
| 1498 Append(for_value); | 1559 Append(for_value); |
| 1499 InstanceSetterComp* setter = new InstanceSetterComp(node->id(), | 1560 InstanceSetterComp* setter = |
| 1500 node->token_index(), | 1561 new InstanceSetterComp(node->id(), |
| 1501 node->field_name(), | 1562 node->token_index(), |
| 1502 for_receiver.value(), | 1563 owner()->try_index(), |
| 1503 for_value.value()); | 1564 node->field_name(), |
| 1565 for_receiver.value(), | |
| 1566 for_value.value()); | |
| 1504 ReturnComputation(setter); | 1567 ReturnComputation(setter); |
| 1505 } | 1568 } |
| 1506 | 1569 |
| 1507 | 1570 |
| 1508 void EffectGraphVisitor::VisitStaticGetterNode(StaticGetterNode* node) { | 1571 void EffectGraphVisitor::VisitStaticGetterNode(StaticGetterNode* node) { |
| 1509 const String& getter_name = | 1572 const String& getter_name = |
| 1510 String::Handle(Field::GetterName(node->field_name())); | 1573 String::Handle(Field::GetterName(node->field_name())); |
| 1511 const Function& getter_function = | 1574 const Function& getter_function = |
| 1512 Function::ZoneHandle(node->cls().LookupStaticFunction(getter_name)); | 1575 Function::ZoneHandle(node->cls().LookupStaticFunction(getter_name)); |
| 1513 ASSERT(!getter_function.IsNull()); | 1576 ASSERT(!getter_function.IsNull()); |
| 1514 ZoneGrowableArray<Value*>* values = new ZoneGrowableArray<Value*>(); | 1577 ZoneGrowableArray<Value*>* values = new ZoneGrowableArray<Value*>(); |
| 1515 StaticCallComp* call = new StaticCallComp(node->token_index(), | 1578 StaticCallComp* call = new StaticCallComp(node->token_index(), |
| 1579 owner()->try_index(), | |
| 1516 getter_function, | 1580 getter_function, |
| 1517 Array::ZoneHandle(), // No names. | 1581 Array::ZoneHandle(), // No names. |
| 1518 values); | 1582 values); |
| 1519 ReturnComputation(call); | 1583 ReturnComputation(call); |
| 1520 } | 1584 } |
| 1521 | 1585 |
| 1522 | 1586 |
| 1523 void EffectGraphVisitor::VisitStaticSetterNode(StaticSetterNode* node) { | 1587 void EffectGraphVisitor::VisitStaticSetterNode(StaticSetterNode* node) { |
| 1524 const String& setter_name = | 1588 const String& setter_name = |
| 1525 String::Handle(Field::SetterName(node->field_name())); | 1589 String::Handle(Field::SetterName(node->field_name())); |
| 1526 const Function& setter_function = | 1590 const Function& setter_function = |
| 1527 Function::ZoneHandle(node->cls().LookupStaticFunction(setter_name)); | 1591 Function::ZoneHandle(node->cls().LookupStaticFunction(setter_name)); |
| 1528 ASSERT(!setter_function.IsNull()); | 1592 ASSERT(!setter_function.IsNull()); |
| 1529 ArgumentGraphVisitor for_value(owner(), temp_index()); | 1593 ArgumentGraphVisitor for_value(owner(), temp_index()); |
| 1530 node->value()->Visit(&for_value); | 1594 node->value()->Visit(&for_value); |
| 1531 Append(for_value); | 1595 Append(for_value); |
| 1532 StaticSetterComp* call = new StaticSetterComp(node->token_index(), | 1596 StaticSetterComp* call = new StaticSetterComp(node->token_index(), |
| 1597 owner()->try_index(), | |
| 1533 setter_function, | 1598 setter_function, |
| 1534 for_value.value()); | 1599 for_value.value()); |
| 1535 ReturnComputation(call); | 1600 ReturnComputation(call); |
| 1536 } | 1601 } |
| 1537 | 1602 |
| 1538 | 1603 |
| 1539 void EffectGraphVisitor::VisitNativeBodyNode(NativeBodyNode* node) { | 1604 void EffectGraphVisitor::VisitNativeBodyNode(NativeBodyNode* node) { |
| 1540 NativeCallComp* native_call = new NativeCallComp(node); | 1605 NativeCallComp* native_call = |
| 1606 new NativeCallComp(node, owner()->try_index()); | |
| 1541 ReturnComputation(native_call); | 1607 ReturnComputation(native_call); |
| 1542 } | 1608 } |
| 1543 | 1609 |
| 1544 | 1610 |
| 1545 void EffectGraphVisitor::VisitPrimaryNode(PrimaryNode* node) { | 1611 void EffectGraphVisitor::VisitPrimaryNode(PrimaryNode* node) { |
| 1546 // PrimaryNodes are temporary during parsing. | 1612 // PrimaryNodes are temporary during parsing. |
| 1547 UNREACHABLE(); | 1613 UNREACHABLE(); |
| 1548 } | 1614 } |
| 1549 | 1615 |
| 1550 | 1616 |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1649 node->array()->Visit(&for_array); | 1715 node->array()->Visit(&for_array); |
| 1650 Append(for_array); | 1716 Append(for_array); |
| 1651 ArgumentGraphVisitor for_index(owner(), for_array.temp_index()); | 1717 ArgumentGraphVisitor for_index(owner(), for_array.temp_index()); |
| 1652 node->index_expr()->Visit(&for_index); | 1718 node->index_expr()->Visit(&for_index); |
| 1653 Append(for_index); | 1719 Append(for_index); |
| 1654 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2); | 1720 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2); |
| 1655 arguments->Add(for_array.value()); | 1721 arguments->Add(for_array.value()); |
| 1656 arguments->Add(for_index.value()); | 1722 arguments->Add(for_index.value()); |
| 1657 const String& name = | 1723 const String& name = |
| 1658 String::ZoneHandle(String::NewSymbol(Token::Str(Token::kINDEX))); | 1724 String::ZoneHandle(String::NewSymbol(Token::Str(Token::kINDEX))); |
| 1659 InstanceCallComp* call = | 1725 InstanceCallComp* call = new InstanceCallComp( |
| 1660 new InstanceCallComp(node->id(), node->token_index(), name, | 1726 node->id(), node->token_index(), owner()->try_index(), name, |
| 1661 arguments, Array::ZoneHandle(), 1); | 1727 arguments, Array::ZoneHandle(), 1); |
| 1662 ReturnComputation(call); | 1728 ReturnComputation(call); |
| 1663 } | 1729 } |
| 1664 | 1730 |
| 1665 | 1731 |
| 1666 void EffectGraphVisitor::VisitStoreIndexedNode(StoreIndexedNode* node) { | 1732 void EffectGraphVisitor::VisitStoreIndexedNode(StoreIndexedNode* node) { |
| 1667 ArgumentGraphVisitor for_array(owner(), temp_index()); | 1733 ArgumentGraphVisitor for_array(owner(), temp_index()); |
| 1668 node->array()->Visit(&for_array); | 1734 node->array()->Visit(&for_array); |
| 1669 Append(for_array); | 1735 Append(for_array); |
| 1670 ArgumentGraphVisitor for_index(owner(), for_array.temp_index()); | 1736 ArgumentGraphVisitor for_index(owner(), for_array.temp_index()); |
| 1671 node->index_expr()->Visit(&for_index); | 1737 node->index_expr()->Visit(&for_index); |
| 1672 Append(for_index); | 1738 Append(for_index); |
| 1673 ArgumentGraphVisitor for_value(owner(), for_index.temp_index()); | 1739 ArgumentGraphVisitor for_value(owner(), for_index.temp_index()); |
| 1674 node->value()->Visit(&for_value); | 1740 node->value()->Visit(&for_value); |
| 1675 Append(for_value); | 1741 Append(for_value); |
| 1676 StoreIndexedComp* store = new StoreIndexedComp(node->id(), | 1742 StoreIndexedComp* store = new StoreIndexedComp(node->id(), |
| 1677 node->token_index(), | 1743 node->token_index(), |
| 1744 owner()->try_index(), | |
| 1678 for_array.value(), | 1745 for_array.value(), |
| 1679 for_index.value(), | 1746 for_index.value(), |
| 1680 for_value.value()); | 1747 for_value.value()); |
| 1681 ReturnComputation(store); | 1748 ReturnComputation(store); |
| 1682 } | 1749 } |
| 1683 | 1750 |
| 1684 | 1751 |
| 1685 bool EffectGraphVisitor::MustSaveRestoreContext(SequenceNode* node) const { | 1752 bool EffectGraphVisitor::MustSaveRestoreContext(SequenceNode* node) const { |
| 1686 return (node == owner()->parsed_function().node_sequence()) && | 1753 return (node == owner()->parsed_function().node_sequence()) && |
| 1687 (owner()->parsed_function().saved_context_var() != NULL); | 1754 (owner()->parsed_function().saved_context_var() != NULL); |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 1704 // label: SourceLabel } | 1771 // label: SourceLabel } |
| 1705 void EffectGraphVisitor::VisitSequenceNode(SequenceNode* node) { | 1772 void EffectGraphVisitor::VisitSequenceNode(SequenceNode* node) { |
| 1706 LocalScope* scope = node->scope(); | 1773 LocalScope* scope = node->scope(); |
| 1707 const intptr_t num_context_variables = | 1774 const intptr_t num_context_variables = |
| 1708 (scope != NULL) ? scope->num_context_variables() : 0; | 1775 (scope != NULL) ? scope->num_context_variables() : 0; |
| 1709 int previous_context_level = owner()->context_level(); | 1776 int previous_context_level = owner()->context_level(); |
| 1710 if (num_context_variables > 0) { | 1777 if (num_context_variables > 0) { |
| 1711 // The loop local scope declares variables that are captured. | 1778 // The loop local scope declares variables that are captured. |
| 1712 // Allocate and chain a new context. | 1779 // Allocate and chain a new context. |
| 1713 // Allocate context computation (uses current CTX) | 1780 // Allocate context computation (uses current CTX) |
| 1714 AllocateContextComp* comp = new AllocateContextComp(node->token_index(), | 1781 AllocateContextComp* comp = new AllocateContextComp( |
| 1715 num_context_variables); | 1782 node->token_index(), |
| 1783 owner()->try_index(), | |
| 1784 num_context_variables); | |
| 1716 AddInstruction(new BindInstr(temp_index(), comp)); | 1785 AddInstruction(new BindInstr(temp_index(), comp)); |
| 1717 Value* allocated_context_value = new TempVal(temp_index()); | 1786 Value* allocated_context_value = new TempVal(temp_index()); |
| 1718 | 1787 |
| 1719 // If this node_sequence is the body of the function being compiled, and if | 1788 // If this node_sequence is the body of the function being compiled, and if |
| 1720 // this function is not a closure, do not link the current context as the | 1789 // this function is not a closure, do not link the current context as the |
| 1721 // parent of the newly allocated context, as it is not accessible. Instead, | 1790 // parent of the newly allocated context, as it is not accessible. Instead, |
| 1722 // save it in a pre-allocated variable and restore it on exit. | 1791 // save it in a pre-allocated variable and restore it on exit. |
| 1723 if (MustSaveRestoreContext(node)) { | 1792 if (MustSaveRestoreContext(node)) { |
| 1724 AddInstruction(new BindInstr(temp_index() + 1, new CurrentContextComp())); | 1793 AddInstruction(new BindInstr(temp_index() + 1, new CurrentContextComp())); |
| 1725 StoreLocalComp* store_local = new StoreLocalComp( | 1794 StoreLocalComp* store_local = new StoreLocalComp( |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1794 Append(for_effect); | 1863 Append(for_effect); |
| 1795 if (!is_open()) { | 1864 if (!is_open()) { |
| 1796 // E.g., because of a JumpNode. | 1865 // E.g., because of a JumpNode. |
| 1797 break; | 1866 break; |
| 1798 } | 1867 } |
| 1799 } | 1868 } |
| 1800 | 1869 |
| 1801 if (is_open()) { | 1870 if (is_open()) { |
| 1802 if (MustSaveRestoreContext(node)) { | 1871 if (MustSaveRestoreContext(node)) { |
| 1803 ASSERT(num_context_variables > 0); | 1872 ASSERT(num_context_variables > 0); |
| 1804 LoadLocalComp* load_comp = | 1873 BuildLoadContext(*owner()->parsed_function().saved_context_var(), 0); |
| 1805 new LoadLocalComp(*owner()->parsed_function().saved_context_var(), 0); | |
| 1806 AddInstruction(new BindInstr(temp_index(), load_comp)); | |
| 1807 TempVal* local_value = new TempVal(temp_index()); | |
| 1808 StoreContextComp* store_context = new StoreContextComp(local_value); | |
| 1809 AddInstruction(new DoInstr(store_context)); | |
| 1810 } else if (num_context_variables > 0) { | 1874 } else if (num_context_variables > 0) { |
| 1811 UnchainContext(); | 1875 UnchainContext(); |
| 1812 } | 1876 } |
| 1813 } | 1877 } |
| 1814 | 1878 |
| 1815 // No continue on sequence allowed. | 1879 // No continue on sequence allowed. |
| 1816 ASSERT((node->label() == NULL) || | 1880 ASSERT((node->label() == NULL) || |
| 1817 (node->label()->join_for_continue() == NULL)); | 1881 (node->label()->join_for_continue() == NULL)); |
| 1818 // If this node sequence is labeled, a break out of the sequence will have | 1882 // If this node sequence is labeled, a break out of the sequence will have |
| 1819 // taken care of unchaining the context. | 1883 // taken care of unchaining the context. |
| 1820 if ((node->label() != NULL) && | 1884 if ((node->label() != NULL) && |
| 1821 (node->label()->join_for_break() != NULL)) { | 1885 (node->label()->join_for_break() != NULL)) { |
| 1822 if (is_open()) { | 1886 if (is_open()) { |
| 1823 AddInstruction(node->label()->join_for_break()); | 1887 AddInstruction(node->label()->join_for_break()); |
| 1824 } else { | 1888 } else { |
| 1825 exit_ = node->label()->join_for_break(); | 1889 exit_ = node->label()->join_for_break(); |
| 1826 } | 1890 } |
| 1827 } | 1891 } |
| 1828 | 1892 |
| 1829 // The outermost function sequence cannot contain a label. | 1893 // The outermost function sequence cannot contain a label. |
| 1830 ASSERT((node->label() == NULL) || | 1894 ASSERT((node->label() == NULL) || |
| 1831 (node != owner()->parsed_function().node_sequence())); | 1895 (node != owner()->parsed_function().node_sequence())); |
| 1832 owner()->set_context_level(previous_context_level); | 1896 owner()->set_context_level(previous_context_level); |
| 1833 } | 1897 } |
| 1834 | 1898 |
| 1835 | 1899 |
| 1836 void EffectGraphVisitor::VisitCatchClauseNode(CatchClauseNode* node) { | 1900 void EffectGraphVisitor::VisitCatchClauseNode(CatchClauseNode* node) { |
| 1837 Bailout("EffectGraphVisitor::VisitCatchClauseNode"); | 1901 // NOTE: The implicit variables ':saved_context', ':exception_var' |
| 1902 // and ':stacktrace_var' can never be captured variables. | |
| 1903 // Restores CTX from local variable ':saved_context'. | |
| 1904 CatchEntryComp* catch_entry = new CatchEntryComp(node->exception_var(), | |
| 1905 node->stacktrace_var()); | |
| 1906 AddInstruction(new DoInstr(catch_entry)); | |
| 1907 BuildLoadContext(node->context_var(), temp_index()); | |
| 1908 | |
| 1909 EffectGraphVisitor for_catch(owner(), temp_index()); | |
| 1910 node->VisitChildren(&for_catch); | |
| 1911 Append(for_catch); | |
| 1838 } | 1912 } |
| 1839 | 1913 |
| 1840 | 1914 |
| 1841 void EffectGraphVisitor::VisitTryCatchNode(TryCatchNode* node) { | 1915 void EffectGraphVisitor::VisitTryCatchNode(TryCatchNode* node) { |
| 1842 Bailout("EffectGraphVisitor::VisitTryCatchNode"); | 1916 intptr_t old_try_index = owner()->try_index(); |
| 1917 intptr_t try_index = owner()->allocate_try_index(); | |
| 1918 owner()->set_try_index(try_index); | |
| 1919 | |
| 1920 // Preserve CTX into local variable '%saved_context'. | |
| 1921 BuildStoreContext(node->context_var(), temp_index()); | |
| 1922 | |
| 1923 EffectGraphVisitor for_try_block(owner(), temp_index()); | |
| 1924 node->try_block()->Visit(&for_try_block); | |
| 1925 Append(for_try_block); | |
| 1926 | |
| 1927 // We are done generating code for the try block. | |
| 1928 owner()->set_try_index(old_try_index); | |
| 1929 | |
| 1930 CatchClauseNode* catch_block = node->catch_block(); | |
| 1931 if (catch_block != NULL) { | |
| 1932 // Set the corresponding try index for this catch block so | |
| 1933 // that we can set the appropriate handler pc when we generate | |
| 1934 // code for this catch block. | |
| 1935 catch_block->set_try_index(try_index); | |
| 1936 EffectGraphVisitor for_catch_block(owner(), temp_index()); | |
| 1937 for_catch_block.AddInstruction(new TargetEntryInstr(try_index)); | |
| 1938 catch_block->Visit(&for_catch_block); | |
| 1939 owner()->AddCatchEntry(try_index, for_catch_block.entry()); | |
| 1940 ASSERT(!for_catch_block.is_open()); | |
| 1941 if ((node->end_catch_label() != NULL) && | |
| 1942 (node->end_catch_label()->join_for_continue() != NULL)) { | |
| 1943 if (is_open()) { | |
| 1944 AddInstruction(node->end_catch_label()->join_for_continue()); | |
| 1945 } else { | |
| 1946 exit_ = node->end_catch_label()->join_for_continue(); | |
| 1947 } | |
| 1948 } | |
| 1949 } | |
| 1950 | |
| 1951 if (node->finally_block() != NULL) { | |
| 1952 Bailout("EffectGraphVisitor::VisitTryCatchNode finally"); | |
| 1953 } | |
| 1843 } | 1954 } |
| 1844 | 1955 |
| 1845 | 1956 |
| 1846 void EffectGraphVisitor::BuildThrowNode(ThrowNode* node) { | 1957 void EffectGraphVisitor::BuildThrowNode(ThrowNode* node) { |
| 1847 ValueGraphVisitor for_exception(owner(), temp_index()); | 1958 ValueGraphVisitor for_exception(owner(), temp_index()); |
| 1848 node->exception()->Visit(&for_exception); | 1959 node->exception()->Visit(&for_exception); |
| 1849 Append(for_exception); | 1960 Append(for_exception); |
| 1850 Instruction* instr = NULL; | 1961 Instruction* instr = NULL; |
| 1851 if (node->stacktrace() == NULL) { | 1962 if (node->stacktrace() == NULL) { |
| 1852 instr = new ThrowInstr( | 1963 instr = new ThrowInstr(node->id(), |
| 1853 node->id(), node->token_index(), for_exception.value()); | 1964 node->token_index(), |
| 1965 owner()->try_index(), | |
| 1966 for_exception.value()); | |
| 1854 } else { | 1967 } else { |
| 1855 ValueGraphVisitor for_stack_trace(owner(), temp_index() + 1); | 1968 ValueGraphVisitor for_stack_trace(owner(), temp_index() + 1); |
| 1856 node->stacktrace()->Visit(&for_stack_trace); | 1969 node->stacktrace()->Visit(&for_stack_trace); |
| 1857 Append(for_stack_trace); | 1970 Append(for_stack_trace); |
| 1858 instr = new ReThrowInstr(node->id(), | 1971 instr = new ReThrowInstr(node->id(), |
| 1859 node->token_index(), | 1972 node->token_index(), |
| 1973 owner()->try_index(), | |
| 1860 for_exception.value(), | 1974 for_exception.value(), |
| 1861 for_stack_trace.value()); | 1975 for_stack_trace.value()); |
| 1862 } | 1976 } |
| 1863 AddInstruction(instr); | 1977 AddInstruction(instr); |
| 1864 } | 1978 } |
| 1865 | 1979 |
| 1866 | 1980 |
| 1867 void EffectGraphVisitor::VisitThrowNode(ThrowNode* node) { | 1981 void EffectGraphVisitor::VisitThrowNode(ThrowNode* node) { |
| 1868 BuildThrowNode(node); | 1982 BuildThrowNode(node); |
| 1869 CloseFragment(); | 1983 CloseFragment(); |
| (...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2176 } | 2290 } |
| 2177 | 2291 |
| 2178 | 2292 |
| 2179 void FlowGraphPrinter::VisitCloneContext(CloneContextComp* comp) { | 2293 void FlowGraphPrinter::VisitCloneContext(CloneContextComp* comp) { |
| 2180 OS::Print("CloneContext("); | 2294 OS::Print("CloneContext("); |
| 2181 comp->context_value()->Accept(this); | 2295 comp->context_value()->Accept(this); |
| 2182 OS::Print(")"); | 2296 OS::Print(")"); |
| 2183 } | 2297 } |
| 2184 | 2298 |
| 2185 | 2299 |
| 2300 void FlowGraphPrinter::VisitCatchEntry(CatchEntryComp* comp) { | |
| 2301 OS::Print("CatchEntry(%s, %s)", comp->exception_var().name().ToCString(), | |
| 2302 comp->stacktrace_var().name().ToCString()); | |
| 2303 } | |
| 2304 | |
| 2305 | |
| 2186 void FlowGraphPrinter::VisitStoreContext(StoreContextComp* comp) { | 2306 void FlowGraphPrinter::VisitStoreContext(StoreContextComp* comp) { |
| 2187 OS::Print("StoreContext("); | 2307 OS::Print("StoreContext("); |
| 2188 comp->value()->Accept(this); | 2308 comp->value()->Accept(this); |
| 2189 OS::Print(")"); | 2309 OS::Print(")"); |
| 2190 } | 2310 } |
| 2191 | 2311 |
| 2192 | 2312 |
| 2193 void FlowGraphPrinter::VisitJoinEntry(JoinEntryInstr* instr) { | 2313 void FlowGraphPrinter::VisitJoinEntry(JoinEntryInstr* instr) { |
| 2194 OS::Print("%2d: [join]", reverse_index(instr->postorder_number())); | 2314 OS::Print("%2d: [join]", reverse_index(instr->postorder_number())); |
| 2195 } | 2315 } |
| 2196 | 2316 |
| 2197 | 2317 |
| 2198 void FlowGraphPrinter::VisitTargetEntry(TargetEntryInstr* instr) { | 2318 void FlowGraphPrinter::VisitTargetEntry(TargetEntryInstr* instr) { |
| 2199 OS::Print("%2d: [target]", reverse_index(instr->postorder_number())); | 2319 OS::Print("%2d: [target", reverse_index(instr->postorder_number())); |
| 2320 if (instr->HasTryIndex()) { | |
| 2321 OS::Print(" catch %d]", instr->try_index()); | |
| 2322 } else { | |
| 2323 OS::Print("]"); | |
| 2324 } | |
| 2200 } | 2325 } |
| 2201 | 2326 |
| 2202 | 2327 |
| 2203 void FlowGraphPrinter::VisitPickTemp(PickTempInstr* instr) { | 2328 void FlowGraphPrinter::VisitPickTemp(PickTempInstr* instr) { |
| 2204 OS::Print(" t%d <- Pick(t%d)", instr->destination(), instr->source()); | 2329 OS::Print(" t%d <- Pick(t%d)", instr->destination(), instr->source()); |
| 2205 } | 2330 } |
| 2206 | 2331 |
| 2207 | 2332 |
| 2208 void FlowGraphPrinter::VisitTuckTemp(TuckTempInstr* instr) { | 2333 void FlowGraphPrinter::VisitTuckTemp(TuckTempInstr* instr) { |
| 2209 OS::Print(" t%d := t%d", instr->destination(), instr->source()); | 2334 OS::Print(" t%d := t%d", instr->destination(), instr->source()); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2257 if (FLAG_print_ast) { | 2382 if (FLAG_print_ast) { |
| 2258 // Print the function ast before IL generation. | 2383 // Print the function ast before IL generation. |
| 2259 AstPrinter::PrintFunctionNodes(parsed_function()); | 2384 AstPrinter::PrintFunctionNodes(parsed_function()); |
| 2260 } | 2385 } |
| 2261 const Function& function = parsed_function().function(); | 2386 const Function& function = parsed_function().function(); |
| 2262 EffectGraphVisitor for_effect(this, 0); | 2387 EffectGraphVisitor for_effect(this, 0); |
| 2263 for_effect.AddInstruction(new TargetEntryInstr()); | 2388 for_effect.AddInstruction(new TargetEntryInstr()); |
| 2264 parsed_function().node_sequence()->Visit(&for_effect); | 2389 parsed_function().node_sequence()->Visit(&for_effect); |
| 2265 // Check that the graph is properly terminated. | 2390 // Check that the graph is properly terminated. |
| 2266 ASSERT(!for_effect.is_open()); | 2391 ASSERT(!for_effect.is_open()); |
| 2392 GrowableArray<intptr_t> parent; | |
| 2393 for (intptr_t i = 0; i < catch_entries_.length(); i++) { | |
| 2394 Instruction* entry = catch_entries_[i]; | |
| 2395 entry->DiscoverBlocks(NULL, // Entry block predecessor. | |
| 2396 &preorder_block_entries_, | |
| 2397 &postorder_block_entries_, | |
| 2398 &parent); | |
| 2399 ComputeDominators(&preorder_block_entries_, &parent); | |
| 2400 } | |
| 2267 if (for_effect.entry() != NULL) { | 2401 if (for_effect.entry() != NULL) { |
| 2268 // Perform a depth-first traversal of the graph to build preorder and | 2402 // Perform a depth-first traversal of the graph to build preorder and |
| 2269 // postorder block orders. | 2403 // postorder block orders. |
| 2270 GrowableArray<intptr_t> parent; | |
| 2271 for_effect.entry()->DiscoverBlocks(NULL, // Entry block predecessor. | 2404 for_effect.entry()->DiscoverBlocks(NULL, // Entry block predecessor. |
| 2272 &preorder_block_entries_, | 2405 &preorder_block_entries_, |
| 2273 &postorder_block_entries_, | 2406 &postorder_block_entries_, |
| 2274 &parent); | 2407 &parent); |
| 2275 ComputeDominators(&preorder_block_entries_, &parent); | 2408 ComputeDominators(&preorder_block_entries_, &parent); |
| 2276 } | 2409 } |
| 2277 if (FLAG_print_flow_graph) { | 2410 if (FLAG_print_flow_graph) { |
| 2278 intptr_t length = postorder_block_entries_.length(); | 2411 intptr_t length = postorder_block_entries_.length(); |
| 2279 GrowableArray<BlockEntryInstr*> reverse_postorder(length); | 2412 GrowableArray<BlockEntryInstr*> reverse_postorder(length); |
| 2280 for (intptr_t i = length - 1; i >= 0; --i) { | 2413 for (intptr_t i = length - 1; i >= 0; --i) { |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2380 char* chars = reinterpret_cast<char*>( | 2513 char* chars = reinterpret_cast<char*>( |
| 2381 Isolate::Current()->current_zone()->Allocate(len)); | 2514 Isolate::Current()->current_zone()->Allocate(len)); |
| 2382 OS::SNPrint(chars, len, kFormat, function_name, reason); | 2515 OS::SNPrint(chars, len, kFormat, function_name, reason); |
| 2383 const Error& error = Error::Handle( | 2516 const Error& error = Error::Handle( |
| 2384 LanguageError::New(String::Handle(String::New(chars)))); | 2517 LanguageError::New(String::Handle(String::New(chars)))); |
| 2385 Isolate::Current()->long_jump_base()->Jump(1, error); | 2518 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 2386 } | 2519 } |
| 2387 | 2520 |
| 2388 | 2521 |
| 2389 } // namespace dart | 2522 } // namespace dart |
| OLD | NEW |