Example usage for org.objectweb.asm MethodVisitor visitJumpInsn

List of usage examples for org.objectweb.asm MethodVisitor visitJumpInsn

Introduction

In this page you can find the example usage for org.objectweb.asm MethodVisitor visitJumpInsn.

Prototype

public void visitJumpInsn(final int opcode, final Label label) 

Source Link

Document

Visits a jump instruction.

Usage

From source file:cn.annoreg.asm.DelegateGenerator.java

License:Open Source License

public static MethodVisitor generateNonStaticMethod(ClassVisitor parentClass, MethodVisitor parent,
        String className, String methodName, String desc, final Side side) {

    //convert desc to a non-static method form
    String nonstaticDesc;/* w ww .ja v  a  2 s .  co  m*/
    {
        Type staticType = Type.getMethodType(desc);
        Type retType = staticType.getReturnType();
        Type[] argsType = staticType.getArgumentTypes();
        Type[] argsTypeWithThis = new Type[argsType.length + 1];
        argsTypeWithThis[0] = Type.getType('L' + className.replace('.', '/') + ';');
        System.arraycopy(argsType, 0, argsTypeWithThis, 1, argsType.length);
        nonstaticDesc = Type.getMethodDescriptor(retType, argsTypeWithThis);
    }

    //delegateName is a string used by both sides to identify a network-call delegate.
    final String delegateName = className + ":" + methodName + ":" + desc;
    final Type[] args = Type.getArgumentTypes(nonstaticDesc);
    final Type ret = Type.getReturnType(nonstaticDesc);

    //Check types
    for (Type t : args) {
        //TODO support these types
        if (!t.getDescriptor().startsWith("L") && !t.getDescriptor().startsWith("[")) {
            throw new RuntimeException("Unsupported argument type in network call. ");
        }
    }
    if (!ret.equals(Type.VOID_TYPE)) {
        throw new RuntimeException(
                "Unsupported return value type in network call. " + "Only void is supported.");
    }

    //Generate call to NetworkCallManager in parent.
    parent.visitCode();
    //First parameter
    parent.visitLdcInsn(delegateName);
    //Second parameter: object array
    pushIntegerConst(parent, args.length); //this (0) has been included
    parent.visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/Object");
    for (int i = 0; i < args.length; ++i) {
        parent.visitInsn(Opcodes.DUP);
        pushIntegerConst(parent, i);
        parent.visitVarInsn(Opcodes.ALOAD, i);
        parent.visitInsn(Opcodes.AASTORE);
    }
    //Call cn.annoreg.mc.network.NetworkCallManager.onNetworkCall
    parent.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(NetworkCallManager.class),
            "onNetworkCall", "(Ljava/lang/String;[Ljava/lang/Object;)V");
    parent.visitInsn(Opcodes.RETURN);
    parent.visitMaxs(5, args.length);
    parent.visitEnd();

    //Create delegate object.
    final ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
    final String delegateId = Integer.toString(delegateNextID++);
    final Type delegateClassType = Type.getType("cn/annoreg/asm/NetworkCallDelegate_" + delegateId);
    cw.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC, delegateClassType.getInternalName(), null,
            Type.getInternalName(Object.class),
            new String[] { Type.getInternalName(NetworkCallDelegate.class) });
    //package cn.annoreg.asm;
    //class NetworkCallDelegate_? implements NetworkCallDelegate {
    {
        MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
        mv.visitCode();
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(Object.class), "<init>", "()V");
        mv.visitInsn(Opcodes.RETURN);
        mv.visitMaxs(1, 1);
        mv.visitEnd();
    }
    //public NetworkCallDelegate_?() {}

    final String delegateMethodName = methodName + "_delegate_" + delegateId;
    {
        MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "invoke",
                Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(Object[].class)), null, null);
        mv.visitCode();

        //check if this is null
        mv.visitVarInsn(Opcodes.ALOAD, 1); //0 is this
        pushIntegerConst(mv, 0);
        mv.visitInsn(Opcodes.AALOAD);
        Label lblEnd = new Label();
        mv.visitJumpInsn(Opcodes.IFNULL, lblEnd);

        for (int i = 0; i < args.length; ++i) {
            mv.visitVarInsn(Opcodes.ALOAD, 1); //0 is this
            pushIntegerConst(mv, i);
            mv.visitInsn(Opcodes.AALOAD);
            mv.visitTypeInsn(Opcodes.CHECKCAST, args[i].getInternalName());
        }
        mv.visitMethodInsn(Opcodes.INVOKESTATIC,
                //delegateClassType.getInternalName(), 
                className.replace('.', '/'), delegateMethodName, nonstaticDesc);

        mv.visitLabel(lblEnd);

        mv.visitInsn(Opcodes.RETURN);
        mv.visitMaxs(args.length + 2, 2);
        mv.visitEnd();
    }
    //@Override public void invoke(Object[] args) {
    //    delegated((Type0) args[0], (Type1) args[1], ...);
    //}

    //The returned MethodVisitor will visit the original version of the method,
    //including its annotation, where we can get StorageOptions.
    return new MethodVisitor(Opcodes.ASM4, parentClass.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC,
            delegateMethodName, nonstaticDesc, null, null)) {

        //Remember storage options for each argument
        StorageOption.Option[] options = new StorageOption.Option[args.length];
        int targetIndex = -1;
        double sendRange = -1;
        StorageOption.Target.RangeOption range = StorageOption.Target.RangeOption.SINGLE;

        {
            for (int i = 0; i < options.length; ++i) {
                options[i] = StorageOption.Option.NULL; //set default value
            }
            options[0] = StorageOption.Option.INSTANCE;
        }

        @Override
        public AnnotationVisitor visitParameterAnnotation(int parameter_in_func, String desc, boolean visible) {
            final int parameter = parameter_in_func + 1; //skip this
            Type type = Type.getType(desc);
            if (type.equals(Type.getType(StorageOption.Data.class))) {
                options[parameter] = StorageOption.Option.DATA;
            } else if (type.equals(Type.getType(StorageOption.Instance.class))) {
                //INSTANCE as defualt
                options[parameter] = StorageOption.Option.INSTANCE;

                //Change to NULLABLE_INSTANCE if nullable set to true
                return new AnnotationVisitor(this.api,
                        super.visitParameterAnnotation(parameter, desc, visible)) {
                    @Override
                    public void visit(String name, Object value) {
                        if (name.equals("nullable")) {
                            if ((Boolean) value == true) {
                                options[parameter] = StorageOption.Option.NULLABLE_INSTANCE;
                            }
                        }
                        super.visit(name, value);
                    }
                };
            } else if (type.equals(Type.getType(StorageOption.Update.class))) {
                options[parameter] = StorageOption.Option.UPDATE;
            } else if (type.equals(Type.getType(StorageOption.Null.class))) {
                options[parameter] = StorageOption.Option.NULL;
            } else if (type.equals(Type.getType(StorageOption.Target.class))) {
                if (!args[parameter].equals(Type.getType(EntityPlayer.class))) {
                    throw new RuntimeException("Target annotation can only be used on EntityPlayer.");
                }
                if (targetIndex != -1) {
                    throw new RuntimeException("You can not specify multiple targets.");
                }
                options[parameter] = StorageOption.Option.INSTANCE;
                targetIndex = parameter;
                return new AnnotationVisitor(this.api,
                        super.visitParameterAnnotation(parameter, desc, visible)) {
                    @Override
                    public void visitEnum(String name, String desc, String value) {
                        super.visitEnum(name, desc, value);
                        range = StorageOption.Target.RangeOption.valueOf(value);
                    }
                };
            } else if (type.equals(Type.getType(StorageOption.RangedTarget.class))) {
                if (targetIndex != -1) {
                    throw new RuntimeException("You can not specify multiple targets.");
                }
                targetIndex = parameter;
                range = null;
                return new AnnotationVisitor(this.api,
                        super.visitParameterAnnotation(parameter, desc, visible)) {
                    @Override
                    public void visit(String name, Object value) {
                        super.visit(name, value);
                        sendRange = (double) value;
                    }
                };
            }
            return super.visitParameterAnnotation(parameter, desc, visible);
        }

        //TODO this option (from annotation)

        @Override
        public void visitEnd() {
            super.visitEnd();
            //This is the last method in the delegate class.
            //Finish the class and do the registration.
            cw.visitEnd();
            try {
                Class<?> clazz = classLoader.defineClass(delegateClassType.getClassName(), cw.toByteArray());
                NetworkCallDelegate delegateObj = (NetworkCallDelegate) clazz.newInstance();
                if (side == Side.CLIENT) {
                    NetworkCallManager.registerClientDelegateClass(delegateName, delegateObj, options,
                            targetIndex, range, sendRange);
                } else {
                    NetworkCallManager.registerServerDelegateClass(delegateName, delegateObj, options);
                }
            } catch (Throwable e) {
                throw new RuntimeException("Can not create delegate for network call.", e);
            }
        }
    };
    //public static void delegated(Type0 arg0, Type1, arg1, ...) {
    //    //Code generated by caller.
    //}
    //}
}

From source file:co.paralleluniverse.fibers.instrument.InstrumentMethod.java

License:Open Source License

public void accept(MethodVisitor mv, boolean hasAnnotation) {
    db.log(LogLevel.INFO, "Instrumenting method %s#%s%s", className, mn.name, mn.desc);

    mv.visitAnnotation(ALREADY_INSTRUMENTED_DESC, true);
    final boolean handleProxyInvocations = HANDLE_PROXY_INVOCATIONS & hasSuspendableSuperCalls;
    mv.visitCode();/*from  w w w . j  av  a 2s . c om*/

    Label lMethodStart = new Label();
    Label lMethodStart2 = new Label();
    Label lMethodEnd = new Label();
    Label lCatchSEE = new Label();
    Label lCatchUTE = new Label();
    Label lCatchAll = new Label();
    Label[] lMethodCalls = new Label[numCodeBlocks - 1];

    for (int i = 1; i < numCodeBlocks; i++)
        lMethodCalls[i - 1] = new Label();

    mv.visitInsn(Opcodes.ACONST_NULL);
    mv.visitVarInsn(Opcodes.ASTORE, lvarInvocationReturnValue);

    //        if (verifyInstrumentation) {
    //            mv.visitInsn(Opcodes.ICONST_0);
    //            mv.visitVarInsn(Opcodes.ISTORE, lvarSuspendableCalled);
    //        }
    mv.visitTryCatchBlock(lMethodStart, lMethodEnd, lCatchSEE, EXCEPTION_NAME);
    if (handleProxyInvocations)
        mv.visitTryCatchBlock(lMethodStart, lMethodEnd, lCatchUTE, UNDECLARED_THROWABLE_NAME);

    // Prepare visitTryCatchBlocks for InvocationTargetException.
    // With reflective invocations, the SuspendExecution exception will be wrapped in InvocationTargetException. We need to catch it and unwrap it.
    // Note that the InvocationTargetException will be regenrated on every park, adding further overhead on top of the reflective call.
    // This must be done here, before all other visitTryCatchBlock, because the exception's handler
    // will be matched according to the order of in which visitTryCatchBlock has been called. Earlier calls take precedence.
    Label[][] refInvokeTryCatch = new Label[numCodeBlocks - 1][];
    for (int i = 1; i < numCodeBlocks; i++) {
        FrameInfo fi = codeBlocks[i];
        AbstractInsnNode in = mn.instructions.get(fi.endInstruction);
        if (mn.instructions.get(fi.endInstruction) instanceof MethodInsnNode) {
            MethodInsnNode min = (MethodInsnNode) in;
            if (isReflectInvocation(min.owner, min.name)) {
                Label[] ls = new Label[3];
                for (int k = 0; k < 3; k++)
                    ls[k] = new Label();
                refInvokeTryCatch[i - 1] = ls;
                mv.visitTryCatchBlock(ls[0], ls[1], ls[2], "java/lang/reflect/InvocationTargetException");
            }
        }
    }

    for (Object o : mn.tryCatchBlocks) {
        TryCatchBlockNode tcb = (TryCatchBlockNode) o;
        if (EXCEPTION_NAME.equals(tcb.type) && !hasAnnotation) // we allow catch of SuspendExecution in method annotated with @Suspendable.
            throw new UnableToInstrumentException("catch for SuspendExecution", className, mn.name, mn.desc);
        if (handleProxyInvocations && UNDECLARED_THROWABLE_NAME.equals(tcb.type)) // we allow catch of SuspendExecution in method annotated with @Suspendable.
            throw new UnableToInstrumentException("catch for UndeclaredThrowableException", className, mn.name,
                    mn.desc);
        //          if (INTERRUPTED_EXCEPTION_NAME.equals(tcb.type))
        //              throw new UnableToInstrumentException("catch for " + InterruptedException.class.getSimpleName(), className, mn.name, mn.desc);

        tcb.accept(mv);
    }

    if (mn.visibleParameterAnnotations != null)
        dumpParameterAnnotations(mv, mn.visibleParameterAnnotations, true);

    if (mn.invisibleParameterAnnotations != null)
        dumpParameterAnnotations(mv, mn.invisibleParameterAnnotations, false);

    if (mn.visibleAnnotations != null) {
        for (Object o : mn.visibleAnnotations) {
            AnnotationNode an = (AnnotationNode) o;
            an.accept(mv.visitAnnotation(an.desc, true));
        }
    }

    mv.visitTryCatchBlock(lMethodStart, lMethodEnd, lCatchAll, null);

    mv.visitMethodInsn(Opcodes.INVOKESTATIC, STACK_NAME, "getStack", "()L" + STACK_NAME + ";");
    mv.visitInsn(Opcodes.DUP);
    mv.visitVarInsn(Opcodes.ASTORE, lvarStack);

    // println(mv, "STACK: ", lvarStack);
    // dumpStack(mv);
    if (DUAL) {
        mv.visitJumpInsn(Opcodes.IFNULL, lMethodStart);
        mv.visitVarInsn(Opcodes.ALOAD, lvarStack);
    }

    emitStoreResumed(mv, true); // we'll assume we have been resumed

    mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, STACK_NAME, "nextMethodEntry", "()I");
    mv.visitTableSwitchInsn(1, numCodeBlocks - 1, lMethodStart2, lMethodCalls);

    mv.visitLabel(lMethodStart2);

    // the following code handles the case of an instrumented method called not as part of a suspendable code path
    // isFirstInStack will return false in that case.
    mv.visitVarInsn(Opcodes.ALOAD, lvarStack);
    mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, STACK_NAME, "isFirstInStackOrPushed", "()Z");
    mv.visitJumpInsn(Opcodes.IFNE, lMethodStart); // if true
    mv.visitInsn(Opcodes.ACONST_NULL);
    mv.visitVarInsn(Opcodes.ASTORE, lvarStack);

    mv.visitLabel(lMethodStart);

    emitStoreResumed(mv, false); // no, we have not been resumed

    dumpCodeBlock(mv, 0, 0);

    for (int i = 1; i < numCodeBlocks; i++) {
        FrameInfo fi = codeBlocks[i];

        MethodInsnNode min = (MethodInsnNode) (mn.instructions.get(fi.endInstruction));
        if (isYieldMethod(min.owner, min.name)) { // special case - call to yield
            if (min.getOpcode() != Opcodes.INVOKESTATIC)
                throw new UnableToInstrumentException("invalid call to suspending method.", className, mn.name,
                        mn.desc);

            final int numYieldArgs = TypeAnalyzer.getNumArguments(min.desc);
            final boolean yieldReturnsValue = (Type.getReturnType(min.desc) != Type.VOID_TYPE);

            emitStoreState(mv, i, fi, numYieldArgs); // we preserve the arguments for the call to yield on the operand stack
            emitStoreResumed(mv, false); // we have not been resumed
            // emitSuspendableCalled(mv);

            min.accept(mv); // we call the yield method
            if (yieldReturnsValue)
                mv.visitInsn(Opcodes.POP); // we ignore the returned value...
            mv.visitLabel(lMethodCalls[i - 1]); // we resume AFTER the call

            final Label afterPostRestore = new Label();
            mv.visitVarInsn(Opcodes.ILOAD, lvarResumed);
            mv.visitJumpInsn(Opcodes.IFEQ, afterPostRestore);
            emitPostRestore(mv);
            mv.visitLabel(afterPostRestore);

            emitRestoreState(mv, i, fi, numYieldArgs);
            if (yieldReturnsValue)
                mv.visitVarInsn(Opcodes.ILOAD, lvarResumed); // ... and replace the returned value with the value of resumed

            dumpCodeBlock(mv, i, 1); // skip the call
        } else {
            final Label lbl = new Label();
            if (DUAL) {
                mv.visitVarInsn(Opcodes.ALOAD, lvarStack);
                mv.visitJumpInsn(Opcodes.IFNULL, lbl);
            }

            // normal case - call to a suspendable method - resume before the call
            emitStoreState(mv, i, fi, 0);
            emitStoreResumed(mv, false); // we have not been resumed
            // emitPreemptionPoint(mv, PREEMPTION_CALL);

            mv.visitLabel(lMethodCalls[i - 1]);
            emitRestoreState(mv, i, fi, 0);

            if (DUAL)
                mv.visitLabel(lbl);

            if (isReflectInvocation(min.owner, min.name)) {
                // We catch the InvocationTargetException and unwrap it if it wraps a SuspendExecution exception.
                Label[] ls = refInvokeTryCatch[i - 1];
                final Label startTry = ls[0];
                final Label endTry = ls[1];
                final Label startCatch = ls[2];
                final Label endCatch = new Label();
                final Label notSuspendExecution = new Label();

                // mv.visitTryCatchBlock(startTry, endTry, startCatch, "java/lang/reflect/InvocationTargetException");
                mv.visitLabel(startTry); // try {
                min.accept(mv); //   method.invoke()
                mv.visitVarInsn(Opcodes.ASTORE, lvarInvocationReturnValue); // save return value
                mv.visitLabel(endTry); // }
                mv.visitJumpInsn(Opcodes.GOTO, endCatch);
                mv.visitLabel(startCatch); // catch(InvocationTargetException ex) {
                mv.visitInsn(Opcodes.DUP);
                mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Throwable", "getCause",
                        "()Ljava/lang/Throwable;");
                mv.visitTypeInsn(Opcodes.INSTANCEOF, EXCEPTION_NAME);
                mv.visitJumpInsn(Opcodes.IFEQ, notSuspendExecution);
                mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Throwable", "getCause",
                        "()Ljava/lang/Throwable;");
                mv.visitLabel(notSuspendExecution);
                mv.visitInsn(Opcodes.ATHROW);
                mv.visitLabel(endCatch);

                mv.visitVarInsn(Opcodes.ALOAD, lvarInvocationReturnValue); // restore return value
                dumpCodeBlock(mv, i, 1); // skip the call
            } else {
                // emitSuspendableCalled(mv);
                dumpCodeBlock(mv, i, 0);
            }
        }
    }

    mv.visitLabel(lMethodEnd);

    if (handleProxyInvocations) {
        mv.visitLabel(lCatchUTE);
        mv.visitInsn(Opcodes.DUP);

        // println(mv, "CTCH: ");
        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Throwable", "getCause", "()Ljava/lang/Throwable;");
        // println(mv, "CAUSE: ");
        mv.visitTypeInsn(Opcodes.INSTANCEOF, EXCEPTION_NAME);
        mv.visitJumpInsn(Opcodes.IFEQ, lCatchAll);
        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Throwable", "getCause", "()Ljava/lang/Throwable;");
        mv.visitJumpInsn(Opcodes.GOTO, lCatchSEE);
    }

    mv.visitLabel(lCatchAll);
    emitPopMethod(mv);
    mv.visitLabel(lCatchSEE);

    // println(mv, "THROW: ");
    mv.visitInsn(Opcodes.ATHROW); // rethrow shared between catchAll and catchSSE

    if (mn.localVariables != null) {
        for (Object o : mn.localVariables)
            ((LocalVariableNode) o).accept(mv);
    }

    mv.visitMaxs(mn.maxStack + ADD_OPERANDS, mn.maxLocals + NUM_LOCALS + additionalLocals);
    mv.visitEnd();
}

