All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.amygdalum.testrecorder.asm.WrapMethod Maven / Gradle / Ivy

The newest version!
package net.amygdalum.testrecorder.asm;

import static org.objectweb.asm.Opcodes.GOTO;
import static org.objectweb.asm.Opcodes.IRETURN;
import static org.objectweb.asm.Opcodes.RETURN;

import java.util.ListIterator;

import org.objectweb.asm.Type;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.InsnList;
import org.objectweb.asm.tree.InsnNode;
import org.objectweb.asm.tree.JumpInsnNode;
import org.objectweb.asm.tree.LabelNode;

public class WrapMethod implements SequenceInstruction {

	private LabelNode returnLabel;

	private SequenceInstruction prependInstructions;
	private SequenceInstruction appendInstructions;

	public WrapMethod() {
		this.prependInstructions = Nop.NOP;
		this.appendInstructions = Nop.NOP;
	}

	public WrapMethod prepend(SequenceInstruction prependInstructions) {
		this.prependInstructions = prependInstructions;
		return this;
	}

	public WrapMethod append(SequenceInstruction appendInstructions) {
		this.appendInstructions = appendInstructions;
		if (appendInstructions != Nop.NOP) {
			this.returnLabel = new LabelNode();
		}
		return this;
	}

	@Override
	public InsnList build(MethodContext context) {
		Type returnType = context.getResultType();

		InsnList insnList = new InsnList();

		insnList.add(prependInstructions.build(context));

		ListIterator instructions = context.instructions().iterator();
		while (instructions.hasNext()) {
			AbstractInsnNode insn = instructions.next();
			if (returnLabel != null && isReturn(insn)) {
				insnList.add(new JumpInsnNode(GOTO, returnLabel));
			} else {
				insnList.add(insn);
			}
		}

		if (returnLabel != null) {
			insnList.add(returnLabel);

			insnList.add(appendInstructions.build(context));

			insnList.add(new InsnNode(returnType.getOpcode(IRETURN)));
		}

		return insnList;
	}

	private boolean isReturn(AbstractInsnNode insn) {
		return IRETURN <= insn.getOpcode() && insn.getOpcode() <= RETURN;
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy