Repository: groovy
Updated Branches:
  refs/heads/GROOVY_2_5_X e4c4d663f -> 46bad1d83


Minor refactoring: remove the duplicated code

(cherry picked from commit ae713cb)


Project: http://git-wip-us.apache.org/repos/asf/groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/9c95e8d1
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/9c95e8d1
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/9c95e8d1

Branch: refs/heads/GROOVY_2_5_X
Commit: 9c95e8d19f4bf04890ce2a85f32342721c7b9dd8
Parents: e4c4d66
Author: sunlan <sun...@apache.org>
Authored: Tue Feb 6 08:57:16 2018 +0800
Committer: sunlan <sun...@apache.org>
Committed: Tue Feb 6 17:12:15 2018 +0800

----------------------------------------------------------------------
 .../groovy/classgen/asm/BytecodeHelper.java     | 120 +++++++++++++++----
 .../groovy/classgen/asm/OperandStack.java       |  47 +++-----
 2 files changed, 114 insertions(+), 53 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/9c95e8d1/src/main/java/org/codehaus/groovy/classgen/asm/BytecodeHelper.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/classgen/asm/BytecodeHelper.java 
b/src/main/java/org/codehaus/groovy/classgen/asm/BytecodeHelper.java
index d680731..491cd7b 100644
--- a/src/main/java/org/codehaus/groovy/classgen/asm/BytecodeHelper.java
+++ b/src/main/java/org/codehaus/groovy/classgen/asm/BytecodeHelper.java
@@ -508,26 +508,6 @@ public class BytecodeHelper implements Opcodes {
         ret.append(end);
     }
 
