X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.scl.compiler%2Fsrc%2Forg%2Fsimantics%2Fscl%2Fcompiler%2Finternal%2Fcodegen%2Futils%2FCodeBuilderUtils.java;h=cc8f3e0c5ab5a7f5dfefb8cf43b77b28b76c756e;hp=ec44be75a1531adf48204c4d78653c09c87cb340;hb=a8758de5bc19e5adb3f618d3038743a164f09912;hpb=969bd23cab98a79ca9101af33334000879fb60c5 diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/utils/CodeBuilderUtils.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/utils/CodeBuilderUtils.java index ec44be75a..cc8f3e0c5 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/utils/CodeBuilderUtils.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/utils/CodeBuilderUtils.java @@ -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) {