This is an automated email from the ASF dual-hosted git repository.

emilles pushed a commit to branch GROOVY_2_5_X
in repository https://gitbox.apache.org/repos/asf/groovy.git


The following commit(s) were added to refs/heads/GROOVY_2_5_X by this push:
     new abebae2503 GROOVY-10918: direct store to local variable or parameter 
(no temporary)
abebae2503 is described below

commit abebae25031cc59ad402bc45e4d86765ff67d5c8
Author: Eric Milles <[email protected]>
AuthorDate: Thu Feb 16 08:48:35 2023 -0600

    GROOVY-10918: direct store to local variable or parameter (no temporary)
    
    2_5_X backport
---
 .../classgen/asm/BinaryExpressionHelper.java       | 271 +++++++++++----------
 .../classgen/asm/sc/StaticCompilationTest.groovy   |  41 ++--
 2 files changed, 156 insertions(+), 156 deletions(-)

diff --git 
a/src/main/java/org/codehaus/groovy/classgen/asm/BinaryExpressionHelper.java 
b/src/main/java/org/codehaus/groovy/classgen/asm/BinaryExpressionHelper.java
index 63b105c7d5..5bdf80ff86 100644
--- a/src/main/java/org/codehaus/groovy/classgen/asm/BinaryExpressionHelper.java
+++ b/src/main/java/org/codehaus/groovy/classgen/asm/BinaryExpressionHelper.java
@@ -22,6 +22,7 @@ import groovy.lang.GroovyRuntimeException;
 import org.codehaus.groovy.GroovyBugError;
 import org.codehaus.groovy.ast.ClassHelper;
 import org.codehaus.groovy.ast.ClassNode;
+import org.codehaus.groovy.ast.Variable;
 import org.codehaus.groovy.ast.expr.ArgumentListExpression;
 import org.codehaus.groovy.ast.expr.ArrayExpression;
 import org.codehaus.groovy.ast.expr.BinaryExpression;
@@ -46,10 +47,10 @@ import org.codehaus.groovy.classgen.BytecodeExpression;
 import org.codehaus.groovy.runtime.ScriptBytecodeAdapter;
 import org.codehaus.groovy.syntax.SyntaxException;
 import org.codehaus.groovy.syntax.Token;
-import org.codehaus.groovy.syntax.Types;
 import org.objectweb.asm.Label;
 import org.objectweb.asm.MethodVisitor;
 
+import static org.apache.groovy.ast.tools.ExpressionUtils.isNullConstant;
 import static org.codehaus.groovy.syntax.Types.BITWISE_AND;
 import static org.codehaus.groovy.syntax.Types.BITWISE_AND_EQUAL;
 import static org.codehaus.groovy.syntax.Types.BITWISE_OR;
@@ -81,12 +82,14 @@ import static org.codehaus.groovy.syntax.Types.LOGICAL_OR;
 import static org.codehaus.groovy.syntax.Types.MATCH_REGEX;
 import static org.codehaus.groovy.syntax.Types.MINUS;
 import static org.codehaus.groovy.syntax.Types.MINUS_EQUAL;
+import static org.codehaus.groovy.syntax.Types.MINUS_MINUS;
 import static org.codehaus.groovy.syntax.Types.MOD;
 import static org.codehaus.groovy.syntax.Types.MOD_EQUAL;
 import static org.codehaus.groovy.syntax.Types.MULTIPLY;
 import static org.codehaus.groovy.syntax.Types.MULTIPLY_EQUAL;
 import static org.codehaus.groovy.syntax.Types.PLUS;
 import static org.codehaus.groovy.syntax.Types.PLUS_EQUAL;
+import static org.codehaus.groovy.syntax.Types.PLUS_PLUS;
 import static org.codehaus.groovy.syntax.Types.POWER;
 import static org.codehaus.groovy.syntax.Types.POWER_EQUAL;
 import static org.codehaus.groovy.syntax.Types.RIGHT_SHIFT;
@@ -115,15 +118,15 @@ public class BinaryExpressionHelper {
     private static final MethodCaller isCaseMethod = 
MethodCaller.newStatic(ScriptBytecodeAdapter.class, "isCase");
 
     private final WriterController controller;
-    
+
     public BinaryExpressionHelper(WriterController wc) {
         this.controller = wc;
     }
-    
+
     public WriterController getController(){
         return controller;
     }
-    
+
     public void eval(BinaryExpression expression) {
         switch (expression.getOperation().getType()) {
         case EQUAL: // = assignment
@@ -306,7 +309,7 @@ public class BinaryExpressionHelper {
             throw new GroovyBugError("Operation: " + expression.getOperation() 
+ " not supported");
         }
     }
-    
+
     protected void assignToArray(Expression parent, Expression receiver, 
Expression index, Expression rhsValueLoader) {
         // let's replace this assignment to a subscript operator with a
         // method call
@@ -322,47 +325,49 @@ public class BinaryExpressionHelper {
         rhsValueLoader.visit(controller.getAcg());
     }
 
-    private static boolean isNull(Expression exp) {
-        if (exp instanceof ConstantExpression){
-            return ((ConstantExpression) exp).getValue()==null;
-        } else {
-            return false;
-        }
-    }
-
-    public void evaluateEqual(BinaryExpression expression, boolean 
defineVariable) {
+    public void evaluateEqual(final BinaryExpression expression, final boolean 
defineVariable) {
         AsmClassGenerator acg = controller.getAcg();
         CompileStack compileStack = controller.getCompileStack();
         OperandStack operandStack = controller.getOperandStack();
-        Expression rightExpression = expression.getRightExpression();
         Expression leftExpression = expression.getLeftExpression();
+        Expression rightExpression = expression.getRightExpression();
+        boolean directAssignment = defineVariable && !(leftExpression 
instanceof TupleExpression);
 
-        if (    defineVariable &&
-                rightExpression instanceof EmptyExpression && 
-                !(leftExpression instanceof TupleExpression) )
-        {
-            VariableExpression ve = (VariableExpression) leftExpression;
-            BytecodeVariable var = compileStack.defineVariable(ve, 
controller.getTypeChooser().resolveType(ve, controller.getClassNode()), false);
-            operandStack.loadOrStoreVariable(var, false);
-            return;
-        }
-        // evaluate the RHS and store the result
         // TODO: LHS has not been visited, it could be a variable in a closure 
and type chooser is not aware.
         ClassNode lhsType = 
controller.getTypeChooser().resolveType(leftExpression, 
controller.getClassNode());
+
+        if (directAssignment && rightExpression instanceof EmptyExpression) {
+            BytecodeVariable v = compileStack.defineVariable((Variable) 
leftExpression, lhsType, false);
+            operandStack.loadOrStoreVariable(v, false);
+            return;
+        }
+
+        // evaluate RHS and store the value
+
         if (rightExpression instanceof ListExpression && lhsType.isArray()) {
             ListExpression list = (ListExpression) rightExpression;
             ArrayExpression array = new 
ArrayExpression(lhsType.getComponentType(), list.getExpressions());
             array.setSourcePosition(list);
             array.visit(acg);
         } else if (rightExpression instanceof EmptyExpression) {
-            loadInitValue(leftExpression.getType());
+            loadInitValue(lhsType); // null or zero (or false)
         } else {
             rightExpression.visit(acg);
         }
 
+        // GROOVY-10918: direct store to local variable or parameter (no temp)
+        if (!defineVariable && leftExpression instanceof VariableExpression) {
+            BytecodeVariable v = 
compileStack.getVariable(leftExpression.getText(), false);
+            if (v != null) {
+                operandStack.dup(); // return value of the assignment 
expression
+                operandStack.storeVar(v);
+                return;
+            }
+        }
+
         ClassNode rhsType = operandStack.getTopOperand();
-        boolean directAssignment = defineVariable && !(leftExpression 
instanceof TupleExpression);
         int rhsValueId;
+
         if (directAssignment) {
             VariableExpression var = (VariableExpression) leftExpression;
             if (var.isClosureSharedVariable() && 
ClassHelper.isPrimitiveType(rhsType)) {
@@ -371,18 +376,18 @@ public class BinaryExpressionHelper {
                 operandStack.box();
             }
 
-            // ensure we try to unbox null to cause a runtime NPE in case we 
assign 
-            // null to a primitive typed variable, even if it is used only in 
boxed 
+            // ensure we try to unbox null to cause a runtime NPE in case we 
assign
+            // null to a primitive typed variable, even if it is used only in 
boxed
             // form as it is closure shared
-            if (var.isClosureSharedVariable() && 
ClassHelper.isPrimitiveType(var.getOriginType()) && isNull(rightExpression)) {
+            if (var.isClosureSharedVariable() && 
ClassHelper.isPrimitiveType(var.getOriginType()) && 
isNullConstant(rightExpression)) {
                 operandStack.doGroovyCast(var.getOriginType());
-                // these two are never reached in bytecode and only there 
-                // to avoid verifyerrors and compiler infrastructure hazzle
-                operandStack.box(); 
+                // these two are never reached in bytecode and only there
+                // to avoid verify errors and compiler infrastructure hazzle
+                operandStack.box();
                 operandStack.doGroovyCast(lhsType);
             }
-            // normal type transformation 
-            if (!ClassHelper.isPrimitiveType(lhsType) && 
isNull(rightExpression)) {
+            // normal type transformation
+            if (!ClassHelper.isPrimitiveType(lhsType) && 
isNullConstant(rightExpression)) {
                 operandStack.replace(lhsType);
             } else {
                 operandStack.doGroovyCast(lhsType);
@@ -392,57 +397,53 @@ public class BinaryExpressionHelper {
         } else {
             rhsValueId = compileStack.defineTemporaryVariable("$rhs", rhsType, 
true);
         }
-        //TODO: if rhs is VariableSlotLoader already, then skip crating a new 
one
-        BytecodeExpression rhsValueLoader = new 
VariableSlotLoader(rhsType,rhsValueId,operandStack); 
-        
+        // TODO: if rhs is VariableSlotLoader already, then skip crating a new 
one
+        BytecodeExpression rhsValueLoader = new 
VariableSlotLoader(rhsType,rhsValueId,operandStack);
+
         // assignment for subscript
         if (leftExpression instanceof BinaryExpression) {
             BinaryExpression leftBinExpr = (BinaryExpression) leftExpression;
-            if (leftBinExpr.getOperation().getType() == 
Types.LEFT_SQUARE_BRACKET) {
+            if (leftBinExpr.getOperation().getType() == LEFT_SQUARE_BRACKET) {
                 assignToArray(expression, leftBinExpr.getLeftExpression(), 
leftBinExpr.getRightExpression(), rhsValueLoader);
             }
             compileStack.removeVar(rhsValueId);
             return;
         }
-        
+
         compileStack.pushLHS(true);
 
-        // multiple declaration
         if (leftExpression instanceof TupleExpression) {
+            // multiple declaration
             TupleExpression tuple = (TupleExpression) leftExpression;
             int i = 0;
             for (Expression e : tuple.getExpressions()) {
-                VariableExpression var = (VariableExpression) e;
-                MethodCallExpression call = new MethodCallExpression(
-                        rhsValueLoader, "getAt",
-                        new ArgumentListExpression(new ConstantExpression(i)));
+                Expression call = new MethodCallExpression(rhsValueLoader, 
"getAt",
+                        new ArgumentListExpression(new ConstantExpression( i++ 
)));
                 call.visit(acg);
-                i++;
                 if (defineVariable) {
-                    operandStack.doGroovyCast(var);
-                    compileStack.defineVariable(var, true);
+                    Variable v = (Variable) e;
+                    operandStack.doGroovyCast(v);
+                    compileStack.defineVariable(v, true);
                     operandStack.remove(1);
                 } else {
-                    acg.visitVariableExpression(var);
+                    e.visit(acg);
                 }
             }
-        } 
-        // single declaration
-        else if (defineVariable) {
+        } else if (defineVariable) {
+            // single declaration
             rhsValueLoader.visit(acg);
             operandStack.remove(1);
             compileStack.popLHS();
             return;
-        } 
-        // normal assignment
-        else {
+        } else {
+            // normal assignment
             int mark = operandStack.getStackLength();
             rhsValueLoader.visit(acg);
             leftExpression.visit(acg);
-            operandStack.remove(operandStack.getStackLength()-mark);
+            operandStack.remove(operandStack.getStackLength() - mark);
         }
         compileStack.popLHS();
-        
+
         // return value of assignment
         rhsValueLoader.visit(acg);
         compileStack.removeVar(rhsValueId);
@@ -468,35 +469,35 @@ public class BinaryExpressionHelper {
 
         boolean done = false;
         if (    ClassHelper.isPrimitiveType(leftType) &&
-                ClassHelper.isPrimitiveType(rightType)) 
+                ClassHelper.isPrimitiveType(rightType))
         {
             BinaryExpressionMultiTypeDispatcher helper = new 
BinaryExpressionMultiTypeDispatcher(getController());
             done = helper.doPrimitiveCompare(leftType, rightType, expression);
         }
-        
+
         if (!done) {
             AsmClassGenerator acg = controller.getAcg();
             OperandStack operandStack = controller.getOperandStack();
-            
+
             leftExp.visit(acg);
             operandStack.box();
             rightExp.visit(acg);
             operandStack.box();
-    
+
             compareMethod.call(controller.getMethodVisitor());
             ClassNode resType = ClassHelper.boolean_TYPE;
             if (compareMethod==findRegexMethod) {
                 resType = ClassHelper.OBJECT_TYPE;
-            } 
+            }
             operandStack.replace(resType,2);
         }
     }
-    
+
     private void evaluateCompareTo(BinaryExpression expression) {
         Expression leftExpression = expression.getLeftExpression();
         AsmClassGenerator acg = controller.getAcg();
         OperandStack operandStack = controller.getOperandStack();
-        
+
         leftExpression.visit(acg);
         operandStack.box();
 
@@ -532,7 +533,7 @@ public class BinaryExpressionHelper {
         mv.visitLabel(trueCase);
         operandStack.remove(1); // have to remove 1 because of the GOTO
     }
-    
+
     private void evaluateLogicalOrExpression(BinaryExpression expression) {
         MethodVisitor mv = controller.getMethodVisitor();
         AsmClassGenerator acg = controller.getAcg();
@@ -543,21 +544,21 @@ public class BinaryExpressionHelper {
         expression.getLeftExpression().visit(acg);
         operandStack.doGroovyCast(ClassHelper.boolean_TYPE);
         Label trueCase = operandStack.jump(IFNE);
-        
+
         expression.getRightExpression().visit(acg);
         operandStack.doGroovyCast(ClassHelper.boolean_TYPE);
         Label falseCase = operandStack.jump(IFEQ);
-        
+
         mv.visitLabel(trueCase);
         ConstantExpression.PRIM_TRUE.visit(acg);
         operandStack.jump(GOTO, end);
 
         mv.visitLabel(falseCase);
         ConstantExpression.PRIM_FALSE.visit(acg);
-        
+
         mv.visitLabel(end);
     }
-    
+
     protected void evaluateBinaryExpression(String message, BinaryExpression 
binExp) {
         CompileStack compileStack = controller.getCompileStack();
 
@@ -567,7 +568,7 @@ public class BinaryExpressionHelper {
         // ensure VariableArguments are read, not stored
         compileStack.pushLHS(false);
         controller.getInvocationWriter().makeSingleArgumentCall(receiver, 
message, arguments);
-        compileStack.popLHS();        
+        compileStack.popLHS();
     }
 
     protected void evaluateArrayAssignmentWithOperator(String method, 
BinaryExpression expression, BinaryExpression leftBinExpr) {
@@ -603,28 +604,28 @@ public class BinaryExpressionHelper {
         Expression leftExpression = expression.getLeftExpression();
         AsmClassGenerator acg = controller.getAcg();
         OperandStack operandStack = controller.getOperandStack();
-        
+
         if (leftExpression instanceof BinaryExpression) {
             BinaryExpression leftBinExpr = (BinaryExpression) leftExpression;
-            if (leftBinExpr.getOperation().getType() == 
Types.LEFT_SQUARE_BRACKET) {
+            if (leftBinExpr.getOperation().getType() == LEFT_SQUARE_BRACKET) {
                 evaluateArrayAssignmentWithOperator(method, expression, 
leftBinExpr);
                 return;
             }
-        } 
+        }
 
         evaluateBinaryExpression(method, expression);
 
         // br to leave a copy of rvalue on the stack. see also isPopRequired()
         operandStack.dup();
-        
+
         controller.getCompileStack().pushLHS(true);
         leftExpression.visit(acg);
         controller.getCompileStack().popLHS();
     }
-    
+
     private void evaluateInstanceof(BinaryExpression expression) {
         OperandStack operandStack = controller.getOperandStack();
-        
+
         expression.getLeftExpression().visit(controller.getAcg());
         operandStack.box();
         Expression rightExp = expression.getRightExpression();
@@ -648,21 +649,21 @@ public class BinaryExpressionHelper {
     private void evaluatePostfixMethod(int op, String method, Expression 
expression, Expression orig) {
         CompileStack compileStack = controller.getCompileStack();
         final OperandStack operandStack = controller.getOperandStack();
-        
+
         // load Expressions
         VariableSlotLoader usesSubscript = loadWithSubscript(expression);
 
         // save copy for later
         operandStack.dup();
-        ClassNode expressionType = operandStack.getTopOperand(); 
+        ClassNode expressionType = operandStack.getTopOperand();
         int tempIdx = compileStack.defineTemporaryVariable("postfix_" + 
method, expressionType, true);
-        
+
         // execute Method
         
execMethodAndStoreForSubscriptOperator(op,method,expression,usesSubscript,orig);
-        
+
         // remove the result of the method call
-        operandStack.pop();        
-        
+        operandStack.pop();
+
         //reload saved value
         operandStack.load(expressionType, tempIdx);
         compileStack.removeVar(tempIdx);
@@ -672,10 +673,10 @@ public class BinaryExpressionHelper {
     public void evaluatePostfixMethod(PostfixExpression expression) {
         int op = expression.getOperation().getType();
         switch (op) {
-            case Types.PLUS_PLUS:
+            case PLUS_PLUS:
                 evaluatePostfixMethod(op, "next", expression.getExpression(), 
expression);
                 break;
-            case Types.MINUS_MINUS:
+            case MINUS_MINUS:
                 evaluatePostfixMethod(op, "previous", 
expression.getExpression(), expression);
                 break;
         }
@@ -684,33 +685,33 @@ public class BinaryExpressionHelper {
     public void evaluatePrefixMethod(PrefixExpression expression) {
         int type = expression.getOperation().getType();
         switch (type) {
-            case Types.PLUS_PLUS:
+            case PLUS_PLUS:
                 evaluatePrefixMethod(type, "next", expression.getExpression(), 
expression);
                 break;
-            case Types.MINUS_MINUS:
+            case MINUS_MINUS:
                 evaluatePrefixMethod(type, "previous", 
expression.getExpression(), expression);
                 break;
         }
     }
-    
+
     private void evaluatePrefixMethod(int op, String method, Expression 
expression, Expression orig) {
         // load Expressions
         VariableSlotLoader usesSubscript = loadWithSubscript(expression);
-        
+
         // execute Method
         
execMethodAndStoreForSubscriptOperator(op,method,expression,usesSubscript,orig);
 
         // new value is already on stack, so nothing to do here
         if (usesSubscript!=null) 
controller.getCompileStack().removeVar(usesSubscript.getIndex());
     }
-    
+
     private VariableSlotLoader loadWithSubscript(Expression expression) {
         final OperandStack operandStack = controller.getOperandStack();
         // if we have a BinaryExpression, let us check if it is with
         // subscription
         if (expression instanceof BinaryExpression) {
             BinaryExpression be = (BinaryExpression) expression;
-            if (be.getOperation().getType()==Types.LEFT_SQUARE_BRACKET) {
+            if (be.getOperation().getType() == LEFT_SQUARE_BRACKET) {
                 // right expression is the subscript expression
                 // we store the result of the subscription on the stack
                 Expression subscript = be.getRightExpression();
@@ -727,14 +728,14 @@ public class BinaryExpressionHelper {
                 newBe.setSourcePosition(be);
                 newBe.visit(controller.getAcg());
                 return subscriptExpression;
-            } 
-        } 
-        
+            }
+        }
+
         // normal loading of expression
         expression.visit(controller.getAcg());
         return null;
     }
-    
+
     private void execMethodAndStoreForSubscriptOperator(int op, String method, 
Expression expression, VariableSlotLoader usesSubscript, Expression orig) {
         final OperandStack operandStack = controller.getOperandStack();
         writePostOrPrefixMethod(op,method,expression,orig);
@@ -743,20 +744,20 @@ public class BinaryExpressionHelper {
         if (usesSubscript!=null) {
             CompileStack compileStack = controller.getCompileStack();
             BinaryExpression be = (BinaryExpression) expression;
-            
+
             ClassNode methodResultType = operandStack.getTopOperand();
             final int resultIdx = 
compileStack.defineTemporaryVariable("postfix_" + method, methodResultType, 
true);
             BytecodeExpression methodResultLoader = new 
VariableSlotLoader(methodResultType, resultIdx, operandStack);
-            
-            // execute the assignment, this will leave the right side 
+
+            // execute the assignment, this will leave the right side
             // (here the method call result) on the stack
             assignToArray(be, be.getLeftExpression(), usesSubscript, 
methodResultLoader);
 
             compileStack.removeVar(resultIdx);
-        } 
+        }
         // here we handle a.b++ and a++
         else if (expression instanceof VariableExpression ||
-            expression instanceof FieldExpression || 
+            expression instanceof FieldExpression ||
             expression instanceof PropertyExpression)
         {
             operandStack.dup();
@@ -771,19 +772,19 @@ public class BinaryExpressionHelper {
         final OperandStack operandStack = controller.getOperandStack();
         // at this point the receiver will be already on the stack.
         // in a[1]++ the method will be "++" aka "next" and the receiver a[1]
-        
+
         ClassNode BEType = controller.getTypeChooser().resolveType(expression, 
controller.getClassNode());
         Expression callSiteReceiverSwap = new BytecodeExpression(BEType) {
             @Override
             public void visit(MethodVisitor mv) {
-                // CallSite is normally not showing up on the 
+                // CallSite is normally not showing up on the
                 // operandStack, so we place a dummy here with same
                 // slot length.
                 operandStack.push(ClassHelper.OBJECT_TYPE);
                 // change (receiver,callsite) to (callsite,receiver)
                 operandStack.swap();
                 setType(operandStack.getTopOperand());
-                
+
                 // no need to keep any of those on the operand stack
                 // after this expression is processed, the operand stack
                 // will contain callSiteReceiverSwap.getType()
@@ -793,7 +794,7 @@ public class BinaryExpressionHelper {
         // execute method
         // this will load the callsite and the receiver normally in the wrong
         // order since the receiver is already present, but before the callsite
-        // Therefore we use callSiteReceiverSwap to correct the order. 
+        // Therefore we use callSiteReceiverSwap to correct the order.
         // After this call the JVM operand stack will contain the result of
         // the method call... usually simply Object in operandStack
         controller.getCallSiteWriter().makeCallSite(
@@ -801,37 +802,37 @@ public class BinaryExpressionHelper {
                 method,
                 MethodCallExpression.NO_ARGUMENTS,
                 false, false, false, false);
-        // now rhs is completely done and we need only to store. In a[1]++ 
this 
+        // now rhs is completely done and we need only to store. In a[1]++ this
         // would be a.getAt(1).next() for the rhs, "lhs" code is a.putAt(1, 
rhs)
-         
+
     }
-    
+
     private void evaluateElvisOperatorExpression(ElvisOperatorExpression 
expression) {
         MethodVisitor mv = controller.getMethodVisitor();
         CompileStack compileStack = controller.getCompileStack();
         OperandStack operandStack = controller.getOperandStack();
         TypeChooser typeChooser = controller.getTypeChooser();
-        
+
         Expression boolPart = 
expression.getBooleanExpression().getExpression();
         Expression falsePart = expression.getFalseExpression();
-        
+
         ClassNode truePartType = typeChooser.resolveType(boolPart, 
controller.getClassNode());
         ClassNode falsePartType = typeChooser.resolveType(falsePart, 
controller.getClassNode());
         ClassNode common = WideningCategories.lowestUpperBound(truePartType, 
falsePartType);
-        
-        // x?:y is equal to x?x:y, which evals to 
+
+        // x?:y is equal to x?x:y, which evals to
         //      var t=x; boolean(t)?t:y
-        // first we load x, dup it, convert the dupped to boolean, then 
+        // first we load x, dup it, convert the dupped to boolean, then
         // jump depending on the value. For true we are done, for false we
-        // have to load y, thus we first remove x and then load y. 
+        // have to load y, thus we first remove x and then load y.
         // But since x and y may have different stack lengths, this cannot work
         // Thus we have to have to do the following:
-        // Be X the type of x, Y the type of y and S the common supertype of 
-        // X and Y, then we have to see x?:y as  
+        // Be X the type of x, Y the type of y and S the common supertype of
+        // X and Y, then we have to see x?:y as
         //      var t=x;boolean(t)?S(t):S(y)
-        // so we load x, dup it, store the value in a local variable (t), then 
-        // do boolean conversion. In the true part load t and cast it to S, 
-        // in the false part load y and cast y to S 
+        // so we load x, dup it, store the value in a local variable (t), then
+        // do boolean conversion. In the true part load t and cast it to S,
+        // in the false part load y and cast y to S
 
         // load x, dup it, store one in $t and cast the remaining one to 
boolean
         int mark = operandStack.getStackLength();
@@ -842,66 +843,66 @@ public class BinaryExpressionHelper {
         }
         int retValueId = compileStack.defineTemporaryVariable("$t", 
truePartType, true);
         operandStack.castToBool(mark,true);
-        
+
         Label l0 = operandStack.jump(IFEQ);
         // true part: load $t and cast to S
         operandStack.load(truePartType, retValueId);
         operandStack.doGroovyCast(common);
         Label l1 = new Label();
         mv.visitJumpInsn(GOTO, l1);
-        
+
         // false part: load false expression and cast to S
         mv.visitLabel(l0);
-        falsePart.visit(controller.getAcg());        
+        falsePart.visit(controller.getAcg());
         operandStack.doGroovyCast(common);
-        
+
         // finish and cleanup
         mv.visitLabel(l1);
         compileStack.removeVar(retValueId);
-        controller.getOperandStack().replace(common, 2);        
-        
+        controller.getOperandStack().replace(common, 2);
+
     }
 
     private void evaluateNormalTernary(TernaryExpression expression) {
         MethodVisitor mv = controller.getMethodVisitor();
         OperandStack operandStack = controller.getOperandStack();
         TypeChooser typeChooser = controller.getTypeChooser();
-        
+
         Expression boolPart = expression.getBooleanExpression();
         Expression truePart = expression.getTrueExpression();
         Expression falsePart = expression.getFalseExpression();
-        
+
         ClassNode truePartType = typeChooser.resolveType(truePart, 
controller.getClassNode());
         ClassNode falsePartType = typeChooser.resolveType(falsePart, 
controller.getClassNode());
         ClassNode common = WideningCategories.lowestUpperBound(truePartType, 
falsePartType);
 
-        // we compile b?x:y as 
+        // we compile b?x:y as
         //      boolean(b)?S(x):S(y), S = common super type of x,y
-        // so we load b, do boolean conversion. 
-        // In the true part load x and cast it to S, 
-        // in the false part load y and cast y to S 
+        // so we load b, do boolean conversion.
+        // In the true part load x and cast it to S,
+        // in the false part load y and cast y to S
 
         // load b and convert to boolean
         int mark = operandStack.getStackLength();
         boolPart.visit(controller.getAcg());
         operandStack.castToBool(mark,true);
-        
+
         Label l0 = operandStack.jump(IFEQ);
         // true part: load x and cast to S
         truePart.visit(controller.getAcg());
         operandStack.doGroovyCast(common);
         Label l1 = new Label();
         mv.visitJumpInsn(GOTO, l1);
-        
+
         // false part: load y and cast to S
         mv.visitLabel(l0);
-        falsePart.visit(controller.getAcg());        
+        falsePart.visit(controller.getAcg());
         operandStack.doGroovyCast(common);
-        
+
         // finish and cleanup
         mv.visitLabel(l1);
-        controller.getOperandStack().replace(common, 2);        
-        
+        controller.getOperandStack().replace(common, 2);
+
     }
 
     public void evaluateTernary(TernaryExpression expression) {
diff --git 
a/src/test/org/codehaus/groovy/classgen/asm/sc/StaticCompilationTest.groovy 
b/src/test/org/codehaus/groovy/classgen/asm/sc/StaticCompilationTest.groovy
index 318f692b93..fa4eadce52 100644
--- a/src/test/org/codehaus/groovy/classgen/asm/sc/StaticCompilationTest.groovy
+++ b/src/test/org/codehaus/groovy/classgen/asm/sc/StaticCompilationTest.groovy
@@ -270,27 +270,26 @@ class StaticCompilationTest extends 
AbstractBytecodeTestCase {
         }
         m 'Cedric'
         ''').hasStrictSequence([
-                "ICONST",
-                "INVOKESTATIC java/lang/Integer.valueOf 
(I)Ljava/lang/Integer;",
-                "ASTORE",
-                "L1",
-                "ALOAD 2",
-                "POP",
-                "L2",
-                "LINENUMBER",
-                "ALOAD 1",
-                "ASTORE 3",
-                "ALOAD 3",
-                "ASTORE 2",
-                "ALOAD 3",
-                "POP",
-                "L3",
-                "LINENUMBER",
-                "ALOAD 2",
-                "CHECKCAST java/lang/String",
-                "INVOKEVIRTUAL java/lang/String.toUpperCase 
()Ljava/lang/String;",
-                "ARETURN",
-                "L4"
+                'LINENUMBER 4',
+                'ICONST_1',
+                'INVOKESTATIC java/lang/Integer.valueOf 
(I)Ljava/lang/Integer;',
+                'ASTORE 2',
+                'L1',
+                'ALOAD 2',
+                'POP',
+                'L2',
+                'LINENUMBER 5',
+                'ALOAD 1',
+                'DUP',
+                'ASTORE 2',
+                'POP',
+                'L3',
+                'LINENUMBER 6',
+                'ALOAD 2',
+                'CHECKCAST java/lang/String',
+                'INVOKEVIRTUAL java/lang/String.toUpperCase 
()Ljava/lang/String;',
+                'ARETURN',
+                'L4'
         ])
     }
 

Reply via email to