List of usage examples for org.objectweb.asm MethodVisitor visitLdcInsn
public void visitLdcInsn(final Object value)
From source file:kr.debop4j.core.reflect.FieldAccess.java
License:Apache License
static private MethodVisitor insertThrowExceptionForFieldType(MethodVisitor mv, String fieldType) { mv.visitTypeInsn(NEW, "java/lang/IllegalArgumentException"); mv.visitInsn(DUP);/*from w w w.j av a 2s . c o m*/ mv.visitTypeInsn(NEW, "java/lang/StringBuilder"); mv.visitInsn(DUP); mv.visitLdcInsn("Field not declared as " + fieldType + ": "); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuilder", "<init>", "(Ljava/lang/String;)V"); mv.visitVarInsn(ILOAD, 2); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(I)Ljava/lang/StringBuilder;"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;"); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/IllegalArgumentException", "<init>", "(Ljava/lang/String;)V"); mv.visitInsn(ATHROW); return mv; }
From source file:kr.debop4j.core.reflect.MethodAccess.java
License:Apache License
/** * ? ? ?? MethodAccess ./*from w w w . j a v a 2 s. c o m*/ * * @param type * @return the method access */ public static MethodAccess get(final Class type) { Guard.shouldNotBeNull(type, "type"); List<Method> methods = Lists.newArrayList(); Class nextClass = type; while (nextClass != Object.class) { Method[] declaredMethods = nextClass.getDeclaredMethods(); for (Method method : declaredMethods) { int modifiers = method.getModifiers(); if (Modifier.isStatic(modifiers)) continue; if (Modifier.isPrivate(modifiers)) continue; methods.add(method); } nextClass = nextClass.getSuperclass(); } Class[][] parameterTypes = new Class[methods.size()][]; String[] methodNames = new String[methods.size()]; for (int i = 0, size = methodNames.length; i < size; i++) { Method method = methods.get(i); methodNames[i] = method.getName(); parameterTypes[i] = method.getParameterTypes(); } String className = type.getName(); String accessClassName = className + "MethodAccess"; if (accessClassName.startsWith("java.")) accessClassName = ReflectConsts.BASE_PACKAGE + "." + accessClassName; Class accessClass; AccessClassLoader loader = AccessClassLoader.get(type); synchronized (loader) { try { accessClass = loader.loadClass(accessClassName); } catch (ClassNotFoundException ignored) { String accessClassNameInternal = accessClassName.replace('.', '/'); String classNameInternal = className.replace('.', '/'); ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); MethodVisitor mv; cw.visit(V1_1, ACC_PUBLIC + ACC_SUPER, accessClassNameInternal, null, ReflectConsts.METHOD_ACCESS_PATH, null); { mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, ReflectConsts.METHOD_ACCESS_PATH, "<init>", "()V"); mv.visitInsn(RETURN); mv.visitMaxs(0, 0); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC + ACC_VARARGS, "invoke", "(Ljava/lang/Object;I[Ljava/lang/Object;)Ljava/lang/Object;", null, null); mv.visitCode(); if (!methods.isEmpty()) { mv.visitVarInsn(ALOAD, 1); mv.visitTypeInsn(CHECKCAST, classNameInternal); mv.visitVarInsn(ASTORE, 4); mv.visitVarInsn(ILOAD, 2); Label[] labels = new Label[methods.size()]; for (int i = 0, n = labels.length; i < n; i++) labels[i] = new Label(); Label defaultLabel = new Label(); mv.visitTableSwitchInsn(0, labels.length - 1, defaultLabel, labels); StringBuilder buffer = new StringBuilder(128); for (int i = 0, n = labels.length; i < n; i++) { mv.visitLabel(labels[i]); if (i == 0) mv.visitFrame(Opcodes.F_APPEND, 1, new Object[] { classNameInternal }, 0, null); else mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); mv.visitVarInsn(ALOAD, 4); buffer.setLength(0); buffer.append('('); Method method = methods.get(i); Class[] paramTypes = method.getParameterTypes(); for (int paramIndex = 0; paramIndex < paramTypes.length; paramIndex++) { mv.visitVarInsn(ALOAD, 3); mv.visitIntInsn(BIPUSH, paramIndex); mv.visitInsn(AALOAD); Type paramType = Type.getType(paramTypes[paramIndex]); switch (paramType.getSort()) { case Type.BOOLEAN: mv.visitTypeInsn(CHECKCAST, "java/lang/Boolean"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z"); break; case Type.BYTE: mv.visitTypeInsn(CHECKCAST, "java/lang/Byte"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Byte", "byteValue", "()B"); break; case Type.CHAR: mv.visitTypeInsn(CHECKCAST, "java/lang/Character"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Character", "charValue", "()C"); break; case Type.SHORT: mv.visitTypeInsn(CHECKCAST, "java/lang/Short"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Short", "shortValue", "()S"); break; case Type.INT: mv.visitTypeInsn(CHECKCAST, "java/lang/Integer"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Integer", "intValue", "()I"); break; case Type.FLOAT: mv.visitTypeInsn(CHECKCAST, "java/lang/Float"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Float", "floatValue", "()F"); break; case Type.LONG: mv.visitTypeInsn(CHECKCAST, "java/lang/Long"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Long", "longValue", "()J"); break; case Type.DOUBLE: mv.visitTypeInsn(CHECKCAST, "java/lang/Double"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Double", "doubleValue", "()D"); break; case Type.ARRAY: mv.visitTypeInsn(CHECKCAST, paramType.getDescriptor()); break; case Type.OBJECT: mv.visitTypeInsn(CHECKCAST, paramType.getInternalName()); break; } buffer.append(paramType.getDescriptor()); } buffer.append(')'); buffer.append(Type.getDescriptor(method.getReturnType())); mv.visitMethodInsn(INVOKEVIRTUAL, classNameInternal, method.getName(), buffer.toString()); switch (Type.getType(method.getReturnType()).getSort()) { case Type.VOID: mv.visitInsn(ACONST_NULL); break; case Type.BOOLEAN: mv.visitMethodInsn(INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;"); break; case Type.BYTE: mv.visitMethodInsn(INVOKESTATIC, "java/lang/Byte", "valueOf", "(B)Ljava/lang/Byte;"); break; case Type.CHAR: mv.visitMethodInsn(INVOKESTATIC, "java/lang/Character", "valueOf", "(C)Ljava/lang/Character;"); break; case Type.SHORT: mv.visitMethodInsn(INVOKESTATIC, "java/lang/Short", "valueOf", "(S)Ljava/lang/Short;"); break; case Type.INT: mv.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;"); break; case Type.FLOAT: mv.visitMethodInsn(INVOKESTATIC, "java/lang/Float", "valueOf", "(F)Ljava/lang/Float;"); break; case Type.LONG: mv.visitMethodInsn(INVOKESTATIC, "java/lang/Long", "valueOf", "(J)Ljava/lang/Long;"); break; case Type.DOUBLE: mv.visitMethodInsn(INVOKESTATIC, "java/lang/Double", "valueOf", "(D)Ljava/lang/Double;"); break; } mv.visitInsn(ARETURN); } mv.visitLabel(defaultLabel); mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); } mv.visitTypeInsn(NEW, "java/lang/IllegalArgumentException"); mv.visitInsn(DUP); mv.visitTypeInsn(NEW, "java/lang/StringBuilder"); mv.visitInsn(DUP); mv.visitLdcInsn("Method not found: "); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuilder", "<init>", "(Ljava/lang/String;)V"); mv.visitVarInsn(ILOAD, 2); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(I)Ljava/lang/StringBuilder;"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;"); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/IllegalArgumentException", "<init>", "(Ljava/lang/String;)V"); mv.visitInsn(ATHROW); mv.visitMaxs(0, 0); mv.visitEnd(); } cw.visitEnd(); byte[] data = cw.toByteArray(); accessClass = loader.defineClass(accessClassName, data); } } try { MethodAccess access = (MethodAccess) accessClass.newInstance(); access.methodNames = methodNames; access.parameterTypes = parameterTypes; return access; } catch (Exception ex) { throw new RuntimeException("Error constructing method access class=[" + accessClassName + "]", ex); } }
From source file:lapin.comp.asm.ASMByteCodeGenerator.java
License:Open Source License
private void generateConstructor(Env env) { /*/*from w w w .ja v a 2 s . c om*/ * local variables (reserved) * 0: this * 1: env */ MethodVisitor mv = _cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", //"(Llapin/lang/Env;)V", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { TYPE_ENV }), null, null); mv.visitCode(); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitLdcInsn(super.classInfo.name().pname()); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "lapin/function/CompiledExpr", "<init>", //"(Ljava/lang/String;)V"); Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { TYPE_STRING })); Iterator it; // fields for constants it = constTable.keySet().iterator(); while (it.hasNext()) { Object key = it.next(); // key: object (const) String val = Data.string(constTable.get(key)); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitLdcInsn(Printer.prin1ToString(key, env)); mv.visitVarInsn(Opcodes.ALOAD, 1); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "lapin/function/CompiledExpr", "toSexp", Type.getMethodDescriptor(TYPE_OBJECT, new Type[] { TYPE_STRING, TYPE_ENV })); mv.visitFieldInsn(Opcodes.PUTFIELD, toInternalName(super.classInfo.classname()), val, TYPE_OBJECT.getDescriptor()); } // fields for vars it = varTable.keySet().iterator(); while (it.hasNext()) { Object key = it.next(); // key: symbol (var) String val = Data.string(varTable.get(key)); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitLdcInsn(Printer.prin1ToString(key, env)); mv.visitVarInsn(Opcodes.ALOAD, 1); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "lapin/function/CompiledExpr", "toSexp", Type.getMethodDescriptor(TYPE_OBJECT, new Type[] { TYPE_STRING, TYPE_ENV })); mv.visitMethodInsn(Opcodes.INVOKESTATIC, "lapin/lang/Data", "symbol", Type.getMethodDescriptor(TYPE_SYMBOL, new Type[] { TYPE_OBJECT })); mv.visitFieldInsn(Opcodes.PUTFIELD, toInternalName(super.classInfo.classname()), val, TYPE_SYMBOL.getDescriptor()); } // fields for lambdaLists it = llTable.keySet().iterator(); while (it.hasNext()) { Object key = it.next(); // key: lambdaList String val = Data.string(llTable.get(key)); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitLdcInsn(Printer.prin1ToString(Data.lambdaList(key).params(), env)); mv.visitVarInsn(Opcodes.ALOAD, 1); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "lapin/function/CompiledExpr", "toLambdaList", Type.getMethodDescriptor(TYPE_LAMBDA_LIST, new Type[] { TYPE_STRING, TYPE_ENV })); mv.visitFieldInsn(Opcodes.PUTFIELD, toInternalName(super.classInfo.classname()), val, TYPE_LAMBDA_LIST.getDescriptor()); } // field for SELF (static field) mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitFieldInsn(Opcodes.PUTSTATIC, toInternalName(super.classInfo.classname()), "SELF", toTypeDescriptor(super.classInfo.classname())); mv.visitInsn(Opcodes.RETURN); mv.visitMaxs(0, 0); mv.visitEnd(); }
From source file:lapin.comp.asm.ASMByteCodeGenerator.java
License:Open Source License
private void generateCall(CallableInfo ci, Env env) { /*/*from w w w. j a v a 2 s. co 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 * // w w w . j a v a 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 * 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 method of the generated class * //w w w.j a v a 2 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 * 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 * /*from w ww.j a va 2s. c om*/ * @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 www .j a v a2 s . 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 code throwing {@link IllegalArgumentException} * /*from ww w . jav a 2 s . c o m*/ * @param p_MethodVisitor * The {@link MethodVisitor} of the generated method * @param p_Message * The message of the exception, or <code>null</code> if none */ private void generateThrowingIllegalArgumentException(MethodVisitor p_MethodVisitor, String p_Message) { MethodVisitor mv = p_MethodVisitor; mv.visitTypeInsn(NEW, "java/lang/IllegalArgumentException"); mv.visitInsn(DUP); if (p_Message != null) { mv.visitLdcInsn(p_Message); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/IllegalArgumentException", "<init>", "(Ljava/lang/String;)V"); } else { mv.visitMethodInsn(INVOKESPECIAL, "java/lang/IllegalArgumentException", "<init>", "()V"); } mv.visitInsn(ATHROW); }
From source file:ldapbeans.bean.LdapBeanClassManager.java
License:LGPL
/** * Generate code to convert ldapAttribute witch is on the top of the stack * to LdapBean/* www . j a v a2s.co 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 * @param p_Object * Index of the object to convert on the stack * @param p_Result * Index of the converted object on the stack */ private void generateConvertToLdapBean(MethodVisitor p_MethodVisitor, String p_ClassName, LdapAttribute p_LdapAttribute, Class<?> p_ReturnType, int p_Object, int p_Result) { MethodVisitor mv = p_MethodVisitor; Label l1 = new Label(); Label l0 = new Label(); // if(object == null) { mv.visitVarInsn(ALOAD, p_Object); mv.visitJumpInsn(IFNULL, l0); // result = m_LdapBeanManager.searchFirst(p_ReturnType, // "search_filter"); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, INTERNAL_PACKAGE_NAME + '/' + p_ClassName, "m_LdapBeanManager", "Lldapbeans/bean/LdapBeanManager;"); if (p_ReturnType != null) { mv.visitLdcInsn(Type.getType(p_ReturnType)); } else { mv.visitInsn(ACONST_NULL); } if (p_LdapAttribute.search().length() == 0) { mv.visitVarInsn(ALOAD, p_Object); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "toString", "()Ljava/lang/String;"); mv.visitMethodInsn(INVOKEVIRTUAL, "ldapbeans/bean/LdapBeanManager", "findByDn", "(Ljava/lang/Class;Ljava/lang/String;)" + "Lldapbeans/bean/LdapBean;"); } else { mv.visitLdcInsn(p_LdapAttribute.search()); if (p_LdapAttribute.pattern().length() != 0) { // regExpGroup = StringUtil.getRegexpGroup(object.toString(), // pattern) mv.visitVarInsn(ALOAD, p_Object); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "toString", "()Ljava/lang/String;"); mv.visitLdcInsn(p_LdapAttribute.pattern()); mv.visitMethodInsn(INVOKESTATIC, "ldapbeans/util/StringUtil", "getRegexpGroup", "(Ljava/lang/String;Ljava/lang/String;)" + "[Ljava/lang/String;"); } else { // regExpGroup = new Object[] { object } mv.visitInsn(ICONST_1); mv.visitTypeInsn(ANEWARRAY, "java/lang/Object"); mv.visitInsn(DUP); mv.visitInsn(ICONST_0); mv.visitVarInsn(ALOAD, p_Object); mv.visitInsn(AASTORE); } // searchFilter = StringUtil.format("search_filter", regExpGroup); mv.visitMethodInsn(INVOKESTATIC, "ldapbeans/util/StringUtil", "format", "(Ljava/lang/String;[Ljava/lang/Object;)" + "Ljava/lang/String;"); // result = m_LdapBeanManager.searchFirst(foo.class, searchFilter); mv.visitMethodInsn(INVOKEVIRTUAL, "ldapbeans/bean/LdapBeanManager", "searchFirst", "(Ljava/lang/Class;Ljava/lang/String;)" + "Lldapbeans/bean/LdapBean;"); } mv.visitVarInsn(ASTORE, p_Result); // } else { mv.visitJumpInsn(GOTO, l1); mv.visitLabel(l0); // result = null; mv.visitInsn(ACONST_NULL); mv.visitVarInsn(ASTORE, p_Result); // } mv.visitLabel(l1); }