use of org.objectweb.asm.tree.MethodNode in project groovy by apache.
the class VerifyClass method readClass.
private boolean readClass(String clazz) throws IOException {
ClassNode ca;
try (final InputStream inputStream = new BufferedInputStream(new FileInputStream(clazz))) {
ClassReader cr = new ClassReader(inputStream);
ca = new ClassNode() {
@Override
public void visitEnd() {
// accept(cv);
}
};
cr.accept(new CheckClassAdapter(ca), ClassWriter.COMPUTE_MAXS);
}
boolean failed = false;
List<MethodNode> methods = ca.methods;
for (MethodNode method : methods) {
if (method.instructions.size() > 0) {
Analyzer<?> a = new Analyzer<>(new SimpleVerifier());
try {
a.analyze(ca.name, method);
continue;
} catch (Exception e) {
e.printStackTrace();
}
if (!failed) {
failed = true;
log("verifying of class " + clazz + " failed");
}
if (verbose)
log(method.name + method.desc);
TraceMethodVisitor mv = new TraceMethodVisitor(null);
for (int j = 0; j < method.instructions.size(); ++j) {
AbstractInsnNode insn = method.instructions.get(j);
if (insn != null) {
insn.accept(mv);
} else {
mv.visitLabel(null);
}
}
mv.visitMaxs(method.maxStack, method.maxLocals);
}
}
return !failed;
}
use of org.objectweb.asm.tree.MethodNode in project quasar by puniverse.
the class InstrumentClass method visitMethod.
@Override
public MethodVisitor visitMethod(final int access, final String name, final String desc, final String signature, final String[] exceptions) {
SuspendableType markedSuspendable = null;
if (suspendableInterface)
markedSuspendable = SuspendableType.SUSPENDABLE_SUPER;
if (markedSuspendable == null)
markedSuspendable = classifier.isSuspendable(db, sourceName, sourceDebugInfo, isInterface, className, classEntry.getSuperName(), classEntry.getInterfaces(), name, desc, signature, exceptions);
final SuspendableType setSuspendable = classEntry.check(name, desc);
if (setSuspendable == null)
classEntry.set(name, desc, markedSuspendable != null ? markedSuspendable : SuspendableType.NON_SUSPENDABLE);
final SuspendableType suspendable = max(markedSuspendable, setSuspendable, SuspendableType.NON_SUSPENDABLE);
if (checkAccessForMethodVisitor(access) && !isYieldMethod(className, name)) {
if (methods == null)
methods = new ArrayList<>();
final MethodNode mn = new MethodNode(access, name, desc, signature, exceptions);
return new MethodVisitor(ASMAPI, mn) {
private SuspendableType susp = suspendable;
private boolean commited = false;
@Override
public AnnotationVisitor visitAnnotation(String adesc, boolean visible) {
// look for @Suspendable or @DontInstrument annotation
if (adesc.equals(SUSPENDABLE_DESC))
susp = SuspendableType.SUSPENDABLE;
else if (adesc.equals(DONT_INSTRUMENT_DESC))
susp = SuspendableType.NON_SUSPENDABLE;
susp = suspendableToSuperIfAbstract(access, susp);
return super.visitAnnotation(adesc, visible);
}
@Override
public void visitCode() {
commit();
super.visitCode();
}
@Override
public void visitEnd() {
if (exception != null)
return;
commit();
try {
super.visitEnd();
} catch (RuntimeException e) {
exception = e;
}
}
private void commit() {
if (commited)
return;
commited = true;
if (db.isDebug())
db.log(LogLevel.INFO, "Method %s#%s%s suspendable: %s (markedSuspendable: %s setSuspendable: %s)", className, name, desc, susp, susp, setSuspendable);
classEntry.set(name, desc, susp);
if (susp == SuspendableType.SUSPENDABLE && checkAccessForMethodInstrumentation(access)) {
if (isSynchronized(access)) {
if (!db.isAllowMonitors())
throw new UnableToInstrumentException("synchronization", className, name, desc);
else
db.log(LogLevel.WARNING, "Method %s#%s%s is synchronized", className, name, desc);
}
methods.add(mn);
} else {
MethodVisitor _mv = makeOutMV(mn);
_mv = new JSRInlinerAdapter(_mv, access, name, desc, signature, exceptions);
mn.accept(new MethodVisitor(ASMAPI, _mv) {
@Override
public void visitEnd() {
// don't call visitEnd on MV
}
});
// write method as-is
this.mv = _mv;
}
}
};
}
return super.visitMethod(access, name, desc, signature, exceptions);
}
use of org.objectweb.asm.tree.MethodNode in project quasar by puniverse.
the class OldSuspendablesScanner method findSuperDeclarations.
private boolean findSuperDeclarations(ClassNode cls, ClassNode declaringClass, MethodNode method) throws IOException {
if (cls == null)
return false;
boolean foundMethod = false;
MethodNode m;
if ((m = getMethod(method, cls)) != null) {
foundMethod = true;
if (!ASMUtil.equals(cls, declaringClass) && !isSuspendable(cls, m)) {
log("Found parent of annotated method: " + declaringClass.name + "." + method.name + method.signature + " in " + cls.name, Project.MSG_VERBOSE);
results.add(cls.name.replace('/', '.') + '.' + method.name);
}
}
// recursively look in superclass and interfaces
boolean methodInParent = false;
methodInParent |= findSuperDeclarations(getClassNode(cls.superName, cl, true), declaringClass, method);
for (String iface : (List<String>) cls.interfaces) methodInParent |= findSuperDeclarations(getClassNode(iface, cl, true), declaringClass, method);
if (!foundMethod && methodInParent) {
log("Found parent of annotated method in a parent of: " + declaringClass.name + "." + method.name + method.signature + " in " + cls.name, Project.MSG_VERBOSE);
results.add(cls.name.replace('/', '.') + '.' + method.name);
}
return foundMethod | methodInParent;
}
use of org.objectweb.asm.tree.MethodNode in project quasar by puniverse.
the class SuspOffsetsAfterInstrClassVisitor method visitMethod.
@Override
public MethodVisitor visitMethod(final int access, final String name, final String desc, final String signature, final String[] exceptions) {
if ((access & Opcodes.ACC_NATIVE) == 0 && !isYieldMethod(className, name)) {
// Bytecode-level AST of a method, being a MethodVisitor itself can be filled through delegation from another visitor
final MethodNode mn = new MethodNode(access, name, desc, signature, exceptions);
// Analyze, fill and enqueue method ASTs
final MethodVisitor outMV = super.visitMethod(access, name, desc, signature, exceptions);
return new MethodVisitor(ASMAPI, outMV) {
private Label currLabel = null;
private int prevOffset = -1;
private boolean instrumented;
private boolean optimized = false;
private int methodStart = -1, methodEnd = -1;
private int[] suspCallSites = new int[0];
private String[] suspCallSiteNames = new String[0];
private List<Integer> suspOffsetsAfterInstrL = new ArrayList<>();
@Override
public AnnotationVisitor visitAnnotation(final String adesc, boolean visible) {
if (Classes.INSTRUMENTED_DESC.equals(adesc)) {
instrumented = true;
return new // Only collect info
AnnotationVisitor(// Only collect info
ASMAPI) {
@Override
public void visit(String attrib, Object value) {
if (null != attrib)
switch(attrib) {
case Instrumented.FIELD_NAME_METHOD_START:
methodStart = (Integer) value;
break;
case Instrumented.FIELD_NAME_METHOD_END:
methodEnd = (Integer) value;
break;
case Instrumented.FIELD_NAME_METHOD_OPTIMIZED:
optimized = (Boolean) value;
break;
case Instrumented.FIELD_NAME_SUSPENDABLE_CALL_SITES:
suspCallSites = (int[]) value;
break;
case Instrumented.FIELD_NAME_SUSPENDABLE_CALL_SITES_OFFSETS_AFTER_INSTR:
// Ignore, we're filling it
;
break;
default:
throw new RuntimeException("Unexpected `@Instrumented` field: " + attrib);
}
}
@Override
public AnnotationVisitor visitArray(String attrib) {
// String[] value not handled by visit
if (Instrumented.FIELD_NAME_SUSPENDABLE_CALL_SITE_NAMES.equals(attrib))
return new AnnotationVisitor(ASMAPI) {
List<String> callSites = new ArrayList<>();
@Override
public void visit(String attrib, Object value) {
callSites.add((String) value);
}
@Override
public void visitEnd() {
suspCallSiteNames = callSites.toArray(new String[0]);
}
};
else
return super.visitArray(name);
}
};
}
return super.visitAnnotation(adesc, visible);
}
@Override
public void visitLocalVariable(String name, String desc, String sig, Label lStart, Label lEnd, int slot) {
super.visitLocalVariable(name, desc, sig, lStart, lEnd, slot);
}
@Override
public void visitLabel(Label label) {
if (instrumented) {
currLabel = label;
}
super.visitLabel(label);
}
@Override
public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean isInterface) {
if (instrumented) {
final int type = AbstractInsnNode.METHOD_INSN;
if (InstrumentMethod.isSuspendableCall(db, type, opcode, owner, name, desc) && // postRestore
!Classes.STACK_NAME.equals(owner) && currLabel != null && currLabel.info instanceof Integer)
addLine();
}
super.visitMethodInsn(opcode, owner, name, desc, isInterface);
}
@Override
public void visitInvokeDynamicInsn(String name, String desc, Handle handle, Object... objects) {
if (instrumented) {
final int type = AbstractInsnNode.INVOKE_DYNAMIC_INSN;
final int opcode = Opcodes.INVOKEDYNAMIC;
if (InstrumentMethod.isSuspendableCall(db, type, opcode, handle.getOwner(), name, desc) && // postRestore
!Classes.STACK_NAME.equals(handle.getOwner()) && currLabel != null && currLabel.info instanceof Integer)
addLine();
}
super.visitInvokeDynamicInsn(name, desc, handle, objects);
}
@Override
public void visitEnd() {
if (instrumented)
InstrumentMethod.emitInstrumentedAnn(db, outMV, mn, sourceName, className, optimized, methodStart, methodEnd, suspCallSites, suspCallSiteNames, toIntArray(suspOffsetsAfterInstrL));
super.visitEnd();
}
private void addLine() {
final int currOffset = (Integer) currLabel.info;
if (currOffset > prevOffset) {
suspOffsetsAfterInstrL.add(currOffset);
prevOffset = currOffset;
}
}
};
}
return super.visitMethod(access, name, desc, signature, exceptions);
}
use of org.objectweb.asm.tree.MethodNode in project spring-loaded by spring-projects.
the class SpringLoadedTests method checkAnnotations.
@SuppressWarnings("unchecked")
protected void checkAnnotations(byte[] bytes, String methodNameAndDescriptor, String... expected) {
ClassNode cn = new ClassNode();
ClassReader cr = new ClassReader(bytes);
cr.accept(cn, 0);
if (expected == null) {
expected = new String[0];
}
boolean checked = false;
List<MethodNode> methods = cn.methods;
for (MethodNode mn : methods) {
if (methodNameAndDescriptor.equals(mn.name + mn.desc)) {
List<AnnotationNode> annotations = mn.visibleAnnotations;
if (annotations == null) {
annotations = Collections.emptyList();
}
Assert.assertEquals(expected.length, annotations.size());
for (int i = 0; i < expected.length; i++) {
// StringTokenizer tokenizer = new StringTokenizer(expected[i], ":");
// String expectedName = tokenizer.nextToken();
// String expectedDesc = tokenizer.nextToken();
AnnotationNode annotation = annotations.get(i);
Assert.assertEquals(expected[i], toString(annotation));
}
checked = true;
}
}
if (!checked) {
for (MethodNode mn : methods) {
System.out.println(mn.name + mn.desc);
}
Assert.fail("Unable to find method " + methodNameAndDescriptor);
}
}
Aggregations