/** * For each method in the class being instrumented, <code>visitMethod</code> * is called and the returned MethodVisitor is used to visit the method. * Note that a new MethodVisitor is constructed for each method. */ @Override public MethodVisitor visitMethod(int access, String base, String desc, String signature, String[] exceptions) { MethodVisitor mv = cv.visitMethod(access, base, desc, signature, exceptions); if (mv != null) { // We need to compute stackmaps (see // AllocationInstrumenter#instrument). This can't really be // done for old bytecode that contains JSR and RET instructions. // So, we remove JSRs and RETs. JSRInlinerAdapter jsria = new JSRInlinerAdapter( mv, access, base, desc, signature, exceptions); AllocationMethodAdapter aimv = new AllocationMethodAdapter(jsria, recorderClass, recorderMethod); LocalVariablesSorter lvs = new LocalVariablesSorter(access, desc, aimv); aimv.lvs = lvs; mv = lvs; } return mv; }
private void generateTraverseMethod() { LocalVariablesSorter mv = new LocalVariablesSorter( TRAVERSE_METHOD_ACC_FLAGS, TRAVERSE_METHOD_DESC, this.visitMethod( this.getTraverseMethodAccess(), this.getTraverseMethodName(), TRAVERSE_METHOD_DESC, null, null)); mv.visitCode(); if (isAllowed(this.thisClass.getFqn())) { this.generateTraverseMethodPreamble(mv); if (!this.fields.isEmpty()) { for (Pair<String, String> field : this.fields) { this.generateFieldAccess(mv, field); } } } mv.visitInsn(RETURN); mv.visitMaxs(0, 0); mv.visitEnd(); }
/** * For each method in the class being instrumented, * <code>visitMethod</code> is called and the returned * MethodVisitor is used to visit the method. Note that a new * MethodVisitor is constructed for each method. */ @Override public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { MethodVisitor mv = cv.visitMethod(access, name, desc, signature, exceptions); if ((mv != null) && "<init>".equals(name)){ ConstructorMethodAdapter aimv = new ConstructorMethodAdapter(mv, cl); LocalVariablesSorter lvs = new LocalVariablesSorter(access, desc, aimv); aimv.lvs = lvs; mv = lvs; } return mv; }
private static ArrayList<Integer> newLocalVarsFromTypes( ArrayList<Type> types, LocalVariablesSorter lvs) { ArrayList<Integer> vars = new ArrayList<Integer>(); for (Type type : types) { vars.add(lvs.newLocal(type)); } return vars; }
protected void generateFieldAccess(LocalVariablesSorter mv, Pair<String, String> field) { Type fieldType = Type.getType(field.getValue1()); if (!isAllowed(fieldType.getClassName())) { return; } this.getFieldOwner(mv); mv.visitInsn(DUP); mv.visitFieldInsn( GETFIELD, this.thisClass.getASMType().getInternalName(), field.getValue0(), field.getValue1()); mv.visitMethodInsn( INVOKESTATIC, REGISTER_METHOD_OWNER_NAME, REGISTER_METHOD_NAME, REGISTER_METHOD_SIMPLE_DESC, false); if (this.version != null) { mv.visitTypeInsn(CHECKCAST, this.version.eraseUpdatableType(this.namespace.getClass(fieldType)).getASMType().getInternalName()); } else { mv.visitTypeInsn(CHECKCAST, fieldType.getInternalName()); } mv.visitFieldInsn( PUTFIELD, this.thisClass.getASMType().getInternalName(), field.getValue0(), field.getValue1()); }
@Override public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { MethodVisitor mv = cv.visitMethod(access, name, desc, signature, exceptions); return methods == null || methods.contains(new ObfMapping(owner, name, desc)) ? new LocalVariablesSorter(access, desc, mv) : mv; }
public InliningAdapter(LocalVariablesSorter mv, int access, String desc, Label end) { super(Opcodes.ASM5, access, desc, mv); this.end = end; this.lvs = mv; }
public LocalVarsSaver(MethodVisitor mv, LocalVariablesSorter lvs) { this.mv = mv; this.lvs = lvs; }
public void setLocalVarsSorter(LocalVariablesSorter lvs) { localVarsSorter = lvs; }
@Override public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { if (name.equals(ProcessUpdateClass.METHOD_NAME) || name.equals(ProcessUpdateClass.METHOD_NAME_STATIC)) return this.cv.visitMethod(access, name, desc, signature, exceptions); MethodVisitor ret = new MethodVisitor(ASM5) { }; if (Modifier.isStatic(access)) return ret; LocalVariablesSorter mv = new LocalVariablesSorter( access, desc, this.cv.visitMethod(METHOD_ACCESS, name, desc, signature, exceptions)); String ownerName = this.owner.getASMType().getInternalName(); int newObjectVar = mv.newLocal(OBJECT_TYPE.getASMType()); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn( INVOKESTATIC, RUBAH_TYPE.getInternalName(), "getConverted", Type.getMethodDescriptor(OBJECT_TYPE, OBJECT_TYPE), false); mv.visitTypeInsn(CHECKCAST, ownerName); int arg = 1; for (Type t : Type.getArgumentTypes(desc)) { mv.visitVarInsn(t.getOpcode(ILOAD), arg); arg += t.getSize(); } mv.visitMethodInsn( INVOKEVIRTUAL, ownerName, name, desc, false); mv.visitInsn(Type.getReturnType(desc).getOpcode(IRETURN)); mv.visitMaxs(0, 0); mv.visitEnd(); return ret; }
@Test @SuppressWarnings("unchecked") public void testReaderHint() throws Exception { AsmVisitorWrapper asmVisitorWrapper = mock(AsmVisitorWrapper.class); when(asmVisitorWrapper.wrap(any(TypeDescription.class), any(ClassVisitor.class), any(Implementation.Context.class), any(TypePool.class), any(FieldList.class), any(MethodList.class), anyInt(), anyInt())).then(new Answer<ClassVisitor>() { @Override public ClassVisitor answer(InvocationOnMock invocationOnMock) throws Throwable { return new ClassVisitor(Opcodes.ASM6, (ClassVisitor) invocationOnMock.getArguments()[1]) { @Override public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { return new LocalVariablesSorter(access, desc, super.visitMethod(access, name, desc, signature, exceptions)); } }; } }); when(asmVisitorWrapper.mergeWriter(0)).thenReturn(ClassWriter.COMPUTE_MAXS); when(asmVisitorWrapper.mergeReader(0)).thenReturn(ClassReader.EXPAND_FRAMES); Class<?> type = create(StackMapFrames.class) .visit(asmVisitorWrapper) .make() .load(ClassLoadingStrategy.BOOTSTRAP_LOADER, ClassLoadingStrategy.Default.WRAPPER) .getLoaded(); assertThat(type.getDeclaredMethod(FOO).invoke(type.getDeclaredConstructor().newInstance()), is((Object) BAR)); verify(asmVisitorWrapper).mergeWriter(0); verify(asmVisitorWrapper).mergeReader(0); verify(asmVisitorWrapper).wrap(any(TypeDescription.class), any(ClassVisitor.class), any(Implementation.Context.class), any(TypePool.class), any(FieldList.class), any(MethodList.class), anyInt(), anyInt()); verifyNoMoreInteractions(asmVisitorWrapper); }