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

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

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

import static org.objectweb.asm.Opcodes.AASTORE;
import static org.objectweb.asm.Opcodes.ASTORE;
import static org.objectweb.asm.Opcodes.DUP;
import static org.objectweb.asm.Opcodes.ILOAD;
import static org.objectweb.asm.Opcodes.INVOKESTATIC;
import static org.objectweb.asm.Opcodes.ISTORE;

import java.util.Arrays;

import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.InsnList;
import org.objectweb.asm.tree.InsnNode;
import org.objectweb.asm.tree.LdcInsnNode;
import org.objectweb.asm.tree.MethodInsnNode;
import org.objectweb.asm.tree.TypeInsnNode;
import org.objectweb.asm.tree.VarInsnNode;

public class CaptureCall implements SequenceInstruction {

	private MethodInsnNode call;
	private String variableBase;
	private String variableArguments;

	public CaptureCall(MethodInsnNode call, String variableBase, String variableArguments) {
		this.call = call;
		this.variableBase = variableBase;
		this.variableArguments = variableArguments;
	}

	@Override
	public InsnList build(MethodContext context) {
		InsnList insnList = new InsnList();
		
		Type ownerType = Type.getObjectType(call.owner);
		Type methodType = Type.getMethodType(call.desc);
		Type[] argumentTypes = methodType.getArgumentTypes();

		Local base = context.newLocal(variableBase, Type.getType(Object.class));
		if (call.getOpcode() == INVOKESTATIC) {
			insnList.add(new LdcInsnNode(ownerType));
			insnList.add(new VarInsnNode(ASTORE, base.index));
		} else {
			insnList.add(new InsnNode(DUP));
			insnList.add(new VarInsnNode(ASTORE, base.index));
		}
		
		Local[] arguments = Arrays.stream(argumentTypes).map(type -> context.newLocal(type)).toArray(Local[]::new);
		insnList.add(new LdcInsnNode(arguments.length));
		insnList.add(new TypeInsnNode(Opcodes.ANEWARRAY, Type.getInternalName(Object.class)));
		for (int i = 0; i < arguments.length; i++) {
			Local arg = arguments[i];
			insnList.add(new InsnNode(DUP));
			insnList.add(new LdcInsnNode(i));

			insnList.add(new VarInsnNode(arg.type.getOpcode(ILOAD), arg.index));

			insnList.add(new BoxPrimitives(arg.type).build(context));

			insnList.add(new InsnNode(AASTORE));
		}
		Local args = context.newLocal(variableArguments, Type.getType(Object[].class));
		insnList.add(new VarInsnNode(ASTORE, args.index));
		
		for (Local arg : arguments) {
			int storecode = arg.type.getOpcode(ISTORE);
			insnList.insert(new VarInsnNode(storecode, arg.index));
			int loadcode = arg.type.getOpcode(ILOAD);
			insnList.add(new VarInsnNode(loadcode, arg.index));
		}
		
		return insnList;
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy