Example usage for org.objectweb.asm Opcodes ASTORE

List of usage examples for org.objectweb.asm Opcodes ASTORE

Introduction

In this page you can find the example usage for org.objectweb.asm Opcodes ASTORE.

Prototype

int ASTORE

To view the source code for org.objectweb.asm Opcodes ASTORE.

Click Source Link

Usage

From source file:io.awacs.plugin.stacktrace.ClassTransformer.java

License:Apache License

/**
 * ?//from   w w w  . java2  s.c  o m
 * 1?try catch?                 try{
 * 2????        io.awacs.plugin.stacktrace.StackFrames.init();
 * 3????                io.awacs.plugin.stacktrace.StackFrames.push(className,methodName,0);
 * 4?                          Object val = methodName_origin_className(args);
 * 5?????                io.awacs.plugin.stacktrace.StackFrames.push(className,methodName,1);
 * 5???          List list = io.awacs.plugin.stacktrace.StackFrames.dump();
 * 7?????          io.awacs.plugin.stacktrace.StackTracePlugin.incrAccess(list);
 * 8?                          return val;
 * }catch(java.lang.Exception e){
 * 9??                io.awacs.plugin.stacktrace.StackTracePlugin.incrFailure(e);
 * 10?               throw e;
 * }
 */
private void transformTerminatedMethod(MethodNode origin, MethodNode proxy, ClassNode owner) {
    LabelNode l0 = new LabelNode();
    LabelNode l1 = new LabelNode();
    LabelNode l2 = new LabelNode();
    //try catch?
    proxy.tryCatchBlocks.add(new TryCatchBlockNode(l0, l1, l2, "java/lang/Exception"));
    proxy.instructions.add(l0);
    //?
    proxy.instructions.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "io/awacs/plugin/stacktrace/StackFrames",
            "init", "()V", false));
    proxy.instructions.add(new LdcInsnNode(owner.name.replaceAll("/", ".")));
    proxy.instructions.add(new LdcInsnNode(proxy.name));
    proxy.instructions.add(new LdcInsnNode(0));
    //
    proxy.instructions.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "io/awacs/plugin/stacktrace/StackFrames",
            "push", "(Ljava/lang/String;Ljava/lang/String;I)V", false));
    int varIndex = 0;//???
    //???,????this?
    if ((proxy.access & Opcodes.ACC_STATIC) != Opcodes.ACC_STATIC) {
        proxy.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0));
        varIndex = 1;
    }
    List<String> parameters = resolveParameters(proxy.desc);
    //???
    for (String param : parameters) {
        VarInsnNode insnNode;
        switch (param) {
        case "J":
            insnNode = new VarInsnNode(Opcodes.LLOAD, varIndex);
            varIndex += 2;
            break;
        case "D":
            insnNode = new VarInsnNode(Opcodes.DLOAD, varIndex);
            varIndex += 2;
            break;
        case "F":
            insnNode = new VarInsnNode(Opcodes.FLOAD, varIndex++);
            break;
        case "I":
            insnNode = new VarInsnNode(Opcodes.ILOAD, varIndex++);
            break;
        case "S":
            insnNode = new VarInsnNode(Opcodes.ILOAD, varIndex++);
            break;
        case "Z":
            insnNode = new VarInsnNode(Opcodes.ILOAD, varIndex++);
            break;
        case "B":
            insnNode = new VarInsnNode(Opcodes.ILOAD, varIndex++);
            break;
        case "C":
            insnNode = new VarInsnNode(Opcodes.ILOAD, varIndex++);
            break;
        default:
            insnNode = new VarInsnNode(Opcodes.ALOAD, varIndex++);
            break;
        }
        proxy.instructions.add(insnNode);
    }
    //
    if ((origin.access & Opcodes.ACC_STATIC) == Opcodes.ACC_STATIC)
        proxy.instructions
                .add(new MethodInsnNode(Opcodes.INVOKESTATIC, owner.name, origin.name, origin.desc, false));
    else
        proxy.instructions
                .add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, owner.name, origin.name, origin.desc, false));
    proxy.instructions.add(new LdcInsnNode(owner.name.replaceAll("/", ".")));
    proxy.instructions.add(new LdcInsnNode(proxy.name));
    proxy.instructions.add(new LdcInsnNode(1));
    //?
    proxy.instructions.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "io/awacs/plugin/stacktrace/StackFrames",
            "push", "(Ljava/lang/String;Ljava/lang/String;I)V", false));
    //??
    proxy.instructions.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "io/awacs/plugin/stacktrace/StackFrames",
            "dump", "()Ljava/util/List;", false));
    //???
    proxy.instructions.add(new MethodInsnNode(Opcodes.INVOKESTATIC,
            "io/awacs/plugin/stacktrace/StackTracePlugin", "incrAccess", "(Ljava/util/List;)V", false));
    proxy.instructions.add(l1);
    //
    String returnType = origin.desc.substring(origin.desc.indexOf(')') + 1);
    switch (returnType) {
    case "J":
        proxy.instructions.add(new InsnNode(Opcodes.LRETURN));
        break;
    case "D":
        proxy.instructions.add(new InsnNode(Opcodes.DRETURN));
        break;
    case "F":
        proxy.instructions.add(new InsnNode(Opcodes.FRETURN));
        break;
    case "I":
        proxy.instructions.add(new InsnNode(Opcodes.IRETURN));
        break;
    case "S":
        proxy.instructions.add(new InsnNode(Opcodes.IRETURN));
        break;
    case "C":
        proxy.instructions.add(new InsnNode(Opcodes.IRETURN));
        break;
    case "B":
        proxy.instructions.add(new InsnNode(Opcodes.IRETURN));
        break;
    case "Z":
        proxy.instructions.add(new InsnNode(Opcodes.IRETURN));
        break;
    case "V":
        proxy.instructions.add(new InsnNode(Opcodes.RETURN));
        break;
    default:
        proxy.instructions.add(new InsnNode(Opcodes.ARETURN));
        break;
    }
    proxy.instructions.add(l2);
    //?
    proxy.instructions.add(new FrameNode(Opcodes.F_SAME1, 0, null, 1, new Object[] { "java/lang/Exception" }));
    proxy.instructions.add(new VarInsnNode(Opcodes.ASTORE, varIndex));
    proxy.instructions.add(new VarInsnNode(Opcodes.ALOAD, varIndex));
    proxy.instructions.add(new MethodInsnNode(Opcodes.INVOKESTATIC,
            "io/awacs/plugin/stacktrace/StackTracePlugin", "incrFailure", "(Ljava/lang/Throwable;)V", false));
    proxy.instructions.add(new VarInsnNode(Opcodes.ALOAD, varIndex));
    proxy.instructions.add(new InsnNode(Opcodes.ATHROW));
    proxy.maxLocals = varIndex + 1;
    proxy.maxStack = Math.max(varIndex, 5);
}

From source file:io.syncframework.optimizer.OControllerStaticMethodVisitor.java

License:Apache License

public void visitInsn(int opcode) {
    if (opcode != Opcodes.RETURN) {
        mv.visitInsn(opcode);/*from  w  ww  . ja v  a 2 s  .c  o  m*/
        return;
    }

    Label start = new Label();
    Label l1 = new Label();
    Label l2 = new Label();
    Label interceptorsLabel = new Label();

    mv.visitCode();
    mv.visitTryCatchBlock(start, l1, l2, "java/lang/Throwable");

    /*
     * _asActions = new HashMap<String,Boolean>();
     */
    {
        mv.visitLabel(start);
        mv.visitTypeInsn(Opcodes.NEW, "java/util/HashMap");
        mv.visitInsn(Opcodes.DUP);
        mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/util/HashMap", "<init>", "()V", false);
        mv.visitFieldInsn(Opcodes.PUTSTATIC, reflector.getClazzInternalName(), "_asActions", "Ljava/util/Map;");
    }
    /*
     * _asActions.put("main", true);
     * _asActions.put("action1", true);
     */
    for (String name : reflector.getActions().keySet()) {
        Label l = new Label();
        mv.visitLabel(l);
        mv.visitFieldInsn(Opcodes.GETSTATIC, reflector.getClazzInternalName(), "_asActions", "Ljava/util/Map;");
        mv.visitLdcInsn(name);
        mv.visitInsn(Opcodes.ICONST_1);
        mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;",
                false);
        mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/Map", "put",
                "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", true);
        mv.visitInsn(Opcodes.POP);
    }

    /*
     * _asInterceptors = new HashMap<String,Class<?>[]>()
     */
    {
        Label l = new Label();
        mv.visitLabel(l);
        mv.visitTypeInsn(Opcodes.NEW, "java/util/HashMap");
        mv.visitInsn(Opcodes.DUP);
        mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/util/HashMap", "<init>", "()V", false);
        mv.visitFieldInsn(Opcodes.PUTSTATIC, reflector.getClazzInternalName(), "_asInterceptors",
                "Ljava/util/Map;");
    }

    /*
     * List<Class<?>> l = new ArrayList<Class<?>>();
     */
    mv.visitLabel(interceptorsLabel);
    mv.visitTypeInsn(Opcodes.NEW, "java/util/ArrayList");
    mv.visitInsn(Opcodes.DUP);
    mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/util/ArrayList", "<init>", "()V", false);
    mv.visitVarInsn(Opcodes.ASTORE, 0);

    for (String name : reflector.getActions().keySet()) {
        Class<?> interceptors[] = reflector.getInterceptors().get(name);
        if (interceptors == null || interceptors.length == 0)
            continue;

        /*
         * l.clear();
         */
        Label l01 = new Label();
        mv.visitLabel(l01);
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/List", "clear", "()V", true);

        for (Class<?> interceptor : interceptors) {
            /*
             * l.add(LoginInterceptor.class);
             */
            Label l02 = new Label();
            mv.visitLabel(l02);
            mv.visitVarInsn(Opcodes.ALOAD, 0);
            mv.visitLdcInsn(Type.getType(interceptor));
            mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/List", "add", "(Ljava/lang/Object;)Z", true);
        }

        /*
         * _asInterceptors.put("upload", l.toArray(new Class[0]));
         */
        Label l03 = new Label();
        mv.visitLabel(l03);
        mv.visitFieldInsn(Opcodes.GETSTATIC, reflector.getClazzInternalName(), "_asInterceptors",
                "Ljava/util/Map;");
        mv.visitLdcInsn(name);
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitInsn(Opcodes.ICONST_0);
        mv.visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/Class");
        mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/List", "toArray",
                "([Ljava/lang/Object;)[Ljava/lang/Object;", true);
        mv.visitTypeInsn(Opcodes.CHECKCAST, "[Ljava/lang/Class;");
        mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/Map", "put",
                "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", true);
        mv.visitInsn(Opcodes.POP);
    }

    /* 
     * _asParameters = new HashMap<String,Class<?>>() 
     */
    {
        Label l = new Label();
        mv.visitLabel(l);
        mv.visitTypeInsn(Opcodes.NEW, "java/util/HashMap");
        mv.visitInsn(Opcodes.DUP);
        mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/util/HashMap", "<init>", "()V", false);
        mv.visitFieldInsn(Opcodes.PUTSTATIC, reflector.getClazzInternalName(), "_asParameters",
                "Ljava/util/Map;");
    }
    /*
     * _asParameters.put("name", Type.class);
     */
    for (String name : reflector.getParameters().keySet()) {
        Label l = new Label();
        mv.visitLabel(l);
        mv.visitFieldInsn(Opcodes.GETSTATIC, reflector.getClazzInternalName(), "_asParameters",
                "Ljava/util/Map;");
        mv.visitLdcInsn(name);
        mv.visitLdcInsn(Type.getType(reflector.getParameters().get(name)));
        mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/Map", "put",
                "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", true);
        mv.visitInsn(Opcodes.POP);
    }

    /* 
     * _asConverters = new HashMap<String,Class<?>>() 
     */
    {
        Label l = new Label();
        mv.visitLabel(l);
        mv.visitTypeInsn(Opcodes.NEW, "java/util/HashMap");
        mv.visitInsn(Opcodes.DUP);
        mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/util/HashMap", "<init>", "()V", false);
        mv.visitFieldInsn(Opcodes.PUTSTATIC, reflector.getClazzInternalName(), "_asConverters",
                "Ljava/util/Map;");
    }
    /*
     * _asConverters.put("name", Type.class);
     */
    for (String name : reflector.getParameters().keySet()) {
        if (reflector.getConverters().get(name) != null) {
            Class<?> converter = reflector.getConverters().get(name);
            Label l = new Label();
            mv.visitLabel(l);
            mv.visitFieldInsn(Opcodes.GETSTATIC, reflector.getClazzInternalName(), "_asConverters",
                    "Ljava/util/Map;");
            mv.visitLdcInsn(name);
            mv.visitLdcInsn(Type.getType(converter));
            mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/Map", "put",
                    "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", true);
            mv.visitInsn(Opcodes.POP);
        }
    }

    /*
     * }
     * catch(Throwable t) {
     *    throw t;
     * }
     */
    Label throwableStart = new Label();
    Label throwableEnd = new Label();

    mv.visitLabel(l1);
    mv.visitJumpInsn(Opcodes.GOTO, throwableEnd);
    mv.visitLabel(l2);
    mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] { "java/lang/Throwable" });
    mv.visitVarInsn(Opcodes.ASTORE, 0);
    mv.visitLabel(throwableStart);
    mv.visitVarInsn(Opcodes.ALOAD, 0);
    mv.visitInsn(Opcodes.ATHROW);

    mv.visitLabel(throwableEnd);
    mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
    mv.visitInsn(Opcodes.RETURN);
    mv.visitLocalVariable("l", "Ljava/util/List;", null, interceptorsLabel, l1, 0);
    mv.visitLocalVariable("t", "Ljava/lang/Throwable;", null, throwableStart, throwableEnd, 0);
}

From source file:io.syncframework.optimizer.OInterceptorStaticMethodVisitor.java

License:Apache License

public void visitInsn(int opcode) {
    if (opcode != Opcodes.RETURN) {
        mv.visitInsn(opcode);/*from w  w w .  j ava2  s  .co m*/
        return;
    }

    Label start = new Label();
    Label l1 = new Label();
    Label l2 = new Label();

    mv.visitCode();
    mv.visitTryCatchBlock(start, l1, l2, "java/lang/Throwable");

    /* 
     * _asParameters = new HashMap<String,Class<?>>() 
     */
    {
        mv.visitLabel(start);
        mv.visitTypeInsn(Opcodes.NEW, "java/util/HashMap");
        mv.visitInsn(Opcodes.DUP);
        mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/util/HashMap", "<init>", "()V", false);
        mv.visitFieldInsn(Opcodes.PUTSTATIC, reflector.getClazzInternalName(), "_asParameters",
                "Ljava/util/Map;");
    }
    /*
     * _asParameters.put("name", Type.class);
     */
    for (String name : reflector.getParameters().keySet()) {
        Label l = new Label();
        mv.visitLabel(l);
        mv.visitFieldInsn(Opcodes.GETSTATIC, reflector.getClazzInternalName(), "_asParameters",
                "Ljava/util/Map;");
        mv.visitLdcInsn(name);
        mv.visitLdcInsn(Type.getType(reflector.getParameters().get(name)));
        mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/Map", "put",
                "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", true);
        mv.visitInsn(Opcodes.POP);
    }

    /* 
     * _asConverters = new HashMap<String,Class<?>>() 
     */
    {
        Label l = new Label();
        mv.visitLabel(l);
        mv.visitTypeInsn(Opcodes.NEW, "java/util/HashMap");
        mv.visitInsn(Opcodes.DUP);
        mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/util/HashMap", "<init>", "()V", false);
        mv.visitFieldInsn(Opcodes.PUTSTATIC, reflector.getClazzInternalName(), "_asConverters",
                "Ljava/util/Map;");
    }
    /*
     * _asConverters.put("name", Type.class);
     */
    for (String name : reflector.getParameters().keySet()) {
        if (reflector.getConverters().get(name) != null) {
            Class<?> converter = reflector.getConverters().get(name);
            Label l = new Label();
            mv.visitLabel(l);
            mv.visitFieldInsn(Opcodes.GETSTATIC, reflector.getClazzInternalName(), "_asConverters",
                    "Ljava/util/Map;");
            mv.visitLdcInsn(name);
            mv.visitLdcInsn(Type.getType(converter));
            mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/Map", "put",
                    "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", true);
            mv.visitInsn(Opcodes.POP);
        }
    }

    /*
     * }
     * catch(Throwable t) {
     *    throw t;
     * }
     */
    Label throwableStart = new Label();
    Label throwableEnd = new Label();

    mv.visitLabel(l1);
    mv.visitJumpInsn(Opcodes.GOTO, throwableEnd);

    mv.visitLabel(l2);
    mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] { "java/lang/Throwable" });
    mv.visitVarInsn(Opcodes.ASTORE, 0);

    mv.visitLabel(throwableStart);
    mv.visitVarInsn(Opcodes.ALOAD, 0);
    mv.visitInsn(Opcodes.ATHROW);

    mv.visitLabel(throwableEnd);
    mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
    mv.visitInsn(Opcodes.RETURN);
    mv.visitLocalVariable("t", "Ljava/lang/Throwable;", null, throwableStart, throwableEnd, 0);
}

From source file:jp.co.dgic.testing.common.virtualmock.asm.AbstractAsmMethodVisitor.java

License:Open Source License

protected int getStoreOpcodeByType(Type type) {
    if (type.equals(Type.BOOLEAN_TYPE))
        return Opcodes.ISTORE;
    if (type.equals(Type.BYTE_TYPE))
        return Opcodes.ISTORE;
    if (type.equals(Type.CHAR_TYPE))
        return Opcodes.ISTORE;
    if (type.equals(Type.SHORT_TYPE))
        return Opcodes.ISTORE;
    if (type.equals(Type.INT_TYPE))
        return Opcodes.ISTORE;
    if (type.equals(Type.LONG_TYPE))
        return Opcodes.LSTORE;
    if (type.equals(Type.DOUBLE_TYPE))
        return Opcodes.DSTORE;
    if (type.equals(Type.FLOAT_TYPE))
        return Opcodes.FSTORE;
    return Opcodes.ASTORE;
}

From source file:jpcsp.Allegrex.compiler.CompilerContext.java

License:Open Source License

/**
 * Generate the required Java code to load one parameter for
 * the syscall function from the CPU registers.
 *
 * The following code is generated based on the parameter type:
 * Processor: parameterValue = RuntimeContext.processor
 * int:       parameterValue = cpu.gpr[paramIndex++]
 * float:     parameterValue = cpu.fpr[paramFloatIndex++]
 * long:      parameterValue = (cpu.gpr[paramIndex++] & 0xFFFFFFFFL) + ((long) cpu.gpr[paramIndex++]) << 32)
 * boolean:   parameterValue = cpu.gpr[paramIndex++]
 * TPointer,/*w w  w. ja  v a  2s .  c  o m*/
 * TPointer8,
 * TPointer16,
 * TPointer32,
 * TPointer64,
 * TErrorPointer32:
 *            if (checkMemoryAccess()) {
 *                if (canBeNullParam && address == 0) {
 *                    goto addressGood;
 *                }
 *                if (RuntimeContext.checkMemoryPointer(address)) {
 *                    goto addressGood;
 *                }
 *                cpu.gpr[_v0] = SceKernelErrors.ERROR_INVALID_POINTER;
 *                pop all the parameters already prepared on the stack;
 *                goto afterSyscall;
 *                addressGood:
 *            }
 *            <parameterType> pointer = new <parameterType>(address);
 *            if (parameterType == TErrorPointer32.class) {
 *                parameterReader.setHasErrorPointer(true);
 *                localVar[LOCAL_ERROR_POINTER] = pointer;
 *            }
 *            parameterValue = pointer
 * HLEUidClass defined in annotation:
 *            <parameterType> uidObject = HLEUidObjectMapping.getObject("<parameterType>", uid);
 *            if (uidObject == null) {
 *                cpu.gpr[_v0] = errorValueOnNotFound;
 *                pop all the parameters already prepared on the stack;
 *                goto afterSyscall;
 *            }
 *            parameterValue = uidObject
 *
 * And then common for all the types:
 *            try {
 *                parameterValue = <module>.<methodToCheck>(parameterValue);
 *            } catch (SceKernelErrorException e) {
 *                goto catchSceKernelErrorException;
 *            }
 *            push parameterValue on stack
 *
 * @param parameterReader               the current parameter state
 * @param func                          the syscall function
 * @param parameterType                 the type of the parameter
 * @param afterSyscallLabel             the Label pointing after the call to the syscall function
 * @param catchSceKernelErrorException  the Label pointing to the SceKernelErrorException catch handler
 */
private void loadParameter(CompilerParameterReader parameterReader, HLEModuleFunction func,
        Class<?> parameterType, Annotation[] parameterAnnotations, Label afterSyscallLabel,
        Label catchSceKernelErrorException) {
    if (parameterType == Processor.class) {
        loadProcessor();
        parameterReader.incrementCurrentStackSize();
    } else if (parameterType == CpuState.class) {
        loadCpu();
        parameterReader.incrementCurrentStackSize();
    } else if (parameterType == int.class) {
        parameterReader.loadNextInt();
        parameterReader.incrementCurrentStackSize();
    } else if (parameterType == float.class) {
        parameterReader.loadNextFloat();
        parameterReader.incrementCurrentStackSize();
    } else if (parameterType == long.class) {
        parameterReader.loadNextLong();
        parameterReader.incrementCurrentStackSize(2);
    } else if (parameterType == boolean.class) {
        parameterReader.loadNextInt();
        parameterReader.incrementCurrentStackSize();
    } else if (parameterType == String.class) {
        parameterReader.loadNextInt();

        int maxLength = 16 * 1024;
        for (Annotation parameterAnnotation : parameterAnnotations) {
            if (parameterAnnotation instanceof StringInfo) {
                StringInfo stringInfo = ((StringInfo) parameterAnnotation);
                maxLength = stringInfo.maxLength();
                break;
            }
        }
        loadImm(maxLength);
        mv.visitMethodInsn(Opcodes.INVOKESTATIC, runtimeContextInternalName, "readStringNZ",
                "(II)" + Type.getDescriptor(String.class));
        parameterReader.incrementCurrentStackSize();
    } else if (parameterType == PspString.class) {
        parameterReader.loadNextInt();

        int maxLength = 16 * 1024;
        boolean canBeNull = false;
        for (Annotation parameterAnnotation : parameterAnnotations) {
            if (parameterAnnotation instanceof StringInfo) {
                StringInfo stringInfo = ((StringInfo) parameterAnnotation);
                maxLength = stringInfo.maxLength();
            }
            if (parameterAnnotation instanceof CanBeNull) {
                canBeNull = true;
            }
        }
        loadImm(maxLength);
        loadImm(canBeNull);
        mv.visitMethodInsn(Opcodes.INVOKESTATIC, runtimeContextInternalName, "readPspStringNZ",
                "(IIZ)" + Type.getDescriptor(PspString.class));
        parameterReader.incrementCurrentStackSize();
    } else if (parameterType == TPointer.class || parameterType == TPointer8.class
            || parameterType == TPointer16.class || parameterType == TPointer32.class
            || parameterType == TPointer64.class || parameterType == TErrorPointer32.class) {
        // if (checkMemoryAccess()) {
        //     if (canBeNullParam && address == 0) {
        //         goto addressGood;
        //     }
        //     if (RuntimeContext.checkMemoryPointer(address)) {
        //         goto addressGood;
        //     }
        //     cpu.gpr[_v0] = SceKernelErrors.ERROR_INVALID_POINTER;
        //     pop all the parameters already prepared on the stack;
        //     goto afterSyscall;
        //     addressGood:
        // }
        // <parameterType> pointer = new <parameterType>(address);
        // if (parameterType == TErrorPointer32.class) {
        //     parameterReader.setHasErrorPointer(true);
        //     localVar[LOCAL_ERROR_POINTER] = pointer;
        // }
        mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(parameterType));
        mv.visitInsn(Opcodes.DUP);
        loadMemory();
        parameterReader.loadNextInt();

        boolean canBeNull = false;
        for (Annotation parameterAnnotation : parameterAnnotations) {
            if (parameterAnnotation instanceof CanBeNull) {
                canBeNull = true;
                break;
            }
        }

        if (checkMemoryAccess() && afterSyscallLabel != null) {
            Label addressGood = new Label();
            if (canBeNull) {
                mv.visitInsn(Opcodes.DUP);
                mv.visitJumpInsn(Opcodes.IFEQ, addressGood);
            }
            mv.visitInsn(Opcodes.DUP);
            mv.visitMethodInsn(Opcodes.INVOKESTATIC, runtimeContextInternalName, "checkMemoryPointer", "(I)Z");
            mv.visitJumpInsn(Opcodes.IFNE, addressGood);
            storeRegister(_v0, SceKernelErrors.ERROR_INVALID_POINTER);
            parameterReader.popAllStack(4);
            mv.visitJumpInsn(Opcodes.GOTO, afterSyscallLabel);
            mv.visitLabel(addressGood);
        }
        if (parameterType == TPointer8.class || parameterType == TPointer16.class
                || parameterType == TPointer32.class || parameterType == TPointer64.class) {
            loadImm(canBeNull);
            mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(parameterType), "<init>",
                    "(" + memoryDescriptor + "IZ)V");
        } else {
            mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(parameterType), "<init>",
                    "(" + memoryDescriptor + "I)V");
        }
        if (parameterType == TErrorPointer32.class) {
            parameterReader.setHasErrorPointer(true);
            mv.visitInsn(Opcodes.DUP);
            mv.visitVarInsn(Opcodes.ASTORE, LOCAL_ERROR_POINTER);
        }
        parameterReader.incrementCurrentStackSize();
    } else if (pspAbstractMemoryMappedStructure.class.isAssignableFrom(parameterType)) {
        parameterReader.loadNextInt();

        boolean canBeNull = false;
        for (Annotation parameterAnnotation : parameterAnnotations) {
            if (parameterAnnotation instanceof CanBeNull) {
                canBeNull = true;
                break;
            }
        }

        if (checkMemoryAccess() && afterSyscallLabel != null) {
            Label addressGood = new Label();
            if (canBeNull) {
                mv.visitInsn(Opcodes.DUP);
                mv.visitJumpInsn(Opcodes.IFEQ, addressGood);
            }
            mv.visitInsn(Opcodes.DUP);
            mv.visitMethodInsn(Opcodes.INVOKESTATIC, runtimeContextInternalName, "checkMemoryPointer", "(I)Z");
            mv.visitJumpInsn(Opcodes.IFNE, addressGood);
            storeRegister(_v0, SceKernelErrors.ERROR_INVALID_POINTER);
            parameterReader.popAllStack(1);
            mv.visitJumpInsn(Opcodes.GOTO, afterSyscallLabel);
            mv.visitLabel(addressGood);
        }

        mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(parameterType));
        mv.visitInsn(Opcodes.DUP);
        mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(parameterType), "<init>", "()V");
        mv.visitInsn(Opcodes.DUP_X1);
        mv.visitInsn(Opcodes.SWAP);
        loadMemory();
        mv.visitInsn(Opcodes.SWAP);
        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(parameterType), "read",
                "(" + memoryDescriptor + "I)V");
        parameterReader.incrementCurrentStackSize();
    } else {
        HLEUidClass hleUidClass = parameterType.getAnnotation(HLEUidClass.class);
        if (hleUidClass != null) {
            int errorValueOnNotFound = hleUidClass.errorValueOnNotFound();

            // <parameterType> uidObject = HLEUidObjectMapping.getObject("<parameterType>", uid);
            // if (uidObject == null) {
            //     cpu.gpr[_v0] = errorValueOnNotFound;
            //     pop all the parameters already prepared on the stack;
            //     goto afterSyscall;
            // }
            mv.visitLdcInsn(parameterType.getName());
            // Load the UID
            parameterReader.loadNextInt();

            // Load the UID Object
            mv.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(HLEUidObjectMapping.class),
                    "getObject",
                    "(" + Type.getDescriptor(String.class) + "I)" + Type.getDescriptor(Object.class));
            if (afterSyscallLabel != null) {
                Label foundUid = new Label();
                mv.visitInsn(Opcodes.DUP);
                mv.visitJumpInsn(Opcodes.IFNONNULL, foundUid);
                storeRegister(_v0, errorValueOnNotFound);
                parameterReader.popAllStack(1);
                mv.visitJumpInsn(Opcodes.GOTO, afterSyscallLabel);
                mv.visitLabel(foundUid);
            }
            mv.visitTypeInsn(Opcodes.CHECKCAST, Type.getInternalName(parameterType));
            parameterReader.incrementCurrentStackSize();
        } else {
            log.error(String.format("Unsupported sycall parameter type '%s'", parameterType.getName()));
            Emulator.PauseEmuWithStatus(Emulator.EMU_STATUS_UNIMPLEMENTED);
        }
    }

    Method methodToCheck = null;
    if (afterSyscallLabel != null) {
        for (Annotation parameterAnnotation : parameterAnnotations) {
            if (parameterAnnotation instanceof CheckArgument) {
                CheckArgument checkArgument = (CheckArgument) parameterAnnotation;
                try {
                    methodToCheck = func.getHLEModule().getClass().getMethod(checkArgument.value(),
                            parameterType);
                } catch (Exception e) {
                    log.error(String.format("CheckArgument method '%s' not found in %s", checkArgument.value(),
                            func.getModuleName()), e);
                }
                break;
            }
        }
    }

    if (methodToCheck != null) {
        // try {
        //     parameterValue = <module>.<methodToCheck>(parameterValue);
        // } catch (SceKernelErrorException e) {
        //     goto catchSceKernelErrorException;
        // }
        loadModule(func.getModuleName());
        mv.visitInsn(Opcodes.SWAP);

        Label tryStart = new Label();
        Label tryEnd = new Label();
        mv.visitTryCatchBlock(tryStart, tryEnd, catchSceKernelErrorException,
                Type.getInternalName(SceKernelErrorException.class));

        mv.visitLabel(tryStart);
        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(methodToCheck.getDeclaringClass()),
                methodToCheck.getName(),
                "(" + Type.getDescriptor(parameterType) + ")" + Type.getDescriptor(parameterType));
        mv.visitLabel(tryEnd);
    }

    parameterReader.incrementCurrentParameterIndex();
}

From source file:jpcsp.Allegrex.compiler.CompilerContext.java

License:Open Source License

public void startSequenceMethod() {
    if (storeCpuLocal) {
        mv.visitFieldInsn(Opcodes.GETSTATIC, runtimeContextInternalName, "cpu", cpuDescriptor);
        mv.visitVarInsn(Opcodes.ASTORE, LOCAL_CPU);
    }//from w  ww  . j a v  a  2 s . c  o  m

    if (storeMemoryIntLocal) {
        mv.visitFieldInsn(Opcodes.GETSTATIC, runtimeContextInternalName, "memoryInt", "[I");
        mv.visitVarInsn(Opcodes.ASTORE, LOCAL_MEMORY_INT);
    }

    if (enableIntructionCounting) {
        currentInstructionCount = 0;
        mv.visitInsn(Opcodes.ICONST_0);
        storeLocalVar(LOCAL_INSTRUCTION_COUNT);
    }

    startNonBranchingCodeSequence();
}

From source file:lapin.comp.asm.ASMByteCodeGenerator.java

License:Open Source License

private void generateCall(CallableInfo ci, Env env) {
    /*/*from w  w  w  .ja v  a2  s . c o  m*/
     * local variables
     * <Callable#call>
     * 0: this
     * 1: args (list of arguments)
     * 2: env
     *
     * <Callable0#call0>
     * 0: this
     * 1: env
     *
     * <Callable1#call1>
     * 0: this
     * 1: arg0
     * 2: env
     *
     * <Callable2#call2>
     * 0: this
     * 1: arg0
     * 2: arg1
     * 3: env
     *
     * ...
     *
     */
    MethodVisitor mv = _cw.visitMethod(
            ci.mi.implCallable() ? Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL : Opcodes.ACC_FINAL, ci.mi.name(),
            Type.getMethodDescriptor(ci.retType, ci.paramTypes), null, null);

    // instruction list
    int len = ci.mi.instLen();
    // label
    Label label = null;

    // generate code
    for (int i = 0; i < len; i++) {
        Object inst = ci.mi.getInst(i);
        if (Logger.tracelevelp(env))
            Logger.trace("[asm:gen]" + i + ":\t~S", Lists.list(inst), env);

        // inst is symbol
        // -> convert tag (Symbol) to label (ASMe Label object)
        if (Data.isSymbol(inst)) {
            Symbol tag = Data.symbol(inst);
            Label l = (Label) ci.labelTable.get(tag);
            if (l == null) {
                throw new NotReachedException("label is null: ~S.", Lists.list(tag));
            } else if (l != label) {
                mv.visitLabel(l);
                label = l;
                if (Logger.tracelevelp(env))
                    Logger.trace("[asm:gen]" + i + ":\ttag ~S -> label ~S", Lists.list(tag, l), env);
            } else {
                if (Logger.tracelevelp(env))
                    Logger.trace("[asm:gen]" + i + ":\ttag ~S -> label ~S" + " (dup)", Lists.list(tag, l), env);
            }
            continue;
        }

        // inst must be the form of (id <arg1> <arg2> ....)
        Object id = Lists.car(inst);
        if (id == Insts.CONST) {
            /* push const on the stack. */
            Object obj = Lists.cadr(inst);
            String val = Data.string(constTable.get(obj));
            mv.visitVarInsn(Opcodes.ALOAD, 0);
            mv.visitFieldInsn(Opcodes.GETFIELD, toInternalName(super.classInfo.classname()), val,
                    TYPE_OBJECT.getDescriptor());
        } else if (id == Insts.VAR) {
            /* push var on the stack */
            Object var = Lists.cadr(inst);
            String val = Data.string(varTable.get(var));
            mv.visitVarInsn(Opcodes.ALOAD, 0);
            mv.visitFieldInsn(Opcodes.GETFIELD, toInternalName(super.classInfo.classname()), val,
                    TYPE_SYMBOL.getDescriptor());
        } else if (id == Insts.LAMBDA_LIST) {
            /* push lambdaList on the stack */
            Object var = Lists.cadr(inst);
            /* push _ll_<i> on the stack */
            String val = Data.string(llTable.get(var));
            mv.visitVarInsn(Opcodes.ALOAD, 0);
            mv.visitFieldInsn(Opcodes.GETFIELD, toInternalName(super.classInfo.classname()), val,
                    TYPE_LAMBDA_LIST.getDescriptor());
        } else if (id == Insts.ENV_GET) {
            /* env.get */
            Class type = Data.javaClass(Lists.cadr(inst));
            if (type.equals(int.class)) {
                mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, TYPE_ENV.getInternalName(), "getInt",
                        Type.getMethodDescriptor(Type.INT_TYPE, new Type[] { TYPE_SYMBOL }));
            } else if (type.equals(double.class)) {
                mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, TYPE_ENV.getInternalName(), "getDouble",
                        Type.getMethodDescriptor(Type.DOUBLE_TYPE, new Type[] { TYPE_SYMBOL }));
            } else if (type.equals(char.class)) {
                mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, TYPE_ENV.getInternalName(), "getChar",
                        Type.getMethodDescriptor(Type.CHAR_TYPE, new Type[] { TYPE_SYMBOL }));
            } else if (Object.class.isAssignableFrom(type)) {
                mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, TYPE_ENV.getInternalName(), "get",
                        Type.getMethodDescriptor(TYPE_OBJECT, new Type[] { TYPE_SYMBOL }));
            } else {
                throw new NotReachedException("unsupported type: ~S.", Lists.list(type));
            }
        } else if (id == Insts.ENV_SET) {
            /* env.set */
            Class type = Data.javaClass(Lists.cadr(inst));
            if (type.equals(int.class)) {
                mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, TYPE_ENV.getInternalName(), "set",
                        Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { TYPE_SYMBOL, Type.INT_TYPE }));
            } else if (type.equals(double.class)) {
                mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, TYPE_ENV.getInternalName(), "set",
                        Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { TYPE_SYMBOL, Type.DOUBLE_TYPE }));
            } else if (type.equals(char.class)) {
                mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, TYPE_ENV.getInternalName(), "set",
                        Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { TYPE_SYMBOL, Type.CHAR_TYPE }));
            } else if (Object.class.isAssignableFrom(type)) {
                mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, TYPE_ENV.getInternalName(), "set",
                        Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { TYPE_SYMBOL, TYPE_OBJECT }));
            } else {
                throw new NotReachedException("unsupported type: ~S.", Lists.list(type));
            }
        } else if (id == Insts.ENV_BIND) {
            /* env.bind */
            Class type = Data.javaClass(Lists.cadr(inst));
            if (type.equals(int.class)) {
                mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, TYPE_ENV.getInternalName(), "bind",
                        Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { TYPE_SYMBOL, Type.INT_TYPE }));
            } else if (type.equals(double.class)) {
                mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, TYPE_ENV.getInternalName(), "bind",
                        Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { TYPE_SYMBOL, Type.DOUBLE_TYPE }));
            } else if (type.equals(char.class)) {
                mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, TYPE_ENV.getInternalName(), "bind",
                        Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { TYPE_SYMBOL, Type.CHAR_TYPE }));
            } else if (Object.class.isAssignableFrom(type)) {
                mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, TYPE_ENV.getInternalName(), "bind",
                        Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { TYPE_SYMBOL, TYPE_OBJECT }));
            } else {
                throw new NotReachedException("unsupported type: ~S.", Lists.list(type));
            }
        } else if (id == Insts.ENV_UNBIND) {
            /* env.unbind */
            Class type = Data.javaClass(Lists.cadr(inst));
            if (type.equals(int.class)) {
                mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, TYPE_ENV.getInternalName(), "unbindInt",
                        Type.getMethodDescriptor(Type.INT_TYPE, new Type[] { TYPE_SYMBOL }));
            } else if (type.equals(double.class)) {
                mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, TYPE_ENV.getInternalName(), "unbindDouble",
                        Type.getMethodDescriptor(Type.DOUBLE_TYPE, new Type[] { TYPE_SYMBOL }));
            } else if (type.equals(char.class)) {
                mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, TYPE_ENV.getInternalName(), "unbindChar",
                        Type.getMethodDescriptor(Type.CHAR_TYPE, new Type[] { TYPE_SYMBOL }));
            } else if (Object.class.isAssignableFrom(type)) {
                mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, TYPE_ENV.getInternalName(), "unbind",
                        Type.getMethodDescriptor(TYPE_OBJECT, new Type[] { TYPE_SYMBOL }));
            } else {
                throw new NotReachedException("unsupported type: ~S.", Lists.list(type));
            }
        } else if (id == Insts.ENV_CHILD) {
            /* env.child */
            Object oldEnvVar = Lists.cadr(inst);
            Object newEnvVar = Lists.caddr(inst);
            Object oldSlot = Lists.cadr(oldEnvVar);
            Object newSlot = Lists.cadr(newEnvVar);
            int oldLocal = Data.fixnum(ci.localTable.get(oldSlot)).intValue();
            int newLocal = Data.fixnum(ci.localTable.get(newSlot)).intValue();
            if (Logger.tracelevelp(env))
                Logger.trace("[asm:gen]" + i + ":\tenv-child: local ~S -> ~S",
                        Lists.list(Data.toFixnum(oldLocal), Data.toFixnum(newLocal)), env);
            mv.visitVarInsn(Opcodes.ALOAD, oldLocal);
            mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, TYPE_ENV.getInternalName(), "child",
                    Type.getMethodDescriptor(TYPE_ENV, TYPE_NO_ARGS));
            mv.visitVarInsn(Opcodes.ASTORE, newLocal);
        } else if (id == Insts.CALL) {
            /* funcall */
            int nargs = Data.fixnum(Lists.cadr(inst)).intValue();
            String className = "lapin.eval.Funcall";
            String methodName = nargs < 0 ? "funcall" : "funcall" + nargs;
            Class rType = Object.class;
            Class[] pTypes;
            if (nargs < 0) {
                pTypes = new Class[] { Function.class, Object.class, // list of args
                        Env.class };
            } else {
                pTypes = new Class[nargs + 2];
                pTypes[0] = Function.class;
                for (int j = 0; j < nargs; j++) {
                    pTypes[j + 1] = Object.class;
                }
                pTypes[nargs + 1] = Env.class;
            }

            Type retType = Type.getType(rType);
            Type[] paramTypes = new Type[pTypes.length];
            for (int j = 0; j < pTypes.length; j++)
                paramTypes[j] = Type.getType(pTypes[j]);

            mv.visitMethodInsn(Opcodes.INVOKESTATIC, toInternalName(className), methodName,
                    Type.getMethodDescriptor(retType, paramTypes));
        } else if (id == Insts.CALL_DIRECT) {
            /*
             * public class Foo
             *   extends CompiledExpr implements Callable2 {
             *  public Object call2(Object arg0, Object arg1, Env env) {
             *   ...
             *  }
             * }
             */
            MethodInfo mi = (MethodInfo) Lists.cadr(inst);
            String className = mi.classInfo().classname();
            int nargs = mi.nargs();
            boolean rest = mi.rest();
            String methodName = mi.name();
            Class rType = mi.retType();
            Class[] pTypes = mi.paramTypes();

            Type retType = Type.getType(rType);
            Type[] paramTypes = new Type[pTypes.length];
            for (int j = 0; j < pTypes.length; j++)
                paramTypes[j] = Type.getType(pTypes[j]);

            mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, toInternalName(className), methodName,
                    Type.getMethodDescriptor(retType, paramTypes));
        } else if (id == Insts.COMPILED_EXPR) {
            /*
             * public class Foo extends CompiledExpr {
             *  static public Foo SELF;
             *  ...
             * }
             */
            String className = Data.string(Lists.cadr(inst));
            String fieldName = "SELF";
            String typeName = className;
            mv.visitFieldInsn(Opcodes.GETSTATIC, toInternalName(className), fieldName,
                    toTypeDescriptor(typeName));
        } else if (id == Insts.RETURN) {
            /* return */
            Class type = Data.javaClass(Lists.cadr(inst));
            if (type.equals(int.class) || type.equals(short.class) || type.equals(byte.class)
                    || type.equals(char.class)) {
                mv.visitInsn(Opcodes.IRETURN);
            } else if (type.equals(long.class)) {
                mv.visitInsn(Opcodes.LRETURN);
            } else if (type.equals(float.class)) {
                mv.visitInsn(Opcodes.FRETURN);
            } else if (type.equals(double.class)) {
                mv.visitInsn(Opcodes.DRETURN);
            } else if (type.equals(void.class)) {
                //mv.visitInsn(Opcodes.RETURN);
                throw new NotReachedException("unsupported returnType: ~S.", Lists.list(type));
            } else {
                mv.visitInsn(Opcodes.ARETURN);
            }
        } else if (id == Insts.IFEQ) {
            /* conditional jump */
            Symbol tag = Data.symbol(Lists.cadr(inst));
            Label l = (Label) ci.labelTable.get(tag);
            if (l == null) {
                throw new NotReachedException("label not found: ~S.", Lists.list(tag));
            }
            mv.visitJumpInsn(Opcodes.IFEQ, l);
        } else if (id == Insts.IFNE) {
            /* conditional jump */
            Symbol tag = Data.symbol(Lists.cadr(inst));
            Label l = (Label) ci.labelTable.get(tag);
            if (l == null) {
                throw new NotReachedException("label not found: ~S.", Lists.list(tag));
            }
            mv.visitJumpInsn(Opcodes.IFNE, l);
        } else if (id == Insts.GOTO) {
            /* jump */
            Symbol tag = Data.symbol(Lists.cadr(inst));
            Label l = (Label) ci.labelTable.get(tag);
            if (l == null) {
                throw new NotReachedException("label not found: ~S.", Lists.list(tag));
            }
            mv.visitJumpInsn(Opcodes.GOTO, l);
        } else if (id == Insts.LOAD) {
            /* local -> stack */
            Object localVar = Lists.cadr(inst);
            Object slot = Lists.cadr(localVar);
            Class type = Data.javaClass(Lists.caddr(localVar));
            int local = Data.fixnum(ci.localTable.get(slot)).intValue();
            int op = Type.getType(type).getOpcode(Opcodes.ILOAD);
            if (Logger.tracelevelp(env))
                Logger.trace("[asm:gen]" + i + ":\tload: local=~S type=~S",
                        Lists.list(Data.toFixnum(local), type), env);
            mv.visitVarInsn(op, local);
        } else if (id == Insts.STORE) {
            /* stack -> local */
            Object localVar = Lists.cadr(inst);
            Object slot = Lists.cadr(localVar);
            Class type = Data.javaClass(Lists.caddr(localVar));
            int local = Data.fixnum(ci.localTable.get(slot)).intValue();
            int op = Type.getType(type).getOpcode(Opcodes.ISTORE);
            if (Logger.tracelevelp(env))
                Logger.trace("[asm:gen]" + i + ":\tstore: local=~S type=~S",
                        Lists.list(Data.toFixnum(local), type), env);
            mv.visitVarInsn(op, local);
        } else if (id == Insts.POP) {
            /* pop a value and discard it */
            Class type = Data.javaClass(Lists.cadr(inst));
            int op;
            switch (Classes.sizeOf(type)) {
            case 1:
                op = Opcodes.POP;
                break;
            case 2:
                op = Opcodes.POP2;
                break;
            default:
                throw new NotReachedException("unsupported type: ~S.", Lists.list(type));
            }
            mv.visitInsn(op);
        } else if (id == Insts.DUP) {
            /* peek a value and duplicate it */
            Class type = Data.javaClass(Lists.cadr(inst));
            int op;
            switch (Classes.sizeOf(type)) {
            case 1:
                op = Opcodes.DUP;
                break;
            case 2:
                op = Opcodes.DUP2;
                break;
            default:
                throw new NotReachedException("unsupported type: ~S.", Lists.list(type));
            }
            mv.visitInsn(op);
        } else if (id == Insts.PUSH) {
            /* push a constant */
            Object val = Lists.cadr(inst);
            if (Data.isJavaBoolean(val)) {
                if (Data.javaBoolean(val).booleanValue())
                    mv.visitInsn(Opcodes.ICONST_1);
                else
                    mv.visitInsn(Opcodes.ICONST_0);
            } else if (val instanceof Byte || val instanceof Short || val instanceof Integer) {
                int n = Data.javaNumber(val).intValue();
                if (n == -1)
                    mv.visitInsn(Opcodes.ICONST_M1);
                else if (n == 0)
                    mv.visitInsn(Opcodes.ICONST_0);
                else if (n == 1)
                    mv.visitInsn(Opcodes.ICONST_1);
                else if (n == 2)
                    mv.visitInsn(Opcodes.ICONST_2);
                else if (n == 3)
                    mv.visitInsn(Opcodes.ICONST_3);
                else if (n == 4)
                    mv.visitInsn(Opcodes.ICONST_4);
                else if (n == 5)
                    mv.visitInsn(Opcodes.ICONST_5);
                else if (Byte.MIN_VALUE <= n && n <= Byte.MAX_VALUE)
                    mv.visitIntInsn(Opcodes.BIPUSH, n);
                else if (Short.MIN_VALUE <= n && n <= Short.MAX_VALUE)
                    mv.visitIntInsn(Opcodes.SIPUSH, n);
                else
                    mv.visitLdcInsn(Data.toFixnum(n));
            } else if (val instanceof Long) {
                long n = Data.javaNumber(val).longValue();
                if (n == 0L)
                    mv.visitInsn(Opcodes.LCONST_0);
                else if (n == 1L)
                    mv.visitInsn(Opcodes.LCONST_1);
                else
                    mv.visitLdcInsn(val);
            } else if (val instanceof Float) {
                float n = Data.javaNumber(val).floatValue();
                if (n == 0.0f)
                    mv.visitInsn(Opcodes.FCONST_0);
                else if (n == 1.0f)
                    mv.visitInsn(Opcodes.FCONST_1);
                else if (n == 2.0f)
                    mv.visitInsn(Opcodes.FCONST_2);
                else
                    mv.visitLdcInsn(val);
            } else if (val instanceof Double) {
                double n = Data.javaNumber(val).doubleValue();
                if (n == 0.0)
                    mv.visitInsn(Opcodes.DCONST_0);
                else if (n == 1.0)
                    mv.visitInsn(Opcodes.DCONST_1);
                else
                    mv.visitLdcInsn(val);
            } else if (Data.isCharacter(val)) {
                Character c = Data.character(val);
                int n = (int) c.charValue();
                if (Byte.MIN_VALUE <= n && n <= Byte.MAX_VALUE)
                    mv.visitIntInsn(Opcodes.BIPUSH, n);
                else if (Short.MIN_VALUE <= n && n <= Short.MAX_VALUE)
                    mv.visitIntInsn(Opcodes.SIPUSH, n);
                else
                    mv.visitLdcInsn(Data.toFixnum(n));
            } else if (Data.isString(val)) {
                mv.visitLdcInsn(val);
            } else {
                throw new NotReachedException("cannot push: ~S.", Lists.list(val));
            }
        } else if (id == Insts.GET) {
            Field f = Data.javaField(Lists.cadr(inst));
            String fieldName = f.getName();
            Class c = f.getDeclaringClass();
            String className = c.getName();
            Class t = f.getType();
            String typeName = t.getName();

            boolean isStatic = Classes.isStatic(f);
            int op = isStatic ? Opcodes.GETSTATIC : Opcodes.GETFIELD;

            mv.visitFieldInsn(op, toInternalName(className), fieldName, toTypeDescriptor(typeName));
        } else if (id == Insts.PUT) {
            Field f = Data.javaField(Lists.cadr(inst));
            String fieldName = f.getName();
            Class c = f.getDeclaringClass();
            String className = c.getName();
            Class t = f.getType();
            String typeName = t.getName();

            boolean isStatic = Classes.isStatic(f);
            int op = isStatic ? Opcodes.PUTSTATIC : Opcodes.PUTFIELD;

            mv.visitFieldInsn(op, toInternalName(className), fieldName, toTypeDescriptor(typeName));
        } else if (id == Insts.INVOKE) {
            Method m = Data.javaMethod(Lists.cadr(inst));
            String methodName = m.getName();
            Class c = m.getDeclaringClass();
            String className = c.getName();
            Class rType = m.getReturnType();
            Class[] pTypes = m.getParameterTypes();
            if (rType.equals(void.class)) {
                throw new NotReachedException("unsupported returnType: ~S.", Lists.list(rType));
            }
            Type retType = Type.getType(rType);
            Type[] paramTypes = new Type[pTypes.length];
            for (int j = 0; j < pTypes.length; j++)
                paramTypes[j] = Type.getType(pTypes[j]);

            boolean isStatic = Classes.isStatic(m);
            boolean isInterface = c.isInterface();
            int op = isStatic ? Opcodes.INVOKESTATIC
                    : isInterface ? Opcodes.INVOKEINTERFACE : Opcodes.INVOKEVIRTUAL;

            mv.visitMethodInsn(op, toInternalName(className), methodName,
                    Type.getMethodDescriptor(retType, paramTypes));
        } else if (id == Insts.CHECKCAST) {
            Class c = Data.javaClass(Lists.cadr(inst));
            Type t = Type.getType(c);
            mv.visitTypeInsn(Opcodes.CHECKCAST, t.getInternalName());
        } else if (id == Insts.THROW) {
            mv.visitInsn(Opcodes.ATHROW);
        } else if (id == Insts.CATCH) {
            Symbol tagS = Data.symbol(Lists.cadr(inst));
            Symbol tagE = Data.symbol(Lists.caddr(inst));
            Symbol tagH = Data.symbol(Lists.cadddr(inst));
            String className;
            if (Lists.isEnd(Lists.cddddr(inst))) {
                className = null;
            } else {
                Class c = Data.javaClass(Lists.car(Lists.cddddr(inst)));
                className = toInternalName(c.getName());
            }
            Label labelS = (Label) ci.labelTable.get(tagS);
            if (labelS == null) {
                throw new NotReachedException("label not found: ~S.", Lists.list(tagS));
            }
            Label labelE = (Label) ci.labelTable.get(tagE);
            if (labelE == null) {
                throw new NotReachedException("label not found: ~S.", Lists.list(tagE));
            }
            Label labelH = (Label) ci.labelTable.get(tagH);
            if (labelH == null) {
                throw new NotReachedException("label not found: ~S.", Lists.list(tagH));
            }
            mv.visitTryCatchBlock(labelS, labelE, labelH, className);
        }
        //else if (id == Insts.CATCH_FROM ||
        //         id == Insts.CATCH_TO ||
        //         id == Insts.CATCH_HANDLER) {
        //    /* nothing emitted */
        //    continue;
        //}
        else {
            throw new NotReachedException("unknown inst: ~S.", Lists.list(inst));
        }
    }
    mv.visitMaxs(0, 0);
    mv.visitEnd();
}

From source file:net.minecraftforge.fml.common.asm.transformers.SoundEngineFixTransformer.java

License:Open Source License

@Override
public byte[] transform(String name, String transformedName, byte[] basicClass) {
    if (transformedName.equals("paulscode.sound.Source")) {
        ClassNode classNode = new ClassNode();
        ClassReader classReader = new ClassReader(basicClass);
        classReader.accept(classNode, 0);

        classNode.fields.add(new FieldNode(Opcodes.ACC_PUBLIC, "removed", "Z", null, null)); // adding field 'public boolean removed;'

        ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
        classNode.accept(writer);/*  w w  w . jav a  2s. c om*/
        return writer.toByteArray();
    } else if (transformedName.equals("paulscode.sound.Library")) {
        ClassNode classNode = new ClassNode();
        ClassReader classReader = new ClassReader(basicClass);
        classReader.accept(classNode, 0);

        MethodNode method = null;
        for (MethodNode m : classNode.methods) {
            if (m.name.equals("removeSource") && m.desc.equals("(Ljava/lang/String;)V")) // trying to find paulscode.sound.Library.removeSource(String)
            {
                method = m;
                break;
            }
        }
        if (method == null)
            throw new RuntimeException(
                    "Error processing " + transformedName + " - no removeSource method found");

        AbstractInsnNode referenceNode = null;

        for (Iterator<AbstractInsnNode> iterator = method.instructions.iterator(); iterator.hasNext();) {
            AbstractInsnNode insn = iterator.next();
            if (insn instanceof MethodInsnNode && ((MethodInsnNode) insn).owner.equals("paulscode/sound/Source") // searching for mySource.cleanup() node (line 1086)
                    && ((MethodInsnNode) insn).name.equals("cleanup")) {
                referenceNode = insn;
                break;
            }
        }

        if (referenceNode != null) {
            LabelNode after = (LabelNode) referenceNode.getNext();

            AbstractInsnNode beginning = referenceNode.getPrevious();

            int varIndex = ((VarInsnNode) beginning).var;

            method.instructions.insertBefore(beginning, new VarInsnNode(Opcodes.ALOAD, varIndex)); // adding extra if (mySource.toStream)
            method.instructions.insertBefore(beginning,
                    new FieldInsnNode(Opcodes.GETFIELD, "paulscode/sound/Source", "toStream", "Z"));
            LabelNode elseNode = new LabelNode();
            method.instructions.insertBefore(beginning, new JumpInsnNode(Opcodes.IFEQ, elseNode)); // if fails (else) -> go to mySource.cleanup();

            method.instructions.insertBefore(beginning, new VarInsnNode(Opcodes.ALOAD, varIndex)); // if (mySource.toStream) { mySource.removed = true; }
            method.instructions.insertBefore(beginning, new InsnNode(Opcodes.ICONST_1));
            method.instructions.insertBefore(beginning,
                    new FieldInsnNode(Opcodes.PUTFIELD, "paulscode/sound/Source", "removed", "Z"));

            method.instructions.insertBefore(beginning, new JumpInsnNode(Opcodes.GOTO, after)); // still inside if -> jump to sourceMap.remove( sourcename );

            method.instructions.insertBefore(beginning, elseNode);
        }

        ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
        classNode.accept(writer);
        return writer.toByteArray();
    } else if (transformedName.equals("paulscode.sound.StreamThread")) {
        ClassNode classNode = new ClassNode();
        ClassReader classReader = new ClassReader(basicClass);
        classReader.accept(classNode, 0);

        MethodNode method = null;
        for (MethodNode m : classNode.methods) {
            if (m.name.equals("run") && m.desc.equals("()V")) // trying to find paulscode.sound.StreamThread.run();
            {
                method = m;
                break;
            }
        }
        if (method == null)
            throw new RuntimeException("Error processing " + transformedName + " - no run method found");

        AbstractInsnNode referenceNode = null;

        for (Iterator<AbstractInsnNode> iterator = method.instructions.iterator(); iterator.hasNext();) {
            AbstractInsnNode insn = iterator.next();
            if (insn instanceof MethodInsnNode && ((MethodInsnNode) insn).owner.equals("java/util/ListIterator") // searching for 'src = iter.next();' node (line 110)
                    && ((MethodInsnNode) insn).name.equals("next")) {
                referenceNode = insn.getNext().getNext();
                break;
            }
        }

        if (referenceNode != null) {
            int varIndex = ((VarInsnNode) referenceNode).var;

            LabelNode after = (LabelNode) referenceNode.getNext();
            method.instructions.insertBefore(after, new VarInsnNode(Opcodes.ALOAD, varIndex)); // add if(removed)
            method.instructions.insertBefore(after,
                    new FieldInsnNode(Opcodes.GETFIELD, "paulscode/sound/Source", "removed", "Z"));
            method.instructions.insertBefore(after, new JumpInsnNode(Opcodes.IFEQ, after));

            // if the source has been marked as removed, clean it up and set the variable to null so it will be removed from the list
            method.instructions.insertBefore(after, new VarInsnNode(Opcodes.ALOAD, varIndex)); // src.cleanup();
            method.instructions.insertBefore(after, new MethodInsnNode(Opcodes.INVOKEVIRTUAL,
                    "paulscode/sound/Source", "cleanup", "()V", false));
            method.instructions.insertBefore(after, new InsnNode(Opcodes.ACONST_NULL)); // src = null;
            method.instructions.insertBefore(after, new VarInsnNode(Opcodes.ASTORE, varIndex));
        }

        ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
        classNode.accept(writer);
        return writer.toByteArray();
    }

    return basicClass;
}

From source file:net.sourceforge.cobertura.instrument.pass3.AtomicArrayCodeProvider.java

License:GNU General Public License

/**
 * <pre>//from   w ww  . j  a  va2s . c  o  m
 * int[] __cobertura_get_and_reset_counters() {
 * int[] res = new int[counters.length()];
 * for(int i=0; i<counters.length(); i++){
 * res[i]=counters.getAndSet(i, 0);
 * }
 * return res;
 * }
 * </pre>
 */
public void generateCoberturaGetAndResetCountersMethod(ClassVisitor cv, String className) {
    MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC,
            COBERTURA_GET_AND_RESET_COUNTERS_METHOD_NAME, "()[I", null, null);

    mv.visitCode();
    mv.visitFieldInsn(Opcodes.GETSTATIC, className, COBERTURA_COUNTERS_FIELD_NAME,
            COBERTURA_COUNTERS_FIELD_TYPE);
    mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/util/concurrent/atomic/AtomicIntegerArray", "length",
            "()I");
    mv.visitIntInsn(Opcodes.NEWARRAY, Opcodes.T_INT);
    mv.visitVarInsn(Opcodes.ASTORE, 0);
    mv.visitInsn(Opcodes.ICONST_0);
    mv.visitVarInsn(Opcodes.ISTORE, 1);
    Label l3 = new Label();
    mv.visitJumpInsn(Opcodes.GOTO, l3);
    Label l4 = new Label();
    mv.visitLabel(l4);
    mv.visitVarInsn(Opcodes.ALOAD, 0);
    mv.visitVarInsn(Opcodes.ILOAD, 1);
    mv.visitFieldInsn(Opcodes.GETSTATIC, className, COBERTURA_COUNTERS_FIELD_NAME,
            COBERTURA_COUNTERS_FIELD_TYPE);
    mv.visitVarInsn(Opcodes.ILOAD, 1);
    mv.visitInsn(Opcodes.ICONST_0);
    mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/util/concurrent/atomic/AtomicIntegerArray", "getAndSet",
            "(II)I");
    mv.visitInsn(Opcodes.IASTORE);
    mv.visitIincInsn(1, 1);
    mv.visitLabel(l3);
    mv.visitVarInsn(Opcodes.ILOAD, 1);
    mv.visitFieldInsn(Opcodes.GETSTATIC, className, COBERTURA_COUNTERS_FIELD_NAME,
            COBERTURA_COUNTERS_FIELD_TYPE);
    mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/util/concurrent/atomic/AtomicIntegerArray", "length",
            "()I");
    mv.visitJumpInsn(Opcodes.IF_ICMPLT, l4);
    mv.visitVarInsn(Opcodes.ALOAD, 0);
    mv.visitInsn(Opcodes.ARETURN);
    mv.visitMaxs(0, 0);//will be recalculated by writer
    mv.visitEnd();
}

From source file:net.sourceforge.cobertura.instrument.pass3.FastArrayCodeProvider.java

License:GNU General Public License

public void generateCoberturaGetAndResetCountersMethod(ClassVisitor cv, String className) {
    MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC,
            COBERTURA_GET_AND_RESET_COUNTERS_METHOD_NAME, "()[I", null, null);
    mv.visitCode();/*www . ja  v  a  2 s.  c  o  m*/
    /*cobertura_counters.*/
    mv.visitFieldInsn(Opcodes.GETSTATIC, className, COBERTURA_COUNTERS_FIELD_NAME,
            COBERTURA_COUNTERS_FIELD_TYPE);
    mv.visitVarInsn(Opcodes.ASTORE, 0);
    /*cobertura_counters.*/
    mv.visitFieldInsn(Opcodes.GETSTATIC, className, COBERTURA_COUNTERS_FIELD_NAME,
            COBERTURA_COUNTERS_FIELD_TYPE);
    mv.visitInsn(Opcodes.ARRAYLENGTH);

    mv.visitIntInsn(Opcodes.NEWARRAY, Opcodes.T_INT);
    mv.visitFieldInsn(Opcodes.PUTSTATIC, className, COBERTURA_COUNTERS_FIELD_NAME,
            COBERTURA_COUNTERS_FIELD_TYPE);
    mv.visitVarInsn(Opcodes.ALOAD, 0);
    mv.visitInsn(Opcodes.ARETURN);
    mv.visitMaxs(0, 0);//will be recalculated by writer
    mv.visitEnd();
}