package fr.inria.diversify.transformation.bytecode; import fr.inria.diversify.util.Log; import javassist.CtMethod; import javassist.bytecode.BadBytecode; import javassist.bytecode.CodeAttribute; import javassist.bytecode.CodeIterator; import javassist.bytecode.MethodInfo; import org.json.JSONException; import org.json.JSONObject; import java.io.IOException; import java.util.Arrays; import java.util.List; /** * User: Simon * Date: 11/6/13 * Time: 5:28 PM */ public class BytecodeAdd extends BytecodeTransformation { protected byte[] byteCodeToAdd; public BytecodeAdd(CtMethod method, int index, byte[] bytecode, List<CtMethod> methods) { methodLocation = method; opcodeIndex = index; byteCodeToAdd = bytecode; this.methods = methods; name = "add"; type = "adrBytecode"; } public BytecodeAdd() { name = "add"; type = "adrBytecode"; } @Override public JSONObject toJSONObject() throws JSONException { JSONObject object = super.toJSONObject(); object.put("methodLocation", methodLocation.getLongName()); object.put("opcodeIndex",opcodeIndex); object.put("byteCodeToAdd", Arrays.toString(byteCodeToAdd)); return object; } @Override protected void apply() throws BadBytecode { MethodInfo minfo = methodLocation.getMethodInfo(); CodeAttribute ca = minfo.getCodeAttribute(); List<Integer> opCodeIndexList = opCodeIndexList(ca); Log.debug("transformation: {}, {}",type,name); Log.info("add opcode in method {} at index {} (size: {})", methodLocation.getName(), opCodeIndexList.get(opcodeIndex), byteCodeToAdd.length); addOpcode(ca, opCodeIndexList.get(opcodeIndex),byteCodeToAdd); } protected void addOpcode(CodeAttribute ca, int index, byte[] bytecode) throws BadBytecode { CodeIterator i = ca.iterator(); i.insert(index, bytecode); } public void setByteCodeToAdd(byte[] byteCodeToAdd) { this.byteCodeToAdd = byteCodeToAdd; } }