-    public static void load(MethodVisitor mv, ClassNode type, int idx) {
-        if (type == ClassHelper.double_TYPE) {
-            mv.visitVarInsn(DLOAD, idx);
-        } else if (type == ClassHelper.float_TYPE) {
-            mv.visitVarInsn(FLOAD, idx);
-        } else if (type == ClassHelper.long_TYPE) {
-            mv.visitVarInsn(LLOAD, idx);
-        } else if (
-                type == ClassHelper.boolean_TYPE
-                        || type == ClassHelper.char_TYPE
-                        || type == ClassHelper.byte_TYPE
-                        || type == ClassHelper.int_TYPE
-                        || type == ClassHelper.short_TYPE) {
-            mv.visitVarInsn(ILOAD, idx);
-        } else {
-            mv.visitVarInsn(ALOAD, idx);
-        }
-    }
-    
-
     public static void doCast(MethodVisitor mv, ClassNode type) {
         if (type == ClassHelper.OBJECT_TYPE) return;
         if (ClassHelper.isPrimitiveType(type) && type != 
ClassHelper.VOID_TYPE) {
@@ -674,4 +654,104 @@ public class BytecodeHelper implements Opcodes {
         }
         return h;
     }
+
+    /**
+     * Converts a primitive type to boolean.
+     *
+     * @param mv method visitor
+     * @param type primitive type to convert
+     */
+    public static void convertPrimitiveToBoolean(MethodVisitor mv, ClassNode 
type) {
+        if (type == ClassHelper.boolean_TYPE) {
+            return;
+        }
+        // Special handling is done for floating point types in order to
+        // handle checking for 0 or NaN values.
+        if (type == ClassHelper.double_TYPE) {
+            convertDoubleToBoolean(mv, type);
+            return;
+        } else if (type == ClassHelper.float_TYPE) {
+            convertFloatToBoolean(mv, type);
+            return;
+        }
+        Label trueLabel = new Label();
+        Label falseLabel = new Label();
+        // Convert long to int for IFEQ comparison using LCMP
+        if (type==ClassHelper.long_TYPE) {
+            mv.visitInsn(LCONST_0);
+            mv.visitInsn(LCMP);
+        }
+        // This handles byte, short, char and int
+        mv.visitJumpInsn(IFEQ, falseLabel);
+        mv.visitInsn(ICONST_1);
+        mv.visitJumpInsn(GOTO, trueLabel);
+        mv.visitLabel(falseLabel);
+        mv.visitInsn(ICONST_0);
+        mv.visitLabel(trueLabel);
+    }
+
+    private static void convertDoubleToBoolean(MethodVisitor mv, ClassNode 
type) {
+        Label trueLabel = new Label();
+        Label falseLabel = new Label();
+        Label falseLabelWithPop = new Label();
+        mv.visitInsn(DUP2); // will need the extra for isNaN call if required
+        mv.visitInsn(DCONST_0);
+        mv.visitInsn(DCMPL);
+        mv.visitJumpInsn(IFEQ, falseLabelWithPop);
+        mv.visitMethodInsn(INVOKESTATIC, "java/lang/Double", "isNaN", "(D)Z", 
false);
+        mv.visitJumpInsn(IFNE, falseLabel);
+        mv.visitInsn(ICONST_1);
+        mv.visitJumpInsn(GOTO, trueLabel);
+        mv.visitLabel(falseLabelWithPop);
+        mv.visitInsn(POP2);
+        mv.visitLabel(falseLabel);
+        mv.visitInsn(ICONST_0);
+        mv.visitLabel(trueLabel);
+    }
+
+    private static void convertFloatToBoolean(MethodVisitor mv, ClassNode 
type) {
+        Label trueLabel = new Label();
+        Label falseLabel = new Label();
+        Label falseLabelWithPop = new Label();
+        mv.visitInsn(DUP); // will need the extra for isNaN call if required
+        mv.visitInsn(FCONST_0);
+        mv.visitInsn(FCMPL);
+        mv.visitJumpInsn(IFEQ, falseLabelWithPop);
+        mv.visitMethodInsn(INVOKESTATIC, "java/lang/Float", "isNaN", "(F)Z", 
false);
+        mv.visitJumpInsn(IFNE, falseLabel);
+        mv.visitInsn(ICONST_1);
+        mv.visitJumpInsn(GOTO, trueLabel);
+        mv.visitLabel(falseLabelWithPop);
+        mv.visitInsn(POP);
+        mv.visitLabel(falseLabel);
+        mv.visitInsn(ICONST_0);
+        mv.visitLabel(trueLabel);
+    }
+
+    public static void load(MethodVisitor mv, ClassNode type, int idx) {
+        storeOrLoadVar(mv, idx, type, DLOAD, FLOAD, LLOAD, ILOAD, ALOAD);
+    }
+
+    static void store(MethodVisitor mv, ClassNode type, int idx) {
+        storeOrLoadVar(mv, idx, type, DSTORE, FSTORE, LSTORE, ISTORE, ASTORE);
+    }
+
+    private static void storeOrLoadVar(MethodVisitor mv, int idx, ClassNode 
type, int dVarInsn, int fVarInsn, int lVarInsn, int iVarInsn, int aVarInsn) {
+        if (type == ClassHelper.double_TYPE) {
+            mv.visitVarInsn(dVarInsn, idx);
+        } else if (type == ClassHelper.float_TYPE) {
+            mv.visitVarInsn(fVarInsn, idx);
+        } else if (type == ClassHelper.long_TYPE) {
+            mv.visitVarInsn(lVarInsn, idx);
+        } else if (
+                type == ClassHelper.boolean_TYPE
+                        || type == ClassHelper.char_TYPE
+                        || type == ClassHelper.byte_TYPE
+                        || type == ClassHelper.int_TYPE
+                        || type == ClassHelper.short_TYPE) {
+            mv.visitVarInsn(iVarInsn, idx);
+        } else {
+            mv.visitVarInsn(aVarInsn, idx);
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/groovy/blob/9c95e8d1/src/main/java/org/codehaus/groovy/classgen/asm/OperandStack.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/classgen/asm/OperandStack.java 
b/src/main/java/org/codehaus/groovy/classgen/asm/OperandStack.java
index 20d02ff..ace3056 100644
--- a/src/main/java/org/codehaus/groovy/classgen/asm/OperandStack.java
+++ b/src/main/java/org/codehaus/groovy/classgen/asm/OperandStack.java
@@ -39,7 +39,6 @@ import java.util.List;
 
 import static org.objectweb.asm.Opcodes.ACONST_NULL;
 import static org.objectweb.asm.Opcodes.ALOAD;
-import static org.objectweb.asm.Opcodes.ASTORE;
 import static org.objectweb.asm.Opcodes.BIPUSH;
 import static org.objectweb.asm.Opcodes.CHECKCAST;
 import static org.objectweb.asm.Opcodes.D2F;
@@ -48,7 +47,6 @@ import static org.objectweb.asm.Opcodes.D2L;
 import static org.objectweb.asm.Opcodes.DCMPL;
 import static org.objectweb.asm.Opcodes.DCONST_0;
 import static org.objectweb.asm.Opcodes.DCONST_1;
-import static org.objectweb.asm.Opcodes.DSTORE;
 import static org.objectweb.asm.Opcodes.DUP;
 import static org.objectweb.asm.Opcodes.DUP2;
 import static org.objectweb.asm.Opcodes.DUP2_X1;
@@ -61,7 +59,6 @@ import static org.objectweb.asm.Opcodes.FCMPL;
 import static org.objectweb.asm.Opcodes.FCONST_0;
 import static org.objectweb.asm.Opcodes.FCONST_1;
 import static org.objectweb.asm.Opcodes.FCONST_2;
-import static org.objectweb.asm.Opcodes.FSTORE;
 import static org.objectweb.asm.Opcodes.GETSTATIC;
 import static org.objectweb.asm.Opcodes.GOTO;
 import static org.objectweb.asm.Opcodes.I2B;
@@ -79,14 +76,12 @@ import static org.objectweb.asm.Opcodes.ICONST_5;
 import static org.objectweb.asm.Opcodes.IFEQ;
 import static org.objectweb.asm.Opcodes.INVOKESPECIAL;
 import static org.objectweb.asm.Opcodes.INVOKEVIRTUAL;
-import static org.objectweb.asm.Opcodes.ISTORE;
 import static org.objectweb.asm.Opcodes.L2D;
 import static org.objectweb.asm.Opcodes.L2F;
 import static org.objectweb.asm.Opcodes.L2I;
 import static org.objectweb.asm.Opcodes.LCMP;
 import static org.objectweb.asm.Opcodes.LCONST_0;
 import static org.objectweb.asm.Opcodes.LCONST_1;
-import static org.objectweb.asm.Opcodes.LSTORE;
 import static org.objectweb.asm.Opcodes.NEW;
 import static org.objectweb.asm.Opcodes.POP;
 import static org.objectweb.asm.Opcodes.POP2;
@@ -316,16 +311,23 @@ public class OperandStack {
      * replace top level element with new element of given type
      */
     public void replace(ClassNode type) {
+        int size = ensureStackNotEmpty(stack);
+        stack.set(size - 1, type);
+    }
+
+    private int ensureStackNotEmpty(List<ClassNode> stack) {
         int size = stack.size();
+
         try {
-            if (size==0) throw new ArrayIndexOutOfBoundsException("size==0");
+            if (size == 0) throw new ArrayIndexOutOfBoundsException("size==0");
         } catch (ArrayIndexOutOfBoundsException ai) {
-            System.err.println("index problem in 
"+controller.getSourceUnit().getName());
+            System.err.println("index problem in " + 
controller.getSourceUnit().getName());
             throw ai;
         }
-        stack.set(size-1, type);
+
+        return size;
     }
-    
+
     /**
      * replace n top level elements with new element of given type
      */
@@ -688,22 +690,7 @@ public class OperandStack {
             mv.visitMethodInsn(INVOKEVIRTUAL, "groovy/lang/Reference", "set", 
"(Ljava/lang/Object;)V", false);
         } else {
             doGroovyCast(type);
-            if (type == ClassHelper.double_TYPE) {
-                mv.visitVarInsn(DSTORE, idx);
-            } else if (type == ClassHelper.float_TYPE) {
-                mv.visitVarInsn(FSTORE, idx);
-            } else if (type == ClassHelper.long_TYPE) {
-                mv.visitVarInsn(LSTORE, idx);
-            } else if (
-                    type == ClassHelper.boolean_TYPE
-                            || type == ClassHelper.char_TYPE
-                            || type == ClassHelper.byte_TYPE
-                            || type == ClassHelper.int_TYPE
-                            || type == ClassHelper.short_TYPE) {
-                mv.visitVarInsn(ISTORE, idx);
-            } else {
-                mv.visitVarInsn(ASTORE, idx);
-            }
+            BytecodeHelper.store(mv, type, idx);
         }
         // remove RHS value from operand stack
         remove(1);
@@ -726,13 +713,7 @@ public class OperandStack {
     }
 
     public ClassNode getTopOperand() {
-        int size = stack.size();
-        try {
-            if (size==0) throw new ArrayIndexOutOfBoundsException("size==0");
-        } catch (ArrayIndexOutOfBoundsException ai) {
-            System.err.println("index problem in 
"+controller.getSourceUnit().getName());
-            throw ai;
-        }
-        return stack.get(size-1);
+        int size = ensureStackNotEmpty(stack);
+        return stack.get(size - 1);
     }
 }

Reply via email to