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 1435 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1446 context)); | 1446 context)); |
| 1447 ReturnComputation(new StoreContextComp(clone)); | 1447 ReturnComputation(new StoreContextComp(clone)); |
| 1448 } | 1448 } |
| 1449 | 1449 |
| 1450 | 1450 |
| 1451 Value* EffectGraphVisitor::BuildObjectAllocation( | 1451 Value* EffectGraphVisitor::BuildObjectAllocation( |
| 1452 ConstructorCallNode* node) { | 1452 ConstructorCallNode* node) { |
| 1453 const Class& cls = Class::ZoneHandle(node->constructor().owner()); | 1453 const Class& cls = Class::ZoneHandle(node->constructor().owner()); |
| 1454 const bool requires_type_arguments = cls.HasTypeArguments(); | 1454 const bool requires_type_arguments = cls.HasTypeArguments(); |
| 1455 | 1455 |
| 1456 ZoneGrowableArray<Value*>* allocate_arguments = | |
| 1457 new ZoneGrowableArray<Value*>(); | |
| 1458 if (requires_type_arguments) { | |
| 1459 BuildConstructorTypeArguments(node, allocate_arguments); | |
| 1460 } | |
| 1461 // In checked mode, if the type arguments are uninstantiated, they may need to | 1456 // In checked mode, if the type arguments are uninstantiated, they may need to |
| 1462 // be checked against declared bounds at run time. | 1457 // be checked against declared bounds at run time. |
| 1463 Computation* allocate_comp = NULL; | 1458 Computation* allocate_comp = NULL; |
| 1464 if (FLAG_enable_type_checks && | 1459 if (FLAG_enable_type_checks && |
| 1465 requires_type_arguments && | 1460 requires_type_arguments && |
| 1466 !node->type_arguments().IsNull() && | 1461 !node->type_arguments().IsNull() && |
| 1467 !node->type_arguments().IsInstantiated() && | 1462 !node->type_arguments().IsInstantiated() && |
| 1468 !node->type_arguments().IsWithinBoundsOf(cls, | 1463 !node->type_arguments().IsWithinBoundsOf(cls, |
| 1469 node->type_arguments(), | 1464 node->type_arguments(), |
| 1470 NULL)) { | 1465 NULL)) { |
| 1466 Value* type_arguments = NULL; | |
| 1467 Value* instantiator = NULL; | |
| 1468 BuildConstructorTypeArguments(node, &type_arguments, &instantiator, NULL); | |
| 1469 | |
| 1471 // The uninstantiated type arguments cannot be verified to be within their | 1470 // The uninstantiated type arguments cannot be verified to be within their |
| 1472 // bounds at compile time, so verify them at runtime. | 1471 // bounds at compile time, so verify them at runtime. |
| 1473 // Although the type arguments may be uninstantiated at compile time, they | 1472 // Although the type arguments may be uninstantiated at compile time, they |
| 1474 // may represent the identity vector and may be replaced by the instantiated | 1473 // may represent the identity vector and may be replaced by the instantiated |
| 1475 // type arguments of the instantiator at run time. | 1474 // type arguments of the instantiator at run time. |
| 1476 allocate_comp = new AllocateObjectWithBoundsCheckComp(node, | 1475 allocate_comp = new AllocateObjectWithBoundsCheckComp(node, |
| 1477 owner()->try_index(), | 1476 owner()->try_index(), |
| 1478 allocate_arguments); | 1477 type_arguments, |
| 1478 instantiator); | |
| 1479 } else { | 1479 } else { |
| 1480 ZoneGrowableArray<PushArgumentInstr*>* allocate_arguments = | |
| 1481 new ZoneGrowableArray<PushArgumentInstr*>(); | |
| 1482 | |
| 1483 if (requires_type_arguments) { | |
| 1484 BuildConstructorTypeArguments(node, NULL, NULL, allocate_arguments); | |
| 1485 } | |
| 1486 | |
| 1480 allocate_comp = new AllocateObjectComp(node, | 1487 allocate_comp = new AllocateObjectComp(node, |
| 1481 owner()->try_index(), | 1488 owner()->try_index(), |
| 1482 allocate_arguments); | 1489 allocate_arguments); |
| 1483 } | 1490 } |
| 1484 return Bind(allocate_comp); | 1491 return Bind(allocate_comp); |
| 1485 } | 1492 } |
| 1486 | 1493 |
| 1487 | 1494 |
| 1488 void EffectGraphVisitor::BuildConstructorCall( | 1495 void EffectGraphVisitor::BuildConstructorCall( |
| 1489 ConstructorCallNode* node, | 1496 ConstructorCallNode* node, |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1622 BuildInstantiatorTypeArguments(token_pos, NULL); | 1629 BuildInstantiatorTypeArguments(token_pos, NULL); |
| 1623 return Bind(new InstantiateTypeArgumentsComp(token_pos, | 1630 return Bind(new InstantiateTypeArgumentsComp(token_pos, |
| 1624 owner()->try_index(), | 1631 owner()->try_index(), |
| 1625 type_arguments, | 1632 type_arguments, |
| 1626 instantiator_value)); | 1633 instantiator_value)); |
| 1627 } | 1634 } |
| 1628 | 1635 |
| 1629 | 1636 |
| 1630 void EffectGraphVisitor::BuildConstructorTypeArguments( | 1637 void EffectGraphVisitor::BuildConstructorTypeArguments( |
| 1631 ConstructorCallNode* node, | 1638 ConstructorCallNode* node, |
| 1632 ZoneGrowableArray<Value*>* args) { | 1639 Value** type_arguments, |
| 1640 Value** instantiator, | |
| 1641 ZoneGrowableArray<PushArgumentInstr*>* call_arguments) { | |
|
Vyacheslav Egorov (Google)
2012/08/08 19:28:55
This function became a little bit ugly.
I did not
Florian Schneider
2012/08/09 12:25:58
Yes, it seems that this helper is not the right ab
| |
| 1633 const Class& cls = Class::ZoneHandle(node->constructor().owner()); | 1642 const Class& cls = Class::ZoneHandle(node->constructor().owner()); |
| 1634 ASSERT(cls.HasTypeArguments() && !node->constructor().IsFactory()); | 1643 ASSERT(cls.HasTypeArguments() && !node->constructor().IsFactory()); |
| 1635 if (node->type_arguments().IsNull() || | 1644 if (node->type_arguments().IsNull() || |
| 1636 node->type_arguments().IsInstantiated()) { | 1645 node->type_arguments().IsInstantiated()) { |
| 1637 Value* type_args = Bind(new ConstantVal(node->type_arguments())); | 1646 Value* type_arguments_val = Bind(new ConstantVal(node->type_arguments())); |
| 1647 if (call_arguments != NULL) { | |
| 1648 ASSERT(type_arguments == NULL); | |
| 1649 call_arguments->Add(PushArgument(type_arguments_val)); | |
| 1650 } else { | |
| 1651 ASSERT(type_arguments != NULL); | |
| 1652 *type_arguments = type_arguments_val; | |
| 1653 } | |
| 1654 | |
| 1638 // No instantiator required. | 1655 // No instantiator required. |
| 1639 Value* no_instantiator = Bind( | 1656 Value* instantiator_val = Bind( |
| 1640 new ConstantVal(Smi::ZoneHandle(Smi::New(StubCode::kNoInstantiator)))); | 1657 new ConstantVal(Smi::ZoneHandle(Smi::New(StubCode::kNoInstantiator)))); |
| 1641 args->Add(type_args); | 1658 if (call_arguments != NULL) { |
| 1642 args->Add(no_instantiator); | 1659 ASSERT(instantiator == NULL); |
| 1660 call_arguments->Add(PushArgument(instantiator_val)); | |
| 1661 } else { | |
| 1662 ASSERT(instantiator != NULL); | |
| 1663 *instantiator = instantiator_val; | |
| 1664 } | |
| 1643 return; | 1665 return; |
| 1644 } | 1666 } |
| 1645 // The type arguments are uninstantiated. The generated pseudo code: | 1667 // The type arguments are uninstantiated. The generated pseudo code: |
| 1646 // t1 = InstantiatorTypeArguments(); | 1668 // t1 = InstantiatorTypeArguments(); |
| 1647 // t2 = ExtractConstructorTypeArguments(t1); | 1669 // t2 = ExtractConstructorTypeArguments(t1); |
| 1648 // t1 = ExtractConstructorInstantiator(t1); | 1670 // t1 = ExtractConstructorInstantiator(t1); |
| 1649 // t_n <- t2 | 1671 // t_n <- t2 |
| 1650 // t_n+1 <- t1 | 1672 // t_n+1 <- t1 |
| 1651 // Use expression_temp_var and node->allocated_object_var() locals to keep | 1673 // Use expression_temp_var and node->allocated_object_var() locals to keep |
| 1652 // intermediate results around (t1 and t2 above). | 1674 // intermediate results around (t1 and t2 above). |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 1669 | 1691 |
| 1670 Do(BuildStoreLocal(t2, extract_type_arguments)); | 1692 Do(BuildStoreLocal(t2, extract_type_arguments)); |
| 1671 // t2: extracted constructor type arguments. | 1693 // t2: extracted constructor type arguments. |
| 1672 Value* load_instantiator = Bind(BuildLoadLocal(t1)); | 1694 Value* load_instantiator = Bind(BuildLoadLocal(t1)); |
| 1673 | 1695 |
| 1674 Value* extract_instantiator = | 1696 Value* extract_instantiator = |
| 1675 Bind(new ExtractConstructorInstantiatorComp(node, load_instantiator)); | 1697 Bind(new ExtractConstructorInstantiatorComp(node, load_instantiator)); |
| 1676 Do(BuildStoreLocal(t1, extract_instantiator)); | 1698 Do(BuildStoreLocal(t1, extract_instantiator)); |
| 1677 // t2: extracted constructor type arguments. | 1699 // t2: extracted constructor type arguments. |
| 1678 // t1: extracted constructor instantiator. | 1700 // t1: extracted constructor instantiator. |
| 1679 Value* load_0 = Bind(BuildLoadLocal(t2)); | 1701 Value* type_arguments_val = Bind(BuildLoadLocal(t2)); |
| 1680 Value* load_1 = Bind(BuildLoadLocal(t1)); | 1702 if (call_arguments != NULL) { |
| 1681 args->Add(load_0); | 1703 ASSERT(type_arguments == NULL); |
| 1682 args->Add(load_1); | 1704 call_arguments->Add(PushArgument(type_arguments_val)); |
| 1705 } else { | |
| 1706 ASSERT(type_arguments != NULL); | |
| 1707 *type_arguments = type_arguments_val; | |
| 1708 } | |
| 1709 | |
| 1710 Value* instantiator_val = Bind(BuildLoadLocal(t1)); | |
| 1711 if (call_arguments != NULL) { | |
| 1712 ASSERT(instantiator == NULL); | |
| 1713 call_arguments->Add(PushArgument(instantiator_val)); | |
| 1714 } else { | |
| 1715 ASSERT(instantiator != NULL); | |
| 1716 *instantiator = instantiator_val; | |
| 1717 } | |
| 1683 } | 1718 } |
| 1684 | 1719 |
| 1685 | 1720 |
| 1686 void ValueGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) { | 1721 void ValueGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) { |
| 1687 if (node->constructor().IsFactory()) { | 1722 if (node->constructor().IsFactory()) { |
| 1688 EffectGraphVisitor::VisitConstructorCallNode(node); | 1723 EffectGraphVisitor::VisitConstructorCallNode(node); |
| 1689 return; | 1724 return; |
| 1690 } | 1725 } |
| 1691 | 1726 |
| 1692 // t_n contains the allocated and initialized object. | 1727 // t_n contains the allocated and initialized object. |
| (...skipping 1052 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2745 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; | 2780 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; |
| 2746 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); | 2781 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); |
| 2747 OS::SNPrint(chars, len, kFormat, function_name, reason); | 2782 OS::SNPrint(chars, len, kFormat, function_name, reason); |
| 2748 const Error& error = Error::Handle( | 2783 const Error& error = Error::Handle( |
| 2749 LanguageError::New(String::Handle(String::New(chars)))); | 2784 LanguageError::New(String::Handle(String::New(chars)))); |
| 2750 Isolate::Current()->long_jump_base()->Jump(1, error); | 2785 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 2751 } | 2786 } |
| 2752 | 2787 |
| 2753 | 2788 |
| 2754 } // namespace dart | 2789 } // namespace dart |
| OLD | NEW |