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/bit_vector.h" | 8 #include "vm/bit_vector.h" |
| 9 #include "vm/code_descriptors.h" | 9 #include "vm/code_descriptors.h" |
| 10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| (...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 259 (kind == RawFunction::kConstImplicitGetter); | 259 (kind == RawFunction::kConstImplicitGetter); |
| 260 const bool is_static = owner()->parsed_function().function().is_static(); | 260 const bool is_static = owner()->parsed_function().function().is_static(); |
| 261 // Implicit getters do not need a type check at return, unless they compute | 261 // Implicit getters do not need a type check at return, unless they compute |
| 262 // the initial value of a static field. | 262 // the initial value of a static field. |
| 263 if (is_static || !is_implicit_getter) { | 263 if (is_static || !is_implicit_getter) { |
| 264 const AbstractType& dst_type = | 264 const AbstractType& dst_type = |
| 265 AbstractType::ZoneHandle( | 265 AbstractType::ZoneHandle( |
| 266 owner()->parsed_function().function().result_type()); | 266 owner()->parsed_function().function().result_type()); |
| 267 const String& dst_name = | 267 const String& dst_name = |
| 268 String::ZoneHandle(String::NewSymbol("function result")); | 268 String::ZoneHandle(String::NewSymbol("function result")); |
| 269 return_value = BuildAssignableValue(node->value(), | 269 return_value = BuildAssignableValue(node->value()->token_index(), |
| 270 return_value, | 270 return_value, |
| 271 dst_type, | 271 dst_type, |
| 272 dst_name); | 272 dst_name); |
| 273 } | 273 } |
| 274 } | 274 } |
| 275 | 275 |
| 276 intptr_t current_context_level = owner()->context_level(); | 276 intptr_t current_context_level = owner()->context_level(); |
| 277 ASSERT(current_context_level >= 0); | 277 ASSERT(current_context_level >= 0); |
| 278 if (owner()->parsed_function().saved_context_var() != NULL) { | 278 if (owner()->parsed_function().saved_context_var() != NULL) { |
| 279 // CTX on entry was saved, but not linked as context parent. | 279 // CTX on entry was saved, but not linked as context parent. |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 375 // dst_name: String } | 375 // dst_name: String } |
| 376 void EffectGraphVisitor::VisitAssignableNode(AssignableNode* node) { | 376 void EffectGraphVisitor::VisitAssignableNode(AssignableNode* node) { |
| 377 UNREACHABLE(); | 377 UNREACHABLE(); |
| 378 } | 378 } |
| 379 | 379 |
| 380 | 380 |
| 381 void ValueGraphVisitor::VisitAssignableNode(AssignableNode* node) { | 381 void ValueGraphVisitor::VisitAssignableNode(AssignableNode* node) { |
| 382 ValueGraphVisitor for_value(owner(), temp_index()); | 382 ValueGraphVisitor for_value(owner(), temp_index()); |
| 383 node->expr()->Visit(&for_value); | 383 node->expr()->Visit(&for_value); |
| 384 Append(for_value); | 384 Append(for_value); |
| 385 ReturnValue(BuildAssignableValue(node->expr(), | 385 ReturnValue(BuildAssignableValue(node->expr()->token_index(), |
| 386 for_value.value(), | 386 for_value.value(), |
| 387 node->type(), | 387 node->type(), |
| 388 node->dst_name())); | 388 node->dst_name())); |
| 389 } | 389 } |
| 390 | 390 |
| 391 | 391 |
| 392 // <Expression> :: BinaryOp { kind: Token::Kind | 392 // <Expression> :: BinaryOp { kind: Token::Kind |
| 393 // left: <Expression> | 393 // left: <Expression> |
| 394 // right: <Expression> } | 394 // right: <Expression> } |
| 395 void EffectGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) { | 395 void EffectGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) { |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 569 StaticCallComp* call = | 569 StaticCallComp* call = |
| 570 new StaticCallComp(node->token_index(), | 570 new StaticCallComp(node->token_index(), |
| 571 owner()->try_index(), | 571 owner()->try_index(), |
| 572 interpol_func, | 572 interpol_func, |
| 573 interpol_arg->names(), | 573 interpol_arg->names(), |
| 574 values); | 574 values); |
| 575 ReturnComputation(call); | 575 ReturnComputation(call); |
| 576 } | 576 } |
| 577 | 577 |
| 578 | 578 |
| 579 void EffectGraphVisitor::BuildAssertAssignable(intptr_t token_index, | 579 void EffectGraphVisitor::BuildTypecheckArguments( |
| 580 Value* value, | 580 intptr_t token_index, |
| 581 const AbstractType& dst_type, | 581 Value** instantiator_result, |
| 582 const String& dst_name) { | 582 Value** instantiator_type_arguments_result) { |
| 583 // Build the type check computation. | 583 Value* instantiator = NULL; |
| 584 Value* instantiator_type_arguments = NULL; | 584 Value* instantiator_type_arguments = NULL; |
| 585 if (!dst_type.IsInstantiated()) { | 585 const Class& instantiator_class = Class::Handle( |
| 586 owner()->parsed_function().function().owner()); | |
| 587 if (instantiator_class.NumTypeParameters() > 0) { | |
|
regis
2012/05/18 00:41:38
This does not look correct. The instantiator may h
| |
| 588 instantiator = BuildInstantiator(); | |
| 589 if (instantiator == NULL) { | |
| 590 instantiator_type_arguments = | |
| 591 BuildInstantiatorTypeArguments(token_index, NULL); | |
| 592 } else { | |
| 593 // Preserve instantiator. | |
| 594 const LocalVariable& expr_temp = | |
| 595 *owner()->parsed_function().expression_temp_var(); | |
| 596 Definition* saved = | |
| 597 new BindInstr(BuildStoreLocal(expr_temp, instantiator)); | |
| 598 AddInstruction(saved); | |
| 599 instantiator = new UseVal(saved); | |
| 600 Definition* loaded = new BindInstr(BuildLoadLocal(expr_temp)); | |
| 601 AddInstruction(loaded); | |
| 602 instantiator_type_arguments = | |
| 603 BuildInstantiatorTypeArguments(token_index, new UseVal(loaded)); | |
| 604 } | |
| 605 } else { | |
| 586 instantiator_type_arguments = | 606 instantiator_type_arguments = |
| 587 BuildInstantiatorTypeArguments(token_index); | 607 BuildInstantiatorTypeArguments(token_index, NULL); |
| 588 } | 608 } |
| 589 AssertAssignableComp* assert_assignable = | 609 *instantiator_result = instantiator; |
| 590 new AssertAssignableComp(token_index, | 610 *instantiator_type_arguments_result = instantiator_type_arguments; |
| 591 owner()->try_index(), | |
| 592 value, | |
| 593 instantiator_type_arguments, | |
| 594 dst_type, | |
| 595 dst_name); | |
| 596 AddInstruction(new DoInstr(assert_assignable)); | |
| 597 } | 611 } |
| 598 | 612 |
| 599 | 613 |
| 600 Value* EffectGraphVisitor::BuildAssignableValue(AstNode* value_node, | 614 // Used for testing incoming arguments. |
| 615 AssertAssignableComp* EffectGraphVisitor::BuildAssertAssignable( | |
| 616 intptr_t token_index, | |
| 617 Value* value, | |
| 618 const AbstractType& dst_type, | |
| 619 const String& dst_name) { | |
| 620 // Build the type check computation. | |
| 621 Value* instantiator = NULL; | |
| 622 Value* instantiator_type_arguments = NULL; | |
| 623 if (!dst_type.IsInstantiated()) { | |
| 624 BuildTypecheckArguments(token_index, | |
| 625 &instantiator, | |
| 626 &instantiator_type_arguments); | |
| 627 } | |
| 628 return new AssertAssignableComp(token_index, | |
| 629 owner()->try_index(), | |
| 630 value, | |
| 631 instantiator, | |
| 632 instantiator_type_arguments, | |
| 633 dst_type, | |
| 634 dst_name); | |
| 635 } | |
| 636 | |
| 637 | |
| 638 // Used to to test assignments. | |
| 639 Value* EffectGraphVisitor::BuildAssignableValue(intptr_t token_index, | |
| 601 Value* value, | 640 Value* value, |
| 602 const AbstractType& dst_type, | 641 const AbstractType& dst_type, |
| 603 const String& dst_name) { | 642 const String& dst_name) { |
| 604 if (CanSkipTypeCheck(value, dst_type)) { | 643 if (CanSkipTypeCheck(value, dst_type)) { |
| 605 return value; | 644 return value; |
| 606 } | 645 } |
| 607 | 646 AssertAssignableComp* comp = BuildAssertAssignable(token_index, |
| 608 // Build the type check computation. | 647 value, |
| 609 Value* instantiator_type_arguments = NULL; | 648 dst_type, |
| 610 if (!dst_type.IsInstantiated()) { | 649 dst_name); |
| 611 instantiator_type_arguments = | 650 Definition* assert_assignable = new BindInstr(comp); |
| 612 BuildInstantiatorTypeArguments(value_node->token_index()); | |
| 613 } | |
| 614 BindInstr* assert_assignable = | |
| 615 new BindInstr(new AssertAssignableComp(value_node->token_index(), | |
| 616 owner()->try_index(), | |
| 617 value, | |
| 618 instantiator_type_arguments, | |
| 619 dst_type, | |
| 620 dst_name)); | |
| 621 AddInstruction(assert_assignable); | 651 AddInstruction(assert_assignable); |
| 622 return new UseVal(assert_assignable); | 652 return new UseVal(assert_assignable); |
| 623 } | 653 } |
| 624 | 654 |
| 625 | 655 |
| 626 void EffectGraphVisitor::BuildInstanceOf(ComparisonNode* node) { | 656 void EffectGraphVisitor::BuildInstanceOf(ComparisonNode* node) { |
| 627 ASSERT(Token::IsInstanceofOperator(node->kind())); | 657 ASSERT(Token::IsInstanceofOperator(node->kind())); |
| 628 EffectGraphVisitor for_left_value(owner(), temp_index()); | 658 EffectGraphVisitor for_left_value(owner(), temp_index()); |
| 629 node->left()->Visit(&for_left_value); | 659 node->left()->Visit(&for_left_value); |
| 630 Append(for_left_value); | 660 Append(for_left_value); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 676 result = new ConstantVal(negate_result ? bool_true : bool_false); | 706 result = new ConstantVal(negate_result ? bool_true : bool_false); |
| 677 } | 707 } |
| 678 } | 708 } |
| 679 ReturnComputation(result); | 709 ReturnComputation(result); |
| 680 return; | 710 return; |
| 681 } | 711 } |
| 682 | 712 |
| 683 ValueGraphVisitor for_left_value(owner(), temp_index()); | 713 ValueGraphVisitor for_left_value(owner(), temp_index()); |
| 684 node->left()->Visit(&for_left_value); | 714 node->left()->Visit(&for_left_value); |
| 685 Append(for_left_value); | 715 Append(for_left_value); |
| 716 Value* instantiator = NULL; | |
| 686 Value* type_arguments = NULL; | 717 Value* type_arguments = NULL; |
| 687 if (!type.IsInstantiated()) { | 718 if (!type.IsInstantiated()) { |
| 688 type_arguments = | 719 BuildTypecheckArguments(node->token_index(), |
| 689 BuildInstantiatorTypeArguments(node->token_index()); | 720 &instantiator, |
| 721 &type_arguments); | |
| 690 } | 722 } |
| 691 InstanceOfComp* instance_of = | 723 InstanceOfComp* instance_of = |
| 692 new InstanceOfComp(node->token_index(), | 724 new InstanceOfComp(node->token_index(), |
| 693 owner()->try_index(), | 725 owner()->try_index(), |
| 694 for_left_value.value(), | 726 for_left_value.value(), |
| 727 instantiator, | |
| 695 type_arguments, | 728 type_arguments, |
| 696 node->right()->AsTypeNode()->type(), | 729 node->right()->AsTypeNode()->type(), |
| 697 (node->kind() == Token::kISNOT)); | 730 (node->kind() == Token::kISNOT)); |
| 698 ReturnComputation(instance_of); | 731 ReturnComputation(instance_of); |
| 699 } | 732 } |
| 700 | 733 |
| 701 | 734 |
| 702 // <Expression> :: Comparison { kind: Token::Kind | 735 // <Expression> :: Comparison { kind: Token::Kind |
| 703 // left: <Expression> | 736 // left: <Expression> |
| 704 // right: <Expression> } | 737 // right: <Expression> } |
| (...skipping 573 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1278 ASSERT(function.context_scope() != ContextScope::null()); | 1311 ASSERT(function.context_scope() != ContextScope::null()); |
| 1279 | 1312 |
| 1280 // The function type of a closure may have type arguments. In that case, pass | 1313 // The function type of a closure may have type arguments. In that case, pass |
| 1281 // the type arguments of the instantiator. | 1314 // the type arguments of the instantiator. |
| 1282 const Class& cls = Class::Handle(function.signature_class()); | 1315 const Class& cls = Class::Handle(function.signature_class()); |
| 1283 ASSERT(!cls.IsNull()); | 1316 ASSERT(!cls.IsNull()); |
| 1284 const bool requires_type_arguments = cls.HasTypeArguments(); | 1317 const bool requires_type_arguments = cls.HasTypeArguments(); |
| 1285 Value* type_arguments = NULL; | 1318 Value* type_arguments = NULL; |
| 1286 if (requires_type_arguments) { | 1319 if (requires_type_arguments) { |
| 1287 ASSERT(!function.IsImplicitStaticClosureFunction()); | 1320 ASSERT(!function.IsImplicitStaticClosureFunction()); |
| 1288 type_arguments = | 1321 type_arguments = BuildInstantiatorTypeArguments(node->token_index(), NULL); |
| 1289 BuildInstantiatorTypeArguments(node->token_index()); | |
| 1290 } | 1322 } |
| 1291 | 1323 |
| 1292 CreateClosureComp* create = | 1324 CreateClosureComp* create = |
| 1293 new CreateClosureComp(node, owner()->try_index(), type_arguments); | 1325 new CreateClosureComp(node, owner()->try_index(), type_arguments); |
| 1294 ReturnComputation(create); | 1326 ReturnComputation(create); |
| 1295 } | 1327 } |
| 1296 | 1328 |
| 1297 | 1329 |
| 1298 void EffectGraphVisitor::TranslateArgumentList( | 1330 void EffectGraphVisitor::TranslateArgumentList( |
| 1299 const ArgumentListNode& node, | 1331 const ArgumentListNode& node, |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1460 // t_n <- AllocateObject(class) | 1492 // t_n <- AllocateObject(class) |
| 1461 // t_n+1 <- ctor-arg | 1493 // t_n+1 <- ctor-arg |
| 1462 // t_n+2... <- constructor arguments start here | 1494 // t_n+2... <- constructor arguments start here |
| 1463 // StaticCall(constructor, t_n+1, t_n+2, ...) | 1495 // StaticCall(constructor, t_n+1, t_n+2, ...) |
| 1464 // No need to preserve allocated value (simpler than in ValueGraphVisitor). | 1496 // No need to preserve allocated value (simpler than in ValueGraphVisitor). |
| 1465 Definition* allocate = BuildObjectAllocation(node); | 1497 Definition* allocate = BuildObjectAllocation(node); |
| 1466 BuildConstructorCall(node, new UseVal(allocate)); | 1498 BuildConstructorCall(node, new UseVal(allocate)); |
| 1467 } | 1499 } |
| 1468 | 1500 |
| 1469 | 1501 |
| 1470 Value* EffectGraphVisitor::BuildInstantiatorTypeArguments( | 1502 Value* EffectGraphVisitor::BuildInstantiator() { |
| 1471 intptr_t token_index) { | |
| 1472 const Class& instantiator_class = Class::Handle( | 1503 const Class& instantiator_class = Class::Handle( |
| 1473 owner()->parsed_function().function().owner()); | 1504 owner()->parsed_function().function().owner()); |
| 1474 if (instantiator_class.NumTypeParameters() == 0) { | 1505 if (instantiator_class.NumTypeParameters() == 0) { |
| 1506 return NULL; | |
| 1507 } | |
| 1508 Function& outer_function = | |
| 1509 Function::Handle(owner()->parsed_function().function().raw()); | |
| 1510 while (outer_function.IsLocalFunction()) { | |
| 1511 outer_function = outer_function.parent_function(); | |
| 1512 } | |
| 1513 if (outer_function.IsFactory()) { | |
| 1514 return NULL; | |
| 1515 } | |
| 1516 | |
| 1517 ASSERT(owner()->parsed_function().instantiator() != NULL); | |
| 1518 ValueGraphVisitor for_instantiator(owner(), temp_index()); | |
| 1519 owner()->parsed_function().instantiator()->Visit(&for_instantiator); | |
| 1520 Append(for_instantiator); | |
| 1521 return for_instantiator.value(); | |
| 1522 } | |
| 1523 | |
| 1524 | |
| 1525 // 'expression_temp_var' may not be used inside this method if 'instantiator' | |
| 1526 // is not NULL. | |
| 1527 Value* EffectGraphVisitor::BuildInstantiatorTypeArguments( | |
| 1528 intptr_t token_index, Value* instantiator) { | |
| 1529 const Class& instantiator_class = Class::Handle( | |
| 1530 owner()->parsed_function().function().owner()); | |
| 1531 if (instantiator_class.NumTypeParameters() == 0) { | |
| 1475 // The type arguments are compile time constants. | 1532 // The type arguments are compile time constants. |
| 1476 AbstractTypeArguments& type_arguments = AbstractTypeArguments::ZoneHandle(); | 1533 AbstractTypeArguments& type_arguments = AbstractTypeArguments::ZoneHandle(); |
| 1477 // TODO(regis): Temporary type should be allocated in new gen heap. | 1534 // TODO(regis): Temporary type should be allocated in new gen heap. |
| 1478 Type& type = Type::Handle( | 1535 Type& type = Type::Handle( |
| 1479 Type::New(instantiator_class, type_arguments, token_index)); | 1536 Type::New(instantiator_class, type_arguments, token_index)); |
| 1480 type ^= ClassFinalizer::FinalizeType( | 1537 type ^= ClassFinalizer::FinalizeType( |
| 1481 instantiator_class, type, ClassFinalizer::kFinalizeWellFormed); | 1538 instantiator_class, type, ClassFinalizer::kFinalizeWellFormed); |
| 1482 type_arguments = type.arguments(); | 1539 type_arguments = type.arguments(); |
| 1483 BindInstr* args = new BindInstr(new ConstantVal(type_arguments)); | 1540 BindInstr* args = new BindInstr(new ConstantVal(type_arguments)); |
| 1484 AddInstruction(args); | 1541 AddInstruction(args); |
| 1485 return new UseVal(args); | 1542 return new UseVal(args); |
| 1486 } | 1543 } |
| 1487 ASSERT(owner()->parsed_function().instantiator() != NULL); | |
| 1488 ValueGraphVisitor for_instantiator(owner(), temp_index()); | |
| 1489 owner()->parsed_function().instantiator()->Visit(&for_instantiator); | |
| 1490 Append(for_instantiator); | |
| 1491 Function& outer_function = | 1544 Function& outer_function = |
| 1492 Function::Handle(owner()->parsed_function().function().raw()); | 1545 Function::Handle(owner()->parsed_function().function().raw()); |
| 1493 while (outer_function.IsLocalFunction()) { | 1546 while (outer_function.IsLocalFunction()) { |
| 1494 outer_function = outer_function.parent_function(); | 1547 outer_function = outer_function.parent_function(); |
| 1495 } | 1548 } |
| 1496 if (outer_function.IsFactory()) { | 1549 if (outer_function.IsFactory()) { |
| 1497 // All OK. | 1550 // No instantiator for factories. |
| 1551 ASSERT(instantiator == NULL); | |
| 1552 ASSERT(owner()->parsed_function().instantiator() != NULL); | |
| 1553 ValueGraphVisitor for_instantiator(owner(), temp_index()); | |
| 1554 owner()->parsed_function().instantiator()->Visit(&for_instantiator); | |
| 1555 Append(for_instantiator); | |
| 1498 return for_instantiator.value(); | 1556 return for_instantiator.value(); |
| 1499 } | 1557 } |
| 1500 | 1558 if (instantiator == NULL) { |
| 1559 instantiator = BuildInstantiator(); | |
| 1560 } | |
| 1501 // The instantiator is the receiver of the caller, which is not a factory. | 1561 // The instantiator is the receiver of the caller, which is not a factory. |
| 1502 // The receiver cannot be null; extract its AbstractTypeArguments object. | 1562 // The receiver cannot be null; extract its AbstractTypeArguments object. |
| 1503 // Note that in the factory case, the instantiator is the first parameter | 1563 // Note that in the factory case, the instantiator is the first parameter |
| 1504 // of the factory, i.e. already an AbstractTypeArguments object. | 1564 // of the factory, i.e. already an AbstractTypeArguments object. |
| 1505 intptr_t type_arguments_instance_field_offset = | 1565 intptr_t type_arguments_instance_field_offset = |
| 1506 instantiator_class.type_arguments_instance_field_offset(); | 1566 instantiator_class.type_arguments_instance_field_offset(); |
| 1507 ASSERT(type_arguments_instance_field_offset != Class::kNoTypeArguments); | 1567 ASSERT(type_arguments_instance_field_offset != Class::kNoTypeArguments); |
| 1508 | 1568 |
| 1509 BindInstr* load = | 1569 BindInstr* load = |
| 1510 new BindInstr(new NativeLoadFieldComp( | 1570 new BindInstr(new NativeLoadFieldComp( |
| 1511 for_instantiator.value(), | 1571 instantiator, |
| 1512 type_arguments_instance_field_offset, | 1572 type_arguments_instance_field_offset, |
| 1513 Type::ZoneHandle())); // Not an instance, no type. | 1573 Type::ZoneHandle())); // Not an instance, no type. |
| 1514 AddInstruction(load); | 1574 AddInstruction(load); |
| 1515 return new UseVal(load); | 1575 return new UseVal(load); |
| 1516 } | 1576 } |
| 1517 | 1577 |
| 1518 | 1578 |
| 1519 Definition* EffectGraphVisitor::BuildInstantiatedTypeArguments( | 1579 Definition* EffectGraphVisitor::BuildInstantiatedTypeArguments( |
| 1520 intptr_t token_index, | 1580 intptr_t token_index, |
| 1521 const AbstractTypeArguments& type_arguments) { | 1581 const AbstractTypeArguments& type_arguments) { |
| 1522 if (type_arguments.IsNull() || type_arguments.IsInstantiated()) { | 1582 if (type_arguments.IsNull() || type_arguments.IsInstantiated()) { |
| 1523 BindInstr* type_args = | 1583 BindInstr* type_args = |
| 1524 new BindInstr(new ConstantVal(type_arguments)); | 1584 new BindInstr(new ConstantVal(type_arguments)); |
| 1525 AddInstruction(type_args); | 1585 AddInstruction(type_args); |
| 1526 return type_args; | 1586 return type_args; |
| 1527 } | 1587 } |
| 1528 // The type arguments are uninstantiated. | 1588 // The type arguments are uninstantiated. |
| 1529 Value* instantiator_value = BuildInstantiatorTypeArguments(token_index); | 1589 Value* instantiator_value = |
| 1590 BuildInstantiatorTypeArguments(token_index, NULL); | |
| 1530 BindInstr* instantiate = | 1591 BindInstr* instantiate = |
| 1531 new BindInstr(new InstantiateTypeArgumentsComp(token_index, | 1592 new BindInstr(new InstantiateTypeArgumentsComp(token_index, |
| 1532 owner()->try_index(), | 1593 owner()->try_index(), |
| 1533 type_arguments, | 1594 type_arguments, |
| 1534 instantiator_value)); | 1595 instantiator_value)); |
| 1535 AddInstruction(instantiate); | 1596 AddInstruction(instantiate); |
| 1536 return instantiate; | 1597 return instantiate; |
| 1537 } | 1598 } |
| 1538 | 1599 |
| 1539 | 1600 |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 1561 // t1 = InstantiatorTypeArguments(); | 1622 // t1 = InstantiatorTypeArguments(); |
| 1562 // t2 = ExtractConstructorTypeArguments(t1); | 1623 // t2 = ExtractConstructorTypeArguments(t1); |
| 1563 // t1 = ExtractConstructorInstantiator(t1); | 1624 // t1 = ExtractConstructorInstantiator(t1); |
| 1564 // t_n <- t2 | 1625 // t_n <- t2 |
| 1565 // t_n+1 <- t1 | 1626 // t_n+1 <- t1 |
| 1566 // Use expression_temp_var and node->allocated_object_var() locals to keep | 1627 // Use expression_temp_var and node->allocated_object_var() locals to keep |
| 1567 // intermediate results around (t1 and t2 above). | 1628 // intermediate results around (t1 and t2 above). |
| 1568 ASSERT(owner()->parsed_function().expression_temp_var() != NULL); | 1629 ASSERT(owner()->parsed_function().expression_temp_var() != NULL); |
| 1569 const LocalVariable& t1 = *owner()->parsed_function().expression_temp_var(); | 1630 const LocalVariable& t1 = *owner()->parsed_function().expression_temp_var(); |
| 1570 const LocalVariable& t2 = node->allocated_object_var(); | 1631 const LocalVariable& t2 = node->allocated_object_var(); |
| 1571 Value* instantiator = BuildInstantiatorTypeArguments(node->token_index()); | 1632 Value* instantiator_type_arguments = BuildInstantiatorTypeArguments( |
| 1572 ASSERT(instantiator->IsUse()); | 1633 node->token_index(), NULL); |
| 1634 ASSERT(instantiator_type_arguments->IsUse()); | |
| 1573 Definition* stored_instantiator = new BindInstr( | 1635 Definition* stored_instantiator = new BindInstr( |
| 1574 BuildStoreLocal(t1, instantiator)); | 1636 BuildStoreLocal(t1, instantiator_type_arguments)); |
| 1575 AddInstruction(stored_instantiator); | 1637 AddInstruction(stored_instantiator); |
| 1576 // t1: instantiator type arguments. | 1638 // t1: instantiator type arguments. |
| 1577 | 1639 |
| 1578 BindInstr* extract_type_arguments = new BindInstr( | 1640 BindInstr* extract_type_arguments = new BindInstr( |
| 1579 new ExtractConstructorTypeArgumentsComp( | 1641 new ExtractConstructorTypeArgumentsComp( |
| 1580 node->token_index(), | 1642 node->token_index(), |
| 1581 owner()->try_index(), | 1643 owner()->try_index(), |
| 1582 node->type_arguments(), | 1644 node->type_arguments(), |
| 1583 new UseVal(stored_instantiator))); | 1645 new UseVal(stored_instantiator))); |
| 1584 AddInstruction(extract_type_arguments); | 1646 AddInstruction(extract_type_arguments); |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1733 | 1795 |
| 1734 | 1796 |
| 1735 // <Expression> ::= StoreLocal { local: LocalVariable | 1797 // <Expression> ::= StoreLocal { local: LocalVariable |
| 1736 // value: <Expression> } | 1798 // value: <Expression> } |
| 1737 void EffectGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) { | 1799 void EffectGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) { |
| 1738 ValueGraphVisitor for_value(owner(), temp_index()); | 1800 ValueGraphVisitor for_value(owner(), temp_index()); |
| 1739 node->value()->Visit(&for_value); | 1801 node->value()->Visit(&for_value); |
| 1740 Append(for_value); | 1802 Append(for_value); |
| 1741 Value* store_value = for_value.value(); | 1803 Value* store_value = for_value.value(); |
| 1742 if (FLAG_enable_type_checks) { | 1804 if (FLAG_enable_type_checks) { |
| 1743 store_value = BuildAssignableValue(node->value(), | 1805 store_value = BuildAssignableValue(node->value()->token_index(), |
| 1744 store_value, | 1806 store_value, |
| 1745 node->local().type(), | 1807 node->local().type(), |
| 1746 node->local().name()); | 1808 node->local().name()); |
| 1747 } | 1809 } |
| 1748 Computation* store = BuildStoreLocal(node->local(), store_value); | 1810 Computation* store = BuildStoreLocal(node->local(), store_value); |
| 1749 ReturnComputation(store); | 1811 ReturnComputation(store); |
| 1750 } | 1812 } |
| 1751 | 1813 |
| 1752 | 1814 |
| 1753 void EffectGraphVisitor::VisitLoadInstanceFieldNode( | 1815 void EffectGraphVisitor::VisitLoadInstanceFieldNode( |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 1766 ValueGraphVisitor for_instance(owner(), temp_index()); | 1828 ValueGraphVisitor for_instance(owner(), temp_index()); |
| 1767 node->instance()->Visit(&for_instance); | 1829 node->instance()->Visit(&for_instance); |
| 1768 Append(for_instance); | 1830 Append(for_instance); |
| 1769 ValueGraphVisitor for_value(owner(), for_instance.temp_index()); | 1831 ValueGraphVisitor for_value(owner(), for_instance.temp_index()); |
| 1770 node->value()->Visit(&for_value); | 1832 node->value()->Visit(&for_value); |
| 1771 Append(for_value); | 1833 Append(for_value); |
| 1772 Value* store_value = for_value.value(); | 1834 Value* store_value = for_value.value(); |
| 1773 if (FLAG_enable_type_checks) { | 1835 if (FLAG_enable_type_checks) { |
| 1774 const AbstractType& type = AbstractType::ZoneHandle(node->field().type()); | 1836 const AbstractType& type = AbstractType::ZoneHandle(node->field().type()); |
| 1775 const String& dst_name = String::ZoneHandle(node->field().name()); | 1837 const String& dst_name = String::ZoneHandle(node->field().name()); |
| 1776 store_value = BuildAssignableValue(node->value(), | 1838 store_value = BuildAssignableValue(node->value()->token_index(), |
| 1777 store_value, | 1839 store_value, |
| 1778 type, | 1840 type, |
| 1779 dst_name); | 1841 dst_name); |
| 1780 } | 1842 } |
| 1781 StoreInstanceFieldComp* store = | 1843 StoreInstanceFieldComp* store = |
| 1782 new StoreInstanceFieldComp(node, for_instance.value(), store_value); | 1844 new StoreInstanceFieldComp(node, for_instance.value(), store_value); |
| 1783 ReturnComputation(store); | 1845 ReturnComputation(store); |
| 1784 } | 1846 } |
| 1785 | 1847 |
| 1786 | 1848 |
| 1787 void EffectGraphVisitor::VisitLoadStaticFieldNode(LoadStaticFieldNode* node) { | 1849 void EffectGraphVisitor::VisitLoadStaticFieldNode(LoadStaticFieldNode* node) { |
| 1788 LoadStaticFieldComp* load = new LoadStaticFieldComp(node->field()); | 1850 LoadStaticFieldComp* load = new LoadStaticFieldComp(node->field()); |
| 1789 ReturnComputation(load); | 1851 ReturnComputation(load); |
| 1790 } | 1852 } |
| 1791 | 1853 |
| 1792 | 1854 |
| 1793 void EffectGraphVisitor::VisitStoreStaticFieldNode(StoreStaticFieldNode* node) { | 1855 void EffectGraphVisitor::VisitStoreStaticFieldNode(StoreStaticFieldNode* node) { |
| 1794 ValueGraphVisitor for_value(owner(), temp_index()); | 1856 ValueGraphVisitor for_value(owner(), temp_index()); |
| 1795 node->value()->Visit(&for_value); | 1857 node->value()->Visit(&for_value); |
| 1796 Append(for_value); | 1858 Append(for_value); |
| 1797 Value* store_value = for_value.value(); | 1859 Value* store_value = for_value.value(); |
| 1798 if (FLAG_enable_type_checks) { | 1860 if (FLAG_enable_type_checks) { |
| 1799 const AbstractType& type = AbstractType::ZoneHandle(node->field().type()); | 1861 const AbstractType& type = AbstractType::ZoneHandle(node->field().type()); |
| 1800 const String& dst_name = String::ZoneHandle(node->field().name()); | 1862 const String& dst_name = String::ZoneHandle(node->field().name()); |
| 1801 store_value = BuildAssignableValue(node->value(), | 1863 store_value = BuildAssignableValue(node->value()->token_index(), |
| 1802 store_value, | 1864 store_value, |
| 1803 type, | 1865 type, |
| 1804 dst_name); | 1866 dst_name); |
| 1805 } | 1867 } |
| 1806 StoreStaticFieldComp* store = | 1868 StoreStaticFieldComp* store = |
| 1807 new StoreStaticFieldComp(node->field(), store_value); | 1869 new StoreStaticFieldComp(node->field(), store_value); |
| 1808 ReturnComputation(store); | 1870 ReturnComputation(store); |
| 1809 } | 1871 } |
| 1810 | 1872 |
| 1811 | 1873 |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1962 // Skip type checking of type arguments for factory functions. | 2024 // Skip type checking of type arguments for factory functions. |
| 1963 // Skip type checking of receiver for instance functions. | 2025 // Skip type checking of receiver for instance functions. |
| 1964 pos = 1; | 2026 pos = 1; |
| 1965 } | 2027 } |
| 1966 while (pos < num_params) { | 2028 while (pos < num_params) { |
| 1967 const LocalVariable& parameter = *scope->VariableAt(pos); | 2029 const LocalVariable& parameter = *scope->VariableAt(pos); |
| 1968 ASSERT(parameter.owner() == scope); | 2030 ASSERT(parameter.owner() == scope); |
| 1969 if (!CanSkipTypeCheck(NULL, parameter.type())) { | 2031 if (!CanSkipTypeCheck(NULL, parameter.type())) { |
| 1970 BindInstr* load = new BindInstr(BuildLoadLocal(parameter)); | 2032 BindInstr* load = new BindInstr(BuildLoadLocal(parameter)); |
| 1971 AddInstruction(load); | 2033 AddInstruction(load); |
| 1972 BuildAssertAssignable(parameter.token_index(), | 2034 AssertAssignableComp* assert_assignable = |
| 1973 new UseVal(load), | 2035 BuildAssertAssignable(parameter.token_index(), |
| 1974 parameter.type(), | 2036 new UseVal(load), |
| 1975 parameter.name()); | 2037 parameter.type(), |
| 2038 parameter.name()); | |
| 2039 AddInstruction(new DoInstr(assert_assignable)); | |
| 1976 } | 2040 } |
| 1977 pos++; | 2041 pos++; |
| 1978 } | 2042 } |
| 1979 } | 2043 } |
| 1980 | 2044 |
| 1981 intptr_t i = 0; | 2045 intptr_t i = 0; |
| 1982 while (is_open() && (i < node->length())) { | 2046 while (is_open() && (i < node->length())) { |
| 1983 EffectGraphVisitor for_effect(owner(), temp_index()); | 2047 EffectGraphVisitor for_effect(owner(), temp_index()); |
| 1984 node->NodeAt(i++)->Visit(&for_effect); | 2048 node->NodeAt(i++)->Visit(&for_effect); |
| 1985 Append(for_effect); | 2049 Append(for_effect); |
| (...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2312 char* chars = reinterpret_cast<char*>( | 2376 char* chars = reinterpret_cast<char*>( |
| 2313 Isolate::Current()->current_zone()->Allocate(len)); | 2377 Isolate::Current()->current_zone()->Allocate(len)); |
| 2314 OS::SNPrint(chars, len, kFormat, function_name, reason); | 2378 OS::SNPrint(chars, len, kFormat, function_name, reason); |
| 2315 const Error& error = Error::Handle( | 2379 const Error& error = Error::Handle( |
| 2316 LanguageError::New(String::Handle(String::New(chars)))); | 2380 LanguageError::New(String::Handle(String::New(chars)))); |
| 2317 Isolate::Current()->long_jump_base()->Jump(1, error); | 2381 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 2318 } | 2382 } |
| 2319 | 2383 |
| 2320 | 2384 |
| 2321 } // namespace dart | 2385 } // namespace dart |
| OLD | NEW |