From source file:co.paralleluniverse.fibers.instrument.InstrumentMethod.java

License:Open Source License

private void emitPopMethod(MethodVisitor mv) {
    //        emitVerifyInstrumentation(mv);

    final Label lbl = new Label();
    if (DUAL) {/*from   w w w.j a  v  a 2 s  . co m*/
        mv.visitVarInsn(Opcodes.ALOAD, lvarStack);
        mv.visitJumpInsn(Opcodes.IFNULL, lbl);
    }

    mv.visitVarInsn(Opcodes.ALOAD, lvarStack);
    mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, STACK_NAME, "popMethod", "()V");

    if (DUAL)
        mv.visitLabel(lbl);
}

From source file:com.asakusafw.dag.compiler.builtin.BranchOperatorGenerator.java

License:Apache License

static void branch(MethodVisitor method, Context context, UserOperator operator, LocalVarRef input,
        Map<OperatorProperty, FieldRef> dependencies) {
    OperatorOutput[] outputs = outputs(context, operator);
    Label[] caseLabels = Stream.of(outputs).map(o -> new Label()).toArray(Label[]::new);
    Label defaultLabel = new Label();
    Label endLabel = new Label();

    method.visitMethodInsn(Opcodes.INVOKEVIRTUAL, typeOf(Enum.class).getInternalName(), "ordinal",
            Type.getMethodDescriptor(Type.INT_TYPE), false);
    method.visitTableSwitchInsn(0, caseLabels.length - 1, defaultLabel, caseLabels);

    for (int i = 0; i < outputs.length; i++) {
        method.visitLabel(caseLabels[i]);
        FieldRef ref = Invariants.requireNonNull(dependencies.get(outputs[i]));
        ref.load(method);// ww w  .ja va2s.c  o m
        input.load(method);
        invokeResultAdd(method);
        method.visitJumpInsn(Opcodes.GOTO, endLabel);
    }
    method.visitLabel(defaultLabel);
    getNew(method, Descriptions.typeOf(AssertionError.class));
    method.visitInsn(Opcodes.ATHROW);

    method.visitLabel(endLabel);
}

From source file:com.asakusafw.dag.compiler.builtin.MasterCheckOperatorGenerator.java

License:Apache License

@Override
protected void defineProcess(MethodVisitor method, Context context, UserOperator operator, LocalVarRef master,
        LocalVarRef transaction, FieldRef impl, Map<OperatorProperty, FieldRef> dependencies,
        ClassDescription target) {/*from w  w  w .ja  v a  2s.co  m*/
    OperatorOutput found = operator.getOutputs().get(MasterCheck.ID_OUTPUT_FOUND);
    OperatorOutput missed = operator.getOutputs().get(MasterCheck.ID_OUTPUT_MISSED);

    Label onNull = new Label();
    Label end = new Label();
    master.load(method);
    getConst(method, null);
    method.visitJumpInsn(Opcodes.IF_ACMPEQ, onNull);

    dependencies.get(found).load(method);
    transaction.load(method);
    invokeResultAdd(method);
    method.visitJumpInsn(Opcodes.GOTO, end);

    method.visitLabel(onNull);
    dependencies.get(missed).load(method);
    transaction.load(method);
    invokeResultAdd(method);

    method.visitLabel(end);
}

From source file:com.asakusafw.dag.compiler.builtin.MasterJoinOperatorGenerator.java

License:Apache License

@Override
protected void defineProcess(MethodVisitor method, Context context, UserOperator operator, LocalVarRef master,
        LocalVarRef transaction, FieldRef impl, Map<OperatorProperty, FieldRef> dependencies,
        ClassDescription target) {/*ww w  .ja v  a2s. c o m*/
    OperatorOutput joined = operator.getOutput(MasterJoin.ID_OUTPUT_JOINED);
    OperatorOutput missed = operator.getOutput(MasterJoin.ID_OUTPUT_MISSED);

    Label onNull = new Label();
    Label end = new Label();
    master.load(method);
    getConst(method, null);
    method.visitJumpInsn(Opcodes.IF_ACMPEQ, onNull);

    dependencies.get(joined).load(method);
    performJoin(method, context, operator, master, transaction, impl, dependencies, target);
    invokeResultAdd(method);
    method.visitJumpInsn(Opcodes.GOTO, end);

    method.visitLabel(onNull);
    dependencies.get(missed).load(method);
    transaction.load(method);
    invokeResultAdd(method);

    method.visitLabel(end);
}

From source file:com.asakusafw.dag.compiler.builtin.MasterJoinUpdateOperatorGenerator.java

License:Apache License

@Override
protected void defineProcess(MethodVisitor method, Context context, UserOperator operator, LocalVarRef master,
        LocalVarRef transaction, FieldRef impl, Map<OperatorProperty, FieldRef> dependencies,
        ClassDescription target) {/* w w w  .j a va2s.com*/
    OperatorOutput found = operator.getOutputs().get(MasterCheck.ID_OUTPUT_FOUND);
    OperatorOutput missed = operator.getOutputs().get(MasterCheck.ID_OUTPUT_MISSED);

    Label onNull = new Label();
    Label end = new Label();
    master.load(method);
    getConst(method, null);
    method.visitJumpInsn(Opcodes.IF_ACMPEQ, onNull);

    List<ValueRef> arguments = new ArrayList<>();
    arguments.add(impl);
    arguments.add(master);
    arguments.add(transaction);
    appendExtraViews(arguments::add, operator, dependencies::get);
    appendArguments(arguments::add, operator, dependencies::get);
    invoke(method, context, operator, arguments);
    dependencies.get(found).load(method);
    transaction.load(method);
    invokeResultAdd(method);
    method.visitJumpInsn(Opcodes.GOTO, end);

    method.visitLabel(onNull);
    dependencies.get(missed).load(method);
    transaction.load(method);
    invokeResultAdd(method);

    method.visitLabel(end);
}

From source file:com.asakusafw.dag.compiler.builtin.SummarizeOperatorGenerator.java

License:Apache License

private static void defineCheckNull(ClassWriter writer, UserOperator operator, DataModelReference inputType) {

    MethodVisitor method = writer.visitMethod(Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC, METHOD_CHECK_NON_NULL,
            Type.getMethodDescriptor(Type.VOID_TYPE, typeOf(ValueOption.class), typeOf(Object.class),
                    typeOf(String.class)),
            null, null);//  w ww. j a v a  2  s. co m

    LocalVarRef optionVar = new LocalVarRef(Opcodes.ALOAD, 0);
    LocalVarRef objectVar = new LocalVarRef(Opcodes.ALOAD, 1);
    LocalVarRef nameVar = new LocalVarRef(Opcodes.ALOAD, 2);

    // if (option.isNull()) {
    Label ifEnd = new Label();
    optionVar.load(method);
    getNullity(method, VALUE_DESC);
    method.visitJumpInsn(Opcodes.IFEQ, ifEnd);

    // new NullPointerException ...
    method.visitTypeInsn(Opcodes.NEW, typeOf(NullPointerException.class).getInternalName());
    method.visitInsn(Opcodes.DUP);

    // str = String.format("<type>.%s must not be null (in <operator>): %s", name, object)
    getConst(method,
            String.format("%s.%%s must not be null (in %s.%s): %%s", inputType.getDeclaration().getSimpleName(),
                    operator.getMethod().getDeclaringClass().getSimpleName(), operator.getMethod().getName()));

    getArray(method, typeOf(Object.class), new LocalVarRef[] { nameVar, objectVar });
    method.visitMethodInsn(Opcodes.INVOKESTATIC, typeOf(String.class).getInternalName(), "format",
            Type.getMethodDescriptor(typeOf(String.class), typeOf(String.class), typeOf(Object[].class)),
            false);

    // throw new NullPointerException(str)
    method.visitMethodInsn(Opcodes.INVOKESPECIAL, typeOf(NullPointerException.class).getInternalName(),
            CONSTRUCTOR_NAME, Type.getMethodDescriptor(Type.VOID_TYPE, typeOf(String.class)), false);

    method.visitInsn(Opcodes.ATHROW);

    method.visitLabel(ifEnd);
    // }
    method.visitInsn(Opcodes.RETURN);
    method.visitMaxs(0, 0);
    method.visitEnd();
}

