move around some utility methods
git-svn-id: https://wala.svn.sourceforge.net/svnroot/wala/trunk@3810 f5eafffb-2e1d-0410-98e4-8ec43c5233c4
This commit is contained in:
parent
f35d4de0d8
commit
c1860e180c
|
@ -10,6 +10,7 @@
|
|||
*******************************************************************************/
|
||||
package com.ibm.wala.shrikeBT;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
|
||||
|
@ -40,6 +41,24 @@ public final class MethodData {
|
|||
|
||||
private boolean hasChanged = false;
|
||||
|
||||
/**
|
||||
* Create information for a method, with no exception handlers and a dummy mapping of instructions to original bytecodes.
|
||||
* @param access the access flags
|
||||
* @param classType the class in which the method is defined, in JVM type format (e.g., Ljava/lang/Object;)
|
||||
* @param name the method name
|
||||
* @param signature the method signature, in JVM type format (e.g., (ILjava/lang/Object;)V)
|
||||
* @param instructions the instructions making up the method
|
||||
*/
|
||||
public static MethodData makeWithDefaultHandlersAndInstToBytecodes(int access, String classType, String name, String signature, IInstruction[] instructions) {
|
||||
ExceptionHandler[][] handlers = new ExceptionHandler[instructions.length][];
|
||||
Arrays.fill(handlers, new ExceptionHandler[0]);
|
||||
int[] i2b = new int[instructions.length];
|
||||
for (int i = 0; i < i2b.length; i++) {
|
||||
i2b[i] = i;
|
||||
}
|
||||
return new MethodData(access, classType, name, signature, instructions, handlers, i2b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gather the information for a method "from scratch".
|
||||
*
|
||||
|
|
|
@ -11,9 +11,14 @@
|
|||
package com.ibm.wala.shrikeBT.shrikeCT;
|
||||
|
||||
import com.ibm.wala.shrikeBT.Constants;
|
||||
import com.ibm.wala.shrikeBT.MethodData;
|
||||
import com.ibm.wala.shrikeBT.analysis.ClassHierarchyStore;
|
||||
import com.ibm.wala.shrikeCT.ClassReader;
|
||||
import com.ibm.wala.shrikeCT.ClassWriter;
|
||||
import com.ibm.wala.shrikeCT.CodeWriter;
|
||||
import com.ibm.wala.shrikeCT.InvalidClassFileException;
|
||||
import com.ibm.wala.shrikeCT.LineNumberTableWriter;
|
||||
import com.ibm.wala.shrikeCT.ClassWriter.Element;
|
||||
|
||||
/**
|
||||
* This is a dumping ground for useful functions that manipulate class info.
|
||||
|
@ -38,4 +43,52 @@ public class CTUtils {
|
|||
.getAccessFlags() & Constants.ACC_FINAL) != 0, superName != null ? CTDecoder.convertClassToType(superName) : null,
|
||||
superInterfaces);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile and add a method to a {@link ClassWriter}.
|
||||
*
|
||||
* @param md the method data
|
||||
* @param classWriter the target class writer
|
||||
* @param rawLines line number information if available, otherwise <code>null</code>
|
||||
*/
|
||||
public static void compileAndAddMethodToClassWriter(MethodData md, ClassWriter classWriter, ClassWriter.Element rawLines) {
|
||||
if (classWriter == null) {
|
||||
throw new IllegalArgumentException("classWriter is null");
|
||||
}
|
||||
if (md == null) {
|
||||
throw new IllegalArgumentException("md is null");
|
||||
}
|
||||
CTCompiler compiler = CTCompiler.make(classWriter, md);
|
||||
compiler.compile();
|
||||
CTCompiler.Output output = compiler.getOutput();
|
||||
CodeWriter code = new CodeWriter(classWriter);
|
||||
code.setMaxStack(output.getMaxStack());
|
||||
code.setMaxLocals(output.getMaxLocals());
|
||||
code.setCode(output.getCode());
|
||||
code.setRawHandlers(output.getRawHandlers());
|
||||
|
||||
LineNumberTableWriter lines = null;
|
||||
// I guess it is the line numbers in the java files.
|
||||
if (rawLines == null) {
|
||||
// add fake line numbers: just map each bytecode instruction to its own
|
||||
// 'line'
|
||||
|
||||
// NOTE:Should not use md.getInstructions().length, because the
|
||||
// the length of the created code can be smaller than the md's instruction
|
||||
// length
|
||||
|
||||
// WRONG: int[] newLineMap = new int[md.getInstructions().length];
|
||||
int[] newLineMap = new int[code.getCodeLength()];
|
||||
for (int i = 0; i < newLineMap.length; i++) {
|
||||
newLineMap[i] = i;
|
||||
}
|
||||
int[] rawTable = LineNumberTableWriter.makeRawTable(newLineMap);
|
||||
lines = new LineNumberTableWriter(classWriter);
|
||||
lines.setRawTable(rawTable);
|
||||
}
|
||||
code.setAttributes(new ClassWriter.Element[] { rawLines == null ? lines : rawLines });
|
||||
Element[] elements = { code };
|
||||
// System.out.println("Name:"+md.getName()+" Sig:"+md.getSignature());
|
||||
classWriter.addMethod(md.getAccess(), md.getName(), md.getSignature(), elements);
|
||||
}
|
||||
}
|
|
@ -10,7 +10,6 @@
|
|||
*******************************************************************************/
|
||||
package com.ibm.wala.shrikeBT.shrikeCT;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
||||
import com.ibm.wala.shrikeBT.Compiler;
|
||||
|
@ -32,7 +31,6 @@ import com.ibm.wala.shrikeCT.LineNumberTableReader;
|
|||
import com.ibm.wala.shrikeCT.LineNumberTableWriter;
|
||||
import com.ibm.wala.shrikeCT.LocalVariableTableReader;
|
||||
import com.ibm.wala.shrikeCT.LocalVariableTableWriter;
|
||||
import com.ibm.wala.shrikeCT.ClassWriter.Element;
|
||||
|
||||
/**
|
||||
* This class provides a convenient way to instrument every method in a class. It assumes you are using ShrikeCT to read and write
|
||||
|
@ -162,103 +160,6 @@ final public class ClassInstrumenter {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Xiangyu
|
||||
*
|
||||
* @throws IllegalArgumentException if classWriter is null
|
||||
* @throws IllegalArgumentException if instructions is null
|
||||
*
|
||||
*
|
||||
*/
|
||||
public void newMethod(String name, String sig, ArrayList<Instruction> instructions, int access, ClassWriter classWriter,
|
||||
ClassWriter.Element rawLines) {
|
||||
if (instructions == null) {
|
||||
throw new IllegalArgumentException("instructions is null");
|
||||
}
|
||||
if (classWriter == null) {
|
||||
throw new IllegalArgumentException("classWriter is null");
|
||||
}
|
||||
Instruction[] ins = instructions.toArray(new Instruction[instructions.size()]);
|
||||
ExceptionHandler[][] handlers = new ExceptionHandler[ins.length][];
|
||||
Arrays.fill(handlers, noHandlers);
|
||||
int[] i2b = new int[ins.length];
|
||||
for (int i = 0; i < i2b.length; i++) {
|
||||
i2b[i] = i;
|
||||
}
|
||||
MethodData md = null;
|
||||
try {
|
||||
md = new MethodData(access, Util.makeType(cr.getName()), name, sig, ins, handlers, i2b);
|
||||
} catch (InvalidClassFileException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
CTCompiler compiler = CTCompiler.make(classWriter, md);
|
||||
compiler.compile();
|
||||
CTCompiler.Output output = compiler.getOutput();
|
||||
CodeWriter code = new CodeWriter(classWriter);
|
||||
code.setMaxStack(output.getMaxStack());
|
||||
code.setMaxLocals(output.getMaxLocals());
|
||||
code.setCode(output.getCode());
|
||||
code.setRawHandlers(output.getRawHandlers());
|
||||
|
||||
LineNumberTableWriter lines = null;
|
||||
// I guess it is the line numbers in the java files.
|
||||
if (rawLines == null) {
|
||||
// add fake line numbers: just map each bytecode instruction to its own
|
||||
// 'line'
|
||||
int[] newLineMap = new int[instructions.size()];
|
||||
for (int i = 0; i < newLineMap.length; i++) {
|
||||
newLineMap[i] = i;
|
||||
}
|
||||
int[] rawTable = LineNumberTableWriter.makeRawTable(newLineMap);
|
||||
lines = new LineNumberTableWriter(classWriter);
|
||||
lines.setRawTable(rawTable);
|
||||
}
|
||||
code.setAttributes(new ClassWriter.Element[] { rawLines == null ? lines : rawLines });
|
||||
Element[] elements = { code };
|
||||
classWriter.addMethod(access, name, sig, elements);
|
||||
}
|
||||
|
||||
public void newMethod(MethodData md, ClassWriter classWriter, ClassWriter.Element rawLines) {
|
||||
if (classWriter == null) {
|
||||
throw new IllegalArgumentException("classWriter is null");
|
||||
}
|
||||
if (md == null) {
|
||||
throw new IllegalArgumentException("md is null");
|
||||
}
|
||||
CTCompiler compiler = CTCompiler.make(classWriter, md);
|
||||
compiler.compile();
|
||||
CTCompiler.Output output = compiler.getOutput();
|
||||
CodeWriter code = new CodeWriter(classWriter);
|
||||
code.setMaxStack(output.getMaxStack());
|
||||
code.setMaxLocals(output.getMaxLocals());
|
||||
code.setCode(output.getCode());
|
||||
code.setRawHandlers(output.getRawHandlers());
|
||||
|
||||
LineNumberTableWriter lines = null;
|
||||
// I guess it is the line numbers in the java files.
|
||||
if (rawLines == null) {
|
||||
// add fake line numbers: just map each bytecode instruction to its own
|
||||
// 'line'
|
||||
|
||||
// NOTE:Should not use md.getInstructions().length, because the
|
||||
// the length of the created code can be smaller than the md's instruction
|
||||
// length
|
||||
|
||||
// WRONG: int[] newLineMap = new int[md.getInstructions().length];
|
||||
int[] newLineMap = new int[code.getCodeLength()];
|
||||
for (int i = 0; i < newLineMap.length; i++) {
|
||||
newLineMap[i] = i;
|
||||
}
|
||||
int[] rawTable = LineNumberTableWriter.makeRawTable(newLineMap);
|
||||
lines = new LineNumberTableWriter(classWriter);
|
||||
lines.setRawTable(rawTable);
|
||||
}
|
||||
code.setAttributes(new ClassWriter.Element[] { rawLines == null ? lines : rawLines });
|
||||
Element[] elements = { code };
|
||||
// System.out.println("Name:"+md.getName()+" Sig:"+md.getSignature());
|
||||
classWriter.addMethod(md.getAccess(), md.getName(), md.getSignature(), elements);
|
||||
}
|
||||
|
||||
/**
|
||||
* Do something to every method in the class. This will visit all methods, including those already marked for deletion.
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue