further work on geberating stack maps
This commit is contained in:
parent
4e52c00a4b
commit
63232e4a02
|
@ -42,7 +42,7 @@ public class AddBytecodeDebug {
|
|||
|
||||
public static void main(String[] args) throws Exception {
|
||||
for (int i = 0; i < 1; i++) {
|
||||
instrumenter = new OfflineInstrumenter();
|
||||
instrumenter = new OfflineInstrumenter(true);
|
||||
|
||||
Writer w = new BufferedWriter(new FileWriter("report", false));
|
||||
|
||||
|
|
|
@ -61,7 +61,6 @@ public class Bench {
|
|||
|
||||
public static void main(String[] args) throws Exception {
|
||||
for (int i = 0; i < 1; i++) {
|
||||
instrumenter = new OfflineInstrumenter();
|
||||
|
||||
Writer w = new BufferedWriter(new FileWriter("report", false));
|
||||
|
||||
|
@ -74,6 +73,7 @@ public class Bench {
|
|||
doException = true;
|
||||
}
|
||||
}
|
||||
instrumenter = new OfflineInstrumenter(!doException);
|
||||
instrumenter.setPassUnmodifiedClasses(true);
|
||||
instrumenter.beginTraversal();
|
||||
ClassInstrumenter ci;
|
||||
|
|
|
@ -41,7 +41,7 @@ public class InterfaceAnalyzer {
|
|||
final static HashMap<String, TypeStats> typeStats = new HashMap<String, TypeStats>();
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
OfflineInstrumenter instrumenter = new OfflineInstrumenter();
|
||||
OfflineInstrumenter instrumenter = new OfflineInstrumenter(true);
|
||||
|
||||
Writer w = new BufferedWriter(new OutputStreamWriter(System.out));
|
||||
|
||||
|
|
|
@ -57,7 +57,7 @@ public class Mangler {
|
|||
|
||||
public static void main(String[] args) throws Exception {
|
||||
for (int i = 0; i < 1; i++) {
|
||||
instrumenter = new OfflineInstrumenter();
|
||||
instrumenter = new OfflineInstrumenter(true);
|
||||
|
||||
Writer w = new BufferedWriter(new FileWriter("report", false));
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ public class Statistics {
|
|||
|
||||
public static void main(String[] args) throws Exception {
|
||||
for (int i = 0; i < 1; i++) {
|
||||
instrumenter = new OfflineInstrumenter();
|
||||
instrumenter = new OfflineInstrumenter(true);
|
||||
|
||||
Writer w = new BufferedWriter(new FileWriter("report", false));
|
||||
|
||||
|
|
|
@ -60,6 +60,8 @@ public class DynamicCallGraph {
|
|||
private final static boolean disasm = true;
|
||||
private final static boolean verify = true;
|
||||
|
||||
private static boolean patchExits = true;
|
||||
|
||||
private static OfflineInstrumenter instrumenter;
|
||||
|
||||
private static Class<?> runtime = Runtime.class;
|
||||
|
@ -72,24 +74,26 @@ public class DynamicCallGraph {
|
|||
ClassInstrumenter ci;
|
||||
Writer w = new BufferedWriter(new FileWriter("report", false));
|
||||
|
||||
instrumenter = new OfflineInstrumenter();
|
||||
args = instrumenter.parseStandardArgs(args);
|
||||
|
||||
for(int i = 0; i < args.length - 1; i++) {
|
||||
if ("--runtime".equals(args[i])) {
|
||||
runtime = Class.forName(args[i+1]);
|
||||
} else if ("--exclusions".equals(args[i])) {
|
||||
filter = new FileOfClasses(new FileInputStream(args[i+1]));
|
||||
} else if ("--rt-jar".equals(args[i])) {
|
||||
System.err.println("using " + args[i+1] + " as stdlib");
|
||||
OfflineInstrumenter libReader = new OfflineInstrumenter();
|
||||
libReader.addInputJar(new File(args[i+1]));
|
||||
while ((ci = libReader.nextClass()) != null) {
|
||||
CTUtils.addClassToHierarchy(cha, ci.getReader());
|
||||
for(int i = 0; i < args.length - 1; i++) {
|
||||
if ("--runtime".equals(args[i])) {
|
||||
runtime = Class.forName(args[i+1]);
|
||||
} else if ("--exclusions".equals(args[i])) {
|
||||
filter = new FileOfClasses(new FileInputStream(args[i+1]));
|
||||
} else if ("--dont-patch-exits".equals(args[i])) {
|
||||
patchExits = false;
|
||||
} else if ("--rt-jar".equals(args[i])) {
|
||||
System.err.println("using " + args[i+1] + " as stdlib");
|
||||
OfflineInstrumenter libReader = new OfflineInstrumenter(true);
|
||||
libReader.addInputJar(new File(args[i+1]));
|
||||
while ((ci = libReader.nextClass()) != null) {
|
||||
CTUtils.addClassToHierarchy(cha, ci.getReader());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
instrumenter = new OfflineInstrumenter(!patchExits);
|
||||
args = instrumenter.parseStandardArgs(args);
|
||||
|
||||
instrumenter.setPassUnmodifiedClasses(true);
|
||||
|
||||
instrumenter.beginTraversal();
|
||||
|
@ -137,7 +141,7 @@ public class DynamicCallGraph {
|
|||
|
||||
if (verify) {
|
||||
Verifier v = new Verifier(d);
|
||||
v.setClassHierarchy(cha);
|
||||
// v.setClassHierarchy(cha);
|
||||
v.verify();
|
||||
}
|
||||
|
||||
|
@ -163,42 +167,44 @@ public class DynamicCallGraph {
|
|||
}
|
||||
});
|
||||
|
||||
me.addMethodExceptionHandler(null, new MethodEditor.Patch() {
|
||||
@Override
|
||||
public void emitTo(Output w) {
|
||||
w.emit(ConstantInstruction.makeString(theClass));
|
||||
w.emit(ConstantInstruction.makeString(theMethod));
|
||||
//if (nonStatic)
|
||||
// w.emit(LoadInstruction.make(Constants.TYPE_Object, 0)); //load this
|
||||
//else
|
||||
w.emit(Util.makeGet(runtime, "NULL_TAG"));
|
||||
// w.emit(ConstantInstruction.make(Constants.TYPE_null, null));
|
||||
w.emit(ConstantInstruction.make(1)); // true
|
||||
w.emit(Util.makeInvoke(runtime, "termination", new Class[] {String.class, String.class, Object.class, boolean.class}));
|
||||
w.emit(ThrowInstruction.make(false));
|
||||
}
|
||||
});
|
||||
|
||||
me.visitInstructions(new MethodEditor.Visitor() {
|
||||
@Override
|
||||
public void visitReturn(ReturnInstruction instruction) {
|
||||
insertBefore(new MethodEditor.Patch() {
|
||||
@Override
|
||||
public void emitTo(MethodEditor.Output w) {
|
||||
w.emit(ConstantInstruction.makeString(theClass));
|
||||
w.emit(ConstantInstruction.makeString(theMethod));
|
||||
if (nonStatic)
|
||||
w.emit(LoadInstruction.make(Constants.TYPE_Object, 0)); //load this
|
||||
else
|
||||
w.emit(Util.makeGet(runtime, "NULL_TAG"));
|
||||
// w.emit(ConstantInstruction.make(Constants.TYPE, null));
|
||||
w.emit(ConstantInstruction.make(0)); // false
|
||||
w.emit(Util.makeInvoke(runtime, "termination", new Class[] {String.class, String.class, Object.class, boolean.class}));
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
if (patchExits) {
|
||||
me.addMethodExceptionHandler(null, new MethodEditor.Patch() {
|
||||
@Override
|
||||
public void emitTo(Output w) {
|
||||
w.emit(ConstantInstruction.makeString(theClass));
|
||||
w.emit(ConstantInstruction.makeString(theMethod));
|
||||
//if (nonStatic)
|
||||
// w.emit(LoadInstruction.make(Constants.TYPE_Object, 0)); //load this
|
||||
//else
|
||||
w.emit(Util.makeGet(runtime, "NULL_TAG"));
|
||||
// w.emit(ConstantInstruction.make(Constants.TYPE_null, null));
|
||||
w.emit(ConstantInstruction.make(1)); // true
|
||||
w.emit(Util.makeInvoke(runtime, "termination", new Class[] {String.class, String.class, Object.class, boolean.class}));
|
||||
w.emit(ThrowInstruction.make(false));
|
||||
}
|
||||
});
|
||||
|
||||
me.visitInstructions(new MethodEditor.Visitor() {
|
||||
@Override
|
||||
public void visitReturn(ReturnInstruction instruction) {
|
||||
insertBefore(new MethodEditor.Patch() {
|
||||
@Override
|
||||
public void emitTo(MethodEditor.Output w) {
|
||||
w.emit(ConstantInstruction.makeString(theClass));
|
||||
w.emit(ConstantInstruction.makeString(theMethod));
|
||||
if (nonStatic)
|
||||
w.emit(LoadInstruction.make(Constants.TYPE_Object, 0)); //load this
|
||||
else
|
||||
w.emit(Util.makeGet(runtime, "NULL_TAG"));
|
||||
// w.emit(ConstantInstruction.make(Constants.TYPE, null));
|
||||
w.emit(ConstantInstruction.make(0)); // false
|
||||
w.emit(Util.makeInvoke(runtime, "termination", new Class[] {String.class, String.class, Object.class, boolean.class}));
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// this updates the data d
|
||||
me.applyPatches();
|
||||
|
||||
|
@ -210,7 +216,7 @@ public class DynamicCallGraph {
|
|||
|
||||
if (verify) {
|
||||
Verifier v = new Verifier(d);
|
||||
v.setClassHierarchy(cha);
|
||||
// v.setClassHierarchy(cha);
|
||||
v.verify();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -93,7 +93,7 @@ public class CopyWriter {
|
|||
|
||||
final ArrayList<ZipEntry> entries = new ArrayList<ZipEntry>();
|
||||
|
||||
instrumenter = new OfflineInstrumenter();
|
||||
instrumenter = new OfflineInstrumenter(true);
|
||||
instrumenter.setManifestBuilder(new OfflineInstrumenter.ManifestBuilder() {
|
||||
@Override
|
||||
public void addEntry(ZipEntry ze) {
|
||||
|
|
|
@ -1681,7 +1681,7 @@ public abstract class Compiler implements Constants {
|
|||
}
|
||||
|
||||
private void makeTypes() {
|
||||
Verifier v = new Verifier(isConstructor, isStatic, classType, signature, instructions, handlers, instructionsToBytecodes);
|
||||
Verifier v = new Verifier(isConstructor, isStatic, classType, signature, instructions, handlers, instructionsToBytecodes, null);
|
||||
if (hierarchy != null) {
|
||||
v.setClassHierarchy(hierarchy);
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ package com.ibm.wala.shrikeBT.analysis;
|
|||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.BitSet;
|
||||
import java.util.List;
|
||||
|
||||
|
@ -71,12 +72,14 @@ public class Analyzer {
|
|||
protected int[][] backEdges;
|
||||
|
||||
protected int[] instToBC;
|
||||
|
||||
protected String[][] varTypes;
|
||||
|
||||
protected final static String[] noStrings = new String[0];
|
||||
|
||||
protected final static int[] noEdges = new int[0];
|
||||
|
||||
public Analyzer(boolean isConstructor, boolean isStatic, String classType, String signature, IInstruction[] instructions, ExceptionHandler[][] handlers, int[] instToBC) {
|
||||
public Analyzer(boolean isConstructor, boolean isStatic, String classType, String signature, IInstruction[] instructions, ExceptionHandler[][] handlers, int[] instToBC, String[][] vars) {
|
||||
if (instructions == null) {
|
||||
throw new IllegalArgumentException("null instructions");
|
||||
}
|
||||
|
@ -95,6 +98,7 @@ public class Analyzer {
|
|||
this.instructions = instructions;
|
||||
this.handlers = handlers;
|
||||
this.instToBC = instToBC;
|
||||
this.varTypes = vars;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -203,6 +207,15 @@ public class Analyzer {
|
|||
return t1;
|
||||
}
|
||||
|
||||
if (String.valueOf(t1).equals("L;") || String.valueOf(t2).equals("L;")) {
|
||||
System.err.println("++ " + t1 + " -- " + t2 + " ++");
|
||||
if (String.valueOf(t1).equals("L;")) {
|
||||
return t2;
|
||||
} else {
|
||||
return t1;
|
||||
}
|
||||
}
|
||||
|
||||
if (t1 == thisType || t2 == thisType || t1 == topType || t2 == topType) {
|
||||
return topType;
|
||||
}
|
||||
|
@ -213,7 +226,7 @@ public class Analyzer {
|
|||
|
||||
String x = ClassHierarchy.findCommonSupertype(hierarchy, patchType(t1), patchType(t2));
|
||||
|
||||
if ("L?;".equals(x) && ("J".equals(t1) || "J".equals(t2))) {
|
||||
if ("L?;".equals(x)) {
|
||||
System.err.println(t1 + " -- " + t2);
|
||||
}
|
||||
|
||||
|
@ -694,6 +707,28 @@ public class Analyzer {
|
|||
instr.visit(localsUpdate); // visit localStore before popping
|
||||
System.arraycopy(curStack, popped, curStack, 0, curStackSize - popped);
|
||||
curStackSize -= popped;
|
||||
|
||||
if (varTypes != null) {
|
||||
if (instr instanceof IStoreInstruction) {
|
||||
int local = ((IStoreInstruction)instr).getVarIndex();
|
||||
if (Constants.TYPE_null.equals(curLocals[local])) {
|
||||
for(int idx : new int[]{i, i+1}) {
|
||||
int bc = instToBC[idx];
|
||||
if (bc == 667 && local == 16) {
|
||||
System.err.println("got here");
|
||||
}
|
||||
if (bc != -1 && varTypes != null && varTypes.length > bc && varTypes[bc] != null) {
|
||||
if (varTypes[bc].length > local && varTypes[bc][local] != null) {
|
||||
String declaredType = varTypes[bc][local];
|
||||
curLocals[local] = declaredType;
|
||||
|
||||
System.err.println("setting local " + local + " to " + declaredType + " at " + instToBC[i] + " in " + classType + " " + signature);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -710,8 +745,13 @@ public class Analyzer {
|
|||
}
|
||||
}
|
||||
|
||||
//System.err.println(i + " -- " + Arrays.toString(curLocals) + " -- " + Arrays.toString(curStack));
|
||||
|
||||
int[] targets = instr.getBranchTargets();
|
||||
for (int j = 0; j < targets.length; j++) {
|
||||
if (targets[j] == 29 && classType.contains("MetaClassImpl;") && signature.contains("(Ljava/lang/String;Lorg/codehaus/groovy/reflection/CachedClass;)")) {
|
||||
System.err.println("got here");
|
||||
}
|
||||
if (mergeTypes(targets[j], curStack, curStackSize, curLocals, curLocalsSize[0], path)) {
|
||||
computeTypes(targets[j], visitor, makeTypesAt, path);
|
||||
}
|
||||
|
@ -830,11 +870,11 @@ public class Analyzer {
|
|||
}
|
||||
|
||||
protected Analyzer(MethodData info) {
|
||||
this(info.getName().equals("<init>"), info.getIsStatic(), info.getClassType(), info.getSignature(), info.getInstructions(), info.getHandlers(), info.getInstructionsToBytecodes());
|
||||
this(info.getName().equals("<init>"), info.getIsStatic(), info.getClassType(), info.getSignature(), info.getInstructions(), info.getHandlers(), info.getInstructionsToBytecodes(), null);
|
||||
}
|
||||
|
||||
protected Analyzer(MethodData info, int[] instToBC) {
|
||||
this(info.getName().equals("<init>"), info.getIsStatic(), info.getClassType(), info.getSignature(), info.getInstructions(), info.getHandlers(), instToBC);
|
||||
protected Analyzer(MethodData info, int[] instToBC, String[][] vars) {
|
||||
this(info.getName().equals("<init>"), info.getIsStatic(), info.getClassType(), info.getSignature(), info.getInstructions(), info.getHandlers(), instToBC, vars);
|
||||
}
|
||||
|
||||
public static Analyzer createAnalyzer(MethodData info) {
|
||||
|
|
|
@ -277,6 +277,11 @@ public final class ClassHierarchy {
|
|||
}
|
||||
|
||||
private static String findCommonSupertypeHierarchy(ClassHierarchyProvider hierarchy, String t1, String t2) {
|
||||
|
||||
if (hierarchy != null && t1.contains("Reader") && t2.contains("Reader")) {
|
||||
System.err.println("got here");
|
||||
}
|
||||
|
||||
if (isSubtypeOf(hierarchy, t1, t2) == YES) {
|
||||
return t2;
|
||||
} else if (isSubtypeOf(hierarchy, t2, t1) == YES) {
|
||||
|
|
|
@ -287,8 +287,8 @@ public final class Verifier extends Analyzer {
|
|||
/**
|
||||
* Initialize a verifier.
|
||||
*/
|
||||
public Verifier(boolean isConstructor, boolean isStatic, String classType, String signature, IInstruction[] instructions, ExceptionHandler[][] handlers, int[] instToBC) {
|
||||
super(isConstructor, isStatic, classType, signature, instructions, handlers, instToBC);
|
||||
public Verifier(boolean isConstructor, boolean isStatic, String classType, String signature, IInstruction[] instructions, ExceptionHandler[][] handlers, int[] instToBC, String[][] vars) {
|
||||
super(isConstructor, isStatic, classType, signature, instructions, handlers, instToBC, vars);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -300,8 +300,8 @@ public final class Verifier extends Analyzer {
|
|||
super(info);
|
||||
}
|
||||
|
||||
public Verifier(MethodData info, int[] instToBC) throws NullPointerException {
|
||||
super(info, instToBC);
|
||||
public Verifier(MethodData info, int[] instToBC, String[][] vars) throws NullPointerException {
|
||||
super(info, instToBC, vars);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -63,11 +63,13 @@ final public class ClassInstrumenter {
|
|||
|
||||
private final ClassHierarchyProvider cha;
|
||||
|
||||
private final boolean reuseStackMaps;
|
||||
|
||||
/**
|
||||
* Create a class instrumenter from raw bytes.
|
||||
*/
|
||||
public ClassInstrumenter(String inputName, byte[] bytes, ClassHierarchyProvider cha) throws InvalidClassFileException {
|
||||
this(inputName, new ClassReader(bytes), cha);
|
||||
public ClassInstrumenter(String inputName, byte[] bytes, ClassHierarchyProvider cha, boolean reuseStackMaps) throws InvalidClassFileException {
|
||||
this(inputName, new ClassReader(bytes), cha, reuseStackMaps);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -91,12 +93,13 @@ final public class ClassInstrumenter {
|
|||
*
|
||||
* @throws IllegalArgumentException if cr is null
|
||||
*/
|
||||
public ClassInstrumenter(String inputName, ClassReader cr, ClassHierarchyProvider cha) throws InvalidClassFileException {
|
||||
public ClassInstrumenter(String inputName, ClassReader cr, ClassHierarchyProvider cha, boolean reuseStackMaps) throws InvalidClassFileException {
|
||||
if (cr == null) {
|
||||
throw new IllegalArgumentException("cr is null");
|
||||
}
|
||||
this.cr = cr;
|
||||
this.cha = cha;
|
||||
this.reuseStackMaps = reuseStackMaps;
|
||||
methods = new MethodData[cr.getMethodCount()];
|
||||
oldCode = new CodeReader[methods.length];
|
||||
cpr = CTDecoder.makeConstantPoolReader(cr);
|
||||
|
@ -426,7 +429,23 @@ final public class ClassInstrumenter {
|
|||
stacks = new StackMapTableWriter(w, sm, output.getNewBytecodesToOldBytecodes());
|
||||
codeAttrCount++;
|
||||
} else { */
|
||||
stacks = new StackMapTableWriter(w, md, output, cha);
|
||||
String[][] varTypes = null;
|
||||
int[] newToOld = output.getNewBytecodesToOldBytecodes();
|
||||
int[][] vars = LocalVariableTableReader.makeVarMap(oldCode);
|
||||
if (vars != null) {
|
||||
varTypes = new String[newToOld.length][];
|
||||
for(int i = 0; i < newToOld.length; i++) {
|
||||
int idx = newToOld[i];
|
||||
if (idx != -1 && vars[idx] != null) {
|
||||
varTypes[i] = new String[vars[idx].length / 2];
|
||||
for(int j = 1; j < vars[idx].length; j += 2) {
|
||||
int type = vars[idx][j];
|
||||
varTypes[i][j/2] = type==0? null: oldCode.getClassReader().getCP().getCPUtf8(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
stacks = new StackMapTableWriter(w, md, output, cha, varTypes);
|
||||
codeAttrCount++;
|
||||
// }
|
||||
} catch (IOException | FailureException e) {
|
||||
|
|
|
@ -25,11 +25,12 @@ import com.ibm.wala.shrikeCT.InvalidClassFileException;
|
|||
* specialization of OfflineInstrumenterBase to use the shrikeCT functionality.
|
||||
*/
|
||||
final public class OfflineInstrumenter extends OfflineInstrumenterBase {
|
||||
private final boolean reuseStackMaps;
|
||||
/**
|
||||
* Create an empty collection of classes to instrument.
|
||||
*/
|
||||
public OfflineInstrumenter() {
|
||||
|
||||
public OfflineInstrumenter(boolean reuseStackMaps) {
|
||||
this.reuseStackMaps = reuseStackMaps;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -37,7 +38,7 @@ final public class OfflineInstrumenter extends OfflineInstrumenterBase {
|
|||
byte[] bytes = new byte[s.available()];
|
||||
Util.readFully(s, bytes);
|
||||
try {
|
||||
return new ClassInstrumenter(inputName, bytes, cha);
|
||||
return new ClassInstrumenter(inputName, bytes, cha, reuseStackMaps);
|
||||
} catch (InvalidClassFileException e) {
|
||||
throw new IOException("Class is invalid: " + e.getMessage());
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@ public class BatchVerifier {
|
|||
private static int errors = 0;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
OfflineInstrumenter oi = new OfflineInstrumenter();
|
||||
OfflineInstrumenter oi = new OfflineInstrumenter(true);
|
||||
args = oi.parseStandardArgs(args);
|
||||
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
|
|
|
@ -42,7 +42,7 @@ public class BootstrapDumper {
|
|||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
OfflineInstrumenter oi = new OfflineInstrumenter();
|
||||
OfflineInstrumenter oi = new OfflineInstrumenter(true);
|
||||
String[] classpathEntries = oi.parseStandardArgs(args);
|
||||
|
||||
PrintWriter w = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
|
||||
|
|
|
@ -72,7 +72,7 @@ public class ClassPrinter {
|
|||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
OfflineInstrumenter oi = new OfflineInstrumenter();
|
||||
OfflineInstrumenter oi = new OfflineInstrumenter(true);
|
||||
args = oi.parseStandardArgs(args);
|
||||
|
||||
PrintWriter w = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
|
||||
|
|
|
@ -36,7 +36,7 @@ public class ClassSearcher {
|
|||
private static int scanned = 0;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
instrumenter = new OfflineInstrumenter();
|
||||
instrumenter = new OfflineInstrumenter(true);
|
||||
|
||||
Writer w = new BufferedWriter(new FileWriter("report", true));
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ public class MethodTracer {
|
|||
|
||||
public static void main(String[] args) throws Exception {
|
||||
for (int i = 0; i < 1; i++) {
|
||||
instrumenter = new OfflineInstrumenter();
|
||||
instrumenter = new OfflineInstrumenter(true);
|
||||
|
||||
Writer w = new BufferedWriter(new FileWriter("report", false));
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@ import java.util.jar.JarEntry;
|
|||
import java.util.jar.JarFile;
|
||||
import java.util.jar.JarOutputStream;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipException;
|
||||
|
||||
import com.ibm.wala.shrikeBT.analysis.ClassHierarchyProvider;
|
||||
|
||||
|
|
|
@ -97,19 +97,9 @@ public final class LocalVariableTableReader extends AttributeReader {
|
|||
+ " in LocalVariableTable");
|
||||
}
|
||||
|
||||
int rangeStart = startPC;
|
||||
while (rangeStart < startPC + length) {
|
||||
int rangeLength = 1;
|
||||
while (rangeStart + rangeLength < startPC + length && r[rangeStart + rangeLength] == r[rangeStart]) {
|
||||
rangeLength++;
|
||||
}
|
||||
|
||||
int[] newVector = makeVarVector(r[rangeStart], varIndex, nameIndex, typeIndex);
|
||||
for (int k = rangeStart; k < rangeStart + rangeLength; k++) {
|
||||
r[k] = newVector;
|
||||
}
|
||||
|
||||
rangeStart += rangeLength;
|
||||
for (int k = startPC; k < startPC + length; k++) {
|
||||
int[] newVector = makeVarVector(r[k], varIndex, nameIndex, typeIndex);
|
||||
r[k] = newVector;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
package com.ibm.wala.shrikeCT;
|
||||
|
||||
import static com.ibm.wala.shrikeBT.Constants.TYPE_double;
|
||||
import static com.ibm.wala.shrikeBT.Constants.TYPE_float;
|
||||
import static com.ibm.wala.shrikeBT.Constants.TYPE_int;
|
||||
import static com.ibm.wala.shrikeBT.Constants.TYPE_long;
|
||||
import static com.ibm.wala.shrikeBT.Constants.*;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
|
@ -54,8 +51,8 @@ public class StackMapTableWriter extends Element {
|
|||
|
||||
}
|
||||
|
||||
public StackMapTableWriter(ClassWriter writer, MethodData method, Output output, ClassHierarchyProvider cha) throws FailureException, IOException {
|
||||
this(writer, stackMapTable(writer, method, output, cha));
|
||||
public StackMapTableWriter(ClassWriter writer, MethodData method, Output output, ClassHierarchyProvider cha, String[][] vars) throws FailureException, IOException {
|
||||
this(writer, stackMapTable(writer, method, output, cha, vars));
|
||||
}
|
||||
|
||||
private static List<StackMapFrame> remapStackFrames(List<StackMapFrame> sm, int[] newBytecodesToOldBytecodes) {
|
||||
|
@ -97,6 +94,8 @@ public class StackMapTableWriter extends Element {
|
|||
static StackMapType item(String type) {
|
||||
if (type == null) {
|
||||
return Item.ITEM_Top;
|
||||
} else if (type.equals(TYPE_null)) {
|
||||
return Item.ITEM_Null;
|
||||
} else if (type.equals(Analyzer.topType)) {
|
||||
return Item.ITEM_Top;
|
||||
} else if (type.equals(Analyzer.thisType)) {
|
||||
|
@ -138,7 +137,7 @@ public class StackMapTableWriter extends Element {
|
|||
|
||||
static StackMapType[] trim(StackMapType[] types) {
|
||||
int i = types.length-1;
|
||||
while (i >= 0 && (types[i] == null || types[i] == Item.ITEM_Null)) {
|
||||
while (i >= 0 && (types[i] == null || types[i] == Item.ITEM_Null || types[i] == Item.ITEM_Top)) {
|
||||
i--;
|
||||
}
|
||||
|
||||
|
@ -153,12 +152,24 @@ public class StackMapTableWriter extends Element {
|
|||
}
|
||||
}
|
||||
|
||||
private static String hackUnknown(String type) {
|
||||
if (type == null) {
|
||||
return type;
|
||||
} else if (type.startsWith("[")) {
|
||||
return "[" + hackUnknown(type.substring(1));
|
||||
} else if ("L?;".equals(type)) {
|
||||
return "Ljava/lang/Object;";
|
||||
} else {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
static StackMapType[] types(String[] types, boolean locals) {
|
||||
StackMapType[] stackTypes = new StackMapType[ types.length ];
|
||||
|
||||
int x = 0;
|
||||
for(int j = 0; j < types.length; j++) {
|
||||
StackMapType stackType = item("L?;".equals(types[j])? "Ljava/lang/Object;": types[j]);
|
||||
StackMapType stackType = item(hackUnknown(types[j]));
|
||||
stackTypes[x++] = stackType;
|
||||
if (locals && stackType.size() == 2) {
|
||||
j++;
|
||||
|
@ -178,13 +189,13 @@ public class StackMapTableWriter extends Element {
|
|||
return false;
|
||||
}
|
||||
|
||||
public static List<StackMapFrame> stackMapTable(ClassWriter writer, MethodData method, Output output, ClassHierarchyProvider cha) throws FailureException, IOException {
|
||||
public static List<StackMapFrame> stackMapTable(ClassWriter writer, MethodData method, Output output, ClassHierarchyProvider cha, String[][] vars) throws FailureException, IOException {
|
||||
List<StackMapFrame> frames = new ArrayList<StackMapFrame>();
|
||||
|
||||
int[] instructionToBytecode = output.getInstructionOffsets();
|
||||
IInstruction[] insts = method.getInstructions();
|
||||
|
||||
Verifier typeChecker = new Verifier(method, instructionToBytecode);
|
||||
Verifier typeChecker = new Verifier(method, instructionToBytecode, vars);
|
||||
if (cha != null) {
|
||||
typeChecker.setClassHierarchy(cha);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue