List of usage examples for org.objectweb.asm MethodVisitor visitCode
public void visitCode()
From source file:org.codehaus.groovy.classgen.AsmClassGenerator.java
License:Apache License
@Override protected void visitConstructorOrMethod(final MethodNode node, final boolean isConstructor) { controller.resetLineNumber();/*from w w w . j a v a 2 s.c o m*/ Parameter[] parameters = node.getParameters(); String methodType = BytecodeHelper.getMethodDescriptor(node.getReturnType(), parameters); String signature = BytecodeHelper.getGenericsMethodSignature(node); int modifiers = node.getModifiers(); if (isVargs(node.getParameters())) modifiers |= ACC_VARARGS; MethodVisitor mv = classVisitor.visitMethod(modifiers, node.getName(), methodType, signature, buildExceptions(node.getExceptions())); controller.setMethodVisitor(mv); visitAnnotations(node, mv); for (int i = 0, n = parameters.length; i < n; i += 1) { visitParameterAnnotations(parameters[i], i, mv); } // add parameter names to the MethodVisitor (jdk8+ only) if (getCompileUnit().getConfig().getParameters()) { for (Parameter parameter : parameters) { // TODO: handle ACC_SYNTHETIC for enum method parameters? mv.visitParameter(parameter.getName(), 0); } } if (controller.getClassNode().isAnnotationDefinition() && !node.isStaticConstructor()) { visitAnnotationDefault(node, mv); } else if (!node.isAbstract()) { Statement code = node.getCode(); mv.visitCode(); // fast path for getter/setters etc. if (code instanceof BytecodeSequence && ((BytecodeSequence) code).getInstructions().size() == 1 && ((BytecodeSequence) code).getInstructions().get(0) instanceof BytecodeInstruction) { ((BytecodeInstruction) ((BytecodeSequence) code).getInstructions().get(0)).visit(mv); } else { visitStdMethod(node, isConstructor, parameters, code); } try { mv.visitMaxs(0, 0); } catch (Exception e) { Writer writer = null; if (mv instanceof TraceMethodVisitor) { TraceMethodVisitor tracer = (TraceMethodVisitor) mv; writer = new StringBuilderWriter(); PrintWriter p = new PrintWriter(writer); tracer.p.print(p); p.flush(); } StringBuilder message = new StringBuilder(64); message.append("ASM reporting processing error for "); message.append(controller.getClassNode().toString()).append("#").append(node.getName()); message.append(" with signature ").append(node.getTypeDescriptor()); message.append(" in ").append(sourceFile).append(":").append(node.getLineNumber()); if (writer != null) { message.append("\nLast known generated bytecode in last generated method or constructor:\n"); message.append(writer); } throw new GroovyRuntimeException(message.toString(), e); } } mv.visitEnd(); }
From source file:org.codehaus.groovy.classgen.AsmClassGenerator.java
License:Apache License
protected void createSyntheticStaticFields() { if (referencedClasses.isEmpty()) { return;/* w w w . j a v a2 s . c o m*/ } MethodVisitor mv; for (Map.Entry<String, ClassNode> entry : referencedClasses.entrySet()) { String staticFieldName = entry.getKey(); ClassNode cn = entry.getValue(); // generate a field node FieldNode fn = controller.getClassNode().getDeclaredField(staticFieldName); if (fn != null) { boolean type = fn.getType().equals(ClassHelper.CLASS_Type); boolean modifiers = fn.getModifiers() == ACC_STATIC + ACC_SYNTHETIC; if (!type || !modifiers) { String text = ""; if (!type) text = " with wrong type: " + fn.getType() + " (java.lang.Class needed)"; if (!modifiers) text = " with wrong modifiers: " + fn.getModifiers() + " (" + (ACC_STATIC + ACC_SYNTHETIC) + " needed)"; throwException("tried to set a static synthetic field " + staticFieldName + " in " + controller.getClassNode().getName() + " for class resolving, but found already a node of that name " + text); } } else { classVisitor.visitField(ACC_PRIVATE + ACC_STATIC + ACC_SYNTHETIC, staticFieldName, "Ljava/lang/Class;", null, null); } mv = classVisitor.visitMethod(ACC_PRIVATE + ACC_STATIC + ACC_SYNTHETIC, "$get$" + staticFieldName, "()Ljava/lang/Class;", null, null); mv.visitCode(); mv.visitFieldInsn(GETSTATIC, controller.getInternalClassName(), staticFieldName, "Ljava/lang/Class;"); mv.visitInsn(DUP); Label l0 = new Label(); mv.visitJumpInsn(IFNONNULL, l0); mv.visitInsn(POP); mv.visitLdcInsn(BytecodeHelper.getClassLoadingTypeDescription(cn)); mv.visitMethodInsn(INVOKESTATIC, controller.getInternalClassName(), "class$", "(Ljava/lang/String;)Ljava/lang/Class;", false); mv.visitInsn(DUP); mv.visitFieldInsn(PUTSTATIC, controller.getInternalClassName(), staticFieldName, "Ljava/lang/Class;"); mv.visitLabel(l0); mv.visitInsn(ARETURN); mv.visitMaxs(0, 0); mv.visitEnd(); } mv = classVisitor.visitMethod(ACC_STATIC + ACC_SYNTHETIC, "class$", "(Ljava/lang/String;)Ljava/lang/Class;", null, null); Label l0 = new Label(); mv.visitLabel(l0); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESTATIC, "java/lang/Class", "forName", "(Ljava/lang/String;)Ljava/lang/Class;", false); Label l1 = new Label(); mv.visitLabel(l1); mv.visitInsn(ARETURN); Label l2 = new Label(); mv.visitLabel(l2); mv.visitVarInsn(ASTORE, 1); mv.visitTypeInsn(NEW, "java/lang/NoClassDefFoundError"); mv.visitInsn(DUP); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/ClassNotFoundException", "getMessage", "()Ljava/lang/String;", false); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/NoClassDefFoundError", "<init>", "(Ljava/lang/String;)V", false); mv.visitInsn(ATHROW); mv.visitTryCatchBlock(l0, l2, l2, "java/lang/ClassNotFoundException"); // br using l2 as the 2nd param seems create the right table entry mv.visitMaxs(3, 2); }
From source file:org.codehaus.groovy.classgen.AsmClassGenerator.java
License:Apache License
@Override public void visitListExpression(final ListExpression expression) { onLineNumber(expression, "ListExpression"); int size = expression.getExpressions().size(); boolean containsSpreadExpression = containsSpreadExpression(expression); boolean containsOnlyConstants = !containsSpreadExpression && containsOnlyConstants(expression); OperandStack operandStack = controller.getOperandStack(); if (!containsSpreadExpression) { MethodVisitor mv = controller.getMethodVisitor(); BytecodeHelper.pushConstant(mv, size); mv.visitTypeInsn(ANEWARRAY, "java/lang/Object"); int maxInit = 1000; if (size < maxInit || !containsOnlyConstants) { for (int i = 0; i < size; i += 1) { mv.visitInsn(DUP);//www . j av a 2 s .c o m BytecodeHelper.pushConstant(mv, i); expression.getExpression(i).visit(this); operandStack.box(); mv.visitInsn(AASTORE); } controller.getOperandStack().remove(size); } else { List<Expression> expressions = expression.getExpressions(); List<String> methods = new ArrayList<>(); MethodVisitor oldMv = mv; int index = 0; while (index < size) { String methodName = "$createListEntry_" + controller.getNextHelperMethodIndex(); methods.add(methodName); mv = controller.getClassVisitor().visitMethod(ACC_PRIVATE + ACC_STATIC + ACC_SYNTHETIC, methodName, "([Ljava/lang/Object;)V", null, null); controller.setMethodVisitor(mv); mv.visitCode(); int methodBlockSize = Math.min(size - index, maxInit); int methodBlockEnd = index + methodBlockSize; for (; index < methodBlockEnd; index += 1) { mv.visitVarInsn(ALOAD, 0); mv.visitLdcInsn(index); expressions.get(index).visit(this); operandStack.box(); mv.visitInsn(AASTORE); } operandStack.remove(methodBlockSize); mv.visitInsn(RETURN); mv.visitMaxs(0, 0); mv.visitEnd(); } mv = oldMv; controller.setMethodVisitor(mv); for (String methodName : methods) { mv.visitInsn(DUP); mv.visitMethodInsn(INVOKESTATIC, controller.getInternalClassName(), methodName, "([Ljava/lang/Object;)V", false); } } } else { despreadList(expression.getExpressions(), false); } createListMethod.call(controller.getMethodVisitor()); operandStack.push(ClassHelper.LIST_TYPE); }
From source file:org.codehaus.groovy.reflection.MethodHandleFactory.java
License:Apache License
private static void genConstructor(ClassWriter cw, final String superClass) { MethodVisitor mv; mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null); mv.visitCode(); mv.visitVarInsn(Opcodes.ALOAD, 0);/* w w w.j av a2 s .c om*/ mv.visitMethodInsn(Opcodes.INVOKESPECIAL, superClass, "<init>", "()V"); mv.visitInsn(Opcodes.RETURN); mv.visitMaxs(0, 0); mv.visitEnd(); }
From source file:org.codehaus.groovy.reflection.MethodHandleFactory.java
License:Apache License
@Deprecated public static void genInvokeXxxWithArray(ClassWriter cw, Method method) { MethodVisitor mv; mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "invoke", "(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;", null, EXCEPTIONS); mv.visitCode(); Class callClass = method.getDeclaringClass(); boolean useInterface = callClass.isInterface(); String type = BytecodeHelper.getClassInternalName(callClass.getName()); String descriptor = BytecodeHelper.getMethodDescriptor(method.getReturnType(), method.getParameterTypes()); // make call//from w w w. ja v a 2 s .c om if (Modifier.isStatic(method.getModifiers())) { genLoadParameters(2, mv, method); mv.visitMethodInsn(Opcodes.INVOKESTATIC, type, method.getName(), descriptor); } else { mv.visitVarInsn(Opcodes.ALOAD, 1); BytecodeHelper.doCast(mv, callClass); genLoadParameters(2, mv, method); mv.visitMethodInsn((useInterface) ? Opcodes.INVOKEINTERFACE : Opcodes.INVOKEVIRTUAL, type, method.getName(), descriptor); } BytecodeHelper.box(mv, method.getReturnType()); if (method.getReturnType() == void.class) { mv.visitInsn(Opcodes.ACONST_NULL); } mv.visitInsn(Opcodes.ARETURN); mv.visitMaxs(0, 0); mv.visitEnd(); }
From source file:org.codehaus.groovy.reflection.MethodHandleFactory.java
License:Apache License
private static void genInvokeWithFixedParams(ClassWriter cw, Method method) { MethodVisitor mv; final int pc = method.getParameterTypes().length; if (pc <= 4) { StringBuilder pdescb = new StringBuilder(); for (int i = 0; i != pc; ++i) pdescb.append("Ljava/lang/Object;"); String pdesc = pdescb.toString(); mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "invoke", "(Ljava/lang/Object;" + pdesc + ")Ljava/lang/Object;", null, EXCEPTIONS);/*from w ww .j a va2 s. c om*/ mv.visitCode(); Class callClass = method.getDeclaringClass(); boolean useInterface = callClass.isInterface(); String type = BytecodeHelper.getClassInternalName(callClass.getName()); String descriptor = BytecodeHelper.getMethodDescriptor(method.getReturnType(), method.getParameterTypes()); // make call if (Modifier.isStatic(method.getModifiers())) { MethodHandleFactory.genLoadParametersDirect(2, mv, method); mv.visitMethodInsn(Opcodes.INVOKESTATIC, type, method.getName(), descriptor); } else { mv.visitVarInsn(Opcodes.ALOAD, 1); BytecodeHelper.doCast(mv, callClass); MethodHandleFactory.genLoadParametersDirect(2, mv, method); mv.visitMethodInsn((useInterface) ? Opcodes.INVOKEINTERFACE : Opcodes.INVOKEVIRTUAL, type, method.getName(), descriptor); } BytecodeHelper.box(mv, method.getReturnType()); if (method.getReturnType() == void.class) { mv.visitInsn(Opcodes.ACONST_NULL); } mv.visitInsn(Opcodes.ARETURN); mv.visitMaxs(0, 0); mv.visitEnd(); } }
From source file:org.codehaus.groovy.reflection.MethodHandleFactory.java
License:Apache License
private static void genInvokeWithFixedPrimitiveParams(ClassWriter cw, Method method) { MethodVisitor mv; final Class<?>[] pt = method.getParameterTypes(); final int pc = pt.length; if (pc > 0 && pc <= 3) { StringBuilder pdescb = new StringBuilder(); boolean hasPrimitive = false; for (int i = 0; i != pc; ++i) if (pt[i].isPrimitive()) { hasPrimitive = true;/*www .j a v a 2s. co m*/ pdescb.append(BytecodeHelper.getTypeDescription(pt[i])); } else pdescb.append("Ljava/lang/Object;"); if (!hasPrimitive) return; String pdesc = pdescb.toString(); mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "invoke", "(Ljava/lang/Object;" + pdesc + ")Ljava/lang/Object;", null, EXCEPTIONS); mv.visitCode(); Class callClass = method.getDeclaringClass(); boolean useInterface = callClass.isInterface(); String type = BytecodeHelper.getClassInternalName(callClass.getName()); String descriptor = BytecodeHelper.getMethodDescriptor(method.getReturnType(), method.getParameterTypes()); // make call if (Modifier.isStatic(method.getModifiers())) { MethodHandleFactory.genLoadParametersPrimitiveDirect(2, mv, method); mv.visitMethodInsn(Opcodes.INVOKESTATIC, type, method.getName(), descriptor); } else { mv.visitVarInsn(Opcodes.ALOAD, 1); BytecodeHelper.doCast(mv, callClass); MethodHandleFactory.genLoadParametersPrimitiveDirect(2, mv, method); mv.visitMethodInsn((useInterface) ? Opcodes.INVOKEINTERFACE : Opcodes.INVOKEVIRTUAL, type, method.getName(), descriptor); } BytecodeHelper.box(mv, method.getReturnType()); if (method.getReturnType() == void.class) { mv.visitInsn(Opcodes.ACONST_NULL); } mv.visitInsn(Opcodes.ARETURN); mv.visitMaxs(0, 0); mv.visitEnd(); } }
From source file:org.codehaus.groovy.reflection.SunClassLoader.java
License:Apache License
private void loadMagic() { ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); cw.visit(Opcodes.V1_4, Opcodes.ACC_PUBLIC, "sun/reflect/GroovyMagic", null, "sun/reflect/MagicAccessorImpl", null);/*from w w w.ja v a 2s. c o m*/ MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, "sun/reflect/MagicAccessorImpl", "<init>", "()V", false); mv.visitInsn(RETURN); mv.visitMaxs(0, 0); mv.visitEnd(); cw.visitEnd(); define(cw.toByteArray(), "sun.reflect.GroovyMagic"); }
From source file:org.codehaus.groovy.runtime.callsite.CallSiteGenerator.java
License:Apache License
private static MethodVisitor writeMethod(ClassWriter cw, String name, int argumentCount, final String superClass, CachedMethod cachedMethod, String receiverType, String parameterDescription, boolean useArray) { MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "call" + name, "(L" + receiverType + ";" + parameterDescription + ")Ljava/lang/Object;", null, null); mv.visitCode(); final Label tryStart = new Label(); mv.visitLabel(tryStart);/*from ww w . j a v a2 s .c om*/ // call for checking if method is still valid for (int i = 0; i < argumentCount; ++i) mv.visitVarInsn(Opcodes.ALOAD, i); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, superClass, "checkCall", "(Ljava/lang/Object;" + parameterDescription + ")Z", false); Label l0 = new Label(); mv.visitJumpInsn(Opcodes.IFEQ, l0); // valid method branch Class callClass = cachedMethod.getDeclaringClass().getTheClass(); boolean useInterface = callClass.isInterface(); String type = BytecodeHelper.getClassInternalName(callClass.getName()); String descriptor = BytecodeHelper.getMethodDescriptor(cachedMethod.getReturnType(), cachedMethod.getNativeParameterTypes()); // prepare call int invokeMethodCode = Opcodes.INVOKEVIRTUAL; if (cachedMethod.isStatic()) { invokeMethodCode = Opcodes.INVOKESTATIC; } else { mv.visitVarInsn(Opcodes.ALOAD, 1); BytecodeHelper.doCast(mv, callClass); if (useInterface) invokeMethodCode = Opcodes.INVOKEINTERFACE; } Class<?>[] parameters = cachedMethod.getPT(); int size = parameters.length; for (int i = 0; i < size; i++) { if (useArray) { // unpack argument from Object[] mv.visitVarInsn(Opcodes.ALOAD, 2); BytecodeHelper.pushConstant(mv, i); mv.visitInsn(Opcodes.AALOAD); } else { mv.visitVarInsn(Opcodes.ALOAD, i + 2); } // cast argument to parameter class, inclusive unboxing // for methods with primitive types BytecodeHelper.doCast(mv, parameters[i]); } // make call mv.visitMethodInsn(invokeMethodCode, type, cachedMethod.getName(), descriptor, useInterface); // produce result BytecodeHelper.box(mv, cachedMethod.getReturnType()); if (cachedMethod.getReturnType() == void.class) { mv.visitInsn(Opcodes.ACONST_NULL); } // return mv.visitInsn(Opcodes.ARETURN); // fall back after method change mv.visitLabel(l0); for (int i = 0; i < argumentCount; ++i) mv.visitVarInsn(Opcodes.ALOAD, i); if (!useArray) { mv.visitMethodInsn(Opcodes.INVOKESTATIC, "org/codehaus/groovy/runtime/ArrayUtil", "createArray", "(" + parameterDescription + ")[Ljava/lang/Object;", false); } mv.visitMethodInsn(Opcodes.INVOKESTATIC, "org/codehaus/groovy/runtime/callsite/CallSiteArray", "defaultCall" + name, "(Lorg/codehaus/groovy/runtime/callsite/CallSite;L" + receiverType + ";[Ljava/lang/Object;)Ljava/lang/Object;", false); mv.visitInsn(Opcodes.ARETURN); // exception unwrapping for stackless exceptions final Label tryEnd = new Label(); mv.visitLabel(tryEnd); final Label catchStart = new Label(); mv.visitLabel(catchStart); mv.visitMethodInsn(Opcodes.INVOKESTATIC, "org/codehaus/groovy/runtime/ScriptBytecodeAdapter", "unwrap", "(Lgroovy/lang/GroovyRuntimeException;)Ljava/lang/Throwable;", false); mv.visitInsn(Opcodes.ATHROW); mv.visitTryCatchBlock(tryStart, tryEnd, catchStart, "groovy/lang/GroovyRuntimeException"); mv.visitMaxs(0, 0); mv.visitEnd(); return mv; }