List of usage examples for org.objectweb.asm.tree AnnotationNode accept
public void accept(final AnnotationVisitor annotationVisitor)
From source file:co.paralleluniverse.fibers.instrument.InstrumentMethod.java
License:Open Source License
public void accept(MethodVisitor mv, boolean hasAnnotation) { db.log(LogLevel.INFO, "Instrumenting method %s#%s%s", className, mn.name, mn.desc); mv.visitAnnotation(ALREADY_INSTRUMENTED_DESC, true); final boolean handleProxyInvocations = HANDLE_PROXY_INVOCATIONS & hasSuspendableSuperCalls; mv.visitCode();//from ww w .j a va 2 s . c o m Label lMethodStart = new Label(); Label lMethodStart2 = new Label(); Label lMethodEnd = new Label(); Label lCatchSEE = new Label(); Label lCatchUTE = new Label(); Label lCatchAll = new Label(); Label[] lMethodCalls = new Label[numCodeBlocks - 1]; for (int i = 1; i < numCodeBlocks; i++) lMethodCalls[i - 1] = new Label(); mv.visitInsn(Opcodes.ACONST_NULL); mv.visitVarInsn(Opcodes.ASTORE, lvarInvocationReturnValue); // if (verifyInstrumentation) { // mv.visitInsn(Opcodes.ICONST_0); // mv.visitVarInsn(Opcodes.ISTORE, lvarSuspendableCalled); // } mv.visitTryCatchBlock(lMethodStart, lMethodEnd, lCatchSEE, EXCEPTION_NAME); if (handleProxyInvocations) mv.visitTryCatchBlock(lMethodStart, lMethodEnd, lCatchUTE, UNDECLARED_THROWABLE_NAME); // Prepare visitTryCatchBlocks for InvocationTargetException. // With reflective invocations, the SuspendExecution exception will be wrapped in InvocationTargetException. We need to catch it and unwrap it. // Note that the InvocationTargetException will be regenrated on every park, adding further overhead on top of the reflective call. // This must be done here, before all other visitTryCatchBlock, because the exception's handler // will be matched according to the order of in which visitTryCatchBlock has been called. Earlier calls take precedence. Label[][] refInvokeTryCatch = new Label[numCodeBlocks - 1][]; for (int i = 1; i < numCodeBlocks; i++) { FrameInfo fi = codeBlocks[i]; AbstractInsnNode in = mn.instructions.get(fi.endInstruction); if (mn.instructions.get(fi.endInstruction) instanceof MethodInsnNode) { MethodInsnNode min = (MethodInsnNode) in; if (isReflectInvocation(min.owner, min.name)) { Label[] ls = new Label[3]; for (int k = 0; k < 3; k++) ls[k] = new Label(); refInvokeTryCatch[i - 1] = ls; mv.visitTryCatchBlock(ls[0], ls[1], ls[2], "java/lang/reflect/InvocationTargetException"); } } } for (Object o : mn.tryCatchBlocks) { TryCatchBlockNode tcb = (TryCatchBlockNode) o; if (EXCEPTION_NAME.equals(tcb.type) && !hasAnnotation) // we allow catch of SuspendExecution in method annotated with @Suspendable. throw new UnableToInstrumentException("catch for SuspendExecution", className, mn.name, mn.desc); if (handleProxyInvocations && UNDECLARED_THROWABLE_NAME.equals(tcb.type)) // we allow catch of SuspendExecution in method annotated with @Suspendable. throw new UnableToInstrumentException("catch for UndeclaredThrowableException", className, mn.name, mn.desc); // if (INTERRUPTED_EXCEPTION_NAME.equals(tcb.type)) // throw new UnableToInstrumentException("catch for " + InterruptedException.class.getSimpleName(), className, mn.name, mn.desc); tcb.accept(mv); } if (mn.visibleParameterAnnotations != null) dumpParameterAnnotations(mv, mn.visibleParameterAnnotations, true); if (mn.invisibleParameterAnnotations != null) dumpParameterAnnotations(mv, mn.invisibleParameterAnnotations, false); if (mn.visibleAnnotations != null) { for (Object o : mn.visibleAnnotations) { AnnotationNode an = (AnnotationNode) o; an.accept(mv.visitAnnotation(an.desc, true)); } } mv.visitTryCatchBlock(lMethodStart, lMethodEnd, lCatchAll, null); mv.visitMethodInsn(Opcodes.INVOKESTATIC, STACK_NAME, "getStack", "()L" + STACK_NAME + ";"); mv.visitInsn(Opcodes.DUP); mv.visitVarInsn(Opcodes.ASTORE, lvarStack); // println(mv, "STACK: ", lvarStack); // dumpStack(mv); if (DUAL) { mv.visitJumpInsn(Opcodes.IFNULL, lMethodStart); mv.visitVarInsn(Opcodes.ALOAD, lvarStack); } emitStoreResumed(mv, true); // we'll assume we have been resumed mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, STACK_NAME, "nextMethodEntry", "()I"); mv.visitTableSwitchInsn(1, numCodeBlocks - 1, lMethodStart2, lMethodCalls); mv.visitLabel(lMethodStart2); // the following code handles the case of an instrumented method called not as part of a suspendable code path // isFirstInStack will return false in that case. mv.visitVarInsn(Opcodes.ALOAD, lvarStack); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, STACK_NAME, "isFirstInStackOrPushed", "()Z"); mv.visitJumpInsn(Opcodes.IFNE, lMethodStart); // if true mv.visitInsn(Opcodes.ACONST_NULL); mv.visitVarInsn(Opcodes.ASTORE, lvarStack); mv.visitLabel(lMethodStart); emitStoreResumed(mv, false); // no, we have not been resumed dumpCodeBlock(mv, 0, 0); for (int i = 1; i < numCodeBlocks; i++) { FrameInfo fi = codeBlocks[i]; MethodInsnNode min = (MethodInsnNode) (mn.instructions.get(fi.endInstruction)); if (isYieldMethod(min.owner, min.name)) { // special case - call to yield if (min.getOpcode() != Opcodes.INVOKESTATIC) throw new UnableToInstrumentException("invalid call to suspending method.", className, mn.name, mn.desc); final int numYieldArgs = TypeAnalyzer.getNumArguments(min.desc); final boolean yieldReturnsValue = (Type.getReturnType(min.desc) != Type.VOID_TYPE); emitStoreState(mv, i, fi, numYieldArgs); // we preserve the arguments for the call to yield on the operand stack emitStoreResumed(mv, false); // we have not been resumed // emitSuspendableCalled(mv); min.accept(mv); // we call the yield method if (yieldReturnsValue) mv.visitInsn(Opcodes.POP); // we ignore the returned value... mv.visitLabel(lMethodCalls[i - 1]); // we resume AFTER the call final Label afterPostRestore = new Label(); mv.visitVarInsn(Opcodes.ILOAD, lvarResumed); mv.visitJumpInsn(Opcodes.IFEQ, afterPostRestore); emitPostRestore(mv); mv.visitLabel(afterPostRestore); emitRestoreState(mv, i, fi, numYieldArgs); if (yieldReturnsValue) mv.visitVarInsn(Opcodes.ILOAD, lvarResumed); // ... and replace the returned value with the value of resumed dumpCodeBlock(mv, i, 1); // skip the call } else { final Label lbl = new Label(); if (DUAL) { mv.visitVarInsn(Opcodes.ALOAD, lvarStack); mv.visitJumpInsn(Opcodes.IFNULL, lbl); } // normal case - call to a suspendable method - resume before the call emitStoreState(mv, i, fi, 0); emitStoreResumed(mv, false); // we have not been resumed // emitPreemptionPoint(mv, PREEMPTION_CALL); mv.visitLabel(lMethodCalls[i - 1]); emitRestoreState(mv, i, fi, 0); if (DUAL) mv.visitLabel(lbl); if (isReflectInvocation(min.owner, min.name)) { // We catch the InvocationTargetException and unwrap it if it wraps a SuspendExecution exception. Label[] ls = refInvokeTryCatch[i - 1]; final Label startTry = ls[0]; final Label endTry = ls[1]; final Label startCatch = ls[2]; final Label endCatch = new Label(); final Label notSuspendExecution = new Label(); // mv.visitTryCatchBlock(startTry, endTry, startCatch, "java/lang/reflect/InvocationTargetException"); mv.visitLabel(startTry); // try { min.accept(mv); // method.invoke() mv.visitVarInsn(Opcodes.ASTORE, lvarInvocationReturnValue); // save return value mv.visitLabel(endTry); // } mv.visitJumpInsn(Opcodes.GOTO, endCatch); mv.visitLabel(startCatch); // catch(InvocationTargetException ex) { mv.visitInsn(Opcodes.DUP); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Throwable", "getCause", "()Ljava/lang/Throwable;"); mv.visitTypeInsn(Opcodes.INSTANCEOF, EXCEPTION_NAME); mv.visitJumpInsn(Opcodes.IFEQ, notSuspendExecution); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Throwable", "getCause", "()Ljava/lang/Throwable;"); mv.visitLabel(notSuspendExecution); mv.visitInsn(Opcodes.ATHROW); mv.visitLabel(endCatch); mv.visitVarInsn(Opcodes.ALOAD, lvarInvocationReturnValue); // restore return value dumpCodeBlock(mv, i, 1); // skip the call } else { // emitSuspendableCalled(mv); dumpCodeBlock(mv, i, 0); } } } mv.visitLabel(lMethodEnd); if (handleProxyInvocations) { mv.visitLabel(lCatchUTE); mv.visitInsn(Opcodes.DUP); // println(mv, "CTCH: "); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Throwable", "getCause", "()Ljava/lang/Throwable;"); // println(mv, "CAUSE: "); mv.visitTypeInsn(Opcodes.INSTANCEOF, EXCEPTION_NAME); mv.visitJumpInsn(Opcodes.IFEQ, lCatchAll); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Throwable", "getCause", "()Ljava/lang/Throwable;"); mv.visitJumpInsn(Opcodes.GOTO, lCatchSEE); } mv.visitLabel(lCatchAll); emitPopMethod(mv); mv.visitLabel(lCatchSEE); // println(mv, "THROW: "); mv.visitInsn(Opcodes.ATHROW); // rethrow shared between catchAll and catchSSE if (mn.localVariables != null) { for (Object o : mn.localVariables) ((LocalVariableNode) o).accept(mv); } mv.visitMaxs(mn.maxStack + ADD_OPERANDS, mn.maxLocals + NUM_LOCALS + additionalLocals); mv.visitEnd(); }
From source file:co.paralleluniverse.fibers.instrument.InstrumentMethod.java
License:Open Source License
private static void dumpParameterAnnotations(MethodVisitor mv, List[] parameterAnnotations, boolean visible) { for (int i = 0; i < parameterAnnotations.length; i++) { if (parameterAnnotations[i] != null) { for (Object o : parameterAnnotations[i]) { AnnotationNode an = (AnnotationNode) o; an.accept(mv.visitParameterAnnotation(i, an.desc, visible)); }//from www . ja va2 s . c om } } }
From source file:kilim.analysis.ClassWeaver.java
License:Open Source License
private void accept(final ClassVisitor cv) { ClassFlow cf = classFlow;/* www. java 2 s . co m*/ // visits header String[] interfaces = toStringArray(cf.interfaces); cv.visit(cf.version, cf.access, cf.name, cf.signature, cf.superName, interfaces); // visits source if (cf.sourceFile != null || cf.sourceDebug != null) { cv.visitSource(cf.sourceFile, cf.sourceDebug); } // visits outer class if (cf.outerClass != null) { cv.visitOuterClass(cf.outerClass, cf.outerMethod, cf.outerMethodDesc); } // visits attributes and annotations int i, n; AnnotationNode an; n = cf.visibleAnnotations == null ? 0 : cf.visibleAnnotations.size(); for (i = 0; i < n; ++i) { an = (AnnotationNode) cf.visibleAnnotations.get(i); an.accept(cv.visitAnnotation(an.desc, true)); } n = cf.invisibleAnnotations == null ? 0 : cf.invisibleAnnotations.size(); for (i = 0; i < n; ++i) { an = (AnnotationNode) cf.invisibleAnnotations.get(i); an.accept(cv.visitAnnotation(an.desc, false)); } n = cf.attrs == null ? 0 : cf.attrs.size(); for (i = 0; i < n; ++i) { cv.visitAttribute((Attribute) cf.attrs.get(i)); } // visits inner classes for (i = 0; i < cf.innerClasses.size(); ++i) { ((InnerClassNode) cf.innerClasses.get(i)).accept(cv); } // visits fields for (i = 0; i < cf.fields.size(); ++i) { ((FieldNode) cf.fields.get(i)).accept(cv); } /* * Mark this class as "processed" by adding a dummy field, so that * we don't weave an already woven file */ cv.visitField(ACC_PUBLIC | ACC_STATIC | ACC_FINAL, WOVEN_FIELD, "Z", "Z", Boolean.TRUE); // visits methods for (i = 0; i < cf.methods.size(); ++i) { MethodFlow m = (MethodFlow) cf.methods.get(i); if (needsWeaving(m)) { MethodWeaver mw = new MethodWeaver(this, m); mw.accept(cv); mw.makeNotWovenMethod(cv, m); } else { m.accept(cv); } } // visits end cv.visitEnd(); }
From source file:kilim.analysis.MethodFlow.java
License:Open Source License
@Override /**//from w w w .j ava 2 s . c om * Copied verbatim from MethodNode except for the instruction processing. * Unlike MethodNode, we don't keep LabelNodes inline, so we need to * do visitLabel ourselves. * * @param mv a method visitor. */ public void accept(final MethodVisitor mv) { // visits the method attributes int i, j, n; if (annotationDefault != null) { AnnotationVisitor av = mv.visitAnnotationDefault(); acceptAnnotation(av, null, annotationDefault); av.visitEnd(); } n = visibleAnnotations == null ? 0 : visibleAnnotations.size(); for (i = 0; i < n; ++i) { AnnotationNode an = (AnnotationNode) visibleAnnotations.get(i); an.accept(mv.visitAnnotation(an.desc, true)); } n = invisibleAnnotations == null ? 0 : invisibleAnnotations.size(); for (i = 0; i < n; ++i) { AnnotationNode an = (AnnotationNode) invisibleAnnotations.get(i); an.accept(mv.visitAnnotation(an.desc, false)); } n = visibleParameterAnnotations == null ? 0 : visibleParameterAnnotations.length; for (i = 0; i < n; ++i) { List<?> l = visibleParameterAnnotations[i]; if (l == null) { continue; } for (j = 0; j < l.size(); ++j) { AnnotationNode an = (AnnotationNode) l.get(j); an.accept(mv.visitParameterAnnotation(i, an.desc, true)); } } n = invisibleParameterAnnotations == null ? 0 : invisibleParameterAnnotations.length; for (i = 0; i < n; ++i) { List<?> l = invisibleParameterAnnotations[i]; if (l == null) { continue; } for (j = 0; j < l.size(); ++j) { AnnotationNode an = (AnnotationNode) l.get(j); an.accept(mv.visitParameterAnnotation(i, an.desc, false)); } } n = attrs == null ? 0 : attrs.size(); for (i = 0; i < n; ++i) { mv.visitAttribute((Attribute) attrs.get(i)); } // visits the method's code if (instructions.size() > 0) { mv.visitCode(); // visits try catch blocks for (i = 0; i < tryCatchBlocks.size(); ++i) { ((TryCatchBlockNode) tryCatchBlocks.get(i)).accept(mv); } // visits instructions for (i = 0; i < instructions.size(); ++i) { Label l = getLabelAt(i); if (l != null) { mv.visitLabel(l); } ((AbstractInsnNode) instructions.get(i)).accept(mv); } Label l = getLabelAt(instructions.size()); if (l != null) { mv.visitLabel(l); } // visits local variables n = localVariables == null ? 0 : localVariables.size(); for (i = 0; i < n; ++i) { ((LocalVariableNode) localVariables.get(i)).accept(mv); } // visits line numbers /* TODO this was in ASM 2.3.3 but not 3.x or 4.0, find a substitute or remove n = lineNumbers == null ? 0 : lineNumbers.size(); for (i = 0; i < n; ++i) { ((LineNumberNode) lineNumbers.get(i)).accept(mv); } */ // visits maxs mv.visitMaxs(maxStack, maxLocals); } mv.visitEnd(); }
From source file:kilim.analysis.MethodFlow.java
License:Open Source License
public static void acceptAnnotation(final AnnotationVisitor av, final String name, final Object value) { if (value instanceof String[]) { String[] typeconst = (String[]) value; av.visitEnum(name, typeconst[0], typeconst[1]); } else if (value instanceof AnnotationNode) { AnnotationNode an = (AnnotationNode) value; an.accept(av.visitAnnotation(name, an.desc)); } else if (value instanceof List<?>) { AnnotationVisitor v = av.visitArray(name); List<?> array = (List<?>) value; for (int j = 0; j < array.size(); ++j) { acceptAnnotation(v, null, array.get(j)); }/* w ww. j a v a2 s. c o m*/ v.visitEnd(); } else { av.visit(name, value); } }
From source file:kilim.analysis.MethodWeaver.java
License:Open Source License
private void visitAttrs(MethodVisitor mv) { MethodFlow mf = methodFlow;//from www . j av a 2s. c o m // visits the method attributes int i, j, n; if (mf.annotationDefault != null) { AnnotationVisitor av = mv.visitAnnotationDefault(); MethodFlow.acceptAnnotation(av, null, mf.annotationDefault); av.visitEnd(); } n = mf.visibleAnnotations == null ? 0 : mf.visibleAnnotations.size(); for (i = 0; i < n; ++i) { AnnotationNode an = (AnnotationNode) mf.visibleAnnotations.get(i); an.accept(mv.visitAnnotation(an.desc, true)); } n = mf.invisibleAnnotations == null ? 0 : mf.invisibleAnnotations.size(); for (i = 0; i < n; ++i) { AnnotationNode an = (AnnotationNode) mf.invisibleAnnotations.get(i); an.accept(mv.visitAnnotation(an.desc, false)); } n = mf.visibleParameterAnnotations == null ? 0 : mf.visibleParameterAnnotations.length; for (i = 0; i < n; ++i) { List<?> l = mf.visibleParameterAnnotations[i]; if (l == null) { continue; } for (j = 0; j < l.size(); ++j) { AnnotationNode an = (AnnotationNode) l.get(j); an.accept(mv.visitParameterAnnotation(i, an.desc, true)); } } n = mf.invisibleParameterAnnotations == null ? 0 : mf.invisibleParameterAnnotations.length; for (i = 0; i < n; ++i) { List<?> l = mf.invisibleParameterAnnotations[i]; if (l == null) { continue; } for (j = 0; j < l.size(); ++j) { AnnotationNode an = (AnnotationNode) l.get(j); an.accept(mv.visitParameterAnnotation(i, an.desc, false)); } } n = mf.attrs == null ? 0 : mf.attrs.size(); for (i = 0; i < n; ++i) { mv.visitAttribute((Attribute) mf.attrs.get(i)); } }
From source file:net.enilink.composition.asm.meta.ClassInfo.java
License:Open Source License
/** * Copies annotations of this class.// ww w . j a v a 2s.c o m * * @param cv * a class visitor. */ public void copyAnnotations(final ClassVisitor cv) { // visits annotations int i, n; n = visibleAnnotations == null ? 0 : visibleAnnotations.size(); for (i = 0; i < n; ++i) { AnnotationNode an = (AnnotationNode) visibleAnnotations.get(i); an.accept(cv.visitAnnotation(an.desc, true)); } n = invisibleAnnotations == null ? 0 : invisibleAnnotations.size(); for (i = 0; i < n; ++i) { AnnotationNode an = (AnnotationNode) invisibleAnnotations.get(i); an.accept(cv.visitAnnotation(an.desc, false)); } }
From source file:org.jephyr.activeobject.instrument.ActiveObjectClassAdapter.java
License:Open Source License
private static void acceptAnnotation(AnnotationVisitor av, String name, Object value) { if (value instanceof String[]) { String[] args = (String[]) value; av.visitEnum(name, args[0], args[1]); } else if (value instanceof AnnotationNode) { AnnotationNode node = (AnnotationNode) value; node.accept(av.visitAnnotation(name, node.desc)); } else if (value instanceof List) { AnnotationVisitor av1 = av.visitArray(name); if (av1 != null) { for (Object value1 : (Iterable<?>) value) { acceptAnnotation(av1, null, value1); }/*from ww w. ja v a 2 s. com*/ av1.visitEnd(); } } else { av.visit(name, value); } }