From source file:com.asakusafw.dag.compiler.codegen.DataComparatorGenerator.java

License:Apache License

private static void defineCompare(ClassWriter writer, DataModelReference reference,
        List<Group.Ordering> orderings) {
    MethodVisitor v = writer.visitMethod(Opcodes.ACC_PUBLIC, "compare", DESC_COMPARE, null,
            new String[] { typeOf(IOException.class).getInternalName(), });
    LocalVarRef a = new LocalVarRef(Opcodes.ALOAD, 1);
    LocalVarRef b = new LocalVarRef(Opcodes.ALOAD, 2);
    for (Group.Ordering ordering : orderings) {
        PropertyReference property = Invariants
                .requireNonNull(reference.findProperty(ordering.getPropertyName()));

        // int diff = ValueOptionSerDe.compareT({a, b}, {b, a});
        switch (ordering.getDirection()) {
        case ASCENDANT:
            a.load(v);/* w w  w  .  j  a va  2  s.  c  om*/
            b.load(v);
            break;
        case DESCENDANT:
            b.load(v);
            a.load(v);
            break;
        default:
            throw new AssertionError(ordering);
        }
        v.visitMethodInsn(Opcodes.INVOKESTATIC, typeOf(ValueOptionSerDe.class).getInternalName(),
                Invariants.requireNonNull(METHOD_NAMES.get(property.getType())), DESC_COMPARE, false);
        LocalVarRef cmp = putLocalVar(v, Type.INT, 3);
        Label eq = new Label();

        // if (diff != 0) {
        cmp.load(v);
        v.visitJumpInsn(Opcodes.IFEQ, eq);

        // return diff;
        cmp.load(v);
        v.visitInsn(Opcodes.IRETURN);

        // } @ eq
        v.visitLabel(eq);
    }
    getConst(v, 0);
    v.visitInsn(Opcodes.IRETURN);
    v.visitMaxs(0, 0);
    v.visitEnd();
}

