| 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/flags.h" | 7 #include "vm/flags.h" |
| 8 #include "vm/intermediate_language.h" | 8 #include "vm/intermediate_language.h" |
| 9 #include "vm/longjump.h" | 9 #include "vm/longjump.h" |
| 10 #include "vm/os.h" | 10 #include "vm/os.h" |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 122 | 122 |
| 123 void TestGraphVisitor::BranchOnValue(Value* value) { | 123 void TestGraphVisitor::BranchOnValue(Value* value) { |
| 124 BranchInstr* branch = new BranchInstr(value); | 124 BranchInstr* branch = new BranchInstr(value); |
| 125 AddInstruction(branch); | 125 AddInstruction(branch); |
| 126 CloseFragment(); | 126 CloseFragment(); |
| 127 true_successor_address_ = branch->true_successor_address(); | 127 true_successor_address_ = branch->true_successor_address(); |
| 128 false_successor_address_ = branch->false_successor_address(); | 128 false_successor_address_ = branch->false_successor_address(); |
| 129 } | 129 } |
| 130 | 130 |
| 131 | 131 |
| 132 void ArgumentGraphVisitor::ReturnValue(Value* value) { |
| 133 value_ = value; |
| 134 if (value->IsConstant()) { |
| 135 AddInstruction(new BindInstr(temp_index(), value)); |
| 136 value_ = new TempVal(AllocateTempIndex()); |
| 137 } |
| 138 } |
| 139 |
| 140 |
| 132 void EffectGraphVisitor::Bailout(const char* reason) { | 141 void EffectGraphVisitor::Bailout(const char* reason) { |
| 133 owner()->Bailout(reason); | 142 owner()->Bailout(reason); |
| 134 } | 143 } |
| 135 | 144 |
| 136 | 145 |
| 137 // 'bailout' is a statement (without a semicolon), typically a return. | 146 // 'bailout' is a statement (without a semicolon), typically a return. |
| 138 #define CHECK_ALIVE(bailout) \ | 147 #define CHECK_ALIVE(bailout) \ |
| 139 do { \ | 148 do { \ |
| 140 if (!is_open()) { \ | 149 if (!is_open()) { \ |
| 141 bailout; \ | 150 bailout; \ |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 215 | 224 |
| 216 // <Expression> :: BinaryOp { kind: Token::Kind | 225 // <Expression> :: BinaryOp { kind: Token::Kind |
| 217 // left: <Expression> | 226 // left: <Expression> |
| 218 // right: <Expression> } | 227 // right: <Expression> } |
| 219 void EffectGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) { | 228 void EffectGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) { |
| 220 // Operators "&&" and "||" cannot be overloaded therefore do not call | 229 // Operators "&&" and "||" cannot be overloaded therefore do not call |
| 221 // operator. | 230 // operator. |
| 222 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { | 231 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { |
| 223 Bailout("EffectGraphVisitor::VisitBinaryOpNode AND/OR"); | 232 Bailout("EffectGraphVisitor::VisitBinaryOpNode AND/OR"); |
| 224 } | 233 } |
| 225 ValueGraphVisitor for_left_value(owner(), temp_index()); | 234 ArgumentGraphVisitor for_left_value(owner(), temp_index()); |
| 226 node->left()->Visit(&for_left_value); | 235 node->left()->Visit(&for_left_value); |
| 227 Append(for_left_value); | 236 Append(for_left_value); |
| 228 CHECK_ALIVE(return); | 237 ArgumentGraphVisitor for_right_value(owner(), for_left_value.temp_index()); |
| 229 ValueGraphVisitor for_right_value(owner(), for_left_value.temp_index()); | |
| 230 node->right()->Visit(&for_right_value); | 238 node->right()->Visit(&for_right_value); |
| 231 Append(for_right_value); | 239 Append(for_right_value); |
| 232 CHECK_ALIVE(return); | |
| 233 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2); | 240 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2); |
| 234 arguments->Add(for_left_value.value()); | 241 arguments->Add(for_left_value.value()); |
| 235 arguments->Add(for_right_value.value()); | 242 arguments->Add(for_right_value.value()); |
| 236 InstanceCallComp* call = new InstanceCallComp(node->Name(), arguments); | 243 const String& name = String::ZoneHandle(String::NewSymbol(node->Name())); |
| 244 InstanceCallComp* call = |
| 245 new InstanceCallComp(node, name, arguments, Array::ZoneHandle(), 2); |
| 237 ReturnComputation(call); | 246 ReturnComputation(call); |
| 238 } | 247 } |
| 239 | 248 |
| 240 | 249 |
| 241 void EffectGraphVisitor::VisitStringConcatNode(StringConcatNode* node) { | 250 void EffectGraphVisitor::VisitStringConcatNode(StringConcatNode* node) { |
| 242 Bailout("EffectGraphVisitor::VisitStringConcatNode"); | 251 Bailout("EffectGraphVisitor::VisitStringConcatNode"); |
| 243 } | 252 } |
| 244 | 253 |
| 245 | 254 |
| 246 // <Expression> :: Comparison { kind: Token::Kind | 255 // <Expression> :: Comparison { kind: Token::Kind |
| 247 // left: <Expression> | 256 // left: <Expression> |
| 248 // right: <Expression> } | 257 // right: <Expression> } |
| 249 void EffectGraphVisitor::VisitComparisonNode(ComparisonNode* node) { | 258 void EffectGraphVisitor::VisitComparisonNode(ComparisonNode* node) { |
| 250 if (Token::IsInstanceofOperator(node->kind())) { | 259 if (Token::IsInstanceofOperator(node->kind())) { |
| 251 Bailout("instanceof not yet implemented"); | 260 Bailout("instanceof not yet implemented"); |
| 252 } else if ((node->kind() == Token::kEQ) || (node->kind() == Token::kNE)) { | 261 } else if ((node->kind() == Token::kEQ) || (node->kind() == Token::kNE)) { |
| 253 Bailout("'==' or '!=' comparison not yet implemented"); | 262 Bailout("'==' or '!=' comparison not yet implemented"); |
| 254 } | 263 } |
| 255 ValueGraphVisitor for_left_value(owner(), temp_index()); | 264 |
| 256 node->left()->Visit(&for_left_value); | |
| 257 Append(for_left_value); | |
| 258 CHECK_ALIVE(return); | |
| 259 ValueGraphVisitor for_right_value(owner(), for_left_value.temp_index()); | |
| 260 node->right()->Visit(&for_right_value); | |
| 261 Append(for_right_value); | |
| 262 CHECK_ALIVE(return); | |
| 263 if ((node->kind() == Token::kEQ_STRICT) || | 265 if ((node->kind() == Token::kEQ_STRICT) || |
| 264 (node->kind() == Token::kNE_STRICT)) { | 266 (node->kind() == Token::kNE_STRICT)) { |
| 267 ValueGraphVisitor for_left_value(owner(), temp_index()); |
| 268 node->left()->Visit(&for_left_value); |
| 269 Append(for_left_value); |
| 270 ValueGraphVisitor for_right_value(owner(), for_left_value.temp_index()); |
| 271 node->right()->Visit(&for_right_value); |
| 272 Append(for_right_value); |
| 265 StrictCompareComp* comp = new StrictCompareComp( | 273 StrictCompareComp* comp = new StrictCompareComp( |
| 266 node->kind(), for_left_value.value(), for_right_value.value()); | 274 node->kind(), for_left_value.value(), for_right_value.value()); |
| 267 ReturnComputation(comp); | 275 ReturnComputation(comp); |
| 268 return; | 276 return; |
| 269 } | 277 } |
| 278 |
| 279 ArgumentGraphVisitor for_left_value(owner(), temp_index()); |
| 280 node->left()->Visit(&for_left_value); |
| 281 Append(for_left_value); |
| 282 ArgumentGraphVisitor for_right_value(owner(), for_left_value.temp_index()); |
| 283 node->right()->Visit(&for_right_value); |
| 284 Append(for_right_value); |
| 270 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2); | 285 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2); |
| 271 arguments->Add(for_left_value.value()); | 286 arguments->Add(for_left_value.value()); |
| 272 arguments->Add(for_right_value.value()); | 287 arguments->Add(for_right_value.value()); |
| 273 InstanceCallComp* call = new InstanceCallComp(node->Name(), arguments); | 288 const String& name = String::ZoneHandle(String::NewSymbol(node->Name())); |
| 289 InstanceCallComp* call = |
| 290 new InstanceCallComp(node, name, arguments, Array::ZoneHandle(), 2); |
| 274 ReturnComputation(call); | 291 ReturnComputation(call); |
| 275 } | 292 } |
| 276 | 293 |
| 277 | 294 |
| 278 void EffectGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) { | 295 void EffectGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) { |
| 279 // "!" cannot be overloaded, therefore do not call operator. | 296 // "!" cannot be overloaded, therefore do not call operator. |
| 280 if (node->kind() == Token::kNOT) { | 297 if (node->kind() == Token::kNOT) { |
| 281 Bailout("EffectGraphVisitor::VisitUnaryOpNode NOT"); | 298 Bailout("EffectGraphVisitor::VisitUnaryOpNode NOT"); |
| 282 } | 299 } |
| 283 ValueGraphVisitor for_value(owner(), temp_index()); | 300 ArgumentGraphVisitor for_value(owner(), temp_index()); |
| 284 node->operand()->Visit(&for_value); | 301 node->operand()->Visit(&for_value); |
| 285 Append(for_value); | 302 Append(for_value); |
| 286 ZoneGrowableArray<Value*>* argument = new ZoneGrowableArray<Value*>(1); | 303 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(1); |
| 287 argument->Add(for_value.value()); | 304 arguments->Add(for_value.value()); |
| 288 InstanceCallComp* call = new InstanceCallComp(node->Name(), argument); | 305 const String& name = |
| 306 String::ZoneHandle(String::NewSymbol((node->kind() == Token::kSUB) |
| 307 ? Token::Str(Token::kNEGATE) |
| 308 : node->Name())); |
| 309 InstanceCallComp* call = |
| 310 new InstanceCallComp(node, name, arguments, Array::ZoneHandle(), 1); |
| 289 ReturnComputation(call); | 311 ReturnComputation(call); |
| 290 } | 312 } |
| 291 | 313 |
| 292 | 314 |
| 293 void EffectGraphVisitor::VisitIncrOpLocalNode(IncrOpLocalNode* node) { | 315 void EffectGraphVisitor::VisitIncrOpLocalNode(IncrOpLocalNode* node) { |
| 294 Bailout("EffectGraphVisitor::VisitIncrOpLocalNode"); | 316 Bailout("EffectGraphVisitor::VisitIncrOpLocalNode"); |
| 295 } | 317 } |
| 296 | 318 |
| 297 | 319 |
| 298 void EffectGraphVisitor::VisitIncrOpInstanceFieldNode( | 320 void EffectGraphVisitor::VisitIncrOpInstanceFieldNode( |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 383 void EffectGraphVisitor::VisitArrayNode(ArrayNode* node) { | 405 void EffectGraphVisitor::VisitArrayNode(ArrayNode* node) { |
| 384 Bailout("EffectGraphVisitor::VisitArrayNode"); | 406 Bailout("EffectGraphVisitor::VisitArrayNode"); |
| 385 } | 407 } |
| 386 | 408 |
| 387 | 409 |
| 388 void EffectGraphVisitor::VisitClosureNode(ClosureNode* node) { | 410 void EffectGraphVisitor::VisitClosureNode(ClosureNode* node) { |
| 389 Bailout("EffectGraphVisitor::VisitClosureNode"); | 411 Bailout("EffectGraphVisitor::VisitClosureNode"); |
| 390 } | 412 } |
| 391 | 413 |
| 392 | 414 |
| 415 void EffectGraphVisitor::TranslateArgumentList( |
| 416 const ArgumentListNode& node, |
| 417 intptr_t next_temp_index, |
| 418 ZoneGrowableArray<Value*>* values) { |
| 419 for (intptr_t i = 0; i < node.length(); ++i) { |
| 420 ArgumentGraphVisitor for_argument(owner(), next_temp_index); |
| 421 node.NodeAt(i)->Visit(&for_argument); |
| 422 Append(for_argument); |
| 423 next_temp_index = for_argument.temp_index(); |
| 424 values->Add(for_argument.value()); |
| 425 } |
| 426 } |
| 427 |
| 393 void EffectGraphVisitor::VisitInstanceCallNode(InstanceCallNode* node) { | 428 void EffectGraphVisitor::VisitInstanceCallNode(InstanceCallNode* node) { |
| 394 ArgumentListNode* arguments = node->arguments(); | 429 ArgumentListNode* arguments = node->arguments(); |
| 395 int length = arguments->length(); | 430 int length = arguments->length(); |
| 396 ZoneGrowableArray<Value*>* values = new ZoneGrowableArray<Value*>(length + 1); | 431 ZoneGrowableArray<Value*>* values = new ZoneGrowableArray<Value*>(length + 1); |
| 397 | 432 |
| 398 ValueGraphVisitor for_receiver(owner(), temp_index()); | 433 ArgumentGraphVisitor for_receiver(owner(), temp_index()); |
| 399 node->receiver()->Visit(&for_receiver); | 434 node->receiver()->Visit(&for_receiver); |
| 400 Append(for_receiver); | 435 Append(for_receiver); |
| 401 CHECK_ALIVE(return); | 436 values->Add(for_receiver.value()); |
| 402 Value* receiver_value = for_receiver.value(); | |
| 403 temp_index_ = for_receiver.temp_index(); | |
| 404 if (receiver_value->IsConstant()) { | |
| 405 AddInstruction(new BindInstr(temp_index(), receiver_value)); | |
| 406 receiver_value = new TempVal(AllocateTempIndex()); | |
| 407 } | |
| 408 values->Add(receiver_value); | |
| 409 | 437 |
| 410 TranslateArgumentList(*arguments, values); | 438 TranslateArgumentList(*arguments, for_receiver.temp_index(), values); |
| 411 CHECK_ALIVE(return); | |
| 412 InstanceCallComp* call = | 439 InstanceCallComp* call = |
| 413 new InstanceCallComp(node->function_name().ToCString(), values); | 440 new InstanceCallComp(node, node->function_name(), values, |
| 441 arguments->names(), 1); |
| 414 ReturnComputation(call); | 442 ReturnComputation(call); |
| 415 } | 443 } |
| 416 | 444 |
| 417 | 445 |
| 418 void EffectGraphVisitor::TranslateArgumentList( | |
| 419 const ArgumentListNode& node, ZoneGrowableArray<Value*>* values) { | |
| 420 int index = temp_index(); | |
| 421 for (intptr_t i = 0; i < node.length(); ++i) { | |
| 422 ValueGraphVisitor for_value(owner(), index); | |
| 423 node.NodeAt(i)->Visit(&for_value); | |
| 424 Append(for_value); | |
| 425 CHECK_ALIVE(return); | |
| 426 Value* argument_value = for_value.value(); | |
| 427 index = for_value.temp_index(); | |
| 428 if (argument_value->IsConstant()) { | |
| 429 AddInstruction(new BindInstr(index, argument_value)); | |
| 430 argument_value = new TempVal(index++); | |
| 431 } | |
| 432 values->Add(argument_value); | |
| 433 } | |
| 434 } | |
| 435 | |
| 436 // <Expression> ::= StaticCall { function: Function | 446 // <Expression> ::= StaticCall { function: Function |
| 437 // arguments: <ArgumentList> } | 447 // arguments: <ArgumentList> } |
| 438 void EffectGraphVisitor::VisitStaticCallNode(StaticCallNode* node) { | 448 void EffectGraphVisitor::VisitStaticCallNode(StaticCallNode* node) { |
| 439 int length = node->arguments()->length(); | 449 int length = node->arguments()->length(); |
| 440 ZoneGrowableArray<Value*>* values = new ZoneGrowableArray<Value*>(length); | 450 ZoneGrowableArray<Value*>* values = new ZoneGrowableArray<Value*>(length); |
| 441 TranslateArgumentList(*node->arguments(), values); | 451 TranslateArgumentList(*node->arguments(), temp_index(), values); |
| 442 CHECK_ALIVE(return); | 452 StaticCallComp* call = new StaticCallComp(node, values); |
| 443 StaticCallComp* call = new StaticCallComp(node->function(), values); | |
| 444 ReturnComputation(call); | 453 ReturnComputation(call); |
| 445 } | 454 } |
| 446 | 455 |
| 447 | 456 |
| 448 void EffectGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { | 457 void EffectGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { |
| 449 Bailout("EffectGraphVisitor::VisitClosureCallNode"); | 458 Bailout("EffectGraphVisitor::VisitClosureCallNode"); |
| 450 } | 459 } |
| 451 | 460 |
| 452 | 461 |
| 453 void EffectGraphVisitor::VisitCloneContextNode(CloneContextNode* node) { | 462 void EffectGraphVisitor::VisitCloneContextNode(CloneContextNode* node) { |
| 454 Bailout("EffectGraphVisitor::VisitCloneContextNode"); | 463 Bailout("EffectGraphVisitor::VisitCloneContextNode"); |
| 455 } | 464 } |
| 456 | 465 |
| 457 | 466 |
| 458 void EffectGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) { | 467 void EffectGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) { |
| 459 Bailout("EffectGraphVisitor::VisitConstructorCallNode"); | 468 Bailout("EffectGraphVisitor::VisitConstructorCallNode"); |
| 460 } | 469 } |
| 461 | 470 |
| 462 | 471 |
| 463 void EffectGraphVisitor::VisitInstanceGetterNode(InstanceGetterNode* node) { | 472 void EffectGraphVisitor::VisitInstanceGetterNode(InstanceGetterNode* node) { |
| 464 Bailout("EffectGraphVisitor::VisitInstanceGetterNode"); | 473 ArgumentGraphVisitor for_receiver(owner(), temp_index()); |
| 474 node->receiver()->Visit(&for_receiver); |
| 475 Append(for_receiver); |
| 476 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(1); |
| 477 arguments->Add(for_receiver.value()); |
| 478 const String& name = |
| 479 String::ZoneHandle(Field::GetterSymbol(node->field_name())); |
| 480 InstanceCallComp* call = |
| 481 new InstanceCallComp(node, name, arguments, Array::ZoneHandle(), 1); |
| 482 ReturnComputation(call); |
| 465 } | 483 } |
| 466 | 484 |
| 467 | 485 |
| 468 void EffectGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) { | 486 void EffectGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) { |
| 469 Bailout("EffectGraphVisitor::VisitInstanceSetterNode"); | 487 // We preallocate a temporary to overlap with the value of the assignment. |
| 488 const Smi& zero = Smi::ZoneHandle(Smi::New(0)); |
| 489 AddInstruction(new BindInstr(temp_index(), new ConstantVal(zero))); |
| 490 TempVal* placeholder = new TempVal(temp_index()); |
| 491 ArgumentGraphVisitor for_receiver(owner(), temp_index() + 1); |
| 492 node->receiver()->Visit(&for_receiver); |
| 493 Append(for_receiver); |
| 494 ArgumentGraphVisitor for_value(owner(), for_receiver.temp_index()); |
| 495 node->value()->Visit(&for_value); |
| 496 Append(for_value); |
| 497 InstanceSetterComp* setter = new InstanceSetterComp(node, |
| 498 placeholder, |
| 499 for_receiver.value(), |
| 500 for_value.value()); |
| 501 ReturnComputation(setter); |
| 470 } | 502 } |
| 471 | 503 |
| 472 | 504 |
| 473 void EffectGraphVisitor::VisitStaticGetterNode(StaticGetterNode* node) { | 505 void EffectGraphVisitor::VisitStaticGetterNode(StaticGetterNode* node) { |
| 474 Bailout("EffectGraphVisitor::VisitStaticGetterNode"); | 506 Bailout("EffectGraphVisitor::VisitStaticGetterNode"); |
| 475 } | 507 } |
| 476 | 508 |
| 477 | 509 |
| 478 void EffectGraphVisitor::VisitStaticSetterNode(StaticSetterNode* node) { | 510 void EffectGraphVisitor::VisitStaticSetterNode(StaticSetterNode* node) { |
| 479 Bailout("EffectGraphVisitor::VisitStaticSetterNode"); | 511 Bailout("EffectGraphVisitor::VisitStaticSetterNode"); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 505 ReturnComputation(load); | 537 ReturnComputation(load); |
| 506 } | 538 } |
| 507 | 539 |
| 508 | 540 |
| 509 // <Expression> ::= StoreLocal { local: LocalVariable | 541 // <Expression> ::= StoreLocal { local: LocalVariable |
| 510 // value: <Expression> } | 542 // value: <Expression> } |
| 511 void EffectGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) { | 543 void EffectGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) { |
| 512 ValueGraphVisitor for_value(owner(), temp_index()); | 544 ValueGraphVisitor for_value(owner(), temp_index()); |
| 513 node->value()->Visit(&for_value); | 545 node->value()->Visit(&for_value); |
| 514 Append(for_value); | 546 Append(for_value); |
| 515 CHECK_ALIVE(return); | 547 |
| 516 StoreLocalComp* store = new StoreLocalComp(node->local(), for_value.value()); | 548 Value* value = for_value.value(); |
| 549 if (FLAG_enable_type_checks) { |
| 550 AssertAssignableComp* assert = |
| 551 new AssertAssignableComp(value, node->local().type()); |
| 552 AddInstruction(new BindInstr(temp_index(), assert)); |
| 553 value = new TempVal(temp_index()); |
| 554 } |
| 555 |
| 556 StoreLocalComp* store = new StoreLocalComp(node->local(), value); |
| 517 ReturnComputation(store); | 557 ReturnComputation(store); |
| 518 } | 558 } |
| 519 | 559 |
| 520 | 560 |
| 521 void EffectGraphVisitor::VisitLoadInstanceFieldNode( | 561 void EffectGraphVisitor::VisitLoadInstanceFieldNode( |
| 522 LoadInstanceFieldNode* node) { | 562 LoadInstanceFieldNode* node) { |
| 523 Bailout("EffectGraphVisitor::VisitLoadInstanceFieldNode"); | 563 Bailout("EffectGraphVisitor::VisitLoadInstanceFieldNode"); |
| 524 } | 564 } |
| 525 | 565 |
| 526 | 566 |
| 527 void EffectGraphVisitor::VisitStoreInstanceFieldNode( | 567 void EffectGraphVisitor::VisitStoreInstanceFieldNode( |
| 528 StoreInstanceFieldNode* node) { | 568 StoreInstanceFieldNode* node) { |
| 529 Bailout("EffectGraphVisitor::VisitStoreInstanceFieldNode"); | 569 Bailout("EffectGraphVisitor::VisitStoreInstanceFieldNode"); |
| 530 } | 570 } |
| 531 | 571 |
| 532 | 572 |
| 533 void EffectGraphVisitor::VisitLoadStaticFieldNode(LoadStaticFieldNode* node) { | 573 void EffectGraphVisitor::VisitLoadStaticFieldNode(LoadStaticFieldNode* node) { |
| 534 Bailout("EffectGraphVisitor::VisitLoadStaticFieldNode"); | 574 Bailout("EffectGraphVisitor::VisitLoadStaticFieldNode"); |
| 535 } | 575 } |
| 536 | 576 |
| 537 | 577 |
| 538 void EffectGraphVisitor::VisitStoreStaticFieldNode(StoreStaticFieldNode* node) { | 578 void EffectGraphVisitor::VisitStoreStaticFieldNode(StoreStaticFieldNode* node) { |
| 539 Bailout("EffectGraphVisitor::VisitStoreStaticFieldNode"); | 579 Bailout("EffectGraphVisitor::VisitStoreStaticFieldNode"); |
| 540 } | 580 } |
| 541 | 581 |
| 542 | 582 |
| 543 void EffectGraphVisitor::VisitLoadIndexedNode(LoadIndexedNode* node) { | 583 void EffectGraphVisitor::VisitLoadIndexedNode(LoadIndexedNode* node) { |
| 544 Bailout("EffectGraphVisitor::VisitLoadIndexedNode"); | 584 ArgumentGraphVisitor for_array(owner(), temp_index()); |
| 585 node->array()->Visit(&for_array); |
| 586 Append(for_array); |
| 587 ArgumentGraphVisitor for_index(owner(), for_array.temp_index()); |
| 588 node->index_expr()->Visit(&for_index); |
| 589 Append(for_index); |
| 590 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2); |
| 591 arguments->Add(for_array.value()); |
| 592 arguments->Add(for_index.value()); |
| 593 const String& name = |
| 594 String::ZoneHandle(String::NewSymbol(Token::Str(Token::kINDEX))); |
| 595 InstanceCallComp* call = |
| 596 new InstanceCallComp(node, name, arguments, Array::ZoneHandle(), 1); |
| 597 ReturnComputation(call); |
| 545 } | 598 } |
| 546 | 599 |
| 547 | 600 |
| 548 void EffectGraphVisitor::VisitStoreIndexedNode(StoreIndexedNode* node) { | 601 void EffectGraphVisitor::VisitStoreIndexedNode(StoreIndexedNode* node) { |
| 549 Bailout("EffectGraphVisitor::VisitStoreIndexedNode"); | 602 // This is not a straight instance call to e0.[]=(e1, e2), it is a |
| 603 // call to |
| 604 // |
| 605 // (a, i, v) { a.[]=(i, v); return v; }(e0, e1, e2) |
| 606 // |
| 607 // Without constructing that function, we simulate it at the IL |
| 608 // level by preallocating a slot for the return value. |
| 609 const Smi& zero = Smi::ZoneHandle(Smi::New(0)); |
| 610 AddInstruction(new BindInstr(temp_index(), new ConstantVal(zero))); |
| 611 TempVal* placeholder = new TempVal(temp_index()); |
| 612 ArgumentGraphVisitor for_array(owner(), temp_index() + 1); |
| 613 node->array()->Visit(&for_array); |
| 614 Append(for_array); |
| 615 ArgumentGraphVisitor for_index(owner(), for_array.temp_index()); |
| 616 node->index_expr()->Visit(&for_index); |
| 617 Append(for_index); |
| 618 ArgumentGraphVisitor for_value(owner(), for_index.temp_index()); |
| 619 node->value()->Visit(&for_value); |
| 620 Append(for_value); |
| 621 StoreIndexedComp* store = new StoreIndexedComp(node, |
| 622 placeholder, |
| 623 for_array.value(), |
| 624 for_index.value(), |
| 625 for_value.value()); |
| 626 ReturnComputation(store); |
| 550 } | 627 } |
| 551 | 628 |
| 552 | 629 |
| 553 // <Statement> ::= Sequence { scope: LocalScope | 630 // <Statement> ::= Sequence { scope: LocalScope |
| 554 // nodes: <Statement>* | 631 // nodes: <Statement>* |
| 555 // label: SourceLabel } | 632 // label: SourceLabel } |
| 556 void EffectGraphVisitor::VisitSequenceNode(SequenceNode* node) { | 633 void EffectGraphVisitor::VisitSequenceNode(SequenceNode* node) { |
| 557 if ((node->scope() != NULL) && | 634 if ((node->scope() != NULL) && |
| 558 (node->scope()->num_context_variables() != 0)) { | 635 (node->scope()->num_context_variables() != 0)) { |
| 559 Bailout("Sequence needs a context. Gotta have a context."); | 636 Bailout("Sequence needs a context. Gotta have a context."); |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 653 | 730 |
| 654 | 731 |
| 655 void FlowGraphPrinter::VisitAssertAssignable(AssertAssignableComp* comp) { | 732 void FlowGraphPrinter::VisitAssertAssignable(AssertAssignableComp* comp) { |
| 656 OS::Print("AssertAssignable("); | 733 OS::Print("AssertAssignable("); |
| 657 comp->value()->Accept(this); | 734 comp->value()->Accept(this); |
| 658 OS::Print(", %s)", comp->type().ToCString()); | 735 OS::Print(", %s)", comp->type().ToCString()); |
| 659 } | 736 } |
| 660 | 737 |
| 661 | 738 |
| 662 void FlowGraphPrinter::VisitInstanceCall(InstanceCallComp* comp) { | 739 void FlowGraphPrinter::VisitInstanceCall(InstanceCallComp* comp) { |
| 663 OS::Print("InstanceCall(%s", comp->name()); | 740 OS::Print("InstanceCall(%s", comp->function_name().ToCString()); |
| 664 for (int i = 0; i < comp->ArgumentCount(); ++i) { | 741 for (int i = 0; i < comp->ArgumentCount(); ++i) { |
| 665 OS::Print(", "); | 742 OS::Print(", "); |
| 666 comp->ArgumentAt(i)->Accept(this); | 743 comp->ArgumentAt(i)->Accept(this); |
| 667 } | 744 } |
| 668 OS::Print(")"); | 745 OS::Print(")"); |
| 669 } | 746 } |
| 670 | 747 |
| 671 | 748 |
| 672 void FlowGraphPrinter::VisitStrictCompare(StrictCompareComp* comp) { | 749 void FlowGraphPrinter::VisitStrictCompare(StrictCompareComp* comp) { |
| 673 OS::Print("StrictCompare(%s, ", Token::Str(comp->kind())); | 750 OS::Print("StrictCompare(%s, ", Token::Str(comp->kind())); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 695 } | 772 } |
| 696 | 773 |
| 697 | 774 |
| 698 void FlowGraphPrinter::VisitStoreLocal(StoreLocalComp* comp) { | 775 void FlowGraphPrinter::VisitStoreLocal(StoreLocalComp* comp) { |
| 699 OS::Print("StoreLocal(%s, ", comp->local().name().ToCString()); | 776 OS::Print("StoreLocal(%s, ", comp->local().name().ToCString()); |
| 700 comp->value()->Accept(this); | 777 comp->value()->Accept(this); |
| 701 OS::Print(")"); | 778 OS::Print(")"); |
| 702 } | 779 } |
| 703 | 780 |
| 704 | 781 |
| 782 void FlowGraphPrinter::VisitStoreIndexed(StoreIndexedComp* comp) { |
| 783 OS::Print("StoreIndexed("); |
| 784 comp->placeholder()->Accept(this); |
| 785 OS::Print(", "); |
| 786 comp->array()->Accept(this); |
| 787 OS::Print(", "); |
| 788 comp->index()->Accept(this); |
| 789 OS::Print(", "); |
| 790 comp->value()->Accept(this); |
| 791 OS::Print(")"); |
| 792 } |
| 793 |
| 794 |
| 795 void FlowGraphPrinter::VisitInstanceSetter(InstanceSetterComp* comp) { |
| 796 OS::Print("InstanceSetter("); |
| 797 comp->placeholder()->Accept(this); |
| 798 OS::Print(", "); |
| 799 comp->receiver()->Accept(this); |
| 800 OS::Print(", "); |
| 801 comp->value()->Accept(this); |
| 802 OS::Print(")"); |
| 803 } |
| 804 |
| 805 |
| 705 void FlowGraphPrinter::VisitJoinEntry(JoinEntryInstr* instr) { | 806 void FlowGraphPrinter::VisitJoinEntry(JoinEntryInstr* instr) { |
| 706 OS::Print("%2d: [join]", instr->block_number()); | 807 OS::Print("%2d: [join]", instr->block_number()); |
| 707 } | 808 } |
| 708 | 809 |
| 709 | 810 |
| 710 void FlowGraphPrinter::VisitTargetEntry(TargetEntryInstr* instr) { | 811 void FlowGraphPrinter::VisitTargetEntry(TargetEntryInstr* instr) { |
| 711 OS::Print("%2d: [target]", instr->block_number()); | 812 OS::Print("%2d: [target]", instr->block_number()); |
| 712 } | 813 } |
| 713 | 814 |
| 714 | 815 |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 765 char* chars = reinterpret_cast<char*>( | 866 char* chars = reinterpret_cast<char*>( |
| 766 Isolate::Current()->current_zone()->Allocate(len)); | 867 Isolate::Current()->current_zone()->Allocate(len)); |
| 767 OS::SNPrint(chars, len, kFormat, function_name, reason); | 868 OS::SNPrint(chars, len, kFormat, function_name, reason); |
| 768 const Error& error = Error::Handle( | 869 const Error& error = Error::Handle( |
| 769 LanguageError::New(String::Handle(String::New(chars)))); | 870 LanguageError::New(String::Handle(String::New(chars)))); |
| 770 Isolate::Current()->long_jump_base()->Jump(1, error); | 871 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 771 } | 872 } |
| 772 | 873 |
| 773 | 874 |
| 774 } // namespace dart | 875 } // namespace dart |
| OLD | NEW |