]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/utils/CodeBuilderUtils.java
Merged changes from feature/scl to master.
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / internal / codegen / utils / CodeBuilderUtils.java
index ec44be75a1531adf48204c4d78653c09c87cb340..cc8f3e0c5ab5a7f5dfefb8cf43b77b28b76c756e 100644 (file)
@@ -128,23 +128,7 @@ public class CodeBuilderUtils {
                     tsmb.loadField(classBuilder.getClassName(), fieldNamePrefix+i, type);
                     tsmb.loadLocal(other);
                     tsmb.loadField(classBuilder.getClassName(), fieldNamePrefix+i, type);
-                    if(type.isPrimitive())
-                        tsmb.ifComparisonBranch(failure, "!=", type);
-                    else {
-                        Label isNull = tsmb.createLabel();
-                        Label finished = tsmb.createLabel();
-                        tsmb.swap();
-                        tsmb.dup();
-                        tsmb.ifNullBranch(isNull, true);
-                        tsmb.swap();
-                        tsmb.invokeVirtual("java/lang/Object", "equals", TypeDesc.BOOLEAN, Constants.OBJECTS[1]);
-                        tsmb.ifZeroComparisonBranch(failure, "==");
-                        tsmb.branch(finished);
-                        tsmb.setLocation(isNull);
-                        tsmb.pop();
-                        tsmb.ifNullBranch(failure, false);
-                        tsmb.setLocation(finished);
-                    }
+                    equals(tsmb, type, failure);
                 }
 
                 // Return
@@ -169,36 +153,7 @@ public class CodeBuilderUtils {
                     tsmb.math(Opcodes.IMUL);
                     tsmb.loadThis();
                     tsmb.loadField(classBuilder.getClassName(), fieldNamePrefix+i, type);
-                    switch(type.getTypeCode()) {
-                    case TypeDesc.INT_CODE:
-                        break;
-                    case TypeDesc.OBJECT_CODE: {
-                        Label isNull = tsmb.createLabel();
-                        Label finished = tsmb.createLabel();
-                        tsmb.dup();
-                        tsmb.ifNullBranch(isNull, true);
-                        tsmb.invokeVirtual("java/lang/Object", "hashCode", TypeDesc.INT, Constants.EMPTY_TYPEDESC_ARRAY);
-                        tsmb.branch(finished);
-                        tsmb.setLocation(isNull);
-                        tsmb.pop();
-                        tsmb.loadConstant(0);
-                        tsmb.setLocation(finished);
-                    } break;
-                    case TypeDesc.DOUBLE_CODE:
-                        tsmb.invokeStatic("java/lang/Double", "doubleToLongBits", TypeDesc.LONG, new TypeDesc[] { TypeDesc.DOUBLE });
-                    case TypeDesc.LONG_CODE:
-                        tsmb.dup2();
-                        tsmb.loadConstant(32);
-                        tsmb.math(Opcodes.LSHR);
-                        tsmb.math(Opcodes.LXOR);
-                        tsmb.convert(TypeDesc.LONG, TypeDesc.INT);
-                        break;
-                    case TypeDesc.FLOAT_CODE:
-                        tsmb.invokeStatic("java/lang/Float", "floatToIntBits", TypeDesc.INT, new TypeDesc[] { TypeDesc.FLOAT });
-                        break;
-                    default:
-                        tsmb.convert(type, TypeDesc.INT);
-                    }
+                    hashCode(tsmb, type);
                     tsmb.math(Opcodes.IADD);
                 }
                 tsmb.returnValue(TypeDesc.INT);
@@ -207,6 +162,62 @@ public class CodeBuilderUtils {
         }
     }
     
+    public static void equals(MethodBuilderBase mb, TypeDesc typeDesc, Label failure) {
+        if(typeDesc.isPrimitive())
+            mb.ifComparisonBranch(failure, "!=", typeDesc);
+        else {
+            Label isNull = mb.createLabel();
+            Label finished = mb.createLabel();
+            mb.swap();
+            mb.dup();
+            mb.ifNullBranch(isNull, true);
+            mb.swap();
+            mb.invokeVirtual("java/lang/Object", "equals", TypeDesc.BOOLEAN, Constants.OBJECTS[1]);
+            mb.ifZeroComparisonBranch(failure, "==");
+            mb.branch(finished);
+            mb.setLocation(isNull);
+            mb.pop();
+            mb.ifNullBranch(failure, false);
+            mb.setLocation(finished);
+        }
+    }
+    
+    /**
+     * Calculates the hash code of a value in stack.
+     */
+    public static void hashCode(MethodBuilderBase mb, TypeDesc typeDesc) {
+        switch(typeDesc.getTypeCode()) {
+        case TypeDesc.INT_CODE:
+            break;
+        case TypeDesc.OBJECT_CODE: {
+            Label isNull = mb.createLabel();
+            Label finished = mb.createLabel();
+            mb.dup();
+            mb.ifNullBranch(isNull, true);
+            mb.invokeVirtual("java/lang/Object", "hashCode", TypeDesc.INT, Constants.EMPTY_TYPEDESC_ARRAY);
+            mb.branch(finished);
+            mb.setLocation(isNull);
+            mb.pop();
+            mb.loadConstant(0);
+            mb.setLocation(finished);
+        } break;
+        case TypeDesc.DOUBLE_CODE:
+            mb.invokeStatic("java/lang/Double", "doubleToLongBits", TypeDesc.LONG, new TypeDesc[] { TypeDesc.DOUBLE });
+        case TypeDesc.LONG_CODE:
+            mb.dup2();
+            mb.loadConstant(32);
+            mb.math(Opcodes.LSHR);
+            mb.math(Opcodes.LXOR);
+            mb.convert(TypeDesc.LONG, TypeDesc.INT);
+            break;
+        case TypeDesc.FLOAT_CODE:
+            mb.invokeStatic("java/lang/Float", "floatToIntBits", TypeDesc.INT, new TypeDesc[] { TypeDesc.FLOAT });
+            break;
+        default:
+            mb.convert(typeDesc, TypeDesc.INT);
+        }
+    }
+    
     public static void constructRecord(TypeDesc clazz, MethodBuilder mb,
             Type[] parameterTypes, Val... parameters) {
         if(parameters.length == 0) {