/* * Copyright 2008 Wishnu Prasetya. * * This file is part of T2. * T2 is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License (GPL) as published by the * Free Software Foundation; either version 3 of the License, or any * later version. * * T2 is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * A copy of the GNU General Public License can be found in T2 distribution. * If it is missing, see http://www.gnu.org/licenses. */ package t2ext.bcel.utils; import com.sun.org.apache.bcel.internal.Constants; import com.sun.org.apache.bcel.internal.generic.ClassGen; import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen; import com.sun.org.apache.bcel.internal.generic.InstructionFactory; import com.sun.org.apache.bcel.internal.generic.InstructionList; import com.sun.org.apache.bcel.internal.generic.MethodGen; import com.sun.org.apache.bcel.internal.generic.Type; /** * @author Maaike Gerritsen */ public class MethodCallInsertion { private ClassGen _classGen; public MethodCallInsertion(ClassGen cGen){ _classGen = cGen; } public MethodGen addCode(String methodName) { InstructionList il = new InstructionList(); String random = methodName + getRandomNr(); ConstantPoolGen pgen = _classGen.getConstantPool(); MethodGen methodGen = new MethodGen(com.sun.org.apache.bcel.internal.Constants.ACC_PUBLIC, Type.VOID, Type.NO_ARGS, new String[] {}, random, _classGen.getClassName(), il, pgen); // InstructionFactory fact = new InstructionFactory(_classGen); // il.append(fact.createPrintln(random)); il.append(InstructionFactory.createReturn(Type.VOID)); methodGen.setInstructionList(il); methodGen.stripAttributes(true); methodGen.setMaxStack(); methodGen.setMaxLocals(); _classGen.addMethod(methodGen.getMethod()); return methodGen; } public InstructionList callMethod(String methodName) { InstructionFactory ifact = new InstructionFactory(_classGen); InstructionList ilist = new InstructionList(); MethodGen methgen = addCode(methodName); Type result = methgen.getReturnType(); // compute the size of the calling parameters Type[] types = methgen.getArgumentTypes(); int slot = methgen.isStatic() ? 0 : 1; for (int i = 0; i < types.length; i++) { slot += types[i].getSize(); } // call the wrapped method int offset = 0; short invoke = Constants.INVOKESTATIC; if (!methgen.isStatic()) { ilist.append(InstructionFactory.createLoad(Type.OBJECT, 0)); offset = 1; invoke = Constants.INVOKEVIRTUAL; } for (int i = 0; i < types.length; i++) { Type type = types[i]; ilist.append(InstructionFactory.createLoad(type, offset)); offset += type.getSize(); } ilist.append(ifact.createInvoke(_classGen.getClassName(), methgen .getMethod().getName(), result, types, invoke)); // store result for return later if (result != Type.VOID) { ilist.append(InstructionFactory.createStore(result, slot + 2)); } return ilist; } protected String getRandomNr() { Double nr = Math.random(); String nrS = nr.toString(); nrS = nrS.replace(".", ":"); String[] array = nrS.split(":"); nrS = array[1]; nrS = nrS.substring(0, 5); return nrS; } }