| OLD | NEW |
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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.md file. | 3 // BSD-style license that can be found in the LICENSE.md file. |
| 4 | 4 |
| 5 import 'package:kernel/ast.dart' as ir; | 5 import 'package:kernel/ast.dart' as ir; |
| 6 import 'package:kernel/frontend/accessors.dart' | 6 import 'package:kernel/frontend/accessors.dart' |
| 7 show | 7 show |
| 8 Accessor, | 8 Accessor, |
| 9 IndexAccessor, | 9 IndexAccessor, |
| 10 NullAwarePropertyAccessor, | 10 NullAwarePropertyAccessor, |
| (...skipping 692 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 703 ir.DartType guard = computeType(node.type); | 703 ir.DartType guard = computeType(node.type); |
| 704 return new ir.Catch(exception, buildStatementInBlock(node.block), | 704 return new ir.Catch(exception, buildStatementInBlock(node.block), |
| 705 guard: guard, stackTrace: trace); | 705 guard: guard, stackTrace: trace); |
| 706 } | 706 } |
| 707 | 707 |
| 708 @override | 708 @override |
| 709 ir.ConditionalExpression visitConditional(Conditional node) { | 709 ir.ConditionalExpression visitConditional(Conditional node) { |
| 710 return new ir.ConditionalExpression( | 710 return new ir.ConditionalExpression( |
| 711 visitForValue(node.condition), | 711 visitForValue(node.condition), |
| 712 visitWithCurrentContext(node.thenExpression), | 712 visitWithCurrentContext(node.thenExpression), |
| 713 visitWithCurrentContext(node.elseExpression), | 713 visitWithCurrentContext(node.elseExpression)); |
| 714 null); | |
| 715 } | 714 } |
| 716 | 715 |
| 717 @override | 716 @override |
| 718 ir.Statement visitContinueStatement(ContinueStatement node) { | 717 ir.Statement visitContinueStatement(ContinueStatement node) { |
| 719 JumpTarget target = elements.getTargetOf(node); | 718 JumpTarget target = elements.getTargetOf(node); |
| 720 if (target == null || !target.statement.isValidContinueTarget()) { | 719 if (target == null || !target.statement.isValidContinueTarget()) { |
| 721 // This is a continue in an invalid position. | 720 // This is a continue in an invalid position. |
| 722 return new ir.InvalidStatement(); | 721 return new ir.InvalidStatement(); |
| 723 } | 722 } |
| 724 ir.SwitchCase switchCase = getContinueSwitchTarget(target); | 723 ir.SwitchCase switchCase = getContinueSwitchTarget(target); |
| (...skipping 581 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1306 visitForValue(receiver), nameToIrName(name), value); | 1305 visitForValue(receiver), nameToIrName(name), value); |
| 1307 } | 1306 } |
| 1308 | 1307 |
| 1309 @override | 1308 @override |
| 1310 ir.Expression handleDynamicSetIfNulls( | 1309 ir.Expression handleDynamicSetIfNulls( |
| 1311 Send node, Node receiver, Name name, Node rhs, _) { | 1310 Send node, Node receiver, Name name, Node rhs, _) { |
| 1312 ir.Name irName = nameToIrName(name); | 1311 ir.Name irName = nameToIrName(name); |
| 1313 Accessor accessor = (receiver == null) | 1312 Accessor accessor = (receiver == null) |
| 1314 ? new ThisPropertyAccessor(irName, null, null) | 1313 ? new ThisPropertyAccessor(irName, null, null) |
| 1315 : PropertyAccessor.make(visitForValue(receiver), irName, null, null); | 1314 : PropertyAccessor.make(visitForValue(receiver), irName, null, null); |
| 1316 return accessor.buildNullAwareAssignment(visitForValue(rhs), null, | 1315 return accessor.buildNullAwareAssignment(visitForValue(rhs), |
| 1317 voidContext: isVoidContext); | 1316 voidContext: isVoidContext); |
| 1318 } | 1317 } |
| 1319 | 1318 |
| 1320 @override | 1319 @override |
| 1321 ir.TypeLiteral visitDynamicTypeLiteralGet( | 1320 ir.TypeLiteral visitDynamicTypeLiteralGet( |
| 1322 Send node, ConstantExpression constant, _) { | 1321 Send node, ConstantExpression constant, _) { |
| 1323 return buildTypeLiteral(constant); | 1322 return buildTypeLiteral(constant); |
| 1324 } | 1323 } |
| 1325 | 1324 |
| 1326 @override | 1325 @override |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1498 ConstructorElement constructor, | 1497 ConstructorElement constructor, |
| 1499 InterfaceType type, | 1498 InterfaceType type, |
| 1500 NodeList arguments, | 1499 NodeList arguments, |
| 1501 CallStructure callStructure, | 1500 CallStructure callStructure, |
| 1502 _) { | 1501 _) { |
| 1503 return buildConstructorInvoke(node, isConst: false); | 1502 return buildConstructorInvoke(node, isConst: false); |
| 1504 } | 1503 } |
| 1505 | 1504 |
| 1506 Accessor buildNullAwarePropertyAccessor(Node receiver, Name name) { | 1505 Accessor buildNullAwarePropertyAccessor(Node receiver, Name name) { |
| 1507 return new NullAwarePropertyAccessor( | 1506 return new NullAwarePropertyAccessor( |
| 1508 visitForValue(receiver), nameToIrName(name), null, null, null); | 1507 visitForValue(receiver), nameToIrName(name), null, null); |
| 1509 } | 1508 } |
| 1510 | 1509 |
| 1511 @override | 1510 @override |
| 1512 ir.Expression visitIfNotNullDynamicPropertyGet( | 1511 ir.Expression visitIfNotNullDynamicPropertyGet( |
| 1513 Send node, Node receiver, Name name, _) { | 1512 Send node, Node receiver, Name name, _) { |
| 1514 return buildNullAwarePropertyAccessor(receiver, name).buildSimpleRead(); | 1513 return buildNullAwarePropertyAccessor(receiver, name).buildSimpleRead(); |
| 1515 } | 1514 } |
| 1516 | 1515 |
| 1517 @override | 1516 @override |
| 1518 ir.Let visitIfNotNullDynamicPropertyInvoke( | 1517 ir.Let visitIfNotNullDynamicPropertyInvoke( |
| 1519 Send node, Node receiverNode, NodeList arguments, Selector selector, _) { | 1518 Send node, Node receiverNode, NodeList arguments, Selector selector, _) { |
| 1520 ir.VariableDeclaration receiver = | 1519 ir.VariableDeclaration receiver = |
| 1521 makeOrReuseVariable(visitForValue(receiverNode)); | 1520 makeOrReuseVariable(visitForValue(receiverNode)); |
| 1522 return makeLet( | 1521 return makeLet( |
| 1523 receiver, | 1522 receiver, |
| 1524 new ir.ConditionalExpression( | 1523 new ir.ConditionalExpression( |
| 1525 buildIsNull(new ir.VariableGet(receiver)), | 1524 buildIsNull(new ir.VariableGet(receiver)), |
| 1526 new ir.NullLiteral(), | 1525 new ir.NullLiteral(), |
| 1527 buildInvokeSelector(new ir.VariableGet(receiver), selector, | 1526 buildInvokeSelector(new ir.VariableGet(receiver), selector, |
| 1528 buildArguments(arguments)), | 1527 buildArguments(arguments)))); |
| 1529 null)); | |
| 1530 } | 1528 } |
| 1531 | 1529 |
| 1532 @override | 1530 @override |
| 1533 ir.Expression visitIfNotNullDynamicPropertySet( | 1531 ir.Expression visitIfNotNullDynamicPropertySet( |
| 1534 SendSet node, Node receiver, Name name, Node rhs, _) { | 1532 SendSet node, Node receiver, Name name, Node rhs, _) { |
| 1535 return buildNullAwarePropertyAccessor(receiver, name) | 1533 return buildNullAwarePropertyAccessor(receiver, name) |
| 1536 .buildAssignment(visitForValue(rhs), voidContext: isVoidContext); | 1534 .buildAssignment(visitForValue(rhs), voidContext: isVoidContext); |
| 1537 } | 1535 } |
| 1538 | 1536 |
| 1539 @override | 1537 @override |
| 1540 ir.Expression visitIfNotNullDynamicPropertySetIfNull( | 1538 ir.Expression visitIfNotNullDynamicPropertySetIfNull( |
| 1541 Send node, Node receiver, Name name, Node rhs, _) { | 1539 Send node, Node receiver, Name name, Node rhs, _) { |
| 1542 return buildNullAwarePropertyAccessor(receiver, name) | 1540 return buildNullAwarePropertyAccessor(receiver, name) |
| 1543 .buildNullAwareAssignment(visitForValue(rhs), null, | 1541 .buildNullAwareAssignment(visitForValue(rhs), |
| 1544 voidContext: isVoidContext); | 1542 voidContext: isVoidContext); |
| 1545 } | 1543 } |
| 1546 | 1544 |
| 1547 ir.LogicalExpression buildLogicalExpression( | 1545 ir.LogicalExpression buildLogicalExpression( |
| 1548 Node left, Operator operator, Node right) { | 1546 Node left, Operator operator, Node right) { |
| 1549 return new ir.LogicalExpression( | 1547 return new ir.LogicalExpression( |
| 1550 visitForValue(left), operator.source, visitForValue(right)); | 1548 visitForValue(left), operator.source, visitForValue(right)); |
| 1551 } | 1549 } |
| 1552 | 1550 |
| 1553 @override | 1551 @override |
| 1554 ir.Expression visitIfNull(Send node, Node left, Node right, _) { | 1552 ir.LogicalExpression visitIfNull(Send node, Node left, Node right, _) { |
| 1555 var leftValue = new ir.VariableDeclaration.forValue(visitForValue(left)); | 1553 return buildLogicalExpression(left, node.selector, right); |
| 1556 return new ir.Let( | |
| 1557 leftValue, | |
| 1558 new ir.ConditionalExpression(buildIsNull(new ir.VariableGet(leftValue)), | |
| 1559 visitForValue(right), new ir.VariableGet(leftValue), null)); | |
| 1560 } | 1554 } |
| 1561 | 1555 |
| 1562 @override | 1556 @override |
| 1563 ir.Initializer visitImplicitSuperConstructorInvoke(FunctionExpression node, | 1557 ir.Initializer visitImplicitSuperConstructorInvoke(FunctionExpression node, |
| 1564 ConstructorElement superConstructor, InterfaceType type, _) { | 1558 ConstructorElement superConstructor, InterfaceType type, _) { |
| 1565 if (superConstructor == null) { | 1559 if (superConstructor == null) { |
| 1566 // TODO(ahe): Semantic visitor shouldn't call this. | 1560 // TODO(ahe): Semantic visitor shouldn't call this. |
| 1567 return new ir.InvalidInitializer(); | 1561 return new ir.InvalidInitializer(); |
| 1568 } | 1562 } |
| 1569 return new ir.SuperInitializer( | 1563 return new ir.SuperInitializer( |
| (...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1836 NodeList arguments, CallStructure callStructure, _) { | 1830 NodeList arguments, CallStructure callStructure, _) { |
| 1837 return associateNode( | 1831 return associateNode( |
| 1838 buildCall(buildLocalGet(element), callStructure, arguments), node); | 1832 buildCall(buildLocalGet(element), callStructure, arguments), node); |
| 1839 } | 1833 } |
| 1840 | 1834 |
| 1841 @override | 1835 @override |
| 1842 ir.Expression handleLocalSetIfNulls( | 1836 ir.Expression handleLocalSetIfNulls( |
| 1843 SendSet node, LocalElement local, Node rhs, _, | 1837 SendSet node, LocalElement local, Node rhs, _, |
| 1844 {bool isSetterValid}) { | 1838 {bool isSetterValid}) { |
| 1845 return new VariableAccessor(getLocal(local)).buildNullAwareAssignment( | 1839 return new VariableAccessor(getLocal(local)).buildNullAwareAssignment( |
| 1846 visitForValue(rhs), null, | 1840 visitForValue(rhs), |
| 1847 voidContext: isVoidContext); | 1841 voidContext: isVoidContext); |
| 1848 } | 1842 } |
| 1849 | 1843 |
| 1850 @override | 1844 @override |
| 1851 IrFunction visitRedirectingFactoryConstructorDeclaration( | 1845 IrFunction visitRedirectingFactoryConstructorDeclaration( |
| 1852 FunctionExpression node, | 1846 FunctionExpression node, |
| 1853 ConstructorElement constructor, | 1847 ConstructorElement constructor, |
| 1854 NodeList parameters, | 1848 NodeList parameters, |
| 1855 DartType redirectionType, // TODO(ahe): Should be InterfaceType. | 1849 DartType redirectionType, // TODO(ahe): Should be InterfaceType. |
| 1856 ConstructorElement redirectionTarget, | 1850 ConstructorElement redirectionTarget, |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1953 Element getter, | 1947 Element getter, |
| 1954 CompoundGetter getterKind, | 1948 CompoundGetter getterKind, |
| 1955 Element setter, | 1949 Element setter, |
| 1956 CompoundSetter setterKind, | 1950 CompoundSetter setterKind, |
| 1957 Node rhs, | 1951 Node rhs, |
| 1958 _) { | 1952 _) { |
| 1959 if (setterKind == CompoundSetter.INVALID) { | 1953 if (setterKind == CompoundSetter.INVALID) { |
| 1960 setter = null; | 1954 setter = null; |
| 1961 } | 1955 } |
| 1962 return buildStaticAccessor(getter, setter).buildNullAwareAssignment( | 1956 return buildStaticAccessor(getter, setter).buildNullAwareAssignment( |
| 1963 visitForValue(rhs), null, | 1957 visitForValue(rhs), |
| 1964 voidContext: isVoidContext); | 1958 voidContext: isVoidContext); |
| 1965 } | 1959 } |
| 1966 | 1960 |
| 1967 ir.VariableDeclaration getLocal(LocalElement local) { | 1961 ir.VariableDeclaration getLocal(LocalElement local) { |
| 1968 return locals.putIfAbsent(local, () { | 1962 return locals.putIfAbsent(local, () { |
| 1969 // Currently, initializing formals are not final. | 1963 // Currently, initializing formals are not final. |
| 1970 bool isFinal = local.isFinal && !local.isInitializingFormal; | 1964 bool isFinal = local.isFinal && !local.isInitializingFormal; |
| 1971 return associateElement( | 1965 return associateElement( |
| 1972 new ir.VariableDeclaration(local.name, | 1966 new ir.VariableDeclaration(local.name, |
| 1973 initializer: null, | 1967 initializer: null, |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1990 FunctionSignature signature = function.functionSignature; | 1984 FunctionSignature signature = function.functionSignature; |
| 1991 requiredParameterCount = signature.requiredParameterCount; | 1985 requiredParameterCount = signature.requiredParameterCount; |
| 1992 signature.forEachParameter((ParameterElement parameter) { | 1986 signature.forEachParameter((ParameterElement parameter) { |
| 1993 ir.VariableDeclaration variable = getLocal(parameter); | 1987 ir.VariableDeclaration variable = getLocal(parameter); |
| 1994 if (parameter.isNamed) { | 1988 if (parameter.isNamed) { |
| 1995 namedParameters.add(variable); | 1989 namedParameters.add(variable); |
| 1996 } else { | 1990 } else { |
| 1997 positionalParameters.add(variable); | 1991 positionalParameters.add(variable); |
| 1998 } | 1992 } |
| 1999 }); | 1993 }); |
| 2000 namedParameters.sort(); | |
| 2001 signature.forEachParameter((ParameterElement parameter) { | 1994 signature.forEachParameter((ParameterElement parameter) { |
| 2002 if (!parameter.isOptional) return; | 1995 if (!parameter.isOptional) return; |
| 2003 ir.Expression initializer = visitForValue(parameter.initializer); | 1996 ir.Expression initializer = visitForValue(parameter.initializer); |
| 2004 ir.VariableDeclaration variable = getLocal(parameter); | 1997 ir.VariableDeclaration variable = getLocal(parameter); |
| 2005 if (initializer != null) { | 1998 if (initializer != null) { |
| 2006 variable.initializer = initializer; | 1999 variable.initializer = initializer; |
| 2007 initializer.parent = variable; | 2000 initializer.parent = variable; |
| 2008 } | 2001 } |
| 2009 }); | 2002 }); |
| 2010 if (function.isGenerativeConstructor) { | 2003 if (function.isGenerativeConstructor) { |
| (...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2395 Element getter, | 2388 Element getter, |
| 2396 CompoundGetter getterKind, | 2389 CompoundGetter getterKind, |
| 2397 Element setter, | 2390 Element setter, |
| 2398 CompoundSetter setterKind, | 2391 CompoundSetter setterKind, |
| 2399 Node rhs, | 2392 Node rhs, |
| 2400 _) { | 2393 _) { |
| 2401 if (setterKind == CompoundSetter.INVALID) { | 2394 if (setterKind == CompoundSetter.INVALID) { |
| 2402 setter = null; | 2395 setter = null; |
| 2403 } | 2396 } |
| 2404 return buildSuperPropertyAccessor(getter, setter).buildNullAwareAssignment( | 2397 return buildSuperPropertyAccessor(getter, setter).buildNullAwareAssignment( |
| 2405 visitForValue(rhs), null, | 2398 visitForValue(rhs), |
| 2406 voidContext: isVoidContext); | 2399 voidContext: isVoidContext); |
| 2407 } | 2400 } |
| 2408 | 2401 |
| 2409 @override | 2402 @override |
| 2410 ir.SuperMethodInvocation visitSuperIndex( | 2403 ir.SuperMethodInvocation visitSuperIndex( |
| 2411 Send node, FunctionElement function, Node index, _) { | 2404 Send node, FunctionElement function, Node index, _) { |
| 2412 return buildSuperIndexAccessor(index, function).buildSimpleRead(); | 2405 return buildSuperIndexAccessor(index, function).buildSimpleRead(); |
| 2413 } | 2406 } |
| 2414 | 2407 |
| 2415 @override | 2408 @override |
| (...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2624 ir.Expression visitTypeVariableTypeLiteralSet( | 2617 ir.Expression visitTypeVariableTypeLiteralSet( |
| 2625 SendSet node, TypeVariableElement element, Node rhs, _) { | 2618 SendSet node, TypeVariableElement element, Node rhs, _) { |
| 2626 return new ReadOnlyAccessor(buildTypeVariable(element)) | 2619 return new ReadOnlyAccessor(buildTypeVariable(element)) |
| 2627 .buildAssignment(visitForValue(rhs), voidContext: isVoidContext); | 2620 .buildAssignment(visitForValue(rhs), voidContext: isVoidContext); |
| 2628 } | 2621 } |
| 2629 | 2622 |
| 2630 @override | 2623 @override |
| 2631 ir.Expression visitTypeVariableTypeLiteralSetIfNull( | 2624 ir.Expression visitTypeVariableTypeLiteralSetIfNull( |
| 2632 Send node, TypeVariableElement element, Node rhs, _) { | 2625 Send node, TypeVariableElement element, Node rhs, _) { |
| 2633 return new ReadOnlyAccessor(buildTypeVariable(element)) | 2626 return new ReadOnlyAccessor(buildTypeVariable(element)) |
| 2634 .buildNullAwareAssignment(visitForValue(rhs), null, | 2627 .buildNullAwareAssignment(visitForValue(rhs), |
| 2635 voidContext: isVoidContext); | 2628 voidContext: isVoidContext); |
| 2636 } | 2629 } |
| 2637 | 2630 |
| 2638 @override | 2631 @override |
| 2639 ir.TypeLiteral visitTypedefTypeLiteralGet( | 2632 ir.TypeLiteral visitTypedefTypeLiteralGet( |
| 2640 Send node, ConstantExpression constant, _) { | 2633 Send node, ConstantExpression constant, _) { |
| 2641 return buildTypeLiteral(constant); | 2634 return buildTypeLiteral(constant); |
| 2642 } | 2635 } |
| 2643 | 2636 |
| 2644 @override | 2637 @override |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2690 @override | 2683 @override |
| 2691 visitForIn(ForIn node) { | 2684 visitForIn(ForIn node) { |
| 2692 // Shouldn't be called, handled by [visitAsyncForIn] or [visitSyncForIn]. | 2685 // Shouldn't be called, handled by [visitAsyncForIn] or [visitSyncForIn]. |
| 2693 return internalError(node, "ForIn"); | 2686 return internalError(node, "ForIn"); |
| 2694 } | 2687 } |
| 2695 | 2688 |
| 2696 @override | 2689 @override |
| 2697 ir.Expression visitIndexSetIfNull( | 2690 ir.Expression visitIndexSetIfNull( |
| 2698 SendSet node, Node receiver, Node index, Node rhs, _) { | 2691 SendSet node, Node receiver, Node index, Node rhs, _) { |
| 2699 return buildIndexAccessor(receiver, index).buildNullAwareAssignment( | 2692 return buildIndexAccessor(receiver, index).buildNullAwareAssignment( |
| 2700 visitForValue(rhs), null, | 2693 visitForValue(rhs), |
| 2701 voidContext: isVoidContext); | 2694 voidContext: isVoidContext); |
| 2702 } | 2695 } |
| 2703 | 2696 |
| 2704 @override | 2697 @override |
| 2705 ir.Expression visitSuperIndexSetIfNull(SendSet node, MethodElement getter, | 2698 ir.Expression visitSuperIndexSetIfNull(SendSet node, MethodElement getter, |
| 2706 MethodElement setter, Node index, Node rhs, _) { | 2699 MethodElement setter, Node index, Node rhs, _) { |
| 2707 return buildSuperIndexAccessor(index, getter, setter) | 2700 return buildSuperIndexAccessor(index, getter, setter) |
| 2708 .buildNullAwareAssignment(visitForValue(rhs), null, | 2701 .buildNullAwareAssignment(visitForValue(rhs), |
| 2709 voidContext: isVoidContext); | 2702 voidContext: isVoidContext); |
| 2710 } | 2703 } |
| 2711 | 2704 |
| 2712 @override | 2705 @override |
| 2713 ir.Node visitVariableDefinitions(VariableDefinitions definitions) { | 2706 ir.Node visitVariableDefinitions(VariableDefinitions definitions) { |
| 2714 // TODO(ahe): This method is copied from [SemanticDeclarationResolvedMixin] | 2707 // TODO(ahe): This method is copied from [SemanticDeclarationResolvedMixin] |
| 2715 // and modified. Perhaps we can find a way to avoid code duplication. | 2708 // and modified. Perhaps we can find a way to avoid code duplication. |
| 2716 List<ir.VariableDeclaration> variables = <ir.VariableDeclaration>[]; | 2709 List<ir.VariableDeclaration> variables = <ir.VariableDeclaration>[]; |
| 2717 computeVariableStructures(definitions, | 2710 computeVariableStructures(definitions, |
| 2718 (Node node, VariableStructure structure) { | 2711 (Node node, VariableStructure structure) { |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2798 : this(null, true, node, initializers); | 2791 : this(null, true, node, initializers); |
| 2799 | 2792 |
| 2800 accept(ir.Visitor v) => throw "unsupported"; | 2793 accept(ir.Visitor v) => throw "unsupported"; |
| 2801 | 2794 |
| 2802 visitChildren(ir.Visitor v) => throw "unsupported"; | 2795 visitChildren(ir.Visitor v) => throw "unsupported"; |
| 2803 | 2796 |
| 2804 String toString() { | 2797 String toString() { |
| 2805 return "IrFunction($kind, $isConstructor, $node, $initializers)"; | 2798 return "IrFunction($kind, $isConstructor, $node, $initializers)"; |
| 2806 } | 2799 } |
| 2807 } | 2800 } |
| OLD | NEW |