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 part of ssa; | 5 part of ssa; |
6 | 6 |
7 /** | 7 /** |
8 * A special element for the extra parameter taken by intercepted | 8 * A special element for the extra parameter taken by intercepted |
9 * methods. We need to override [Element.computeType] because our | 9 * methods. We need to override [Element.computeType] because our |
10 * optimizers may look at its declared type. | 10 * optimizers may look at its declared type. |
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
268 builder.graph.thisInstruction = thisInstruction; | 268 builder.graph.thisInstruction = thisInstruction; |
269 builder.graph.entry.addAtEntry(thisInstruction); | 269 builder.graph.entry.addAtEntry(thisInstruction); |
270 directLocals[closureData.thisElement] = thisInstruction; | 270 directLocals[closureData.thisElement] = thisInstruction; |
271 } | 271 } |
272 | 272 |
273 // If this method is an intercepted method, add the extra | 273 // If this method is an intercepted method, add the extra |
274 // parameter to it, that is the actual receiver for intercepted | 274 // parameter to it, that is the actual receiver for intercepted |
275 // classes, or the same as [:this:] for non-intercepted classes. | 275 // classes, or the same as [:this:] for non-intercepted classes. |
276 ClassElement cls = element.getEnclosingClass(); | 276 ClassElement cls = element.getEnclosingClass(); |
277 JavaScriptBackend backend = compiler.backend; | 277 JavaScriptBackend backend = compiler.backend; |
278 bool isNativeUpgradeFactory = element.isGenerativeConstructor() | |
ngeoffray
2013/10/17 09:08:59
What is a native upgrade factory?
sra1
2013/10/18 04:09:32
Added comment
| |
279 && Elements.isNativeOrExtendsNative(cls); | |
278 if (backend.isInterceptedMethod(element)) { | 280 if (backend.isInterceptedMethod(element)) { |
279 bool isInterceptorClass = backend.isInterceptorClass(cls.declaration); | 281 bool isInterceptorClass = backend.isInterceptorClass(cls.declaration); |
280 SourceString name = isInterceptorClass | 282 SourceString name = isInterceptorClass |
281 ? const SourceString('receiver') | 283 ? const SourceString('receiver') |
282 : const SourceString('_'); | 284 : const SourceString('_'); |
283 Element parameter = new InterceptedElement( | 285 Element parameter = new InterceptedElement( |
284 cls.computeType(compiler), name, element); | 286 cls.computeType(compiler), name, element); |
285 HParameterValue value = new HParameterValue(parameter); | 287 HParameterValue value = new HParameterValue(parameter); |
286 builder.graph.explicitReceiverParameter = value; | 288 builder.graph.explicitReceiverParameter = value; |
287 builder.graph.entry.addAfter( | 289 builder.graph.entry.addAfter( |
288 directLocals[closureData.thisElement], value); | 290 directLocals[closureData.thisElement], value); |
289 if (isInterceptorClass) { | 291 if (isInterceptorClass) { |
290 // Only use the extra parameter in intercepted classes. | 292 // Only use the extra parameter in intercepted classes. |
291 directLocals[closureData.thisElement] = value; | 293 directLocals[closureData.thisElement] = value; |
292 } | 294 } |
293 value.instructionType = builder.getTypeOfThis(); | 295 value.instructionType = builder.getTypeOfThis(); |
296 } else if (isNativeUpgradeFactory) { | |
297 bool isInterceptorClass = backend.isInterceptorClass(cls.declaration); | |
298 Element parameter = new InterceptedElement( | |
299 cls.computeType(compiler), const SourceString('receiver'), element); | |
300 HParameterValue value = new HParameterValue(parameter); | |
301 builder.graph.explicitReceiverParameter = value; | |
302 builder.graph.entry.addAtEntry(value); | |
303 value.instructionType = builder.getTypeOfThis(); | |
ngeoffray
2013/10/17 09:08:59
This seems very similar to the code line 281 to 29
sra1
2013/10/18 04:09:32
In the fixed version there are more differences, e
| |
294 } | 304 } |
295 } | 305 } |
296 | 306 |
297 bool hasValueForDirectLocal(Element element) { | 307 bool hasValueForDirectLocal(Element element) { |
298 assert(element != null); | 308 assert(element != null); |
299 assert(isAccessedDirectly(element)); | 309 assert(isAccessedDirectly(element)); |
300 return directLocals[element] != null; | 310 return directLocals[element] != null; |
301 } | 311 } |
302 | 312 |
303 /** | 313 /** |
(...skipping 956 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1260 } | 1270 } |
1261 | 1271 |
1262 // Don't inline operator== methods if the parameter can be null. | 1272 // Don't inline operator== methods if the parameter can be null. |
1263 if (element.name == const SourceString('==')) { | 1273 if (element.name == const SourceString('==')) { |
1264 if (element.getEnclosingClass() != compiler.objectClass | 1274 if (element.getEnclosingClass() != compiler.objectClass |
1265 && providedArguments[1].canBeNull()) { | 1275 && providedArguments[1].canBeNull()) { |
1266 return false; | 1276 return false; |
1267 } | 1277 } |
1268 } | 1278 } |
1269 | 1279 |
1280 // Generative constructors of native classes should not be called directly | |
1281 // and have an extra argument that causes problems with inlining. | |
1282 if (element.isGenerativeConstructor() | |
1283 && Elements.isNativeOrExtendsNative(element.getEnclosingClass())) { | |
1284 return false; | |
1285 } | |
1286 | |
1270 // A generative constructor body is not seen by global analysis, | 1287 // A generative constructor body is not seen by global analysis, |
1271 // so we should not query for its type. | 1288 // so we should not query for its type. |
1272 if (!element.isGenerativeConstructorBody()) { | 1289 if (!element.isGenerativeConstructorBody()) { |
1273 // Don't inline if the return type was inferred to be non-null empty. | 1290 // Don't inline if the return type was inferred to be non-null empty. |
1274 // This means that the function always throws an exception. | 1291 // This means that the function always throws an exception. |
1275 TypeMask returnType = | 1292 TypeMask returnType = |
1276 compiler.typesTask.getGuaranteedReturnTypeOfElement(element); | 1293 compiler.typesTask.getGuaranteedReturnTypeOfElement(element); |
1277 if (returnType != null | 1294 if (returnType != null |
1278 && returnType.isEmpty | 1295 && returnType.isEmpty |
1279 && !returnType.isNullable) { | 1296 && !returnType.isNullable) { |
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1579 */ | 1596 */ |
1580 void buildFieldInitializers(ClassElement classElement, | 1597 void buildFieldInitializers(ClassElement classElement, |
1581 Map<Element, HInstruction> fieldValues) { | 1598 Map<Element, HInstruction> fieldValues) { |
1582 assert(invariant(classElement, classElement.isImplementation)); | 1599 assert(invariant(classElement, classElement.isImplementation)); |
1583 classElement.forEachInstanceField( | 1600 classElement.forEachInstanceField( |
1584 (ClassElement enclosingClass, Element member) { | 1601 (ClassElement enclosingClass, Element member) { |
1585 compiler.withCurrentElement(member, () { | 1602 compiler.withCurrentElement(member, () { |
1586 TreeElements definitions = compiler.analyzeElement(member); | 1603 TreeElements definitions = compiler.analyzeElement(member); |
1587 Node node = member.parseNode(compiler); | 1604 Node node = member.parseNode(compiler); |
1588 SendSet assignment = node.asSendSet(); | 1605 SendSet assignment = node.asSendSet(); |
1589 HInstruction value; | |
1590 if (assignment == null) { | 1606 if (assignment == null) { |
1591 value = graph.addConstantNull(compiler); | 1607 // Unassigned fields of native classes are not initialized to |
1608 // prevent overwriting pre-initialized native properties. | |
1609 if (!Elements.isNativeOrExtendsNative(classElement)) { | |
1610 HInstruction value = graph.addConstantNull(compiler); | |
ngeoffray
2013/10/17 09:08:59
Avoid the temporary?
sra1
2013/10/18 04:09:32
Done.
| |
1611 fieldValues[member] = value; | |
1612 } | |
1592 } else { | 1613 } else { |
1593 Node right = assignment.arguments.head; | 1614 Node right = assignment.arguments.head; |
1594 TreeElements savedElements = elements; | 1615 TreeElements savedElements = elements; |
1595 elements = definitions; | 1616 elements = definitions; |
1596 // In case the field initializer uses closures, run the | 1617 // In case the field initializer uses closures, run the |
1597 // closure to class mapper. | 1618 // closure to class mapper. |
1598 compiler.closureToClassMapper.computeClosureToClassMapping( | 1619 compiler.closureToClassMapper.computeClosureToClassMapping( |
1599 member, node, elements); | 1620 member, node, elements); |
1600 inlinedFrom(member, () => right.accept(this)); | 1621 inlinedFrom(member, () => right.accept(this)); |
1601 elements = savedElements; | 1622 elements = savedElements; |
1602 value = pop(); | 1623 HInstruction value = pop(); |
1624 fieldValues[member] = value; | |
ngeoffray
2013/10/17 09:08:59
Avoid the temporary?
sra1
2013/10/18 04:09:32
Done.
| |
1603 } | 1625 } |
1604 fieldValues[member] = value; | |
1605 }); | 1626 }); |
1606 }); | 1627 }); |
1607 } | 1628 } |
1608 | 1629 |
1609 /** | 1630 /** |
1610 * Build the factory function corresponding to the constructor | 1631 * Build the factory function corresponding to the constructor |
1611 * [functionElement]: | 1632 * [functionElement]: |
1612 * - Initialize fields with the values of the field initializers of the | 1633 * - Initialize fields with the values of the field initializers of the |
1613 * current constructor and super constructors or constructors redirected | 1634 * current constructor and super constructors or constructors redirected |
1614 * to, starting from the current constructor. | 1635 * to, starting from the current constructor. |
1615 * - Call the constructor bodies, starting from the constructor(s) in the | 1636 * - Call the constructor bodies, starting from the constructor(s) in the |
1616 * super class(es). | 1637 * super class(es). |
1617 */ | 1638 */ |
1618 HGraph buildFactory(FunctionElement functionElement) { | 1639 HGraph buildFactory(FunctionElement functionElement) { |
1619 functionElement = functionElement.implementation; | 1640 functionElement = functionElement.implementation; |
1620 ClassElement classElement = | 1641 ClassElement classElement = |
1621 functionElement.getEnclosingClass().implementation; | 1642 functionElement.getEnclosingClass().implementation; |
1643 bool isNativeUpgradeFactory = | |
1644 Elements.isNativeOrExtendsNative(classElement); | |
1622 FunctionExpression function = functionElement.parseNode(compiler); | 1645 FunctionExpression function = functionElement.parseNode(compiler); |
1623 // Note that constructors (like any other static function) do not need | 1646 // Note that constructors (like any other static function) do not need |
1624 // to deal with optional arguments. It is the callers job to provide all | 1647 // to deal with optional arguments. It is the callers job to provide all |
1625 // arguments as if they were positional. | 1648 // arguments as if they were positional. |
1626 | 1649 |
1627 if (inliningStack.isEmpty) { | 1650 if (inliningStack.isEmpty) { |
1628 // The initializer list could contain closures. | 1651 // The initializer list could contain closures. |
1629 openFunction(functionElement, function); | 1652 openFunction(functionElement, function); |
1630 } | 1653 } |
1631 | 1654 |
(...skipping 15 matching lines...) Expand all Loading... | |
1647 } | 1670 } |
1648 }); | 1671 }); |
1649 | 1672 |
1650 // Analyze the constructor and all referenced constructors and collect | 1673 // Analyze the constructor and all referenced constructors and collect |
1651 // initializers and constructor bodies. | 1674 // initializers and constructor bodies. |
1652 List<FunctionElement> constructors = <FunctionElement>[functionElement]; | 1675 List<FunctionElement> constructors = <FunctionElement>[functionElement]; |
1653 buildInitializers(functionElement, constructors, fieldValues); | 1676 buildInitializers(functionElement, constructors, fieldValues); |
1654 | 1677 |
1655 // Call the JavaScript constructor with the fields as argument. | 1678 // Call the JavaScript constructor with the fields as argument. |
1656 List<HInstruction> constructorArguments = <HInstruction>[]; | 1679 List<HInstruction> constructorArguments = <HInstruction>[]; |
1680 List<Element> fields = <Element>[]; | |
1681 | |
1657 classElement.forEachInstanceField( | 1682 classElement.forEachInstanceField( |
1658 (ClassElement enclosingClass, Element member) { | 1683 (ClassElement enclosingClass, Element member) { |
1659 constructorArguments.add(potentiallyCheckType( | 1684 HInstruction value = fieldValues[member]; |
1660 fieldValues[member], member.computeType(compiler))); | 1685 if (value == null) { |
1686 // Uninitialized native fields are pre-initialized by the native | |
1687 // implementation. | |
1688 assert(isNativeUpgradeFactory); | |
1689 } else { | |
1690 fields.add(member); | |
1691 constructorArguments.add( | |
1692 potentiallyCheckType(value, member.computeType(compiler))); | |
1693 } | |
1661 }, | 1694 }, |
1662 includeSuperAndInjectedMembers: true); | 1695 includeSuperAndInjectedMembers: true); |
1663 | 1696 |
1664 InterfaceType type = classElement.computeType(compiler); | 1697 InterfaceType type = classElement.computeType(compiler); |
1665 HType ssaType = new HType.nonNullExact(classElement, compiler); | 1698 HType ssaType = new HType.nonNullExact(classElement, compiler); |
1666 List<DartType> instantiatedTypes; | 1699 List<DartType> instantiatedTypes; |
1667 addInlinedInstantiation(type); | 1700 addInlinedInstantiation(type); |
1668 if (!currentInlinedInstantiations.isEmpty) { | 1701 if (!currentInlinedInstantiations.isEmpty) { |
1669 instantiatedTypes = new List<DartType>.from(currentInlinedInstantiations); | 1702 instantiatedTypes = new List<DartType>.from(currentInlinedInstantiations); |
1670 } | 1703 } |
1671 HForeignNew newObject = new HForeignNew(classElement, | 1704 |
1672 ssaType, | 1705 HInstruction newObject; |
1673 constructorArguments, | 1706 if (!isNativeUpgradeFactory) { |
1674 instantiatedTypes); | 1707 newObject = new HForeignNew(classElement, |
1675 add(newObject); | 1708 ssaType, |
1709 constructorArguments, | |
1710 instantiatedTypes); | |
1711 add(newObject); | |
1712 } else { | |
1713 // Bulk assign to the initialized fields. | |
1714 newObject = graph.explicitReceiverParameter; | |
1715 // Null guard ensures an error if we are being called from an explicit | |
1716 // 'new' of the constructor instead of via an upgrade. It is optimized out | |
1717 // if there are field initializers. | |
1718 add(new HFieldGet(null, newObject, isAssignable: false)); | |
1719 for (int i = 0; i < fields.length; i++) { | |
1720 add(new HFieldSet(fields[i], newObject, constructorArguments[i])); | |
1721 } | |
1722 } | |
1676 removeInlinedInstantiation(type); | 1723 removeInlinedInstantiation(type); |
1677 // Create the runtime type information, if needed. | 1724 // Create the runtime type information, if needed. |
1678 if (backend.classNeedsRti(classElement)) { | 1725 if (backend.classNeedsRti(classElement)) { |
1679 List<HInstruction> rtiInputs = <HInstruction>[]; | 1726 List<HInstruction> rtiInputs = <HInstruction>[]; |
1680 classElement.typeVariables.forEach((TypeVariableType typeVariable) { | 1727 classElement.typeVariables.forEach((TypeVariableType typeVariable) { |
1681 rtiInputs.add(localsHandler.readLocal(typeVariable.element)); | 1728 rtiInputs.add(localsHandler.readLocal(typeVariable.element)); |
1682 }); | 1729 }); |
1683 callSetRuntimeTypeInfo(classElement, rtiInputs, newObject); | 1730 callSetRuntimeTypeInfo(classElement, rtiInputs, newObject); |
1684 } | 1731 } |
1685 | 1732 |
1686 // Generate calls to the constructor bodies. | 1733 // Generate calls to the constructor bodies. |
1734 HInstruction interceptor = null; | |
1687 for (int index = constructors.length - 1; index >= 0; index--) { | 1735 for (int index = constructors.length - 1; index >= 0; index--) { |
1688 FunctionElement constructor = constructors[index]; | 1736 FunctionElement constructor = constructors[index]; |
1689 assert(invariant(functionElement, constructor.isImplementation)); | 1737 assert(invariant(functionElement, constructor.isImplementation)); |
1690 ConstructorBodyElement body = getConstructorBody(constructor); | 1738 ConstructorBodyElement body = getConstructorBody(constructor); |
1691 if (body == null) continue; | 1739 if (body == null) continue; |
1740 | |
1692 List bodyCallInputs = <HInstruction>[]; | 1741 List bodyCallInputs = <HInstruction>[]; |
1742 if (isNativeUpgradeFactory) { | |
1743 if (interceptor == null) { | |
1744 Constant constant = new InterceptorConstant( | |
1745 classElement.computeType(compiler)); | |
1746 interceptor = graph.addConstant(constant, compiler); | |
1747 } | |
1748 bodyCallInputs.add(interceptor); | |
1749 } | |
1693 bodyCallInputs.add(newObject); | 1750 bodyCallInputs.add(newObject); |
1694 TreeElements elements = | 1751 TreeElements elements = |
1695 compiler.enqueuer.resolution.getCachedElements(constructor); | 1752 compiler.enqueuer.resolution.getCachedElements(constructor); |
1696 Node node = constructor.parseNode(compiler); | 1753 Node node = constructor.parseNode(compiler); |
1697 ClosureClassMap parameterClosureData = | 1754 ClosureClassMap parameterClosureData = |
1698 compiler.closureToClassMapper.getMappingForNestedFunction(node); | 1755 compiler.closureToClassMapper.getMappingForNestedFunction(node); |
1699 | 1756 |
1700 | |
1701 FunctionSignature functionSignature = body.computeSignature(compiler); | 1757 FunctionSignature functionSignature = body.computeSignature(compiler); |
1702 // Provide the parameters to the generative constructor body. | 1758 // Provide the parameters to the generative constructor body. |
1703 functionSignature.orderedForEachParameter((parameter) { | 1759 functionSignature.orderedForEachParameter((parameter) { |
1704 // If [parameter] is boxed, it will be a field in the box passed as the | 1760 // If [parameter] is boxed, it will be a field in the box passed as the |
1705 // last parameter. So no need to directly pass it. | 1761 // last parameter. So no need to directly pass it. |
1706 if (!localsHandler.isBoxed(parameter)) { | 1762 if (!localsHandler.isBoxed(parameter)) { |
1707 bodyCallInputs.add(localsHandler.readLocal(parameter)); | 1763 bodyCallInputs.add(localsHandler.readLocal(parameter)); |
1708 } | 1764 } |
1709 }); | 1765 }); |
1710 | 1766 |
1711 ClassElement currentClass = constructor.getEnclosingClass(); | 1767 ClassElement currentClass = constructor.getEnclosingClass(); |
1712 if (backend.classNeedsRti(currentClass)) { | 1768 if (backend.classNeedsRti(currentClass)) { |
1713 // If [currentClass] needs RTI, we add the type variables as | 1769 // If [currentClass] needs RTI, we add the type variables as |
1714 // parameters of the generative constructor body. | 1770 // parameters of the generative constructor body. |
1715 currentClass.typeVariables.forEach((DartType argument) { | 1771 currentClass.typeVariables.forEach((DartType argument) { |
1716 bodyCallInputs.add(localsHandler.readLocal(argument.element)); | 1772 bodyCallInputs.add(localsHandler.readLocal(argument.element)); |
1717 }); | 1773 }); |
1718 } | 1774 } |
1719 | 1775 |
1720 // If there are locals that escape (ie mutated in closures), we | 1776 // If there are locals that escape (ie mutated in closures), we |
1721 // pass the box to the constructor. | 1777 // pass the box to the constructor. |
1722 ClosureScope scopeData = parameterClosureData.capturingScopes[node]; | 1778 ClosureScope scopeData = parameterClosureData.capturingScopes[node]; |
1723 if (scopeData != null) { | 1779 if (scopeData != null) { |
1724 bodyCallInputs.add(localsHandler.readLocal(scopeData.boxElement)); | 1780 bodyCallInputs.add(localsHandler.readLocal(scopeData.boxElement)); |
1725 } | 1781 } |
1726 | 1782 |
1727 if (tryInlineMethod(body, null, bodyCallInputs, function)) { | 1783 if (!isNativeUpgradeFactory && // TODO(13836): Fix inlining. |
1784 tryInlineMethod(body, null, bodyCallInputs, function)) { | |
1728 pop(); | 1785 pop(); |
1729 } else { | 1786 } else { |
1730 HInvokeConstructorBody invoke = | 1787 HInvokeConstructorBody invoke = |
1731 new HInvokeConstructorBody(body.declaration, bodyCallInputs); | 1788 new HInvokeConstructorBody(body.declaration, bodyCallInputs); |
1732 invoke.sideEffects = | 1789 invoke.sideEffects = |
1733 compiler.world.getSideEffectsOfElement(constructor); | 1790 compiler.world.getSideEffectsOfElement(constructor); |
1734 add(invoke); | 1791 add(invoke); |
1735 } | 1792 } |
1736 } | 1793 } |
1737 if (inliningStack.isEmpty) { | 1794 if (inliningStack.isEmpty) { |
(...skipping 1820 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3558 } | 3615 } |
3559 | 3616 |
3560 bool isRedirected = functionElement.isRedirectingFactory; | 3617 bool isRedirected = functionElement.isRedirectingFactory; |
3561 InterfaceType type = elements.getType(node); | 3618 InterfaceType type = elements.getType(node); |
3562 DartType expectedType = type; | 3619 DartType expectedType = type; |
3563 if (isRedirected) { | 3620 if (isRedirected) { |
3564 type = functionElement.computeTargetType(compiler, type); | 3621 type = functionElement.computeTargetType(compiler, type); |
3565 } | 3622 } |
3566 | 3623 |
3567 var inputs = <HInstruction>[]; | 3624 var inputs = <HInstruction>[]; |
3625 if (constructor.isGenerativeConstructor() && | |
3626 Elements.isNativeOrExtendsNative(constructor.getEnclosingClass())) { | |
3627 // Native class generative constructors take a pre-constructed object. | |
3628 inputs.add(graph.addConstantNull(compiler)); | |
3629 } | |
3568 // TODO(5347): Try to avoid the need for calling [implementation] before | 3630 // TODO(5347): Try to avoid the need for calling [implementation] before |
3569 // calling [addStaticSendArgumentsToList]. | 3631 // calling [addStaticSendArgumentsToList]. |
3570 bool succeeded = addStaticSendArgumentsToList(selector, send.arguments, | 3632 bool succeeded = addStaticSendArgumentsToList(selector, send.arguments, |
3571 constructor.implementation, | 3633 constructor.implementation, |
3572 inputs); | 3634 inputs); |
3573 if (!succeeded) { | 3635 if (!succeeded) { |
3574 generateWrongArgumentCountError(send, constructor, send.arguments); | 3636 generateWrongArgumentCountError(send, constructor, send.arguments); |
3575 return; | 3637 return; |
3576 } | 3638 } |
3577 | 3639 |
(...skipping 1977 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5555 new HSubGraphBlockInformation(elseBranch.graph)); | 5617 new HSubGraphBlockInformation(elseBranch.graph)); |
5556 | 5618 |
5557 HBasicBlock conditionStartBlock = conditionBranch.block; | 5619 HBasicBlock conditionStartBlock = conditionBranch.block; |
5558 conditionStartBlock.setBlockFlow(info, joinBlock); | 5620 conditionStartBlock.setBlockFlow(info, joinBlock); |
5559 SubGraph conditionGraph = conditionBranch.graph; | 5621 SubGraph conditionGraph = conditionBranch.graph; |
5560 HIf branch = conditionGraph.end.last; | 5622 HIf branch = conditionGraph.end.last; |
5561 assert(branch is HIf); | 5623 assert(branch is HIf); |
5562 branch.blockInformation = conditionStartBlock.blockFlow; | 5624 branch.blockInformation = conditionStartBlock.blockFlow; |
5563 } | 5625 } |
5564 } | 5626 } |
OLD | NEW |