Search in sources :

Example 1 with IntInsnNode

use of org.apache.xbean.asm5.tree.IntInsnNode in project apex-malhar by apache.

the class BeanClassGenerator method addHashCodeMethod.

/**
 * This will add a hashCode method for class being generated. <br>
 * Algorithm is as follows: <br>
 * <i><p>
 * int hashCode = 7;
 * for (field: all fields) {
 * hashCode = 23 * hashCode + field.hashCode()
 * }
 * </p></i>
 * <br>
 * <b> For primitive field, hashcode implemenented is similar to the one present in its wrapper class. </b>
 *
 * @param classNode
 * @param fieldList
 * @throws JSONException
 */
@SuppressWarnings("unchecked")
private static void addHashCodeMethod(ClassNode classNode, List<TupleSchemaRegistry.SQLFieldInfo> fieldList) throws JSONException {
    MethodNode hashCodeNode = new MethodNode(Opcodes.ACC_PUBLIC, "hashCode", "()I", null, null);
    hashCodeNode.visitAnnotation("Ljava/lang/Override;", true);
    hashCodeNode.instructions.add(new IntInsnNode(Opcodes.BIPUSH, 7));
    hashCodeNode.instructions.add(new VarInsnNode(Opcodes.ISTORE, 1));
    for (TupleSchemaRegistry.SQLFieldInfo fieldInfo : fieldList) {
        String fieldName = fieldInfo.getColumnName();
        String fieldType = fieldInfo.getType().getJavaType().getName();
        String fieldJavaType = getJavaType(fieldType);
        hashCodeNode.instructions.add(new IntInsnNode(Opcodes.BIPUSH, 23));
        hashCodeNode.instructions.add(new VarInsnNode(Opcodes.ILOAD, 1));
        hashCodeNode.instructions.add(new InsnNode(Opcodes.IMUL));
        hashCodeNode.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0));
        hashCodeNode.instructions.add(new FieldInsnNode(Opcodes.GETFIELD, classNode.name, fieldName, fieldJavaType));
        switch(fieldType) {
            case "boolean":
                LabelNode falseNode = new LabelNode();
                LabelNode trueNode = new LabelNode();
                hashCodeNode.instructions.add(new JumpInsnNode(Opcodes.IFEQ, falseNode));
                hashCodeNode.instructions.add(new IntInsnNode(Opcodes.SIPUSH, 1231));
                hashCodeNode.instructions.add(new JumpInsnNode(Opcodes.GOTO, trueNode));
                hashCodeNode.instructions.add(falseNode);
                hashCodeNode.instructions.add(new IntInsnNode(Opcodes.SIPUSH, 1237));
                hashCodeNode.instructions.add(trueNode);
                break;
            case "byte":
            case "char":
            case "short":
            case "int":
                break;
            case "float":
                hashCodeNode.instructions.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "java/lang/Float", "floatToIntBits", "(F)I", false));
                break;
            case "long":
                hashCodeNode.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0));
                hashCodeNode.instructions.add(new FieldInsnNode(Opcodes.GETFIELD, classNode.name, fieldName, fieldJavaType));
                hashCodeNode.instructions.add(new IntInsnNode(Opcodes.BIPUSH, 32));
                hashCodeNode.instructions.add(new InsnNode(Opcodes.LUSHR));
                hashCodeNode.instructions.add(new InsnNode(Opcodes.LXOR));
                hashCodeNode.instructions.add(new InsnNode(Opcodes.L2I));
                break;
            case "double":
                hashCodeNode.instructions.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "java/lang/Double", "doubleToLongBits", "(D)J", false));
                hashCodeNode.instructions.add(new InsnNode(Opcodes.DUP2));
                hashCodeNode.instructions.add(new VarInsnNode(Opcodes.LSTORE, 2));
                hashCodeNode.instructions.add(new VarInsnNode(Opcodes.LLOAD, 2));
                hashCodeNode.instructions.add(new IntInsnNode(Opcodes.BIPUSH, 32));
                hashCodeNode.instructions.add(new InsnNode(Opcodes.LUSHR));
                hashCodeNode.instructions.add(new InsnNode(Opcodes.LXOR));
                hashCodeNode.instructions.add(new InsnNode(Opcodes.L2I));
                break;
            default:
                String objectOwnerType = fieldType.replace('.', '/');
                LabelNode nullNode = new LabelNode();
                LabelNode continueNode = new LabelNode();
                hashCodeNode.instructions.add(new JumpInsnNode(Opcodes.IFNULL, nullNode));
                hashCodeNode.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0));
                hashCodeNode.instructions.add(new FieldInsnNode(Opcodes.GETFIELD, classNode.name, fieldName, fieldJavaType));
                hashCodeNode.instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, objectOwnerType, "hashCode", "()I", false));
                hashCodeNode.instructions.add(new JumpInsnNode(Opcodes.GOTO, continueNode));
                hashCodeNode.instructions.add(nullNode);
                hashCodeNode.instructions.add(new InsnNode(Opcodes.ICONST_0));
                hashCodeNode.instructions.add(continueNode);
                break;
        }
        hashCodeNode.instructions.add(new InsnNode(Opcodes.IADD));
        hashCodeNode.instructions.add(new VarInsnNode(Opcodes.ISTORE, 1));
    }
    hashCodeNode.instructions.add(new VarInsnNode(Opcodes.ILOAD, 1));
    hashCodeNode.instructions.add(new InsnNode(Opcodes.IRETURN));
    classNode.methods.add(hashCodeNode);
}
Also used : LabelNode(org.apache.xbean.asm5.tree.LabelNode) FieldInsnNode(org.apache.xbean.asm5.tree.FieldInsnNode) JumpInsnNode(org.apache.xbean.asm5.tree.JumpInsnNode) TypeInsnNode(org.apache.xbean.asm5.tree.TypeInsnNode) InsnNode(org.apache.xbean.asm5.tree.InsnNode) VarInsnNode(org.apache.xbean.asm5.tree.VarInsnNode) MethodInsnNode(org.apache.xbean.asm5.tree.MethodInsnNode) IntInsnNode(org.apache.xbean.asm5.tree.IntInsnNode) LdcInsnNode(org.apache.xbean.asm5.tree.LdcInsnNode) MethodNode(org.apache.xbean.asm5.tree.MethodNode) TupleSchemaRegistry(org.apache.apex.malhar.sql.schema.TupleSchemaRegistry) MethodInsnNode(org.apache.xbean.asm5.tree.MethodInsnNode) JumpInsnNode(org.apache.xbean.asm5.tree.JumpInsnNode) IntInsnNode(org.apache.xbean.asm5.tree.IntInsnNode) FieldInsnNode(org.apache.xbean.asm5.tree.FieldInsnNode) VarInsnNode(org.apache.xbean.asm5.tree.VarInsnNode)

Aggregations

TupleSchemaRegistry (org.apache.apex.malhar.sql.schema.TupleSchemaRegistry)1 FieldInsnNode (org.apache.xbean.asm5.tree.FieldInsnNode)1 InsnNode (org.apache.xbean.asm5.tree.InsnNode)1 IntInsnNode (org.apache.xbean.asm5.tree.IntInsnNode)1 JumpInsnNode (org.apache.xbean.asm5.tree.JumpInsnNode)1 LabelNode (org.apache.xbean.asm5.tree.LabelNode)1 LdcInsnNode (org.apache.xbean.asm5.tree.LdcInsnNode)1 MethodInsnNode (org.apache.xbean.asm5.tree.MethodInsnNode)1 MethodNode (org.apache.xbean.asm5.tree.MethodNode)1 TypeInsnNode (org.apache.xbean.asm5.tree.TypeInsnNode)1 VarInsnNode (org.apache.xbean.asm5.tree.VarInsnNode)1