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:kilim.analysis.MethodWeaver.java

License:Open Source License

/**
 * Generate code for only those catch blocks that are reachable
 * from one or more pausable blocks. fiber.pc tells us which
 * nested call possibly caused an exception, fiber.status tells us
 * whether there is any state that needs to be restored, and
 * fiber.curState gives us access to that state. 
 * //from ww  w. j  av  a 2s.  co m
 * ; Figure out which pausable method could have caused this.
 * 
 * switch (fiber.upEx()) {
 *    0: goto NORMAL_EXCEPTION_HANDLING;
 *    2: goto RESTORE_F
 * }
 * RESTORE_F:
 *   if (fiber.curStatus == HAS_STATE) {
 *      restore variables from the state. don't restore stack
 *      goto NORMAL_EXCEPTION_HANDLING
 *   }
 * ... other RESTOREs
 * 
 * NORMAL_EXCEPTION_HANDLING:
 */
private void genException(MethodVisitor mv, BasicBlock bb, List<CallWeaver> cwList) {
    mv.visitLabel(bb.startLabel);
    Label resumeLabel = new Label();
    VMType.loadVar(mv, VMType.TOBJECT, getFiberVar());
    mv.visitMethodInsn(INVOKEVIRTUAL, FIBER_CLASS, "upEx", "()I");
    // fiber.pc is on stack
    Label[] labels = new Label[cwList.size()];
    int[] keys = new int[cwList.size()];
    for (int i = 0; i < cwList.size(); i++) {
        labels[i] = new Label();
        keys[i] = callWeavers.indexOf(cwList.get(i)) + 1;
    }

    mv.visitLookupSwitchInsn(resumeLabel, keys, labels);
    int i = 0;
    for (CallWeaver cw : cwList) {
        if (i > 0) {
            // This is the jump (to normal exception handling) for the previous
            // switch case.
            mv.visitJumpInsn(GOTO, resumeLabel);
        }
        mv.visitLabel(labels[i]);
        cw.genRestoreEx(mv, labels[i]);
        i++;
    }

    // Consume the first instruction because we have already consumed the
    // corresponding label. (The standard visitInstructions code does a 
    // visitLabel before visiting the instruction itself)
    mv.visitLabel(resumeLabel);
    bb.getInstruction(bb.startPos).accept(mv);
}

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

License:Open Source License