From source file:com.asakusafw.dag.compiler.codegen.ObjectComparatorGenerator.java

License:Apache License

private static void defineCompare(ClassWriter writer, DataModelReference reference,
        List<Group.Ordering> orderings) {
    MethodVisitor v = writer.visitMethod(Opcodes.ACC_PUBLIC, "compare",
            Type.getMethodDescriptor(typeOf(int.class), typeOf(Object.class), typeOf(Object.class)), null,
            null);//  w w  w.j  av a2 s .c  om
    LocalVarRef a = cast(v, 1, reference.getDeclaration());
    LocalVarRef b = cast(v, 2, reference.getDeclaration());
    for (Group.Ordering ordering : orderings) {
        LocalVarRef left;
        LocalVarRef right;
        switch (ordering.getDirection()) {
        case ASCENDANT:
            left = a;
            right = b;
            break;
        case DESCENDANT:
            left = b;
            right = a;
            break;
        default:
            throw new AssertionError(ordering);
        }

        // int diff = left.getXOption().compareTo(right.getXOption());
        PropertyReference property = Invariants
                .requireNonNull(reference.findProperty(ordering.getPropertyName()));
        left.load(v);
        getOption(v, property);
        right.load(v);
        getOption(v, property);
        v.visitMethodInsn(Opcodes.INVOKEINTERFACE, TYPE_COMPARABLE.getInternalName(), "compareTo",
                Type.getMethodDescriptor(typeOf(int.class), typeOf(Object.class)), true);
        LocalVarRef cmp = putLocalVar(v, Type.INT, 3);
        Label eq = new Label();

        // if (diff != 0) {
        cmp.load(v);
        v.visitJumpInsn(Opcodes.IFEQ, eq);

        // return diff;
        cmp.load(v);
        v.visitInsn(Opcodes.IRETURN);

        // } @ eq
        v.visitLabel(eq);
    }
    getConst(v, 0);
    v.visitInsn(Opcodes.IRETURN);
    v.visitMaxs(0, 0);
    v.visitEnd();
}