private void generateCall(CallableInfo ci, Env env) {
    /*/*from  www .  j  a v  a  2 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:ldapbeans.bean.LdapBeanClassManager.java

License:LGPL

/**
 * Generate a method of the generated class
 * /*from www  .j  a va 2 s . c  o m*/
 * @param p_ClassWriter
 *            The {@link ClassWriter} of the generated class
 * @param p_ClassName
 *            The name of the class
 * @param p_Method
 *            the method to generate
 * @param p_MethodDescriptor
 *            The method descriptor
 */
private void generateMethodEquals(ClassWriter p_ClassWriter, String p_ClassName, Method p_Method,
        String p_MethodDescriptor) {
    MethodVisitor mv = p_ClassWriter.visitMethod(ACC_PUBLIC, "equals", "(Ljava/lang/Object;)Z", null, null);
    mv.visitCode();
    mv.visitVarInsn(ALOAD, 1);
    mv.visitTypeInsn(INSTANCEOF, "ldapbeans/bean/LdapBean");
    Label l0 = new Label();
    mv.visitJumpInsn(IFEQ, l0);
    mv.visitVarInsn(ALOAD, 1);
    Label l1 = new Label();
    mv.visitJumpInsn(IFNULL, l1);
    mv.visitVarInsn(ALOAD, 0);
    mv.visitMethodInsn(INVOKEINTERFACE, "ldapbeans/bean/LdapBean", "getDN", "()Ljava/lang/String;");
    mv.visitVarInsn(ALOAD, 1);
    mv.visitTypeInsn(CHECKCAST, "ldapbeans/bean/LdapBean");
    mv.visitMethodInsn(INVOKEINTERFACE, "ldapbeans/bean/LdapBean", "getDN", "()Ljava/lang/String;");
    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z");
    mv.visitJumpInsn(IFEQ, l1);
    mv.visitInsn(ICONST_1);
    mv.visitInsn(IRETURN);
    mv.visitLabel(l1);
    mv.visitInsn(ICONST_0);
    mv.visitInsn(IRETURN);
    mv.visitLabel(l0);
    mv.visitInsn(ICONST_0);
    mv.visitInsn(IRETURN);
    mv.visitMaxs(0, 0);
    mv.visitEnd();
}

From source file:ldapbeans.bean.LdapBeanClassManager.java

License:LGPL

/**
 * Generate a method of the generated class
 * /*from  w w w  . j  a va2  s. c o m*/
 * @param p_MethodVisitor
 *            The {@link MethodVisitor} of the generated method
 * @param p_ClassName
 *            The name of the class
 * @param p_Method
 *            the generated method
 * @param p_StartIndex
 *            First index of the stack after parameters
 * @param p_LdapAttribute
 *            The LdapAttribute that will be used for generating the method
 */
private void generateMethodSetterInitializeAttribute(MethodVisitor p_MethodVisitor, String p_ClassName,
        Method p_Method, int p_StartIndex, LdapAttribute p_LdapAttribute) {
    MethodVisitor mv = p_MethodVisitor;
    String attributeName = p_LdapAttribute.value();
    // Attributes attributes = m_LdapObject.getAttributes();
    mv.visitVarInsn(ALOAD, 0);
    mv.visitFieldInsn(GETFIELD, INTERNAL_PACKAGE_NAME + '/' + p_ClassName, "m_LdapObject",
            "Lldapbeans/bean/LdapObject;");
    mv.visitMethodInsn(INVOKEVIRTUAL, "ldapbeans/bean/LdapObject", "getAttributes",
            "()Ljavax/naming/directory/Attributes;");
    mv.visitVarInsn(ASTORE, p_StartIndex + 2);
    // Attribute attribute = attributes.get("attributeName");
    mv.visitVarInsn(ALOAD, p_StartIndex + 2);
    mv.visitLdcInsn(attributeName);
    mv.visitMethodInsn(INVOKEINTERFACE, "javax/naming/directory/Attributes", "get",
            "(Ljava/lang/String;)Ljavax/naming/directory/Attribute;");
    mv.visitVarInsn(ASTORE, p_StartIndex + 3);
    // if (attribute == null) {
    mv.visitVarInsn(ALOAD, p_StartIndex + 3);
    Label l0 = new Label();
    mv.visitJumpInsn(IFNONNULL, l0);
    // attribute = new BasicAttribute("attributeName");
    mv.visitTypeInsn(NEW, "javax/naming/directory/BasicAttribute");
    mv.visitInsn(DUP);
    mv.visitLdcInsn(attributeName);
    mv.visitMethodInsn(INVOKESPECIAL, "javax/naming/directory/BasicAttribute", "<init>",
            "(Ljava/lang/String;)V");
    mv.visitVarInsn(ASTORE, p_StartIndex + 3);
    // attributes.put(attribute);
    mv.visitVarInsn(ALOAD, p_StartIndex + 2);
    mv.visitVarInsn(ALOAD, p_StartIndex + 3);
    mv.visitMethodInsn(INVOKEINTERFACE, "javax/naming/directory/Attributes", "put",
            "(Ljavax/naming/directory/Attribute;)" + "Ljavax/naming/directory/Attribute;");
    mv.visitInsn(POP);
    if (!p_Method.getName().startsWith("add")) {
        /*
         * If method is not an adder (but a simple setter), attribute has to
         * be cleared
         */
        // } else {
        Label l1 = new Label();
        mv.visitJumpInsn(GOTO, l1);
        mv.visitLabel(l0);
        // attribute.clear();
        mv.visitVarInsn(ALOAD, p_StartIndex + 3);
        mv.visitMethodInsn(INVOKEINTERFACE, "javax/naming/directory/Attribute", "clear", "()V");
        // }
        mv.visitLabel(l1);
    } else {
        // }
        mv.visitLabel(l0);
    }
}

From source file:ldapbeans.bean.LdapBeanClassManager.java

License:LGPL

/**
 * Generate a portion of a method of the generated class
 * /*  ww  w . j a  va2s  .  c  o  m*/
 * @param p_MethodVisitor
 *            The {@link MethodVisitor} of the generated method
 * @param p_ClassName
 *            The name of the class
 * @param p_Method
 *            the generated method
 * @param p_ParamIndex
 *            index of the parameter to convert
 * @param p_StartIndex
 *            first index of the stack after parameters
 * @param p_LdapAttribute
 *            The LdapAttribute that will be used for generating the method
 * @param p_ParameterType
 *            The type of the parameter
 */
private void generateMethodSetterAssignValue(MethodVisitor p_MethodVisitor, String p_ClassName, Method p_Method,
        int p_ParamIndex, int p_StartIndex, LdapAttribute p_LdapAttribute, Class<?> p_ParameterType) {
    MethodVisitor mv = p_MethodVisitor;
    int paramStackIndex = getStackIndexOfParameter(p_Method, p_ParamIndex);
    ConvertAttribute annotation = getConvertAttributeAnnotation(p_Method)[p_ParamIndex];

    if (Collection.class.isAssignableFrom(p_ParameterType)) {
        /*
         * The parameter is a collection, each element of the collection
         * will be added
         */
        // Iterator it = p_AttributeValue.iterator();
        mv.visitVarInsn(ALOAD, paramStackIndex);
        mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Collection", "iterator", "()Ljava/util/Iterator;");
        mv.visitVarInsn(ASTORE, p_StartIndex + 5);
        // while(it.hasNext()) {
        Label l2 = new Label();
        mv.visitLabel(l2);
        mv.visitVarInsn(ALOAD, p_StartIndex + 5);
        mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Iterator", "hasNext", "()Z");
        Label l3 = new Label();
        mv.visitJumpInsn(IFEQ, l3);

        // Object value = it.next();
        mv.visitVarInsn(ALOAD, p_StartIndex + 5);
        mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Iterator", "next", "()Ljava/lang/Object;");
        mv.visitVarInsn(ASTORE, p_StartIndex + 4);
        // convert value to String
        // TODO : Find another way to convert object
        generateMethodSetterAssignValueConvert(mv, p_ClassName, p_Method, p_StartIndex + 4, p_StartIndex,
                p_LdapAttribute, annotation, Object.class);
        generateMethodSetterAssignValueToTempArray(mv, p_ClassName, p_Method, p_StartIndex + 4, p_StartIndex);
        // }
        mv.visitJumpInsn(GOTO, l2);
        mv.visitLabel(l3);
    } else if (p_ParameterType.isArray()) {
        // TODO
        // int i=0;
        mv.visitInsn(ICONST_0);
        mv.visitVarInsn(ISTORE, p_StartIndex + 5);
        // while(i<values.length) {
        Label l0 = new Label();
        Label l1 = new Label();
        mv.visitLabel(l0);
        mv.visitVarInsn(ILOAD, p_StartIndex + 5);
        mv.visitVarInsn(ALOAD, paramStackIndex);
        mv.visitInsn(ARRAYLENGTH);
        mv.visitJumpInsn(IF_ICMPGE, l1);
        // value = values[i];
        mv.visitVarInsn(ALOAD, paramStackIndex);
        mv.visitVarInsn(ILOAD, p_StartIndex + 1);
        mv.visitInsn(AALOAD);
        mv.visitVarInsn(ASTORE, p_StartIndex + 4);
        // convert value to String
        generateMethodSetterAssignValueConvert(mv, p_ClassName, p_Method, p_StartIndex + 4, p_StartIndex,
                p_LdapAttribute, annotation, p_ParameterType.getComponentType());
        generateMethodSetterAssignValueToTempArray(mv, p_ClassName, p_Method, p_StartIndex + 4, p_StartIndex);
        // i++;
        mv.visitIincInsn(p_StartIndex + 5, 1);
        // }
        mv.visitJumpInsn(GOTO, l0);
        mv.visitLabel(l1);
    } else {
        generateMethodSetterAssignValueConvert(mv, p_ClassName, p_Method, paramStackIndex, p_StartIndex,
                p_LdapAttribute, annotation, p_ParameterType);
        generateMethodSetterAssignValueToTempArray(mv, p_ClassName, p_Method, p_StartIndex + 4, p_StartIndex);
    }
}

From source file:ldapbeans.bean.LdapBeanClassManager.java

License:LGPL

/**
 * Generate a method of the generated class
 * /*from  w w w  . j a va 2  s .  c om*/
 * @param p_MethodVisitor
 *            The {@link MethodVisitor} of the generated method
 * @param p_ClassName
 *            The name of the class
 * @param p_Method
 *            the generated method
 * @param p_StartIndex
 *            First index of the stack after parameters
 * @param p_LdapAttribute
 *            LdapAttribute of the generated method
 */
private void generateMethodSetterAssignResult(MethodVisitor p_MethodVisitor, String p_ClassName,
        Method p_Method, int p_StartIndex, LdapAttribute p_LdapAttribute) {
    MethodVisitor mv = p_MethodVisitor;
    if (p_LdapAttribute.pattern().length() == 0) {
        // int i=0;
        mv.visitInsn(ICONST_0);
        mv.visitVarInsn(ISTORE, p_StartIndex + 1);
        // {
        Label l0 = new Label();
        mv.visitJumpInsn(GOTO, l0);
        Label l1 = new Label();
        mv.visitLabel(l1);
        mv.visitVarInsn(ALOAD, p_StartIndex + 3);
        // value = tempValues[i];
        mv.visitVarInsn(ALOAD, p_StartIndex);
        mv.visitVarInsn(ILOAD, p_StartIndex + 1);
        mv.visitInsn(AALOAD);
        // attribute.add(value);
        mv.visitMethodInsn(INVOKEINTERFACE, "javax/naming/directory/Attribute", "add", "(Ljava/lang/Object;)Z");
        mv.visitInsn(POP);
        // i++
        mv.visitIincInsn(p_StartIndex + 1, 1);
        // }
        mv.visitLabel(l0);
        // i < tempValues.length
        mv.visitVarInsn(ILOAD, p_StartIndex + 1);
        mv.visitVarInsn(ALOAD, p_StartIndex);
        mv.visitInsn(ARRAYLENGTH);
        mv.visitJumpInsn(IF_ICMPLT, l1);
    } else {
        mv.visitVarInsn(ALOAD, p_StartIndex + 3);
        mv.visitLdcInsn(p_LdapAttribute.pattern());
        mv.visitVarInsn(ALOAD, p_StartIndex);
        mv.visitMethodInsn(INVOKESTATIC, "ldapbeans/util/StringUtil", "format",
                "(Ljava/lang/String;[Ljava/lang/Object;)" + "Ljava/lang/String;");
        // attribute.add(value);
        mv.visitMethodInsn(INVOKEINTERFACE, "javax/naming/directory/Attribute", "add", "(Ljava/lang/Object;)Z");
        mv.visitInsn(POP);
    }

}

From source file:ldapbeans.bean.LdapBeanClassManager.java

License:LGPL

/**
 * Generate a portion of a method of the generated class
 * //  ww w  . j  a va 2  s .com
 * @param p_MethodVisitor
 *            The {@link MethodVisitor} of the generated method
 * @param p_ObjectStackIndex
 *            index of the object to convert in the stack
 * @param p_StartIndex
 *            first index of the stack after parameters
 * @param p_LdapAttribute
 *            The LdapAttribute that will be used for generating the method
 * @param p_OriginalType
 *            The type before conversion
 */
private void generateMethodSetterAssignValueConvertBoolean(MethodVisitor p_MethodVisitor,
        int p_ObjectStackIndex, int p_StartIndex, LdapAttribute p_LdapAttribute, Class<?> p_OriginalType) {
    MethodVisitor mv = p_MethodVisitor;
    if (Boolean.class.equals(p_OriginalType)) {
        mv.visitVarInsn(ALOAD, p_ObjectStackIndex);
        mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z");
    } else {
        mv.visitVarInsn(ILOAD, p_ObjectStackIndex);
    }
    Label l2 = new Label();
    mv.visitJumpInsn(IFEQ, l2);
    mv.visitLdcInsn(p_LdapAttribute.trueValue()[0]);
    Label l3 = new Label();
    mv.visitJumpInsn(GOTO, l3);
    mv.visitLabel(l2);
    mv.visitLdcInsn(p_LdapAttribute.falseValue()[0]);
    mv.visitLabel(l3);
    mv.visitVarInsn(ASTORE, p_StartIndex + 4);
}

From source file:ldapbeans.bean.LdapBeanClassManager.java

License:LGPL

/**
 * Generate a method of the generated class
 * /*from w  w w.  j  av  a2s  .c o  m*/
 * @param p_MethodVisitor
 *            The {@link MethodVisitor} of the generated method
 * @param p_ClassName
 *            The name of the class
 * @param p_LdapAttribute
 *            The LdapAttribute that will be used for generating the method
 * @param p_ReturnType
 *            The type of the result
 */
private void generateMethodGetterLdapValue(MethodVisitor p_MethodVisitor, String p_ClassName,
        LdapAttribute p_LdapAttribute, Class<?> p_ReturnType) {
    MethodVisitor mv = p_MethodVisitor;
    String attributeName = p_LdapAttribute.value();
    Label l0 = new Label();
    Label l1 = new Label();
    Label l2 = new Label();
    mv.visitTryCatchBlock(l0, l1, l2, "javax/naming/NamingException");
    // Attributes attributes = m_LdapObject.getAttributes();
    mv.visitVarInsn(ALOAD, 0);
    mv.visitFieldInsn(GETFIELD, INTERNAL_PACKAGE_NAME + '/' + p_ClassName, "m_LdapObject",
            "Lldapbeans/bean/LdapObject;");
    mv.visitMethodInsn(INVOKEVIRTUAL, "ldapbeans/bean/LdapObject", "getAttributes",
            "()Ljavax/naming/directory/Attributes;");
    mv.visitVarInsn(ASTORE, 3);
    // Attribute attribute = attributes.get("attributeName");
    mv.visitVarInsn(ALOAD, 3);
    mv.visitLdcInsn(attributeName);
    mv.visitMethodInsn(INVOKEINTERFACE, "javax/naming/directory/Attributes", "get",
            "(Ljava/lang/String;)Ljavax/naming/directory/Attribute;");
    mv.visitVarInsn(ASTORE, 4);
    // try {
    mv.visitLabel(l0);
    // if (attribute != null) {
    Label l3 = new Label();
    mv.visitVarInsn(ALOAD, 4);
    mv.visitJumpInsn(IFNULL, l3);
    generateMethodGetterAssignResult(mv, p_ClassName, p_LdapAttribute, p_ReturnType);
    // }
    mv.visitLabel(l1);
    mv.visitJumpInsn(GOTO, l3);
    // } catch(NamingException e) {
    mv.visitLabel(l2);
    mv.visitVarInsn(ASTORE, 5);
    // throw new IllegalArgumentException()
    // TODO: change the message
    generateThrowingIllegalArgumentException(p_MethodVisitor, "Error when trying to get value");
    // }
    mv.visitLabel(l3);
}

From source file:ldapbeans.bean.LdapBeanClassManager.java

License:LGPL

/**
 * Generate a portion of a method of the generated class
 * /*w  w  w . jav  a  2s . c o  m*/
 * @param p_MethodVisitor
 *            The {@link MethodVisitor} of the generated method
 * @param p_ClassName
 *            Name of the generated class
 * @param p_LdapAttribute
 *            The LdapAttribute that will be used for generating the method
 * @param p_ReturnType
 *            The type of the result
 */
private void generateMethodGetterAssignResultCollection(MethodVisitor p_MethodVisitor, String p_ClassName,
        LdapAttribute p_LdapAttribute, Class<?> p_ReturnType) {
    MethodVisitor mv = p_MethodVisitor;
    // NamingEnumeration<?> enumeration = attribute.getAll();
    mv.visitVarInsn(ALOAD, 4);
    mv.visitMethodInsn(INVOKEINTERFACE, "javax/naming/directory/Attribute", "getAll",
            "()Ljavax/naming/NamingEnumeration;");
    mv.visitVarInsn(ASTORE, 5);
    // result = new [Collection](attribute.size());
    generateMethodGetterInitializeResult(p_MethodVisitor, p_ReturnType);
    // while (enumeration.hasMoreElements()) {
    Label l4 = new Label();
    mv.visitLabel(l4);
    mv.visitVarInsn(ALOAD, 5);
    mv.visitMethodInsn(INVOKEINTERFACE, "javax/naming/NamingEnumeration", "hasMoreElements", "()Z");
    Label l5 = new Label();
    mv.visitJumpInsn(IFEQ, l5);
    // result.add(enumeration.nextElement());
    mv.visitVarInsn(ALOAD, 5);
    mv.visitMethodInsn(INVOKEINTERFACE, "javax/naming/NamingEnumeration", "nextElement",
            "()Ljava/lang/Object;");
    mv.visitVarInsn(ASTORE, 6);
    generateConvert(p_MethodVisitor, p_ClassName, p_LdapAttribute, p_LdapAttribute.componentType(), 6, 7);
    mv.visitVarInsn(ALOAD, 1);
    mv.visitVarInsn(ALOAD, 7);
    mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Collection", "add", "(Ljava/lang/Object;)Z");
    mv.visitInsn(POP);
    // }
    mv.visitJumpInsn(GOTO, l4);
    mv.visitLabel(l5);
    // enumeration.close();
    mv.visitVarInsn(ALOAD, 5);
    mv.visitMethodInsn(INVOKEINTERFACE, "javax/naming/NamingEnumeration", "close", "()V");
}

From source file:ldapbeans.bean.LdapBeanClassManager.java

License:LGPL

/**
 * Generate a portion of a method of the generated class
 * // w  w  w  .  j  a  v  a2 s .c  o  m
 * @param p_MethodVisitor
 *            The {@link MethodVisitor} of the generated method
 * @param p_ClassName
 *            Name of the generated class
 * @param p_LdapAttribute
 *            The LdapAttribute that will be used for generating the method
 * @param p_ReturnType
 *            The type of the result
 */
private void generateMethodGetterAssignResultArray(MethodVisitor p_MethodVisitor, String p_ClassName,
        LdapAttribute p_LdapAttribute, Class<?> p_ReturnType) {
    MethodVisitor mv = p_MethodVisitor;
    // NamingEnumeration<?> enumeration = attribute.getAll();
    mv.visitVarInsn(ALOAD, 4);
    mv.visitMethodInsn(INVOKEINTERFACE, "javax/naming/directory/Attribute", "getAll",
            "()Ljavax/naming/NamingEnumeration;");
    mv.visitVarInsn(ASTORE, 5);
    // result = new Object[attribute.size()];
    generateMethodGetterInitializeResult(p_MethodVisitor, p_ReturnType);
    // int i = 0;
    mv.visitInsn(ICONST_0);
    mv.visitVarInsn(ISTORE, 6);
    // while (enumeration.hasMoreElements()) {
    Label l4 = new Label();
    mv.visitLabel(l4);
    mv.visitVarInsn(ALOAD, 5);
    mv.visitMethodInsn(INVOKEINTERFACE, "javax/naming/NamingEnumeration", "hasMoreElements", "()Z");
    Label l5 = new Label();
    mv.visitJumpInsn(IFEQ, l5);
    // tmp = enumeration.nextElement();
    mv.visitVarInsn(ALOAD, 5);
    mv.visitMethodInsn(INVOKEINTERFACE, "javax/naming/NamingEnumeration", "nextElement",
            "()Ljava/lang/Object;");
    mv.visitVarInsn(ASTORE, 7);
    generateConvert(p_MethodVisitor, p_ClassName, p_LdapAttribute, p_ReturnType.getComponentType(), 7, 8);
    // result[i++] = tmp;
    mv.visitVarInsn(ALOAD, 1);
    mv.visitVarInsn(ILOAD, 6);
    mv.visitIincInsn(6, 1);
    mv.visitVarInsn(ALOAD, 8);
    mv.visitInsn(AASTORE);
    // }
    mv.visitJumpInsn(GOTO, l4);
    mv.visitLabel(l5);
    // enumeration.close();
    mv.visitVarInsn(ALOAD, 5);
    mv.visitMethodInsn(INVOKEINTERFACE, "javax/naming/NamingEnumeration", "close", "()V");
}