
com.lambda.Debugger.Debugify Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of LewisOmniscientDebugger Show documentation
Show all versions of LewisOmniscientDebugger Show documentation
A command line utility for accesing the bowler framework.
The newest version!
/* Debugify.java
Copyright 2003, Bil Lewis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package com.lambda.Debugger;
import java.util.*;
import java.io.*;
import org.apache.bcel.*;
import org.apache.bcel.verifier.*;
import org.apache.bcel.classfile.*;
import org.apache.bcel.generic.*;
import org.apache.bcel.Constants;
public final class Debugify implements Constants {
static String version = Debugger.version;
public static PrintStream outputStream = System.out;
public static final int MAX_ARGS_RECORDED = 10;
private static InstructionFactory factory;
private static final int MAX_SOURCE_LINES = 8000;
// Max that a single method can store
private static boolean isSynchronized = false;
private static boolean replacingVector;
private static boolean calledFromDebugify = false;
private static boolean processedCLINIT = false;
private static ConstantPoolGen cpg;
// private static int out; // reference to D
// private static int printlnString; // reference to PrintStream.println
private static int toString; // reference to PrintStream.println
private static Type traceLine, typeClass, typeClassLoader, typeShadowInt,
typeShadowShort, typeShadowByte;
private static Type typeShadowChar, typeShadowBoolean, typeShadowFloat,
typeShadowLong;
private static Type typeShadowDouble, typeShadowClass, typeCollection;
private static String sourceFileName;
static boolean SILENT = true;
private static boolean DEBUG = false;
static Code code = null;
static String name = null;
static LineNumberTable lineNumberTable = null;
static LocalVariable[] localVariables;
static boolean OneObj = false;
static Type type = null;
static Type returnType = null;
static MethodGen mg = null;
static InstructionList il = null;
static InstructionHandle[] ihs = null;
static InstructionList patch = null;
static LocalVariableGen lg = null;
static LocalVariableGen lg2 = null;
static LocalVariableGen[] lvgs;
static int tl2 = 0;
static int tl = 0;
static int flags = 0;
static int D_new_myvector = 0;
static int D_invoke = 0;
static int D_athrow = 0;
static int D_catch = 0;
static int D_getPreviousTL = 0;
static int D_addUnparented0 = 0;
static int D_addUnparented1 = 0;
static int D_addUnparented2 = 0;
static int D_addUnparented3 = 0;
static int D_addUnparented4 = 0;
static int D_addUnparented5 = 0;
static int D_addUnparented6 = 0;
static int D_addUnparented7 = 0;
static int D_addUnparented8 = 0;
static int D_addUnparented9 = 0;
static int D_addUnparented10 = 0;
// static int D_blankTrace = 0;
// static int D_change = 0;
static int D_changeA = 0, D_changeI = 0, D_changeIvoid = 0, D_changeL = 0,
D_changeB = 0, D_changeC = 0;
static int D_changeS = 0, D_changeF = 0, D_changeZ = 0, D_changeD = 0;
static int D_bind = 0;
static int D_newArray = 0;
static int D_changeIV = 0;
static int D_changeIVA = 0, D_changeIVB = 0, D_changeIVC = 0,
D_changeIVS = 0;
static int D_changeIVI = 0, D_changeIVL = 0, D_changeIVF = 0,
D_changeIVD = 0, D_changeIVZ = 0;
static int D_createShadowClass = 0;
static int D_createShadowClass1 = 0;
static int D_createShadowInt = 0;
static int D_createShadowShort = 0;
static int D_createShadowByte = 0;
static int D_createShadowChar = 0;
static int D_createShadowBoolean = 0;
static int D_changeArrayA = 0, D_changeArrayZ = 0, D_changeArrayB = 0,
D_changeArrayC = 0;
static int D_changeArrayS = 0, D_changeArrayI = 0, D_changeArrayL = 0,
D_changeArrayF = 0, D_changeArrayD = 0;
static int D_createShadowLong = 0;
static int D_createShadowFloat = 0;
static int D_createShadowDouble = 0;
static int D_returnValue_0 = 0;
static int D_returnValueA = 0;
static int D_returnValueB = 0, D_returnValueC = 0, D_returnValueS = 0,
D_returnValueI = 0;
static int D_returnValueL = 0, D_returnValueF = 0, D_returnValueD = 0,
D_returnValueZ = 0;
static int D_returnNew = 0;
static int D_exit = 0;
static int D_invoke_0 = 0;
static int D_invoke_1 = 0;
static int D_invoke_2 = 0;
static int D_invoke_3 = 0;
static int D_invoke_4 = 0;
static int D_invoke_5 = 0;
static int D_invoke_6 = 0;
static int D_invoke_7 = 0;
static int D_invoke_8 = 0;
static int D_invoke_9 = 0;
static int D_invoke_10 = 0;
static int D_newObj_0 = 0;
static int D_newObj_1 = 0;
static int D_newObj_2 = 0;
static int D_newObj_3 = 0;
static int D_newObj_4 = 0;
static int D_newObj_5 = 0;
static int D_newObj_6 = 0;
static int D_newObj_7 = 0;
static int D_newObj_8 = 0;
static int D_newObj_9 = 0;
static int D_newObj_10 = 0;
// static int D_init = 0;
static int D_returnMarker_0 = 0;
static int D_returnMarker_1 = 0;
static int D_gettingLock = 0;
static int D_gotLock = 0;
static int D_releasingLock = 0;
static int D_startingWait = 0;
static int D_endingWait = 0;
static int D_startingJoin = 0;
static int D_endingJoin = 0;
static ArrayType stringArray = new ArrayType(ObjectType.STRING, 1);
static ObjectType methodType = new ObjectType(
"de.fub.bytecode.classfile.Method");
static ArrayType methodArray = new ArrayType(methodType, 1);
static int nMethods = 0;
static int line = 0;
static Instruction ins = null;
static boolean PUBLIC_ONLY = false;
static boolean NO_PUTFIELD = false, NO_PUTSTATIC = false,
NO_ISTORE = false, NO_IINC = false, NO_IASTORE = false,
NO_RETURN = false, NO_RETURNVALUE = false,
NO_INVOKEVIRTUAL = false, NO_ARGUMENTS = true, NO_ASTORE = false,
NO_ATHROW = false, NO_CATCH = false, NO_INVOKESTATIC = false,
NO_NEW = false, NO_AASTORE = false, NO_PREVIOUS = false,
NO_LOCKS = false, NO_WAITS = false, DONT_REPLACE_VECTOR = false;
static VectorD dontRecord, dontInstrument, instrumentOnlyPackages;
static CodeExceptionGen[] ceg;
static String classPackageName, className, classNoNumbers;
// java -DPUTFIELD -DISTORE -DIINC -DIASTORE -DRETURN -DRETURNVALUE
// -DINVOKEVIRTUAL -DASTORE -DATHROW -DCATCH -DARGUMENTS -DINVOKESTATIC
// Debugify
// -DATHROW -DCATCH -DASTORE -DAASTORE -DIASTORE -DRETURN -DRETURNVALUE
// -DINVOKEVIRTUAL -DIINC -DISTORE -DPUTFIELD -DPUTSTATIC -DINVOKESTATIC
// -DARGUMENTS -DNEW
static boolean alreadyDebugified;
public static void main1(String[] args) {
int nFiles = 0;
initialize();
calledFromDebugify = true;
try {
processFiles: for (int i = 0; i < args.length; i++) {
if (args[i].endsWith(".class")) {
JavaClass javaClass = new ClassParser(args[i]).parse();
JavaClass newJC;
String className = javaClass.getClassName();
String packageName = javaClass.getPackageName();
// if (dontProcessPackage(className)) {Debugger.print("-");
// continue;}
if (dontProcessMethod(dontInstrument, "*", className, true)) {
System.out.print("-");
continue;
}
String classFileName = args[i];
newJC = debugifyClass(javaClass, classFileName);
if (!alreadyDebugified) {
newJC.dump(classFileName);
System.out.print("+");
nFiles++;
} else
System.out.print("-");
} else
Debugger.println(args[i] + " is not a .class file");
}
} catch (Exception e) {
Debugger.println("Debugify exiting with exception: ");
e.printStackTrace();
}
Debugger.println(version + " debugified " + nFiles + " files.");
}
public static void main(String[] args) {
main1(args);
System.exit(0);
} // MAIN ENDS
static private boolean initialized = false;
public static void initialize() {
if (initialized)
return;
initialized = true;
if (System.getProperty("NOTHING") != null) {
NO_PUTFIELD = NO_PUTSTATIC = NO_ISTORE = NO_IINC = NO_IASTORE = NO_RETURN = NO_RETURNVALUE = NO_INVOKEVIRTUAL = true;
NO_ASTORE = NO_ATHROW = NO_CATCH = NO_INVOKESTATIC = NO_ARGUMENTS = NO_IASTORE = NO_NEW = NO_AASTORE = true;
}
if (System.getProperty("SILENT") != null)
SILENT = true;
if (System.getProperty("DEBUG_DEBUGIFY") != null)
SILENT = false;
if (System.getProperty("ATHROW") != null)
NO_ATHROW = true;
if (System.getProperty("CATCH") != null)
NO_CATCH = true;
if (System.getProperty("ASTORE") != null)
NO_ASTORE = true;
if (System.getProperty("AASTORE") != null)
NO_AASTORE = true;
if (System.getProperty("IASTORE") != null)
NO_IASTORE = true;
if (System.getProperty("RETURN") != null)
NO_RETURN = true;
if (System.getProperty("RETURNVALUE") != null)
NO_RETURNVALUE = true;
if (System.getProperty("INVOKEVIRTUAL") != null)
NO_INVOKEVIRTUAL = true;
if (System.getProperty("IINC") != null)
NO_IINC = true;
if (System.getProperty("ISTORE") != null)
NO_ISTORE = true;
if (System.getProperty("PUTFIELD") != null)
NO_PUTFIELD = true;
if (System.getProperty("PUTSTATIC") != null)
NO_PUTSTATIC = true;
if (System.getProperty("INVOKESTATIC") != null)
NO_INVOKESTATIC = true;
if (System.getProperty("ARGUMENTS") != null)
NO_ARGUMENTS = true;
if (System.getProperty("NEW") != null)
NO_NEW = true;
if (System.getProperty("NO_LOCKS") != null)
NO_LOCKS = true;
if (System.getProperty("PUBLIC_ONLY") != null) {
PUBLIC_ONLY = true;
}
if (System.getProperty("DONT_REPLACE_VECTOR") != null) {
DONT_REPLACE_VECTOR = true;
}
if (System.getProperty("PUTFIELD_ONLY") != null) {
NO_ISTORE = NO_IINC = NO_IASTORE = NO_RETURN = NO_RETURNVALUE = NO_INVOKEVIRTUAL = true;
NO_ASTORE = NO_ATHROW = NO_CATCH = NO_INVOKESTATIC = NO_ARGUMENTS = NO_PREVIOUS = true;
}
Defaults.readDefaults();
dontRecord = Defaults.dontRecord;
// Read the file for methods not to record
dontInstrument = Defaults.dontInstrument;
// Read the file for methods not to instrument
instrumentOnlyPackages = Defaults.instrumentOnlyPackages;
}
public static JavaClass debugifyClass(JavaClass javaClass1,
String classFileName) {
synchronized (D.class) {
if (PUBLIC_ONLY)
return publicifyClass(javaClass1, classFileName);
classTable = new HashMap();
ConstantPool constants = javaClass1.getConstantPool();
classPackageName = javaClass1.getPackageName();
className = javaClass1.getClassName();
Attribute[] attributes = javaClass1.getAttributes();
initialize();
if (!javaClass1.isClass())
return javaClass1;
// if (dontProcessPackage(className)) {return javaClass1;}
if (dontProcessPackage(className)) {
return publicifyClass(javaClass1, classFileName);
}
sourceFileName = javaClass1.getSourceFileName();
for (int l = 0; l < attributes.length; l++) {
if (!SILENT)
Debugger.println("Attributes " + l + " " + attributes[l]);
String aName = constants.constantToString(attributes[l]
.getNameIndex(), Constants.CONSTANT_Utf8);
if (!SILENT)
Debugger.println("Attribute = " + aName);
if (aName == null)
continue;
if (aName.equals("Debugified")) {
if (!SILENT)
Debugger.println("This file already Debugified.");
alreadyDebugified = true;
return javaClass1;
}
}
if (!SILENT)
Debugger.println("Debugifying: " + classFileName + " "
+ Thread.currentThread());
warningPrinted = false; // 1 flag allowed per file.
cpg = new ConstantPoolGen(constants);
int loc = cpg.addUtf8("Debugified");
byte[] bytes = { 2 };
// CHECK THIS BEFORE ACCEPTING FILE AS CORRECT. (SOMEDAY)
Attribute att = new Unknown(loc, 1, bytes, cpg.getConstantPool());
Attribute[] attributes1 = new Attribute[attributes.length + 1];
for (int l = 0; l < attributes.length; l++) {
attributes1[l] = attributes[l];
}
attributes1[attributes.length] = att;
attributes = javaClass1.getAttributes();
if (!SILENT)
Debugger.println("Attributes of " + javaClass1);
// out = cpg.addFieldref("java.lang.System", "out",
// "Ljava/io/PrintStream;");
// printlnString = cpg.addMethodref("java.io.PrintStream",
// "println", "(Ljava/lang/String;)V");
toString = cpg.addMethodref("java.lang.Object", "toString",
"()Ljava/lang/String;");
typeClass = new ObjectType("java.lang.Class");
typeClassLoader = new ObjectType("java.lang.ClassLoader");
traceLine = new ObjectType("com.lambda.Debugger.TraceLine");
typeShadowInt = new ObjectType("com.lambda.Debugger.ShadowInt");
typeShadowShort = new ObjectType("com.lambda.Debugger.ShadowShort");
typeShadowByte = new ObjectType("com.lambda.Debugger.ShadowByte");
typeShadowChar = new ObjectType("com.lambda.Debugger.ShadowChar");
typeShadowBoolean = new ObjectType(
"com.lambda.Debugger.ShadowBoolean");
typeShadowFloat = new ObjectType("com.lambda.Debugger.ShadowFloat");
typeShadowLong = new ObjectType("com.lambda.Debugger.ShadowLong");
typeShadowDouble = new ObjectType(
"com.lambda.Debugger.ShadowDouble");
typeShadowClass = new ObjectType("com.lambda.Debugger.ShadowClass");
typeCollection = new ObjectType("java.util.Collection");
try {
if (cpg.getSize() > 10000)
throw new DebuggerException("Too many constants in class "
+ className + " " + cpg.getSize() + " > 10,000");
ClassGen classGen = new ClassGen(javaClass1);
classGen.isPublic(true);
if (!SILENT)
Debugger.println("Fields of ");
Field[] fields = classGen.getFields();
for (int j = 0; j < fields.length; j++) {
fields[j].isPublic(true);
fields[j].isPrivate(false);
fields[j].isProtected(false);
if (!SILENT)
Debugger.println(fields[j] + " Private: "
+ fields[j].isPrivate());
}
// Debugger.println("Fields of " + classGen );
reset();
Field f = new FieldGen(Constants.ACC_STATIC
| Constants.ACC_FINAL | Constants.ACC_PRIVATE,
Type.INT, "ODB_offset", cpg).getField();
classGen.addField(f);
createVarMappingsStart(classGen);
Method[] methods = classGen.getMethods();
int clPosition = -1;
for (int j = 0; j < methods.length; j++) {
methods[j].isPrivate(false);
methods[j].isProtected(false);
methods[j].isPublic(true);
String name = methods[j].getName();
if (name.equals("")) {
clPosition = j;
} else {
classGen.replaceMethod(methods[j], debugifyMethod(
classGen, methods[j]));
}
}
if (clPosition > -1)
classGen.replaceMethod(methods[clPosition], debugifyCLinit(
classGen, methods[clPosition]));
createVarMappingsEnd(classGen);
createClassNameMethod(classGen);
if (!processedCLINIT)
createCLinit(classGen);
JavaClass javaClass2 = classGen.getJavaClass();
javaClass2.setConstantPool(cpg.getFinalConstantPool());
// javaClass.setConstantPool(cpg);
alreadyDebugified = false;
javaClass2.setAttributes(attributes1);
// Debugger.println("JC " +javaClass1.toString());
// Debugger.println("GEN " +javaClass2.toString());
Repository.removeClass(javaClass1);
Repository.addClass(javaClass2);
String n = javaClass2.getClassName();
// verify(n);
if (Debugger.TRACE_LOADER)
System.out.print("+");
if (!SILENT)
Debugger.println("Debugified: " + classFileName);
return (javaClass2);
} catch (Exception e) {
if (e instanceof DebuggerException)
outputStream.println(e);
else {
if (Debugger.DEBUG_DEBUGGER)
e.printStackTrace();
else
outputStream.println(e);
// e.printStackTrace();// EXTREA FOR THE MOMENT
}
outputStream.println("Debugify " + version
+ ": Unable to instrument: " + className);
return (javaClass1);
}
}
}
public static JavaClass publicifyClass(JavaClass javaClass1,
String classFileName) {
synchronized (D.class) {
ConstantPool constants = javaClass1.getConstantPool();
classPackageName = javaClass1.getPackageName();
className = javaClass1.getClassName();
Attribute[] attributes = javaClass1.getAttributes();
initialize();
if (!javaClass1.isClass())
return javaClass1;
// if (dontProcessPackage(className)) {return javaClass1;}
sourceFileName = javaClass1.getSourceFileName();
for (int l = 0; l < attributes.length; l++) {
if (!SILENT)
Debugger.println("Attributes " + l + " " + attributes[l]);
String aName = constants.constantToString(attributes[l]
.getNameIndex(), Constants.CONSTANT_Utf8);
if (!SILENT)
Debugger.println("Attribute = " + aName);
if (aName == null)
continue;
if (aName.equals("Debugified")) {
if (!SILENT)
Debugger.println("This file already Debugified.");
alreadyDebugified = true;
return javaClass1;
}
}
if (!SILENT)
Debugger.println("Debugifying: " + classFileName + " "
+ Thread.currentThread());
warningPrinted = false; // 1 flag allowed per file.
cpg = new ConstantPoolGen(constants);
int loc = cpg.addUtf8("Debugified");
byte[] bytes = { 2 };
// CHECK THIS BEFORE ACCEPTING FILE AS CORRECT. (SOMEDAY)
Attribute att = new Unknown(loc, 1, bytes, cpg.getConstantPool());
Attribute[] attributes1 = new Attribute[attributes.length + 1];
for (int l = 0; l < attributes.length; l++) {
attributes1[l] = attributes[l];
}
attributes1[attributes.length] = att;
attributes = javaClass1.getAttributes();
if (!SILENT)
Debugger.println("Attributes of " + javaClass1);
//
try {
ClassGen classGen = new ClassGen(javaClass1);
classGen.isPublic(true);
if (!SILENT)
Debugger.println("Fields of ");
Field[] fields = classGen.getFields();
for (int j = 0; j < fields.length; j++) {
fields[j].isPublic(true);
fields[j].isPrivate(false);
fields[j].isProtected(false);
if (!SILENT)
Debugger.println(fields[j] + " Private: "
+ fields[j].isPrivate());
}
// Debugger.println("Fields of " + classGen );
reset();
JavaClass javaClass2 = classGen.getJavaClass();
javaClass2.setConstantPool(cpg.getFinalConstantPool());
// javaClass.setConstantPool(cpg);
alreadyDebugified = false;
javaClass2.setAttributes(attributes1);
// Debugger.println("JC " +javaClass1.toString());
// Debugger.println("GEN " +javaClass2.toString());
Repository.removeClass(javaClass1);
Repository.addClass(javaClass2);
String n = javaClass2.getClassName();
// verify(n);
if (Debugger.TRACE_LOADER)
System.out.print("+");
if (!SILENT)
Debugger.println("Debugified: " + classFileName);
return (javaClass2);
} catch (Exception e) {
Debugger.println("FAILED Debugified: " + classFileName + " "
+ className);
if (e instanceof DebuggerException)
outputStream.println(e);
else {
if (Debugger.DEBUG_DEBUGGER)
e.printStackTrace();
else
outputStream.println(e);
e.printStackTrace(); // EXTREA FOR THE MOMENT
}
outputStream.println("Unable to instrument: " + className);
return (javaClass1);
}
}
}
static boolean dontProcessPackage(String cName) {
if (calledFromDebugify)
return false; // If this is a direct request, do it!
int len = instrumentOnlyPackages.size();
if (len == 0)
return false;
for (int i = 0; i < len; i++) {
String iOnly = (String) instrumentOnlyPackages.elementAt(i);
// Debugger.println("only methods: " + cName + "."+ "? startswith "
// + iOnly);
if (iOnly.equals("")) {
int dot = cName.indexOf(".");
if (dot == -1)
return false;
} else if (cName.startsWith(iOnly))
return false;
}
if (!Defaults.didntInstrument.contains(cName))
Defaults.didntInstrument.add(cName);
return true;
}
static boolean dontProcessMethod(VectorD cmPairs, String mName,
String cName, boolean exact) { // true -> dont instrument/record
int len = cmPairs.size();
for (int i = 0; i < len; i++) {
String[] cmPair = (String[]) cmPairs.elementAt(i);
if (exact) {
if ((cName.equals(cmPair[0])) && mName.equals(cmPair[1]))
return true;
} else if (mName.equals("*") || mName.equals(cmPair[1])
|| cmPair[1].equals("*")
|| (mName.equals("") && cmPair[1].equals("new"))) { // if
// mName
// is a
// candidate
// Debugger.println("hidden methods: " + cName + "."+ mName +
// "?= " + cmPair[0] + "." + cmPair[1]);
if (cmPair[0].equals("*"))
return true;
if (cName.equals("*"))
return true;
if (cName.equals(cmPair[0]))
return true;
}
}
return false;
}
static boolean dontProcessMethod(VectorD cmPairs, String mName, String cName) {
return dontProcessMethod(cmPairs, mName, cName, false);
}
// ******************************************************** DEBUGIFY METHOD
// ****************************************************************
// ******************************************************** DEBUGIFY METHOD
// ****************************************************************
// ******************************************************** DEBUGIFY METHOD
// ****************************************************************
static void createCLinitPatch(ClassGen classGen, InstructionList patch,
MethodGen clinit) {
InstructionFactory factory = new InstructionFactory(cpg);
patch.append(new PUSH(cpg, version));
patch.append(new PUSH(cpg, className));
patch.append(factory.createInvoke("com.lambda.Debugger.D",
"verifyVersion", Type.VOID, new Type[] { Type.STRING,
Type.STRING }, Constants.INVOKESTATIC));
patch.append(factory.createInvoke(className, "ODB_declareVarMappings",
Type.VOID, new Type[] {}, Constants.INVOKESTATIC));
patch.append(factory.createInvoke(className, "ODB_classNameMethod",
Type.VOID, new Type[] {}, Constants.INVOKESTATIC));
patch.append(new PUSH(cpg, slVector.size()));
// patch.append(new ANEWARRAY(ObjectType.STRING)); ??
patch.append(factory.createInvoke("com.lambda.Debugger.D",
"createStringArray", stringArray, new Type[] { Type.INT },
Constants.INVOKESTATIC));
LocalVariableGen lvgArray = clinit.addLocalVariable("lvArray",
stringArray, null, null);
int lvArray = lvgArray.getIndex();
lvgArray.setStart(patch.append(new ASTORE(lvArray)));
for (int i = 0; i < slVector.size(); i += MAX_SOURCE_LINES) {
String mName = createSLStore(classGen, i);
patch.append(new ALOAD(lvArray));
patch.append(factory.createInvoke(className, mName, Type.VOID,
new Type[] { stringArray }, Constants.INVOKESTATIC));
}
patch.append(new ALOAD(lvArray));
patch.append(factory.createInvoke("com.lambda.Debugger.D",
"addSourceLines", Type.INT, new Type[] { stringArray },
Constants.INVOKESTATIC));
patch
.append(factory.createPutStatic(className, "ODB_offset",
Type.INT));
}
private static String createSLStore(ClassGen classGen, int start) {
int end = slVector.size();
if (end > 8000)
throw new DebuggerException("Too many lines in class "
+ classGen.getClassName() + " " + end + " > 8,000");
int lvArray = 0; // For a static method, the first arg is here
String mName = "ODB_slStoreMethod" + start;
InstructionList patch = new MyInstructionList();
MethodGen slStoreMethod = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC, Type.VOID, new Type[] { stringArray },
new String[] { "lvArray" }, mName, className, patch, cpg);
for (int j = start; j < end; j++) {
// Debugger.println("Adding source line: " + slVector.elementAt(j));
patch.append(new ALOAD(lvArray));
patch.append(new PUSH(cpg, j));
patch.append(new PUSH(cpg, (String) slVector.elementAt(j)));
patch.append(new AASTORE());
}
patch.append(InstructionConstants.RETURN);
slStoreMethod.setMaxStack();
Method m = slStoreMethod.getMethod();
classGen.addMethod(m);
patch.dispose();
return mName;
}
static void createCLinit(ClassGen classGen) { // If there is no clint
InstructionList patch = new MyInstructionList();
MethodGen clinit = new MethodGen(Constants.ACC_STATIC, Type.VOID,
new Type[] {}, new String[] {}, "", className, patch,
cpg);
createCLinitPatch(classGen, patch, clinit);
patch.append(InstructionConstants.RETURN);
clinit.setMaxStack();
classGen.addMethod(clinit.getMethod());
patch.dispose();
}
private static Method debugifyCLinit(ClassGen classGen, Method m) {
// If there IS a clinit
InstructionList patch = new MyInstructionList();
mg = new MethodGen(m, className, cpg);
removeUnknownAttributes();
il = mg.getInstructionList();
ihs = il.getInstructionHandles();
createCLinitPatch(classGen, patch, mg);
il.insert(ihs[0], patch);
patch.dispose();
mg.setMaxStack();
m = mg.getMethod();
processedCLINIT = true;
return m;
}
private static Method debugifyMethod(ClassGen classGen, Method m) {
name = m.getName();
factory = new InstructionFactory(cpg);
// outputStream.println("Debugifying: " + className + "." + name);
// if (name.equals("")) return(debugifyCLinit(classGen, m));
if (name.equals(""))
throw new DebuggerException("impossible");
code = m.getCode();
flags = m.getAccessFlags();
lineNumberTable = m.getLineNumberTable();
LocalVariableTable localVariableTable = m.getLocalVariableTable();
isSynchronized = m.isSynchronized();
String methodID = className + "." + name + ":" + (nMethods++);
// Debugger.println("Original Code length: "+code.getLength());
if (code == null)
return m;
if ((lineNumberTable == null) && (className != classNoNumbers)) {
Debugger.println("No line numbers available for: " + className);
classNoNumbers = className;
}
if (m.isNative() || m.isAbstract() || (code == null)
|| dontProcessMethod(dontInstrument, name, className)) {
if (!SILENT)
Debugger.println("Skipping " + className + " . " + name);
return m;
}
mg = new MethodGen(m, className, cpg);
removeUnknownAttributes();
boolean isStatic = mg.isStatic();
boolean isFinal = mg.isFinal();
LocalVariableGen lvs[] = mg.getLocalVariables();
mg.getLocalVariableTable(cpg);
LocalVariableTable lvt = localVariableTable;
lvgs = lvs;
returnType = mg.getReturnType();
il = mg.getInstructionList();
ceg = mg.getExceptionHandlers();
ihs = il.getInstructionHandles();
patch = new MyInstructionList();
Type[] argTypes = mg.getArgumentTypes();
String[] argNames = mg.getArgumentNames();
String[] exceptions = mg.getExceptions();
if (!NO_LOCKS)
mg.setAccessFlags(flags & ~Constants.ACC_SYNCHRONIZED);
if (!SILENT)
Debugger
.println("================Starting on "
+ (isFinal ? "final " : "")
+ (isStatic ? "static " : "") + returnType + " "
+ name + "() No. Instructions:" + ihs.length + "\n"
+ lineNumberTable + "\n===============");
localVariables = createMissingVarTable(lvs);
int nLocals = localVariables.length;
// if (!mg.isStatic()) nLocals--; // Don't count "this"
int nArgs = argNames.length;
// checkForRET(); // XXXXXXXXXXXXXX
bindMethodNames(patch, cpg);
appendVarMapping(methodID, mg);
lg = mg.addLocalVariable("tl", traceLine, null, null);
tl = lg.getIndex();
lg2 = mg.addLocalVariable("tl2", traceLine, null, null);
tl2 = lg2.getIndex();
if (!SILENT)
Debugger.println("Original Byte Code for " + name + " \n" + il);
// ************************* START PATCHING WITH D.addUnparented()
// ****************************************
doCATCH(code);
line = getLineNumber(0);
IFNONNULL branch;
patch
.append(factory.createGetStatic(className, "ODB_offset",
Type.INT));
patch.append(new PUSH(cpg, buildFileLineN(className, sourceFileName,
line)));
patch.append(new IADD());
patch.append(new PUSH(cpg, name));
patch.append(new PUSH(cpg, methodID));
patch.append(new PUSH(cpg, nLocals));
patch.append(new INVOKESTATIC(D_getPreviousTL));
patch.append(new DUP());
patch.append(branch = new IFNONNULL(null));
{
patch.append(new POP());
patch.append(factory.createGetStatic(className, "ODB_offset",
Type.INT));
patch.append(new PUSH(cpg, buildFileLineN(className,
sourceFileName, line)));
patch.append(new IADD());
if (isStatic || name.equals("")) {
insertGetClass(className, patch);
} else
patch.append(new ALOAD(0));
patch.append(new PUSH(cpg, name));
patch.append(new PUSH(cpg, methodID));
patch.append(new PUSH(cpg, nLocals));
int nArgsRecorded = calculateNArguments(argTypes, lvs, isStatic);
// int nArgsRecorded = Math.min(argTypes.length, MAX_ARGS_RECORDED);
// i nArgsRecorded =Math.min(lvs.length-1, MAX_ARGS_RECORDED);
for (int i = 0; i < nArgsRecorded; i++) {
Type type = argTypes[i];
int index;
if ((!isStatic) && (lvs.length <= i + 1))
outputStream.println("IMPOSSIBLE2 " + lvs[0].getName());
// if ((isStatic) && (lvs.length <= i))
// outputStream.println("IMPOSSIBLE1");
if (isStatic)
index = lvs[i].getIndex();
else
index = lvs[i + 1].getIndex();
if (type instanceof ReferenceType) {
patch.append(new ALOAD(index));
} else if (type == Type.INT) {
patch.append(new ILOAD(index));
patch.append(new INVOKESTATIC(D_createShadowInt));
} else if (type == Type.SHORT) {
patch.append(new ILOAD(index));
patch.append(new INVOKESTATIC(D_createShadowShort));
} else if (type == Type.BYTE) {
patch.append(new ILOAD(index));
patch.append(new INVOKESTATIC(D_createShadowByte));
} else if (type == Type.CHAR) {
patch.append(new ILOAD(index));
patch.append(new INVOKESTATIC(D_createShadowChar));
} else if (type == Type.BOOLEAN) {
patch.append(new ILOAD(index));
patch.append(new INVOKESTATIC(D_createShadowBoolean));
} else if (type == Type.FLOAT) {
patch.append(new FLOAD(index));
patch.append(new INVOKESTATIC(D_createShadowFloat));
}
if (type == Type.DOUBLE) {
patch.append(new DLOAD(index));
patch.append(new INVOKESTATIC(D_createShadowDouble));
}
if (type == Type.LONG) {
patch.append(new LLOAD(index));
patch.append(new INVOKESTATIC(D_createShadowLong));
}
}
switch (nArgsRecorded) {
case 0:
patch.append(new INVOKESTATIC(D_addUnparented0));
break;
case 1:
patch.append(new INVOKESTATIC(D_addUnparented1));
break;
case 2:
patch.append(new INVOKESTATIC(D_addUnparented2));
break;
case 3:
patch.append(new INVOKESTATIC(D_addUnparented3));
break;
case 4:
patch.append(new INVOKESTATIC(D_addUnparented4));
break;
case 5:
patch.append(new INVOKESTATIC(D_addUnparented5));
break;
case 6:
patch.append(new INVOKESTATIC(D_addUnparented6));
break;
case 7:
patch.append(new INVOKESTATIC(D_addUnparented7));
break;
case 8:
patch.append(new INVOKESTATIC(D_addUnparented8));
break;
case 9:
patch.append(new INVOKESTATIC(D_addUnparented9));
break;
case 10:
patch.append(new INVOKESTATIC(D_addUnparented10));
break;
default:
throw new DebuggerException("nArgs>MAX");
}
lg.setStart(patch.append(new ASTORE(tl))); // `tl' valid from here
branch.setTarget(lg.getStart());
if (!SILENT)
Debugger.println("Inserting D.addUnparented():\n" + patch);
// *************************** CHECK FOR SYNCHRONIZED METHOD
// ********************************
if (isSynchronized) {
// Debugger.println("This method: " + m + " is synchronized.");
doMethodLock(patch);
}
il.insert(ihs[0], patch);
doARGUMENTS(nArgsRecorded);
}
// ******************************** THE MAIN LOOP
// ********************************
boolean initMethodBeforeSuperCall = name.equals("");
for (int j = 0; j < ihs.length; j++) {
ins = ihs[j].getInstruction();
line = getLineNumber(ihs[j].getPosition());
if (!SILENT)
Debugger.println("Working on " + j + " " + ins + "\t\t" + line);
// This is a messy way of ensuring that references to THIS are not
// touched
// before the super constructor is called. An ugly compiler could
// fool us
// because we don't PROVE that the THIS ref is passed to super().
if (initMethodBeforeSuperCall) {
if (ins instanceof ALOAD) {
ALOAD al = (ALOAD) ins;
int index = al.getIndex();
if (index != 0)
continue;
while (!(ins instanceof INVOKESPECIAL)) {
j++;
ins = ihs[j].getInstruction();
}
if (ins instanceof INVOKESPECIAL) {
InvokeInstruction ii = (InvokeInstruction) ins;
String methodName = ii.getMethodName(cpg);
String methodClass = ii.getClassName(cpg);
if (true) { // (methodClass.equals("java.lang.Object"))
// {
// Debugger.println("Working on "+j+ " "+ins +
// "\t\t"+line);
initMethodBeforeSuperCall = false;
// 6 invokespecial #2
}
}
}
continue; // No calls allowed before super()
}
if (ins instanceof ATHROW) {
doATHROW(j);
continue;
}
if ((ins instanceof AASTORE) || (ins instanceof IASTORE)
|| (ins instanceof LASTORE) || (ins instanceof FASTORE)
|| (ins instanceof DASTORE) || (ins instanceof SASTORE)
|| (ins instanceof CASTORE) || (ins instanceof BASTORE)) {
createArray1DPatch(j);
continue;
}
if (ins instanceof StoreInstruction) {
createStorePatch(j);
continue;
}
if (ins instanceof PUTFIELD) {
doPUTFIELD(j);
continue;
}
if (ins instanceof PUTSTATIC) {
doPUTSTATIC(j);
continue;
}
if (ins instanceof IINC) {
doIINC(j);
continue;
}
if (ins instanceof ReturnInstruction) {
doRETURN(j); // ReturnMarker! not ReturnLine
continue;
}
if (ins instanceof INVOKEVIRTUAL) {
doINVOKEVIRTUAL(j, false, false);
continue;
}
if (ins instanceof INVOKEINTERFACE) {
doINVOKEVIRTUAL(j, false, false);
continue;
}
if (ins instanceof INVOKESTATIC) {
doINVOKESTATIC(j);
continue;
}
if (ins instanceof INVOKESPECIAL) {
doINVOKESPECIAL(j);
continue;
}
if (ins instanceof NEWARRAY) {
doNEWARRAY(j);
continue;
}
if (ins instanceof ANEWARRAY) {
doNEWARRAY(j);
continue;
}
if (ins instanceof MULTIANEWARRAY) {
doNEWARRAY(j);
continue;
}
if (ins instanceof MONITORENTER) {
doMONITORENTER(j);
continue;
}
if (ins instanceof MONITOREXIT) {
doMONITOREXIT(j);
continue;
}
if (ins instanceof NEW) {
// THE REAL WORK COMES IN THE CONSTRUCTORS
doNEW(j);
continue;
}
} // ******************************** THE MAIN LOOP
// ********************************
if (isSynchronized) {
doMethodLockExit();
}
if (patch.size() > 0)
Debugger
.println("Oh Shit! ****************************************************************\n"
+ patch);
lg.setEnd(ihs[ihs.length - 1]);
// We need a target for end of patch EXISTING?
mg.setMaxStack();
m = mg.getMethod();
if (!SILENT)
Debugger.println("New Byte Code for " + name + " \n" + il);
if (!SILENT)
Debugger.println("==============Done on " + name
+ " No. Instructions:" + ihs.length
+ "==============\n\n\n");
il.dispose(); // Reuse instruction handles
Code code1 = m.getCode();
if (code1.getLength() > 60000)
throw new DebuggerException(
"Method too long. Instrumented version of " + m + " "
+ code1.getLength() + " > 60,000 bytes."
+ " Original version " + code.getLength());
/*
* if ((code1.getLength() > 9000) || ( ((code1.getLength()*10) /
* code.getLength()) > 50) ) { Debugger.println("Orig Code length:
* "+code.getLength()); Debugger.println("Instrumented Code length:
* "+code1.getLength()); Debugger.println("Ratio: "+
* ((code1.getLength()*10) / code.getLength())); }
*/
return m;
}
private static void removeUnknownAttributes() {
Attribute[] attrs = mg.getCodeAttributes();
for (Attribute a : attrs) {
// System.out.println("attr: " + a);
// System.out.println();
// int ix = a.getNameIndex();
// ConstantPool cp = a.getConstantPool();
byte tag = a.getTag();
// if (tag==-1) tag= Constants.CONSTANT_Utf8;
// Constant c = cp.getConstant(ix);
// String s = c.toString();
// if (s.equals("LocalVariableTypeTable")) {
if (tag == -1) {
// System.out.println("removing: " + a);
mg.removeCodeAttribute(a);
}
}
}
private static int calculateNArguments(Type[] argTypes,
LocalVariableGen[] lvs, boolean isStatic) {
int nArgsRecorded = Math.min(argTypes.length, MAX_ARGS_RECORDED);
for (int i = 0; i < nArgsRecorded; i++) {
LocalVariableGen lvg;
if (isStatic) {
if (i >= lvs.length)
return i;
lvg = lvs[i];
} else {
if (i + 1 >= lvs.length)
return i;
lvg = lvs[i + 1];
}
int index = lvg.getIndex();
if (index > 0)
return i;
}
return nArgsRecorded;
}
/*
* Order of instructions:
*
* new astore -> value [dup] invokespecial push filename push line aload <-
* value invokestatic newObj
*
*/
private static InstructionHandle firstIns;
static void doMethodLock(InstructionList patch) {
if (NO_LOCKS)
return;
patch
.append(factory.createGetStatic(className, "ODB_offset",
Type.INT));
patch.append(new PUSH(cpg, buildFileLineN(className, sourceFileName,
line)));
patch.append(new IADD());
if (mg.isStatic() || name.equals("")) {
// patch.append(new PUSH(cpg, className));
// patch.append(new INVOKESTATIC(D_createShadowClass));
// patch.append(factory.createInvoke("java.lang.Class", "forName",
// typeClass, new Type[] {Type.STRING}, Constants.INVOKESTATIC));
// patch.append(new INVOKESTATIC(D_createShadowClass1));
insertGetClass(className, patch);
} else
patch.append(new ALOAD(0));
patch.append(new ALOAD(tl));
patch.append(new INVOKESTATIC(D_gettingLock));
if (mg.isStatic() || name.equals("")) {
// patch.append(new PUSH(cpg, className));
// patch.append(new INVOKESTATIC(D_createShadowClass));
// patch.append(factory.createInvoke("java.lang.Class", "forName",
// typeClass, new Type[] {Type.STRING}, Constants.INVOKESTATIC));
// patch.append(new INVOKESTATIC(D_createShadowClass1));
insertGetClass(className, patch);
} else
patch.append(new ALOAD(0));
patch.append(new MONITORENTER());
firstIns = patch.append(new PUSH(cpg, buildFileLineN(className,
sourceFileName, line)));
patch
.append(factory.createGetStatic(className, "ODB_offset",
Type.INT));
patch.append(new IADD());
if (mg.isStatic() || name.equals("")) {
// patch.append(new PUSH(cpg, className));
// patch.append(new INVOKESTATIC(D_createShadowClass));
// patch.append(factory.createInvoke("java.lang.Class", "forName",
// typeClass, new Type[] {Type.STRING}, Constants.INVOKESTATIC));
// patch.append(new INVOKESTATIC(D_createShadowClass1));
insertGetClass(className, patch);
} else
patch.append(new ALOAD(0));
patch.append(new ALOAD(tl));
patch.append(new INVOKESTATIC(D_gotLock));
}
static void doMONITORENTER(int j) {
if (NO_LOCKS)
return;
LocalVariableGen lg1 = mg.addLocalVariable("obj", Type.OBJECT, null,
null);
int obj = lg1.getIndex();
lg1.setStart(patch.append(new ASTORE(obj))); //
patch
.append(factory.createGetStatic(className, "ODB_offset",
Type.INT));
patch.append(new PUSH(cpg, buildFileLineN(className, sourceFileName,
line)));
patch.append(new IADD());
patch.append(new ALOAD(obj));
patch.append(new ALOAD(tl));
patch.append(new INVOKESTATIC(D_gettingLock));
lg1.setEnd(patch.append(new ALOAD(obj)));
// if (!SILENT) Debugger.println("Inserting
// throw:\n"+patch.toString(true));
// il.insert(ihs[j], patch);
insertPatch(ihs[j], "Inserting gettingLock:\n");
patch
.append(factory.createGetStatic(className, "ODB_offset",
Type.INT));
patch.append(new PUSH(cpg, buildFileLineN(className, sourceFileName,
line)));
patch.append(new IADD());
patch.append(new ALOAD(obj));
patch.append(new ALOAD(tl));
patch.append(new INVOKESTATIC(D_gotLock));
appendPatch(ihs[j], "Appending gotLock:\n");
}
static void doMethodLockExit() { // When you see a synchronized method
if (NO_LOCKS)
return;
// InstructionHandle firstIns = ihs[0];
InstructionHandle lastIns = ihs[ihs.length - 1];
InstructionHandle secondLastIns;
if (ihs.length < 2)
secondLastIns = lastIns;
else
secondLastIns = ihs[ihs.length - 2];
InstructionHandle exceptionIns = patch.append(new PUSH(cpg,
buildFileLineN(className, sourceFileName, line)));
patch
.append(factory.createGetStatic(className, "ODB_offset",
Type.INT));
patch.append(new IADD());
if (mg.isStatic() || name.equals("")) {
// patch.append(new PUSH(cpg, className));
// patch.append(new INVOKESTATIC(D_createShadowClass));
// patch.append(factory.createInvoke("java.lang.Class", "forName",
// typeClass, new Type[] {Type.STRING}, Constants.INVOKESTATIC));
// patch.append(new INVOKESTATIC(D_createShadowClass1));
insertGetClass(className, patch);
} else
patch.append(new ALOAD(0));
patch.append(new ALOAD(tl));
patch.append(new INVOKESTATIC(D_releasingLock));
if (mg.isStatic() || name.equals("")) {
// patch.append(new PUSH(cpg, className));
// patch.append(new INVOKESTATIC(D_createShadowClass));
// patch.append(factory.createInvoke("java.lang.Class", "forName",
// typeClass, new Type[] {Type.STRING}, Constants.INVOKESTATIC));
// patch.append(new INVOKESTATIC(D_createShadowClass1));
insertGetClass(className, patch);
} else
patch.append(new ALOAD(0));
patch.append(new MONITOREXIT());
patch.append(new ATHROW());
appendPatch(lastIns, "Inserting D_releasingLock:\n");
// This was secondLastIns, Why???
mg.addExceptionHandler(firstIns, lastIns, exceptionIns, new ObjectType(
"java.lang.Exception"));
// null == "all"
}
static void doLockReturn(int j) { // when you see a return() instruction
// in a synch method
if (NO_LOCKS)
return;
patch
.append(factory.createGetStatic(className, "ODB_offset",
Type.INT));
patch.append(new PUSH(cpg, buildFileLineN(className, sourceFileName,
line)));
patch.append(new IADD());
if (mg.isStatic() || name.equals("")) {
// patch.append(new PUSH(cpg, className));
// patch.append(new INVOKESTATIC(D_createShadowClass));
// patch.append(factory.createInvoke("java.lang.Class", "forName",
// typeClass, new Type[] {Type.STRING}, Constants.INVOKESTATIC));
// patch.append(new INVOKESTATIC(D_createShadowClass1));
insertGetClass(className, patch);
} else
patch.append(new ALOAD(0));
patch.append(new ALOAD(tl));
patch.append(new INVOKESTATIC(D_releasingLock));
if (mg.isStatic() || name.equals("")) {
// patch.append(new PUSH(cpg, className));
// patch.append(new INVOKESTATIC(D_createShadowClass));
// patch.append(factory.createInvoke("java.lang.Class", "forName",
// typeClass, new Type[] {Type.STRING}, Constants.INVOKESTATIC));
// patch.append(new INVOKESTATIC(D_createShadowClass1));
insertGetClass(className, patch);
} else
patch.append(new ALOAD(0));
patch.append(new MONITOREXIT());
insertPatch(ihs[j], "Inserting D_releasingLock:\n");
}
static void doMONITOREXIT(int j) {
if (NO_LOCKS)
return;
LocalVariableGen lg1 = mg.addLocalVariable("obj", Type.OBJECT, null,
null);
int obj = lg1.getIndex();
lg1.setStart(patch.append(new ASTORE(obj))); //
patch
.append(factory.createGetStatic(className, "ODB_offset",
Type.INT));
patch.append(new PUSH(cpg, buildFileLineN(className, sourceFileName,
line)));
patch.append(new IADD());
patch.append(new ALOAD(obj));
patch.append(new ALOAD(tl));
patch.append(new INVOKESTATIC(D_releasingLock));
lg1.setEnd(patch.append(new ALOAD(obj)));
// if (!SILENT) Debugger.println("Inserting
// throw:\n"+patch.toString(true));
// il.insert(ihs[j], patch);
insertPatch(ihs[j], "Inserting D_releasingLock:\n");
}
static void doNEW(int j) {
NEW ii = (NEW) ins;
String methodClass = ii.getType(cpg).toString();
if (DONT_REPLACE_VECTOR)
return;
if (methodClass.equals("java.util.Vector"))
patch.append(factory.createNew("com.lambda.Debugger.MyVector"));
else if (methodClass.equals("java.util.Hashtable"))
patch.append(factory.createNew("com.lambda.Debugger.MyHashtable"));
else if (methodClass.equals("java.util.HashMap"))
patch.append(factory.createNew("com.lambda.Debugger.MyHashMap"));
else if (methodClass.equals("java.util.ArrayList"))
patch.append(factory.createNew("com.lambda.Debugger.MyArrayList"));
// else if (methodClass.equals("java.util.HashMapXXXXXXXX"))
// patch.append(factory.createNew("com.lambda.Debugger.MyHashMap"));
else
return;
replacePatch(ihs[j], "Replacing w/My Vector/Hashtable:\n");
replacingVector = true;
}
static void doNEWARRAY(int j) {
if (NO_NEW)
return;
if (!SILENT)
Debugger.println("doNEWARRAY ");
patch.append(new DUP());
patch
.append(factory.createGetStatic(className, "ODB_offset",
Type.INT));
patch.append(new PUSH(cpg, buildFileLineN(className, sourceFileName,
line)));
patch.append(new IADD());
patch.append(new INVOKESTATIC(D_newArray));
appendPatch(ihs[j], "Inserting newArray");
}
static void doINVOKESPECIAL(int j) {
if (NO_NEW)
return;
InvokeInstruction ii = (InvokeInstruction) ins;
String methodClass = ii.getClassName(cpg);
String methodName = ii.getMethodName(cpg);
Type[] types = ii.getArgumentTypes(cpg);
// if (dontProcessMethod(dontRecord, "", methodClass)) return;
// if (dontProcessMethod(dontRecord, "", methodClass)) return;
if (!SILENT)
Debugger.println("doINVOKESPECIAL " + methodClass + "."
+ methodName + "()");
// doINVOKEVIRTUAL(j, false, (methodName == ""));
// doINVOKEVIRTUAL(j, false, true);
doINVOKEVIRTUAL(j, false, true);
if (!replacingVector)
return; // If in &1st instruction, it's a super call
if (methodClass.equals("java.util.Vector"))
patch.append(factory.createInvoke("com.lambda.Debugger.MyVector",
"", Type.VOID, types, Constants.INVOKESPECIAL));
else if (methodClass.equals("java.util.Hashtable"))
patch.append(factory.createInvoke(
"com.lambda.Debugger.MyHashtable", "", Type.VOID,
types, Constants.INVOKESPECIAL));
else if (methodClass.equals("java.util.HashMap"))
patch.append(factory.createInvoke("com.lambda.Debugger.MyHashMap",
"", Type.VOID, types, Constants.INVOKESPECIAL));
else if (methodClass.equals("java.util.ArrayList"))
patch.append(factory.createInvoke(
"com.lambda.Debugger.MyArrayList", "", Type.VOID,
types, Constants.INVOKESPECIAL));
else
return;
replacePatch(ihs[j], "Replacing w/ My Vector/Hashtable:\n");
replacingVector = false;
}
static void doARGUMENTS(int start) { // Only called from debugifyMethod()
if (NO_ARGUMENTS)
return;
String[] argNames = mg.getArgumentNames();
Type[] argTypes = mg.getArgumentTypes();
LocalVariableGen lvs[] = mg.getLocalVariables();
// LineNumber[] table = lineNumberTable.getLineNumberTable();
boolean isStatic = mg.isStatic();
/*
* if (table.length > 0) line = table[0].getLineNumber(); else line = 0;
*/
line = getLineNumber(0);
for (int i = start; i < argNames.length; i++) {
Type type = argTypes[i];
// LocalVariableGen lvg;
int index;
// if (isStatic) lvg = lvs[i]; else lvg = lvs[i+1];
if (isStatic)
index = lvs[i].getIndex();
else
index = lvs[i + 1].getIndex();
// if (!SILENT) Debugger.println(mg.getName()+" " +argNames[i]+": "
// +argTypes[i]+" "+lvg);
patch.append(factory.createGetStatic(className, "ODB_offset",
Type.INT));
patch.append(new PUSH(cpg, buildFileLineN(className,
sourceFileName, line)));
patch.append(new IADD());
patch.append(new PUSH(cpg, i));
if (type instanceof ReferenceType) {
patch.append(new ALOAD(index));
} else if (type == Type.INT) {
patch.append(new ILOAD(index));
patch.append(new INVOKESTATIC(D_createShadowInt));
} else if (type == Type.SHORT) {
patch.append(new ILOAD(index));
patch.append(new INVOKESTATIC(D_createShadowShort));
} else if (type == Type.BYTE) {
patch.append(new ILOAD(index));
patch.append(new INVOKESTATIC(D_createShadowByte));
} else if (type == Type.CHAR) {
patch.append(new ILOAD(index));
patch.append(new INVOKESTATIC(D_createShadowChar));
} else if (type == Type.BOOLEAN) {
patch.append(new ILOAD(index));
patch.append(new INVOKESTATIC(D_createShadowBoolean));
} else if (type == Type.FLOAT) {
patch.append(new FLOAD(index));
patch.append(new INVOKESTATIC(D_createShadowFloat));
}
if (type == Type.DOUBLE) {
patch.append(new DLOAD(index));
patch.append(new INVOKESTATIC(D_createShadowDouble));
}
if (type == Type.LONG) {
patch.append(new LLOAD(index));
patch.append(new INVOKESTATIC(D_createShadowLong));
}
patch.append(new ALOAD(tl));
patch.append(new INVOKESTATIC(D_bind));
}
// if (!SILENT) Debugger.println("Inserting (Arguments:
// \n"+patch.toString(true));
// il.insert(ihs[0], patch);
insertPatch(ihs[0], "Inserting Arguments: \n");
}
// catchEx(String sourceFileName, int line, Object ex, TraceLine tl)
// {//Exception
public static void doCATCH(Code code) {
if (NO_CATCH)
return;
if (!SILENT)
Debugger
.println("==========code.getExceptionHandlers() START-------------");
for (int i = 0; i < ceg.length; i++) {
if (!SILENT)
Debugger.println("CodeExceptionGen: " + ceg[i]);
}
ArrayList handlers = new ArrayList();
loop: for (int i = 0; i < ceg.length; i++) { // Don't repeat if
// multiple exceptions
// have same handler
InstructionHandle handlerPC = ceg[i].getHandlerPC();
for (int k = 0; k < i; k++) {
InstructionHandle ih2 = ceg[k].getHandlerPC();
if (ih2.getPosition() == handlerPC.getPosition()) {
// Debugger.println("Duplicate handler: " + ih2);
continue loop;
}
}
handlers.add(ceg[i]);
}
for (int i = 0; i < handlers.size(); i++) {
CodeExceptionGen eg = (CodeExceptionGen) handlers.get(i);
InstructionHandle handlerPC = eg.getHandlerPC();
line = getLineNumber(handlerPC.getPosition());
// lineNumberTable.getSourceLine(handlerPC.getPosition());
if (!SILENT)
Debugger.println("ADDING catch code before " + handlerPC);
LocalVariableGen lg1 = mg.addLocalVariable("exc", Type.OBJECT,
null, null);
int exc = lg1.getIndex();
lg1.setStart(patch.append(new ASTORE(exc))); //
patch.append(factory.createGetStatic(className, "ODB_offset",
Type.INT));
patch.append(new PUSH(cpg, buildFileLineN(className,
sourceFileName, line)));
patch.append(new IADD());
patch.append(new ALOAD(exc));
patch.append(new ALOAD(tl));
patch.append(new INVOKESTATIC(D_catch));
lg1.setEnd(patch.append(new ALOAD(exc)));
// if (!SILENT) Debugger.println("Inserting
// catch:\n"+patch.toString(true));
for (int ii = 0; ii < ceg.length; ii++) { // Retarget all
// exceptions using this
// hander
InstructionHandle handlerPC2 = ceg[ii].getHandlerPC();
if (handlerPC2 == handlerPC)
ceg[ii].setHandlerPC(patch.getStart());
// Why doesn't insertPatch() do this?
}
insertPatch(handlerPC, "Inserting Catch Code:\n");
}
if (!SILENT)
Debugger
.println("==========code.getExceptionHandlers() END-------------");
for (int i = 0; i < ceg.length; i++) {
if (!SILENT)
Debugger.println("CodeExceptionGen: " + ceg[i]);
}
}
// public static synchronized void throwEx(String sourceFileName, int line,
// Exception ex, TraceLine tl) {
public static void doATHROW(int j) {
if (NO_ATHROW)
return;
LocalVariableGen lg1 = mg.addLocalVariable("exc", Type.OBJECT, null,
null);
int exc = lg1.getIndex();
lg1.setStart(patch.append(new ASTORE(exc))); //
patch
.append(factory.createGetStatic(className, "ODB_offset",
Type.INT));
patch.append(new PUSH(cpg, buildFileLineN(className, sourceFileName,
line)));
patch.append(new IADD());
patch.append(new ALOAD(exc));
patch.append(new ALOAD(tl));
patch.append(new INVOKESTATIC(D_athrow));
lg1.setEnd(patch.append(new ALOAD(exc)));
// if (!SILENT) Debugger.println("Inserting
// throw:\n"+patch.toString(true));
// il.insert(ihs[j], patch);
insertPatch(ihs[j], "Inserting throw:\n");
}
private static String dummyName(int st) {
return "unnamedLocalVar" + st;
}
private static int lookupLocalVarIndex(int j, int storeTarget) {
int pos = ihs[j].getPosition() + ins.getLength();
int offSet = 0;
if ((localVariables.length > 0)
&& (localVariables[0].getName().equals("this")))
offSet = 1;
for (int i = 0; i < localVariables.length; i++) {
LocalVariable lv = localVariables[i];
if ((lv.getIndex() == storeTarget) && (lv.getStartPC() <= pos)
&& (lv.getStartPC() + lv.getLength() >= pos)) {
return i - offSet;
}
}
return -1;
}
public static void createStorePatch(int j) {
if (NO_ASTORE)
return;
int storeTarget = ((LocalVariableInstruction) ins).getIndex();
Type type = ((LocalVariableInstruction) ins).getType(cpg);
int targetIndex = 0;
targetIndex = lookupLocalVarIndex(j, storeTarget);
if (targetIndex == -1)
return; // Assume this is a compiler variable
IFNE branch = null;
if ((type == Type.INT) || (type == Type.OBJECT)) {
patch.append(new DUP());
patch.append(new PUSH(cpg, name));
if (type == Type.INT) {
patch.append(factory
.createInvoke("com.lambda.Debugger.D",
"skipChangeLocalVarI", Type.BOOLEAN,
new Type[] { Type.INT, Type.STRING },
Constants.INVOKESTATIC));
}
if (type == Type.OBJECT) {
patch.append(factory.createInvoke("com.lambda.Debugger.D",
"skipChangeLocalVarA", Type.BOOLEAN, new Type[] {
Type.OBJECT, Type.STRING },
Constants.INVOKESTATIC));
}
patch.append(branch = new IFNE(null));
}
if (type == Type.OBJECT) {
patch.append(new DUP());
} // Need exact type here
patch
.append(factory.createGetStatic(className, "ODB_offset",
Type.INT));
patch.append(new PUSH(cpg, buildFileLineN(className, sourceFileName,
line)));
patch.append(new IADD());
patch.append(new PUSH(cpg, targetIndex));
patch.append(new ALOAD(tl));
if (type == Type.OBJECT)
patch.append(new INVOKESTATIC(D_changeA)); // returns VOID!
else if (type == Type.INT)
patch.append(new INVOKESTATIC(D_changeI));
else if (type == Type.SHORT)
patch.append(new INVOKESTATIC(D_changeS));
else if (type == Type.BYTE)
patch.append(new INVOKESTATIC(D_changeB));
else if (type == Type.CHAR)
patch.append(new INVOKESTATIC(D_changeC));
else if (type == Type.BOOLEAN)
patch.append(new INVOKESTATIC(D_changeZ));
else if (type == Type.LONG)
patch.append(new INVOKESTATIC(D_changeL));
else if (type == Type.FLOAT)
patch.append(new INVOKESTATIC(D_changeF));
else if (type == Type.DOUBLE)
patch.append(new INVOKESTATIC(D_changeD));
if ((type == Type.INT) || (type == Type.OBJECT)) {
InstructionHandle ih = patch.append(new NOP());
branch.setTarget(ih);
}
insertPatch(ihs[j], "Appending D_change:" + type + "\n");
}
public static void doIINC(int j) {
if (NO_IINC)
return;
int storeTarget = ((LocalVariableInstruction) ins).getIndex();
int targetIndex = 0;
targetIndex = lookupLocalVarIndex(j, storeTarget);
if (targetIndex == -1)
return; // Assume this is a compiler variable
IFNE branch;
patch.append(new ILOAD(storeTarget));
patch.append(new PUSH(cpg, name));
patch.append(factory.createInvoke("com.lambda.Debugger.D",
"skipChangeLocalVarI", Type.BOOLEAN, new Type[] { Type.INT,
Type.STRING }, Constants.INVOKESTATIC));
patch.append(branch = new IFNE(null));
patch.append(new ILOAD(storeTarget));
patch
.append(factory.createGetStatic(className, "ODB_offset",
Type.INT));
patch.append(new PUSH(cpg, buildFileLineN(className, sourceFileName,
line)));
patch.append(new IADD());
patch.append(new PUSH(cpg, targetIndex));
patch.append(new ALOAD(tl));
patch.append(new INVOKESTATIC(D_changeIvoid));
InstructionHandle ih = patch.append(new NOP());
branch.setTarget(ih);
appendPatch(ihs[j], "Appending D_createShadowInt IINC D_change:");
}
public static void createArray1DPatch(int j) {
if (NO_AASTORE)
return;
Instruction storeIns, loadIns1, loadIns2 = null;
InvokeInstruction changeIns;
Type type = ((ArrayInstruction) ins).getType(cpg);
if (!SILENT)
Debugger.println("createArray1DPatch " + type + " " + ins);
LocalVariableGen lg3 = mg.addLocalVariable("value", type, null, null);
int value = lg3.getIndex();
if ((type == Type.INT) || (type == Type.SHORT) || (type == Type.BYTE)
|| (type == Type.CHAR) || (type == Type.BOOLEAN)) {
storeIns = new ISTORE(value);
loadIns1 = new ILOAD(value);
if (type == Type.INT)
changeIns = new INVOKESTATIC(D_changeArrayI);
else if (type == Type.SHORT)
changeIns = new INVOKESTATIC(D_changeArrayS);
else if (type == Type.BYTE)
changeIns = new INVOKESTATIC(D_changeArrayB);
else if (type == Type.CHAR)
changeIns = new INVOKESTATIC(D_changeArrayC);
else if (type == Type.BOOLEAN)
changeIns = new INVOKESTATIC(D_changeArrayZ);
else {
Debugger.println("IMPOSSIBLE1 createArray1DPatch" + type);
return;
}
} else if (type instanceof ReferenceType) {
storeIns = new ASTORE(value);
loadIns1 = new ALOAD(value);
loadIns2 = new ALOAD(value);
changeIns = new INVOKESTATIC(D_changeArrayA);
} else if (type == Type.LONG) {
storeIns = new LSTORE(value);
loadIns1 = new LLOAD(value);
changeIns = new INVOKESTATIC(D_changeArrayL);
} else if (type == Type.DOUBLE) {
storeIns = new DSTORE(value);
loadIns1 = new DLOAD(value);
changeIns = new INVOKESTATIC(D_changeArrayD);
} else if (type == Type.FLOAT) {
storeIns = new FSTORE(value);
loadIns1 = new FLOAD(value);
changeIns = new INVOKESTATIC(D_changeArrayF);
} else {
Debugger.println("IMPOSSIBLE2 createArray1DPatch" + type);
return;
}
IFNE branch = null;
if ((type == Type.INT) || (type == Type.OBJECT)) {
patch.append(new DUP());
patch.append(new PUSH(cpg, name));
if (type == Type.INT) {
patch.append(factory
.createInvoke("com.lambda.Debugger.D",
"skipChangeArrayI", Type.BOOLEAN, new Type[] {
Type.INT, Type.STRING },
Constants.INVOKESTATIC));
}
if (type == Type.OBJECT) {
patch.append(factory.createInvoke("com.lambda.Debugger.D",
"skipChangeArrayA", Type.BOOLEAN, new Type[] {
Type.OBJECT, Type.STRING },
Constants.INVOKESTATIC));
}
patch.append(branch = new IFNE(null));
}
lg3.setStart(patch.append(storeIns));
// This is the value to be stored.
patch.append(new DUP2()); // Load the index for him
patch.append(loadIns1); // Load the value for him
// Now the stack is restored.
// Change instance var: D.changeArray1D("foo.java", 75, Int[23]{3, 4,
// ...}, index, , tl) SET INSTANCE VAR
patch
.append(factory.createGetStatic(className, "ODB_offset",
Type.INT));
patch.append(new PUSH(cpg, buildFileLineN(className, sourceFileName,
line)));
patch.append(new IADD());
patch.append(new ALOAD(tl));
InstructionHandle h1 = patch.append(changeIns);
if (loadIns2 != null)
h1 = patch.append(loadIns2); // Load the value for us
lg3.setEnd(h1);
if ((type == Type.INT) || (type == Type.OBJECT)) {
InstructionHandle ih = patch.append(new NOP());
branch.setTarget(ih);
}
// if (!SILENT) Debugger.println("Inserting
// (D_changeArray1D:\n"+patch.toString(true));
// il.insert(ihs[j], patch);
insertPatch(ihs[j], "Inserting D_changeArray1D:\n");
}
public static void doPUTFIELD(int j) {
if (NO_PUTFIELD)
return;
createChangeIVPatch(false);
insertPatch(ihs[j], "Inserting D_changeIV:\n");
}
public static void doPUTSTATIC(int j) {
if (NO_PUTSTATIC)
return;
createChangeIVPatch(true);
insertPatch(ihs[j], "Inserting D_changeSTATIC:\n");
}
public static void createChangeIVPatch(boolean isStatic) {
String fieldName = ((FieldInstruction) ins).getFieldName(cpg);
Type fieldType = ((FieldInstruction) ins).getFieldType(cpg);
Type classType = ((FieldInstruction) ins).getClassType(cpg);
LocalVariableGen lg2 = mg.addLocalVariable("value", fieldType, null,
null);
int value = lg2.getIndex();
Instruction storeIns, loadIns1, loadIns2 = null;
InvokeInstruction changeIns;
int obj = -1;
LocalVariableGen lg1 = null;
if ((fieldType == Type.INT) || (fieldType == Type.SHORT)
|| (fieldType == Type.BYTE) || (fieldType == Type.CHAR)
|| (fieldType == Type.BOOLEAN)) {
storeIns = new ISTORE(value);
loadIns1 = new ILOAD(value);
if (fieldType == Type.INT)
changeIns = new INVOKESTATIC(D_changeIVI);
else if (fieldType == Type.SHORT)
changeIns = new INVOKESTATIC(D_changeIVS);
else if (fieldType == Type.BYTE)
changeIns = new INVOKESTATIC(D_changeIVB);
else if (fieldType == Type.CHAR)
changeIns = new INVOKESTATIC(D_changeIVC);
else if (fieldType == Type.BOOLEAN)
changeIns = new INVOKESTATIC(D_changeIVZ);
else
return; // impossible
if (!SILENT)
Debugger.println("doPUTFIELD " + fieldName + " " + fieldType
+ " " + changeIns.getMethodName(cpg));
} else if (fieldType instanceof ReferenceType) {
storeIns = new ASTORE(value);
loadIns1 = new ALOAD(value);
loadIns2 = new ALOAD(value);
changeIns = new INVOKESTATIC(D_changeIVA);
} else if (fieldType == Type.LONG) {
storeIns = new LSTORE(value);
loadIns1 = new LLOAD(value);
changeIns = new INVOKESTATIC(D_changeIVL);
} else if (fieldType == Type.DOUBLE) {
storeIns = new DSTORE(value);
loadIns1 = new DLOAD(value);
changeIns = new INVOKESTATIC(D_changeIVD);
} else if (fieldType == Type.FLOAT) {
storeIns = new FSTORE(value);
loadIns1 = new FLOAD(value);
changeIns = new INVOKESTATIC(D_changeIVF);
} else
return;
IFNE branch = null;
if ((fieldType == Type.INT) || (fieldType == Type.OBJECT)) {
patch.append(new DUP());
patch.append(new PUSH(cpg, name));
if (fieldType == Type.INT) {
patch.append(factory
.createInvoke("com.lambda.Debugger.D",
"skipChangeInstanceVarI", Type.BOOLEAN,
new Type[] { Type.INT, Type.STRING },
Constants.INVOKESTATIC));
}
if (fieldType == Type.OBJECT) {
patch.append(factory.createInvoke("com.lambda.Debugger.D",
"skipChangeInstanceVarA", Type.BOOLEAN, new Type[] {
Type.OBJECT, Type.STRING },
Constants.INVOKESTATIC));
}
patch.append(branch = new IFNE(null));
}
lg2.setStart(patch.append(storeIns));
// This is the value to be stored.
if (!isStatic) {
patch.append(new DUP()); // 'this'
} else {
// patch.append(new PUSH(cpg, classType.toString()));
// patch.append(new INVOKESTATIC(D_createShadowClass));
// patch.append(factory.createInvoke("java.lang.Class", "forName",
// typeClass, new Type[] {Type.STRING}, Constants.INVOKESTATIC));
// patch.append(new INVOKESTATIC(D_createShadowClass1));
insertGetClass(classType.toString(), patch);
}
patch.append(loadIns1); // Load the value
patch
.append(factory.createGetStatic(className, "ODB_offset",
Type.INT));
patch.append(new PUSH(cpg, buildFileLineN(className, sourceFileName,
line)));
patch.append(new IADD());
patch.append(new PUSH(cpg, fieldName));
patch.append(new ALOAD(tl));
patch.append(changeIns);
if (loadIns2 != null)
patch.append(loadIns2); // Load the value
if ((fieldType == Type.INT) || (fieldType == Type.OBJECT)) {
InstructionHandle ih = patch.append(new NOP());
branch.setTarget(ih);
}
}
/*
* public static void createChangeIVPatch(boolean isStatic) { String
* fieldName = ((FieldInstruction)ins).getFieldName(cpg); Type fieldType =
* ((FieldInstruction)ins).getFieldType(cpg); Type classType =
* ((FieldInstruction)ins).getClassType(cpg); LocalVariableGen lg2 =
* mg.addLocalVariable("value", fieldType, null, null); int value =
* lg2.getIndex(); Instruction storeIns, loadIns1, loadIns2;
* InvokeInstruction shadowIns; int obj= -1; LocalVariableGen lg1=null;
*
*
* if ((fieldType == Type.INT) || (fieldType == Type.SHORT) || (fieldType ==
* Type.BYTE) || (fieldType == Type.CHAR) || (fieldType == Type.BOOLEAN)) {
* storeIns = new ISTORE(value); loadIns1 = new ILOAD(value); loadIns2 = new
* ILOAD(value); if (fieldType == Type.INT) shadowIns = new
* INVOKESTATIC(D_createShadowInt); else if (fieldType == Type.SHORT)
* shadowIns = new INVOKESTATIC(D_createShadowShort); else if (fieldType ==
* Type.BYTE) shadowIns = new INVOKESTATIC(D_createShadowByte); else if
* (fieldType == Type.CHAR) shadowIns = new
* INVOKESTATIC(D_createShadowChar); else if (fieldType == Type.BOOLEAN)
* shadowIns = new INVOKESTATIC(D_createShadowBoolean); else return;
* //impossible if (!SILENT) Debugger.println("doPUTFIELD " + fieldName + " " +
* fieldType + " " + shadowIns.getMethodName(cpg)); } else if (fieldType
* instanceof ReferenceType) { storeIns = new ASTORE(value); loadIns1 = new
* ALOAD(value); loadIns2 = new ALOAD(value); shadowIns = null; } else if
* (fieldType == Type.LONG) { storeIns = new LSTORE(value); loadIns1 = new
* LLOAD(value); loadIns2 = new LLOAD(value); shadowIns = new
* INVOKESTATIC(D_createShadowLong); } else if (fieldType == Type.DOUBLE) {
* storeIns = new DSTORE(value); loadIns1 = new DLOAD(value); loadIns2 = new
* DLOAD(value); shadowIns = new INVOKESTATIC(D_createShadowDouble); } else
* if (fieldType == Type.FLOAT) { storeIns = new FSTORE(value); loadIns1 =
* new FLOAD(value); loadIns2 = new FLOAD(value); shadowIns = new
* INVOKESTATIC(D_createShadowFloat); } else return;
*
* lg2.setStart(patch.append(storeIns)); // This is the value to be stored.
*
* if (!isStatic) { lg1 = mg.addLocalVariable("obj", Type.OBJECT, null,
* null); obj = lg1.getIndex(); lg1.setStart(patch.append(new ASTORE(obj))); //
* This is the object for 'this' patch.append(new ALOAD(obj)); // Load the
* 'this' for him } patch.append(loadIns1); // Load the value for him // Now
* the stack is restored. // Change instance var: D.change("foo.java", 75,
* , "a", , tl) SET INSTANCE VAR
* patch.append(factory.createGetStatic(className, "ODB_offset", Type.INT));
* patch.append(new PUSH(cpg, buildFileLineN(className, sourceFileName,
* line))); patch.append(new IADD()); if (isStatic) { //patch.append(new
* PUSH(cpg, classType.toString())); //patch.append(new
* INVOKESTATIC(D_createShadowClass));
* //patch.append(factory.createInvoke("java.lang.Class", "forName",
* typeClass, new Type[] {Type.STRING}, Constants.INVOKESTATIC));
* //patch.append(new INVOKESTATIC(D_createShadowClass1));
* patch.append(getClassFromName(classType.toString())); } else
* lg1.setEnd(patch.append(new ALOAD(obj))); // Load the 'this' for us
* patch.append(new PUSH(cpg, fieldName));
* lg2.setEnd(patch.append(loadIns2)); // Load the value for us if
* (shadowIns != null) patch.append(shadowIns); patch.append(new ALOAD(tl));
* patch.append(new INVOKESTATIC(D_changeIV)); }
*/
static int[] retArray = new int[10000];
// Unlikey there'll be 10k RETs in one method.
static int retIndex = 0; // reset every method
public static void checkForRET() { // List ret targets in array & DON'T
// ASTORE them
retIndex = 0;
for (int j = 0; j < ihs.length; j++) {
Instruction ins = ihs[j].getInstruction();
if (!(ins instanceof RET))
continue;
// system.out.println("There's a
// RET!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");// XXXXXXXXXXXXXX
RET retIns = (RET) ins;
int storeTarget = retIns.getIndex();
// Debugger.println("ret "+ins +" target" + storeTarget);
retArray[retIndex] = storeTarget;
retIndex++;
}
}
public static boolean isRetTarget(int target) {
for (int i = 0; i < retIndex; i++)
if (retArray[i] == target)
return true;
return false;
}
public static void doRETURN(int j) { // Just a marker -- robust
if (isSynchronized)
doLockReturn(j);
if (NO_RETURN)
return;
if (returnType == Type.VOID) {
patch.append(factory.createGetStatic(className, "ODB_offset",
Type.INT));
patch.append(new PUSH(cpg, buildFileLineN(className,
sourceFileName, line)));
patch.append(new IADD());
patch.append(new ALOAD(tl));
patch.append(new INVOKESTATIC(D_returnMarker_0));
insertPatch(ihs[j], "Inserting doRETURN(void) patch");
return;
}
if (returnType == Type.LONG) {
patch.append(new DUP2());
patch.append(new INVOKESTATIC(D_createShadowLong));
} else if (returnType == Type.DOUBLE) {
patch.append(new DUP2());
patch.append(new INVOKESTATIC(D_createShadowDouble));
} else {
patch.append(new DUP());
if (returnType == Type.INT)
patch.append(new INVOKESTATIC(D_createShadowInt));
else if (returnType == Type.SHORT)
patch.append(new INVOKESTATIC(D_createShadowShort));
else if (returnType == Type.BYTE)
patch.append(new INVOKESTATIC(D_createShadowByte));
else if (returnType == Type.CHAR)
patch.append(new INVOKESTATIC(D_createShadowChar));
else if (returnType == Type.BOOLEAN)
patch.append(new INVOKESTATIC(D_createShadowBoolean));
else if (returnType == Type.FLOAT)
patch.append(new INVOKESTATIC(D_createShadowFloat));
else if (returnType instanceof ReferenceType)
;
else {
Debugger.println("IMPOSSIBLE: Appending returnValue "
+ returnType);
return;
}
}
patch
.append(factory.createGetStatic(className, "ODB_offset",
Type.INT));
patch.append(new PUSH(cpg, buildFileLineN(className, sourceFileName,
line)));
patch.append(new IADD());
patch.append(new ALOAD(tl));
patch.append(new INVOKESTATIC(D_returnMarker_1));
insertPatch(ihs[j], "Inserting doRETURN(value) patch");
}
public static void doINVOKESTATIC(int j) {
if (NO_INVOKESTATIC)
return;
doINVOKEVIRTUAL(j, true, false);
}
// Handles ALL combinations. (collects max 10 args)
public static void doINVOKEVIRTUAL(int j, boolean isStatic,
boolean isSpecial) {
doINVOKEVIRTUAL1(j, isStatic, isSpecial);
InvokeInstruction ii = (InvokeInstruction) ins;
String methodName = ii.getMethodName(cpg);
String methodClass = ii.getClassName(cpg);
Type[] types = ii.getArgumentTypes(cpg);
if ((methodName.equals("arraycopy"))
&& (methodClass.equals("java.lang.System")))
patch.append(factory.createInvoke("com.lambda.Debugger.MySystem",
"arraycopy", Type.VOID, types, Constants.INVOKESTATIC));
else if ((methodName.equals("sort"))
&& (methodClass.equals("java.util.Arrays")))
patch.append(factory.createInvoke("com.lambda.Debugger.MyArrays",
"sort", Type.VOID, types, Constants.INVOKESTATIC));
else if ((methodName.equals("fill"))
&& (methodClass.equals("java.util.Arrays")))
patch.append(factory.createInvoke("com.lambda.Debugger.MyArrays",
"fill", Type.VOID, types, Constants.INVOKESTATIC));
else
return;
replacePatch(ihs[j], "Replacing w/ MySystem:\n");
}
public static void doINVOKEVIRTUAL1(int j, boolean isStatic,
boolean isSpecial) {
if (NO_INVOKEVIRTUAL)
return;
InvokeInstruction invokeIns;
InvokeInstruction ii = (InvokeInstruction) ins;
Type returnType = ii.getReturnType(cpg);
String methodName = ii.getMethodName(cpg);
String methodClass = ii.getClassName(cpg);
Type[] argumentTypes = ii.getArgumentTypes(cpg);
LocalVariableGen lvg[] = new LocalVariableGen[argumentTypes.length];
int nArgsRecorded;
boolean isNew = (methodName.equals(""));
if (!SILENT)
Debugger.println("doINVOKEVIRTUAL(" + j + " " + isStatic + " "
+ isSpecial + " " + ii + " " + methodName + " "
+ methodClass);
OneObj = (!dontProcessMethod(dontRecord, methodName, methodClass));
// OneObj = (!dontRecord.contains(methodName)); // &&
// (argumentTypes.length <= MAX_ARGS_RECORDED));
if (!OneObj)
return;
if (methodName.equals("specialMethodThatBreaksDebugger"))
patch.append(new INVOKESTATIC(D_startingWait));
// This will produce bad byte code
for (int i = argumentTypes.length - 1; i >= 0; i--) { // Store the
// args for us
type = argumentTypes[i];
if (!SILENT)
Debugger.println("doINVOKEVIRTUAL " + type);
lvg[i] = mg.addLocalVariable("arg_" + i, type, null, null);
if (!SILENT)
Debugger.println("arg type " + type);
if (type instanceof ReferenceType) {
lvg[i].setStart(patch.append(new ASTORE(lvg[i].getIndex())));
} else if ((type == Type.INT) || (type == Type.BOOLEAN)
|| (type == Type.CHAR) || (type == Type.SHORT)
|| (type == Type.BYTE)) {
lvg[i].setStart(patch.append(new ISTORE(lvg[i].getIndex())));
} else if (type == Type.LONG) {
lvg[i].setStart(patch.append(new LSTORE(lvg[i].getIndex())));
} else if (type == Type.FLOAT) {
lvg[i].setStart(patch.append(new FSTORE(lvg[i].getIndex())));
} else if (type == Type.DOUBLE) {
lvg[i].setStart(patch.append(new DSTORE(lvg[i].getIndex())));
}
}
LocalVariableGen lg1 = mg.addLocalVariable("obj", Type.OBJECT, null,
null);
int obj = lg1.getIndex();
if (!isStatic) {
lg1.setStart(patch.append(new ASTORE(obj)));
// This is the object for 'this'
patch.append(new ALOAD(obj)); // Load the 'this' for him
}
for (int i = 0; i < argumentTypes.length; i++) { // Load the args for
// him
type = argumentTypes[i];
if (type instanceof ReferenceType) {
patch.append(new ALOAD(lvg[i].getIndex()));
} else if ((type == Type.INT) || (type == Type.BOOLEAN)
|| (type == Type.CHAR) || (type == Type.SHORT)
|| (type == Type.BYTE)) {
lvg[i].setStart(patch.append(new ILOAD(lvg[i].getIndex())));
} else if (type == Type.LONG) {
if (!SILENT)
Debugger.println("LLOAD TYPE!!*************************");
lvg[i].setStart(patch.append(new LLOAD(lvg[i].getIndex())));
} else if (type == Type.FLOAT) {
if (!SILENT)
Debugger.println("FLOAD TYPE!!*************************");
lvg[i].setStart(patch.append(new FLOAD(lvg[i].getIndex())));
} else if (type == Type.DOUBLE) {
if (!SILENT)
Debugger.println("DLOAD TYPE!!*************************");
lvg[i].setStart(patch.append(new DLOAD(lvg[i].getIndex())));
}
}
// The stack is now back to where it was
if (isSpecial) {
// insertPatch(ihs[j], "Inserting INVOKESPECIAL patch");
}
// ************************NOW START LOADING THE ARGUMENTS FOR
// INVOKE()*************************
// We will only load a max of MAX_ARGS_RECORDED arguments.
// THIS WILL BE A LITTLE TRICKY... LOAD THE FIRST MAX_ARGS_RECORDED
// ARGUMENTS
// public static synchronized TraceLine invoke(String sourceFileName,
// int line, Object o, String meth)
patch
.append(factory.createGetStatic(className, "ODB_offset",
Type.INT));
patch.append(new PUSH(cpg, buildFileLineN(className, sourceFileName,
line)));
patch.append(new IADD());
if (isStatic || isNew) {
// if (isSpecial && !isNew)
// insertGetClass("com.lambda.Debugger.SUPER", patch); else
insertGetClass(ii.getClassType(cpg).toString(), patch);
} else
lg1.setEnd(patch.append(new ALOAD(obj)));
if (!isNew)
patch.append(new PUSH(cpg, methodName));
patch.append(new ALOAD(tl));
if (argumentTypes.length > MAX_ARGS_RECORDED)
nArgsRecorded = MAX_ARGS_RECORDED;
else
nArgsRecorded = argumentTypes.length;
for (int i = 0; i < nArgsRecorded; i++) {
type = argumentTypes[i];
if (type instanceof ReferenceType) {
lvg[i].setEnd(patch.append(new ALOAD(lvg[i].getIndex())));
} else if (type == Type.INT) {
lvg[i].setEnd(patch.append(new ILOAD(lvg[i].getIndex())));
patch.append(new INVOKESTATIC(D_createShadowInt));
} else if (type == Type.SHORT) {
lvg[i].setEnd(patch.append(new ILOAD(lvg[i].getIndex())));
patch.append(new INVOKESTATIC(D_createShadowShort));
} else if (type == Type.BYTE) {
lvg[i].setEnd(patch.append(new ILOAD(lvg[i].getIndex())));
patch.append(new INVOKESTATIC(D_createShadowByte));
} else if (type == Type.CHAR) {
lvg[i].setEnd(patch.append(new ILOAD(lvg[i].getIndex())));
patch.append(new INVOKESTATIC(D_createShadowChar));
} else if (type == Type.BOOLEAN) {
lvg[i].setEnd(patch.append(new ILOAD(lvg[i].getIndex())));
patch.append(new INVOKESTATIC(D_createShadowBoolean));
} else if (type == Type.LONG) {
lvg[i].setStart(patch.append(new LLOAD(lvg[i].getIndex())));
patch.append(new INVOKESTATIC(D_createShadowLong));
} else if (type == Type.FLOAT) {
lvg[i].setStart(patch.append(new FLOAD(lvg[i].getIndex())));
patch.append(new INVOKESTATIC(D_createShadowFloat));
} else if (type == Type.DOUBLE) {
lvg[i].setStart(patch.append(new DLOAD(lvg[i].getIndex())));
patch.append(new INVOKESTATIC(D_createShadowDouble));
}
}
// The stack is now ready for us.
if (isNew) {
if (nArgsRecorded == 0)
invokeIns = new INVOKESTATIC(D_newObj_0);
else if (nArgsRecorded == 1)
invokeIns = new INVOKESTATIC(D_newObj_1);
else if (nArgsRecorded == 2)
invokeIns = new INVOKESTATIC(D_newObj_2);
else if (nArgsRecorded == 3)
invokeIns = new INVOKESTATIC(D_newObj_3);
else if (nArgsRecorded == 4)
invokeIns = new INVOKESTATIC(D_newObj_4);
else if (nArgsRecorded == 5)
invokeIns = new INVOKESTATIC(D_newObj_5);
else if (nArgsRecorded == 6)
invokeIns = new INVOKESTATIC(D_newObj_6);
else if (nArgsRecorded == 7)
invokeIns = new INVOKESTATIC(D_newObj_7);
else if (nArgsRecorded == 8)
invokeIns = new INVOKESTATIC(D_newObj_8);
else if (nArgsRecorded == 9)
invokeIns = new INVOKESTATIC(D_newObj_9);
else if (nArgsRecorded == 10)
invokeIns = new INVOKESTATIC(D_newObj_10);
else
throw new DebuggerException("nArgs>MAX");
} else {
if (methodName.equals("exit")
&& methodClass.equals("java.lang.System"))
invokeIns = new INVOKESTATIC(D_exit);
else if (nArgsRecorded == 0)
invokeIns = new INVOKESTATIC(D_invoke_0);
else if (nArgsRecorded == 1)
invokeIns = new INVOKESTATIC(D_invoke_1);
else if (nArgsRecorded == 2)
invokeIns = new INVOKESTATIC(D_invoke_2);
else if (nArgsRecorded == 3)
invokeIns = new INVOKESTATIC(D_invoke_3);
else if (nArgsRecorded == 4)
invokeIns = new INVOKESTATIC(D_invoke_4);
else if (nArgsRecorded == 5)
invokeIns = new INVOKESTATIC(D_invoke_5);
else if (nArgsRecorded == 6)
invokeIns = new INVOKESTATIC(D_invoke_6);
else if (nArgsRecorded == 7)
invokeIns = new INVOKESTATIC(D_invoke_7);
else if (nArgsRecorded == 8)
invokeIns = new INVOKESTATIC(D_invoke_8);
else if (nArgsRecorded == 9)
invokeIns = new INVOKESTATIC(D_invoke_9);
else if (nArgsRecorded == 10)
invokeIns = new INVOKESTATIC(D_invoke_10);
else
throw new DebuggerException("nArgs>MAX");
}
patch.append(invokeIns);
patch.append(new ASTORE(tl2)); // Save this TraceLine's return tl.
if (methodName.equals("wait") && (argumentTypes.length == 0)) {
// We really want Object.wait(), but we can't prove that. ??!
patch.append(factory.createGetStatic(className, "ODB_offset",
Type.INT));
patch.append(new PUSH(cpg, buildFileLineN(className,
sourceFileName, line)));
patch.append(new IADD());
patch.append(new ALOAD(obj));
patch.append(new ALOAD(tl));
patch.append(new INVOKESTATIC(D_startingWait));
}
// if (methodName.equals("join") &&
// methodClass.equals("java.lang.Thread")) {
if (methodName.equals("join") && (argumentTypes.length == 0)) {
patch.append(factory.createGetStatic(className, "ODB_offset",
Type.INT));
patch.append(new PUSH(cpg, buildFileLineN(className,
sourceFileName, line)));
patch.append(new IADD());
patch.append(new ALOAD(obj));
patch.append(new ALOAD(tl));
patch.append(new INVOKESTATIC(D_startingJoin));
}
insertPatch(ihs[j], "Inserting invokevirtual/invokespecial: \n");
// ******************************** Insert returnValue after it returns
// ********************************
if (NO_RETURNVALUE)
return;
// After the INVOKEVIRTUAL returns, we'll record the value and insert a
// D.returnValue()
// The stack is CLEAN when we start & finish this. Unrelated to the
// above.
if (methodName.equals("wait") && (argumentTypes.length == 0)) {
patch.append(factory.createGetStatic(className, "ODB_offset",
Type.INT));
patch.append(new PUSH(cpg, buildFileLineN(className,
sourceFileName, line)));
patch.append(new IADD());
patch.append(new ALOAD(obj));
patch.append(new ALOAD(tl));
patch.append(new INVOKESTATIC(D_endingWait));
}
// if (methodName.equals("join") &&
// methodClass.equals("java.lang.Thread")) {
if (methodName.equals("join") && (argumentTypes.length == 0)) {
patch.append(factory.createGetStatic(className, "ODB_offset",
Type.INT));
patch.append(new PUSH(cpg, buildFileLineN(className,
sourceFileName, line)));
patch.append(new IADD());
patch.append(new ALOAD(obj));
patch.append(new ALOAD(tl));
patch.append(new INVOKESTATIC(D_endingJoin));
}
if (isNew) {
// patch.append(new ALOAD(0));
lg1.setEnd(patch.append(new ALOAD(obj)));
patch.append(new ALOAD(tl2));
patch.append(new INVOKESTATIC(D_returnNew));
} else if (returnType == Type.VOID) {
patch.append(new ALOAD(tl2));
patch.append(new INVOKESTATIC(D_returnValue_0));
} else
createReturnPatch(returnType);
if (isNew)
appendPatch(ihs[j], "Appending returnNew: ");
else
appendPatch(ihs[j], "Appending returnValue: " + returnType);
} // doINVOKEVIRTUAL
/*
* public static void createReturnPatch (Type fieldType) { LocalVariableGen
* lg1 = mg.addLocalVariable("value", fieldType, null, null); int value =
* lg1.getIndex(); Instruction storeIns, loadIns1, loadIns2;
* InvokeInstruction shadowIns;
*
* if ((fieldType == Type.INT) || (fieldType == Type.SHORT) || (fieldType ==
* Type.BYTE) || (fieldType == Type.CHAR) || (fieldType == Type.BOOLEAN)) {
* storeIns = new ISTORE(value); loadIns1 = new ILOAD(value); loadIns2 = new
* ILOAD(value); if (fieldType == Type.INT) shadowIns = new
* INVOKESTATIC(D_createShadowInt); else if (fieldType == Type.SHORT)
* shadowIns = new INVOKESTATIC(D_createShadowShort); else if (fieldType ==
* Type.BYTE) shadowIns = new INVOKESTATIC(D_createShadowByte); else if
* (fieldType == Type.CHAR) shadowIns = new
* INVOKESTATIC(D_createShadowChar); else if (fieldType == Type.BOOLEAN)
* shadowIns = new INVOKESTATIC(D_createShadowBoolean); else return;
* //impossible } else if (fieldType instanceof ReferenceType) { storeIns =
* new ASTORE(value); loadIns1 = new ALOAD(value); loadIns2 = new
* ALOAD(value); shadowIns = null; } else if (fieldType == Type.LONG) {
* storeIns = new LSTORE(value); loadIns1 = new LLOAD(value); loadIns2 = new
* LLOAD(value); shadowIns = new INVOKESTATIC(D_createShadowLong); } else if
* (fieldType == Type.DOUBLE) { storeIns = new DSTORE(value); loadIns1 = new
* DLOAD(value); loadIns2 = new DLOAD(value); shadowIns = new
* INVOKESTATIC(D_createShadowDouble); } else if (fieldType == Type.FLOAT) {
* storeIns = new FSTORE(value); loadIns1 = new FLOAD(value); loadIns2 = new
* FLOAD(value); shadowIns = new INVOKESTATIC(D_createShadowFloat); } else {
* Debugger.println("IMPOSSIBLE: Appending returnValue " + fieldType);
* return; }
*
* lg1.setStart(patch.append(storeIns)); // `tl' valid from here
* patch.append(loadIns1); if (shadowIns != null) patch.append(shadowIns);
* patch.append(new ALOAD(tl2)); patch.append(new
* INVOKESTATIC(D_returnValue_1)); lg1.setEnd(patch.append(loadIns2));
*
* if (!SILENT) Debugger.println("Creating return patch " + fieldType); }
*/
public static void createReturnPatch(Type fieldType) {
if (fieldType instanceof ReferenceType)
patch.append(new DUP());
patch.append(new ALOAD(tl2));
if (fieldType == Type.DOUBLE)
patch.append(new INVOKESTATIC(D_returnValueD));
if (fieldType == Type.LONG)
patch.append(new INVOKESTATIC(D_returnValueL));
if (fieldType == Type.INT)
patch.append(new INVOKESTATIC(D_returnValueI));
if (fieldType == Type.BOOLEAN)
patch.append(new INVOKESTATIC(D_returnValueZ));
if (fieldType == Type.FLOAT)
patch.append(new INVOKESTATIC(D_returnValueF));
if (fieldType == Type.SHORT)
patch.append(new INVOKESTATIC(D_returnValueS));
if (fieldType == Type.CHAR)
patch.append(new INVOKESTATIC(D_returnValueC));
if (fieldType == Type.BYTE)
patch.append(new INVOKESTATIC(D_returnValueB));
if (fieldType instanceof ReferenceType)
patch.append(new INVOKESTATIC(D_returnValueA));
}
public static void appendPatch(InstructionHandle ih, String debug) {
if (!SILENT)
Debugger.println(debug + "\n" + patch);
InstructionHandle lastIHInPatch = patch.getEnd();
il.append(ih, patch);
/*
* NOT NECESSARY? BECAUSE WE PROMISE NEVER TO THROW FROM OUR CODE:
* D_invoke() etc. for (int i = 0; i < ceg.length; i++) { // The end of
* handlers for monitors must cover our code. InstructionHandle
* handlerEndPC= ceg[i].getEndPC(); // The other handlers, doesn't
* matter. if (ih == handlerEndPC) { if (!SILENT)
* Debugger.println("appendPatch redirecting handler end from:" +ih + "
* to: "+ lastIHInPatch); ceg[i].setEndPC(lastIHInPatch); return; } }
*/
return;
}
public static void replacePatch(InstructionHandle ih, String debug) {
if (!SILENT)
Debugger.println(debug + "\n" + patch);
InstructionHandle firstIHInPatch = patch.getStart();
il.append(ih, patch);
InstructionTargeter[] it = ih.getTargeters();
if (it != null) {
for (int i = 0; i < it.length; i++) {
if (!SILENT)
Debugger.println("Retargeting: " + className + " " + it[i]
+ " from " + ih + " to " + firstIHInPatch);
if (it[i] instanceof CodeExceptionGen) {
it[i].updateTarget(ih, firstIHInPatch);
} else {
it[i].updateTarget(ih, firstIHInPatch);
}
}
}
try {
il.delete(ih);
} catch (TargetLostException e) {
Debugger.println("Retargeting failed: " + className + " from " + ih
+ " to " + firstIHInPatch);
System.exit(1);
}
return;
}
public static void insertPatch(InstructionHandle ih, String debug) {
if (!SILENT)
Debugger.println(debug + "\n" + patch);
if (patch.size() == 0)
return;
InstructionHandle firstIHInPatch = patch.getStart();
il.insert(ih, patch);
InstructionTargeter[] it = ih.getTargeters();
if (it != null) {
for (int i = 0; i < it.length; i++) {
if (it[i] instanceof CodeExceptionGen) {
// if (!SILENT) Debugger.println("NOT Retargeting: " + it[i]
// + " from " + ih + " to " + firstIHInPatch); WHY NOT?
} else {
// if (!SILENT) Debugger.println("Retargeting: " + it[i] + "
// from " + ih + " to " + firstIHInPatch);
it[i].updateTarget(ih, firstIHInPatch);
}
}
}
return;
}
static LocalVariable[] createMissingVarTable(LocalVariableGen[] lvs) {
InstructionHandle firstIH = ihs[0], lastIH = ihs[ihs.length - 1];
Vector v = new Vector();
for (int i = 0; i < lvs.length; i++) {
LocalVariableGen lvg = lvs[i];
// if (lvg.getName().equals("this")) continue; I HAVE TO LOOK LIKE
// THEM!
v.add(lvg);
}
checkForRET();
for (int j = 0; j < ihs.length; j++) {
ins = ihs[j].getInstruction();
if ((ins instanceof IINC) || (ins instanceof StoreInstruction)) {
int storeTarget = ((LocalVariableInstruction) ins).getIndex();
Type type = ((LocalVariableInstruction) ins).getType(cpg);
if (isRetTarget(storeTarget))
continue; // NOT an OBJECT! "astore_3; ret 3"
if (member(storeTarget, v))
continue;
String name = "var" + v.size();
LocalVariableGen lvg = new LocalVariableGen(storeTarget, name,
type, firstIH, lastIH);
v.add(lvg);
}
}
LocalVariable[] newLV = new LocalVariable[v.size()];
for (int i = 0; i < newLV.length; i++) {
newLV[i] = ((LocalVariableGen) v.elementAt(i))
.getLocalVariable(cpg);
// Debugger.println("New LV: " + newLV[i]);
}
return newLV;
}
static boolean member(int target, Vector v) {
int len = v.size();
for (int i = 0; i < len; i++) {
LocalVariableGen lv = (LocalVariableGen) v.elementAt(i);
if (lv.getIndex() == target)
return true;
}
return false;
}
static void appendVarMapping(String methodID, MethodGen m) {
int start = 0;
if ((localVariables.length > 0)
&& (localVariables[0].getName().equals("this")))
start = 1;
patchVM.append(new PUSH(cpg, localVariables.length - start));
patchVM.append((CPInstruction) factory.createNewArray(Type.STRING,
(short) 1));
LocalVariableGen lvgArray = D_ODB_declareVarMappingsMethod
.addLocalVariable("lvArray", stringArray, null, null);
int lvArray = lvgArray.getIndex();
lvgArray.setStart(patchVM.append(new ASTORE(lvArray)));
for (int j = start; j < localVariables.length; j++) {
patchVM.append(new ALOAD(lvArray));
patchVM.append(new PUSH(cpg, j - start));
patchVM.append(new PUSH(cpg, localVariables[j].getName()));
patchVM.append(new AASTORE());
}
patchVM.append(new PUSH(cpg, methodID));
patchVM.append(new ALOAD(lvArray));
patchVM.append(factory.createInvoke("com.lambda.Debugger.D",
"appendVarNames", Type.VOID, new Type[] { Type.STRING,
stringArray }, Constants.INVOKESTATIC));
LocalVariableGen[] lvgs = m.getLocalVariables();
// Then varTypes
patchVM.append(new PUSH(cpg, localVariables.length - start));
patchVM.append((CPInstruction) factory.createNewArray(Type.STRING,
(short) 1));
patchVM.append(new ASTORE(lvArray));
for (int j = start; j < localVariables.length; j++) {
patchVM.append(new ALOAD(lvArray));
patchVM.append(new PUSH(cpg, j - start));
patchVM.append(new PUSH(cpg, localVariables[j].getSignature()));
patchVM.append(new AASTORE());
}
patchVM.append(new PUSH(cpg, methodID));
patchVM.append(new ALOAD(lvArray));
patchVM.append(new PUSH(cpg, returnType.getSignature()));
patchVM.append(new PUSH(cpg, className));
patchVM.append(factory.createInvoke("java.lang.Class", "forName",
typeClass, new Type[] { Type.STRING }, Constants.INVOKESTATIC));
patchVM.append(factory.createInvoke("java.lang.Class",
"getClassLoader", typeClassLoader, new Type[] {},
Constants.INVOKEVIRTUAL));
patchVM.append(factory.createInvoke("com.lambda.Debugger.D",
"appendVarTypes", Type.VOID, new Type[] { Type.STRING,
stringArray, Type.STRING, typeClassLoader },
Constants.INVOKESTATIC));
}
static InstructionList patchVM;
static InstructionFactory factoryVM;
static void createVarMappingsStart(ClassGen javaClass) {
factoryVM = new InstructionFactory(cpg);
patchVM = new MyInstructionList();
D_ODB_declareVarMappingsMethod = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC, Type.VOID, new Type[] {},
new String[] {}, "ODB_declareVarMappings", className, patchVM,
cpg);
}
static void createVarMappingsEnd(ClassGen javaClass) {
if (patchVM.size() > 40000)
throw new DebuggerException("Too many variables in class "
+ javaClass.getClassName() + " " + patchVM.size() / 4
+ " > 10,000");
patchVM.append(InstructionConstants.RETURN);
D_ODB_declareVarMappingsMethod.setMaxStack();
javaClass.addMethod(D_ODB_declareVarMappingsMethod.getMethod());
patchVM.dispose();
}
static void bindMethodNames(InstructionList patch, ConstantPoolGen cpg) {
bindMethodNames1(patch, cpg);
MethodGen D_getPreviousTLMethod = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED, traceLine,
new Type[] { Type.INT, Type.STRING, Type.STRING, Type.INT },
new String[] { "slIndex", "meth", "methodID", "nLocals" },
"getPreviousTL", "com.lambda.Debugger.D", patch, cpg);
D_getPreviousTL = cpg.addMethodref(D_getPreviousTLMethod);
MethodGen D_addUnparentedMethod0 = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED, traceLine,
new Type[] { Type.INT, Type.OBJECT, Type.STRING, Type.STRING,
Type.INT }, new String[] { "slIndex", "o", "meth",
"methodID", "nLocals" }, "addUnparented0",
"com.lambda.Debugger.D", patch, cpg);
D_addUnparented0 = cpg.addMethodref(D_addUnparentedMethod0);
MethodGen D_addUnparentedMethod8 = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED, traceLine,
new Type[] { Type.INT, Type.OBJECT, Type.STRING, Type.STRING,
Type.INT, Type.OBJECT, Type.OBJECT, Type.OBJECT,
Type.OBJECT, Type.OBJECT, Type.OBJECT, Type.OBJECT,
Type.OBJECT }, new String[] { "slIndex", "o", "meth",
"methodID", "nLocals", "arg0", "arg1", "arg2", "arg3",
"arg4", "arg5", "arg6", "arg7" }, "addUnparented8",
"com.lambda.Debugger.D", patch, cpg);
D_addUnparented8 = cpg.addMethodref(D_addUnparentedMethod8);
MethodGen D_addUnparentedMethod7 = new MethodGen(
Constants.ACC_STATIC | Constants.ACC_PUBLIC
| Constants.ACC_SYNCHRONIZED,
traceLine,
new Type[] { Type.INT, Type.OBJECT, Type.STRING, Type.STRING,
Type.INT, Type.OBJECT, Type.OBJECT, Type.OBJECT,
Type.OBJECT, Type.OBJECT, Type.OBJECT, Type.OBJECT },
new String[] { "slIndex", "o", "meth", "methodID", "nLocals",
"arg0", "arg1", "arg2", "arg3", "arg4", "arg5", "arg6" },
"addUnparented7", "com.lambda.Debugger.D", patch, cpg);
D_addUnparented7 = cpg.addMethodref(D_addUnparentedMethod7);
MethodGen D_addUnparentedMethod6 = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED, traceLine,
new Type[] { Type.INT, Type.OBJECT, Type.STRING, Type.STRING,
Type.INT, Type.OBJECT, Type.OBJECT, Type.OBJECT,
Type.OBJECT, Type.OBJECT, Type.OBJECT }, new String[] {
"slIndex", "o", "meth", "methodID", "nLocals", "arg0",
"arg1", "arg2", "arg3", "arg4", "arg5" },
"addUnparented6", "com.lambda.Debugger.D", patch, cpg);
D_addUnparented6 = cpg.addMethodref(D_addUnparentedMethod6);
MethodGen D_addUnparentedMethod5 = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED, traceLine,
new Type[] { Type.INT, Type.OBJECT, Type.STRING, Type.STRING,
Type.INT, Type.OBJECT, Type.OBJECT, Type.OBJECT,
Type.OBJECT, Type.OBJECT }, new String[] { "slIndex",
"o", "meth", "methodID", "nLocals", "arg0", "arg1",
"arg2", "arg3", "arg4" }, "addUnparented5",
"com.lambda.Debugger.D", patch, cpg);
D_addUnparented5 = cpg.addMethodref(D_addUnparentedMethod5);
MethodGen D_addUnparentedMethod4 = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED, traceLine,
new Type[] { Type.INT, Type.OBJECT, Type.STRING, Type.STRING,
Type.INT, Type.OBJECT, Type.OBJECT, Type.OBJECT,
Type.OBJECT },
new String[] { "slIndex", "o", "meth", "methodID", "nLocals",
"arg0", "arg1", "arg2", "arg3" }, "addUnparented4",
"com.lambda.Debugger.D", patch, cpg);
D_addUnparented4 = cpg.addMethodref(D_addUnparentedMethod4);
MethodGen D_addUnparentedMethod3 = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED, traceLine,
new Type[] { Type.INT, Type.OBJECT, Type.STRING, Type.STRING,
Type.INT, Type.OBJECT, Type.OBJECT, Type.OBJECT },
new String[] { "slIndex", "o", "meth", "methodID", "nLocals",
"arg0", "arg1", "arg2" }, "addUnparented3",
"com.lambda.Debugger.D", patch, cpg);
D_addUnparented3 = cpg.addMethodref(D_addUnparentedMethod3);
MethodGen D_addUnparentedMethod2 = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED, traceLine,
new Type[] { Type.INT, Type.OBJECT, Type.STRING, Type.STRING,
Type.INT, Type.OBJECT, Type.OBJECT }, new String[] {
"slIndex", "o", "meth", "methodID", "nLocals", "arg0",
"arg1" }, "addUnparented2", "com.lambda.Debugger.D",
patch, cpg);
D_addUnparented2 = cpg.addMethodref(D_addUnparentedMethod2);
MethodGen D_addUnparentedMethod1 = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED, traceLine,
new Type[] { Type.INT, Type.OBJECT, Type.STRING, Type.STRING,
Type.INT, Type.OBJECT }, new String[] { "slIndex", "o",
"meth", "methodID", "nLocals", "arg0" },
"addUnparented1", "com.lambda.Debugger.D", patch, cpg);
D_addUnparented1 = cpg.addMethodref(D_addUnparentedMethod1);
MethodGen D_addUnparentedMethod9 = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED, traceLine,
new Type[] { Type.INT, Type.OBJECT, Type.STRING, Type.STRING,
Type.INT, Type.OBJECT, Type.OBJECT, Type.OBJECT,
Type.OBJECT, Type.OBJECT, Type.OBJECT, Type.OBJECT,
Type.OBJECT, Type.OBJECT },
new String[] { "slIndex", "o", "meth", "methodID", "nLocals",
"arg0", "arg1", "arg2", "arg3", "arg4", "arg5", "arg6",
"arg7", "arg8" }, "addUnparented9",
"com.lambda.Debugger.D", patch, cpg);
D_addUnparented9 = cpg.addMethodref(D_addUnparentedMethod9);
MethodGen D_addUnparentedMethod10 = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED, traceLine,
new Type[] { Type.INT, Type.OBJECT, Type.STRING, Type.STRING,
Type.INT, Type.OBJECT, Type.OBJECT, Type.OBJECT,
Type.OBJECT, Type.OBJECT, Type.OBJECT, Type.OBJECT,
Type.OBJECT, Type.OBJECT, Type.OBJECT }, new String[] {
"slIndex", "o", "meth", "methodID", "nLocals", "arg0",
"arg1", "arg2", "arg3", "arg4", "arg5", "arg6", "arg7",
"arg8", "arg9" }, "addUnparented10",
"com.lambda.Debugger.D", patch, cpg);
D_addUnparented10 = cpg.addMethodref(D_addUnparentedMethod10);
MethodGen D_changeAMethod = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED, Type.VOID,
new Type[] { Type.OBJECT, Type.INT, Type.INT, traceLine },
new String[] { "value", "slIndex", "varIndex", "tl" },
"changeA", "com.lambda.Debugger.D", patch, cpg);
D_changeA = cpg.addMethodref(D_changeAMethod);
MethodGen D_changeIMethod = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED, Type.INT,
new Type[] { Type.INT, Type.INT, Type.INT, traceLine },
new String[] { "value", "slIndex", "varIndex", "tl" },
"changeI", "com.lambda.Debugger.D", patch, cpg);
D_changeI = cpg.addMethodref(D_changeIMethod);
MethodGen D_changeIvoidMethod = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED, Type.VOID,
new Type[] { Type.INT, Type.INT, Type.INT, traceLine },
new String[] { "value", "slIndex", "varIndex", "tl" },
"changeIvoid", "com.lambda.Debugger.D", patch, cpg);
D_changeIvoid = cpg.addMethodref(D_changeIvoidMethod);
MethodGen D_changeLMethod = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED, Type.LONG,
new Type[] { Type.LONG, Type.INT, Type.INT, traceLine },
new String[] { "value", "slIndex", "varIndex", "tl" },
"changeL", "com.lambda.Debugger.D", patch, cpg);
D_changeL = cpg.addMethodref(D_changeLMethod);
MethodGen D_changeBMethod = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED, Type.BYTE,
new Type[] { Type.BYTE, Type.INT, Type.INT, traceLine },
new String[] { "value", "slIndex", "varIndex", "tl" },
"changeB", "com.lambda.Debugger.D", patch, cpg);
D_changeB = cpg.addMethodref(D_changeBMethod);
MethodGen D_changeZMethod = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED,
Type.BOOLEAN, new Type[] { Type.BOOLEAN, Type.INT, Type.INT,
traceLine }, new String[] { "value", "slIndex",
"varIndex", "tl" }, "changeZ", "com.lambda.Debugger.D",
patch, cpg);
D_changeZ = cpg.addMethodref(D_changeZMethod);
MethodGen D_changeCMethod = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED, Type.CHAR,
new Type[] { Type.CHAR, Type.INT, Type.INT, traceLine },
new String[] { "value", "slIndex", "varIndex", "tl" },
"changeC", "com.lambda.Debugger.D", patch, cpg);
D_changeC = cpg.addMethodref(D_changeCMethod);
MethodGen D_changeSMethod = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED,
Type.SHORT, new Type[] { Type.SHORT, Type.INT, Type.INT,
traceLine }, new String[] { "value", "slIndex",
"varIndex", "tl" }, "changeS", "com.lambda.Debugger.D",
patch, cpg);
D_changeS = cpg.addMethodref(D_changeSMethod);
MethodGen D_changeFMethod = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED,
Type.FLOAT, new Type[] { Type.FLOAT, Type.INT, Type.INT,
traceLine }, new String[] { "value", "slIndex",
"varIndex", "tl" }, "changeF", "com.lambda.Debugger.D",
patch, cpg);
D_changeF = cpg.addMethodref(D_changeFMethod);
MethodGen D_changeDMethod = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED,
Type.DOUBLE, new Type[] { Type.DOUBLE, Type.INT, Type.INT,
traceLine }, new String[] { "value", "slIndex",
"varIndex", "tl" }, "changeD", "com.lambda.Debugger.D",
patch, cpg);
D_changeD = cpg.addMethodref(D_changeDMethod);
D_bindMethod = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED, Type.VOID,
new Type[] { Type.INT, Type.INT, Type.OBJECT, traceLine },
new String[] { "slIndex", "varIndex", "value", "tl" }, "bind",
"com.lambda.Debugger.D", patch, cpg);
D_bind = cpg.addMethodref(D_bindMethod);
D_newArrayMethod = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED, Type.VOID,
new Type[] { Type.OBJECT, Type.INT },
// NOTE REVERSED ORDER! (so I can use DUP)
new String[] { "array", "slIndex" }, "newArray",
"com.lambda.Debugger.D", patch, cpg);
D_newArray = cpg.addMethodref(D_newArrayMethod);
// ChangeD instance var: D.changeD("foo.java", 75, , "a",
// , tl) SET INSTANCE VAR
D_changeIVMethod = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED, Type.VOID,
new Type[] { Type.INT, Type.OBJECT, Type.STRING, Type.OBJECT,
traceLine }, new String[] { "slIndex", "o", "varName",
"value", "tl" }, "change", "com.lambda.Debugger.D",
patch, cpg);
D_changeIV = cpg.addMethodref(D_changeIVMethod);
MethodGen D_changeIVAMethod = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED, Type.VOID,
new Type[] { Type.OBJECT, Type.OBJECT, Type.INT, Type.STRING,
traceLine }, new String[] { "o", "value", "slIndex",
"varName", "tl" }, "changeIVA",
"com.lambda.Debugger.D", patch, cpg);
D_changeIVA = cpg.addMethodref(D_changeIVAMethod);
MethodGen D_changeIVBMethod = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED, Type.BYTE,
new Type[] { Type.OBJECT, Type.BYTE, Type.INT, Type.STRING,
traceLine }, new String[] { "o", "value", "slIndex",
"varName", "tl" }, "changeIVB",
"com.lambda.Debugger.D", patch, cpg);
D_changeIVB = cpg.addMethodref(D_changeIVBMethod);
MethodGen D_changeIVCMethod = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED, Type.CHAR,
new Type[] { Type.OBJECT, Type.CHAR, Type.INT, Type.STRING,
traceLine }, new String[] { "o", "value", "slIndex",
"varName", "tl" }, "changeIVC",
"com.lambda.Debugger.D", patch, cpg);
D_changeIVC = cpg.addMethodref(D_changeIVCMethod);
MethodGen D_changeIVSMethod = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED,
Type.SHORT, new Type[] { Type.OBJECT, Type.SHORT, Type.INT,
Type.STRING, traceLine }, new String[] { "o", "value",
"slIndex", "varName", "tl" }, "changeIVS",
"com.lambda.Debugger.D", patch, cpg);
D_changeIVS = cpg.addMethodref(D_changeIVSMethod);
MethodGen D_changeIVIMethod = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED, Type.INT,
new Type[] { Type.OBJECT, Type.INT, Type.INT, Type.STRING,
traceLine }, new String[] { "o", "value", "slIndex",
"varName", "tl" }, "changeIVI",
"com.lambda.Debugger.D", patch, cpg);
D_changeIVI = cpg.addMethodref(D_changeIVIMethod);
MethodGen D_changeIVLMethod = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED, Type.LONG,
new Type[] { Type.OBJECT, Type.LONG, Type.INT, Type.STRING,
traceLine }, new String[] { "o", "value", "slIndex",
"varName", "tl" }, "changeIVL",
"com.lambda.Debugger.D", patch, cpg);
D_changeIVL = cpg.addMethodref(D_changeIVLMethod);
MethodGen D_changeIVFMethod = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED,
Type.FLOAT, new Type[] { Type.OBJECT, Type.FLOAT, Type.INT,
Type.STRING, traceLine }, new String[] { "o", "value",
"slIndex", "varName", "tl" }, "changeIVF",
"com.lambda.Debugger.D", patch, cpg);
D_changeIVF = cpg.addMethodref(D_changeIVFMethod);
MethodGen D_changeIVDMethod = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED,
Type.DOUBLE, new Type[] { Type.OBJECT, Type.DOUBLE, Type.INT,
Type.STRING, traceLine }, new String[] { "o", "value",
"slIndex", "varName", "tl" }, "changeIVD",
"com.lambda.Debugger.D", patch, cpg);
D_changeIVD = cpg.addMethodref(D_changeIVDMethod);
MethodGen D_changeIVZMethod = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED,
Type.BOOLEAN, new Type[] { Type.OBJECT, Type.BOOLEAN, Type.INT,
Type.STRING, traceLine }, new String[] { "o", "value",
"slIndex", "varName", "tl" }, "changeIVZ",
"com.lambda.Debugger.D", patch, cpg);
D_changeIVZ = cpg.addMethodref(D_changeIVZMethod);
MethodGen D_changeArrayAMethod = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED, Type.VOID,
new Type[] { Type.OBJECT, Type.INT, Type.OBJECT, Type.INT,
traceLine }, new String[] { "array", "index", "value",
"slIndex", "tl" }, "changeArrayA",
"com.lambda.Debugger.D", patch, cpg);
D_changeArrayA = cpg.addMethodref(D_changeArrayAMethod);
MethodGen D_changeArrayZMethod = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED,
Type.BOOLEAN, new Type[] { Type.OBJECT, Type.INT, Type.BOOLEAN,
Type.INT, traceLine }, new String[] { "array", "index",
"value", "slIndex", "tl" }, "changeArrayZ",
"com.lambda.Debugger.D", patch, cpg);
D_changeArrayZ = cpg.addMethodref(D_changeArrayZMethod);
MethodGen D_changeArrayBMethod = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED, Type.BYTE,
new Type[] { Type.OBJECT, Type.INT, Type.BYTE, Type.INT,
traceLine }, new String[] { "array", "index", "value",
"slIndex", "tl" }, "changeArrayB",
"com.lambda.Debugger.D", patch, cpg);
D_changeArrayB = cpg.addMethodref(D_changeArrayBMethod);
MethodGen D_changeArrayCMethod = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED, Type.CHAR,
new Type[] { Type.OBJECT, Type.INT, Type.CHAR, Type.INT,
traceLine }, new String[] { "array", "index", "value",
"slIndex", "tl" }, "changeArrayC",
"com.lambda.Debugger.D", patch, cpg);
D_changeArrayC = cpg.addMethodref(D_changeArrayCMethod);
MethodGen D_changeArraySMethod = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED,
Type.SHORT, new Type[] { Type.OBJECT, Type.INT, Type.SHORT,
Type.INT, traceLine }, new String[] { "array", "index",
"value", "slIndex", "tl" }, "changeArrayS",
"com.lambda.Debugger.D", patch, cpg);
D_changeArrayS = cpg.addMethodref(D_changeArraySMethod);
MethodGen D_changeArrayIMethod = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED, Type.INT,
new Type[] { Type.OBJECT, Type.INT, Type.INT, Type.INT,
traceLine }, new String[] { "array", "index", "value",
"slIndex", "tl" }, "changeArrayI",
"com.lambda.Debugger.D", patch, cpg);
D_changeArrayI = cpg.addMethodref(D_changeArrayIMethod);
MethodGen D_changeArrayLMethod = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED, Type.LONG,
new Type[] { Type.OBJECT, Type.INT, Type.LONG, Type.INT,
traceLine }, new String[] { "array", "index", "value",
"slIndex", "tl" }, "changeArrayL",
"com.lambda.Debugger.D", patch, cpg);
D_changeArrayL = cpg.addMethodref(D_changeArrayLMethod);
MethodGen D_changeArrayFMethod = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED,
Type.FLOAT, new Type[] { Type.OBJECT, Type.INT, Type.FLOAT,
Type.INT, traceLine }, new String[] { "array", "index",
"value", "slIndex", "tl" }, "changeArrayF",
"com.lambda.Debugger.D", patch, cpg);
D_changeArrayF = cpg.addMethodref(D_changeArrayFMethod);
MethodGen D_changeArrayDMethod = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED,
Type.DOUBLE, new Type[] { Type.OBJECT, Type.INT, Type.DOUBLE,
Type.INT, traceLine }, new String[] { "array", "index",
"value", "slIndex", "tl" }, "changeArrayD",
"com.lambda.Debugger.D", patch, cpg);
D_changeArrayD = cpg.addMethodref(D_changeArrayDMethod);
}
static void bindMethodNames1(InstructionList patch, ConstantPoolGen cpg) {
// The int types
D_createShadowClassMethod = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED,
Type.OBJECT, new Type[] { Type.STRING },
new String[] { "className" }, "createShadowClass",
"com.lambda.Debugger.D", patch, cpg);
D_createShadowClass = cpg.addMethodref(D_createShadowClassMethod);
D_createShadowClass1Method = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED,
Type.OBJECT, new Type[] { typeClass },
new String[] { "className" }, "createShadowClass",
"com.lambda.Debugger.D", patch, cpg);
D_createShadowClass1 = cpg.addMethodref(D_createShadowClass1Method);
D_createShadowShortMethod = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED,
typeShadowShort, new Type[] { Type.SHORT },
new String[] { "i" }, "createShadowShort",
"com.lambda.Debugger.D", patch, cpg);
D_createShadowShort = cpg.addMethodref(D_createShadowShortMethod);
D_createShadowByteMethod = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED,
typeShadowByte, new Type[] { Type.BYTE }, new String[] { "i" },
"createShadowByte", "com.lambda.Debugger.D", patch, cpg);
D_createShadowByte = cpg.addMethodref(D_createShadowByteMethod);
D_createShadowCharMethod = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED,
typeShadowChar, new Type[] { Type.CHAR }, new String[] { "i" },
"createShadowChar", "com.lambda.Debugger.D", patch, cpg);
D_createShadowChar = cpg.addMethodref(D_createShadowCharMethod);
D_createShadowBooleanMethod = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED,
typeShadowBoolean, new Type[] { Type.BOOLEAN },
new String[] { "i" }, "createShadowBoolean",
"com.lambda.Debugger.D", patch, cpg);
D_createShadowBoolean = cpg.addMethodref(D_createShadowBooleanMethod);
D_createShadowIntMethod = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED,
typeShadowInt, new Type[] { Type.INT }, new String[] { "i" },
"createShadowInt", "com.lambda.Debugger.D", patch, cpg);
D_createShadowInt = cpg.addMethodref(D_createShadowIntMethod);
D_createShadowLongMethod = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED,
typeShadowLong, new Type[] { Type.LONG }, new String[] { "i" },
"createShadowLong", "com.lambda.Debugger.D", patch, cpg);
D_createShadowLong = cpg.addMethodref(D_createShadowLongMethod);
D_createShadowFloatMethod = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED,
typeShadowFloat, new Type[] { Type.FLOAT },
new String[] { "i" }, "createShadowFloat",
"com.lambda.Debugger.D", patch, cpg);
D_createShadowFloat = cpg.addMethodref(D_createShadowFloatMethod);
D_createShadowDoubleMethod = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED,
typeShadowDouble, new Type[] { Type.DOUBLE },
new String[] { "i" }, "createShadowDouble",
"com.lambda.Debugger.D", patch, cpg);
D_createShadowDouble = cpg.addMethodref(D_createShadowDoubleMethod);
D_returnValue_0Method = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED, Type.VOID,
new Type[] { traceLine }, new String[] { "tl" }, "returnValue",
"com.lambda.Debugger.D", patch, cpg);
D_returnValue_0 = cpg.addMethodref(D_returnValue_0Method);
MethodGen D_returnValueAMethod = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED, Type.VOID,
new Type[] { Type.OBJECT, traceLine }, new String[] { "rv",
"tl" }, "returnValue", "com.lambda.Debugger.D", patch,
cpg);
D_returnValueA = cpg.addMethodref(D_returnValueAMethod);
// XXX
MethodGen D_returnValueBMethod = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED, Type.BYTE,
new Type[] { Type.BYTE, traceLine },
new String[] { "rv", "tl" }, "returnValueB",
"com.lambda.Debugger.D", patch, cpg);
D_returnValueB = cpg.addMethodref(D_returnValueBMethod);
MethodGen D_returnValueCMethod = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED, Type.CHAR,
new Type[] { Type.CHAR, traceLine },
new String[] { "rv", "tl" }, "returnValueC",
"com.lambda.Debugger.D", patch, cpg);
D_returnValueC = cpg.addMethodref(D_returnValueCMethod);
MethodGen D_returnValueSMethod = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED,
Type.SHORT, new Type[] { Type.SHORT, traceLine }, new String[] {
"rv", "tl" }, "returnValueS", "com.lambda.Debugger.D",
patch, cpg);
D_returnValueS = cpg.addMethodref(D_returnValueSMethod);
MethodGen D_returnValueIMethod = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED, Type.INT,
new Type[] { Type.INT, traceLine },
new String[] { "rv", "tl" }, "returnValueI",
"com.lambda.Debugger.D", patch, cpg);
D_returnValueI = cpg.addMethodref(D_returnValueIMethod);
MethodGen D_returnValueZMethod = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED,
Type.BOOLEAN, new Type[] { Type.BOOLEAN, traceLine },
new String[] { "rv", "tl" }, "returnValueZ",
"com.lambda.Debugger.D", patch, cpg);
D_returnValueZ = cpg.addMethodref(D_returnValueZMethod);
MethodGen D_returnValueLMethod = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED, Type.LONG,
new Type[] { Type.LONG, traceLine },
new String[] { "rv", "tl" }, "returnValueL",
"com.lambda.Debugger.D", patch, cpg);
D_returnValueL = cpg.addMethodref(D_returnValueLMethod);
MethodGen D_returnValueFMethod = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED,
Type.FLOAT, new Type[] { Type.FLOAT, traceLine }, new String[] {
"rv", "tl" }, "returnValueF", "com.lambda.Debugger.D",
patch, cpg);
D_returnValueF = cpg.addMethodref(D_returnValueFMethod);
MethodGen D_returnValueDMethod = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED,
Type.DOUBLE, new Type[] { Type.DOUBLE, traceLine },
new String[] { "rv", "tl" }, "returnValueD",
"com.lambda.Debugger.D", patch, cpg);
D_returnValueD = cpg.addMethodref(D_returnValueDMethod);
// YYY
D_returnNewMethod = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED, Type.VOID,
new Type[] { Type.OBJECT, traceLine },
// SWITCHED ORDER!!!
new String[] { "rv", "tl" }, "returnNew",
"com.lambda.Debugger.D", patch, cpg);
D_returnNew = cpg.addMethodref(D_returnNewMethod);
// public static synchronized void throwEx(String slIndex, int line,
// Object ex, TraceLine tl)
D_athrowMethod = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED, Type.VOID,
new Type[] { Type.INT, Type.OBJECT, traceLine }, new String[] {
"slIndex", "ex", "tl" }, "throwEx",
"com.lambda.Debugger.D", patch, cpg);
D_athrow = cpg.addMethodref(D_athrowMethod);
// public static synchronized void catchEx(String slIndex, int line,
// Object ex, TraceLine tl)
D_catchMethod = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED, Type.VOID,
new Type[] { Type.INT, Type.OBJECT, traceLine }, new String[] {
"slIndex", "ex", "tl" }, "catchEx",
"com.lambda.Debugger.D", patch, cpg);
D_catch = cpg.addMethodref(D_catchMethod);
D_exitMethod = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED, traceLine,
new Type[] { Type.INT, Type.OBJECT, Type.STRING, traceLine,
Type.OBJECT }, new String[] { "slIndex", "o", "meth",
"tl", "arg1" }, "exit", "com.lambda.Debugger.D", patch,
cpg);
D_exit = cpg.addMethodref(D_exitMethod);
D_invoke_0Method = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED, traceLine,
new Type[] { Type.INT, Type.OBJECT, Type.STRING, traceLine },
new String[] { "slIndex", "o", "meth", "tl" }, "invoke",
"com.lambda.Debugger.D", patch, cpg);
D_invoke_0 = cpg.addMethodref(D_invoke_0Method);
D_invoke_1Method = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED, traceLine,
new Type[] { Type.INT, Type.OBJECT, Type.STRING, traceLine,
Type.OBJECT }, new String[] { "slIndex", "o", "meth",
"tl", "arg1" }, "invoke", "com.lambda.Debugger.D",
patch, cpg);
D_invoke_1 = cpg.addMethodref(D_invoke_1Method);
D_invoke_2Method = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED, traceLine,
new Type[] { Type.INT, Type.OBJECT, Type.STRING, traceLine,
Type.OBJECT, Type.OBJECT }, new String[] { "slIndex",
"o", "meth", "tl", "arg1", "arg2" }, "invoke",
"com.lambda.Debugger.D", patch, cpg);
D_invoke_2 = cpg.addMethodref(D_invoke_2Method);
D_invoke_3Method = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED, traceLine,
new Type[] { Type.INT, Type.OBJECT, Type.STRING, traceLine,
Type.OBJECT, Type.OBJECT, Type.OBJECT }, new String[] {
"slIndex", "o", "meth", "tl", "arg1", "arg2", "arg3" },
"invoke", "com.lambda.Debugger.D", patch, cpg);
D_invoke_3 = cpg.addMethodref(D_invoke_3Method);
D_invoke_4Method = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED, traceLine,
new Type[] { Type.INT, Type.OBJECT, Type.STRING, traceLine,
Type.OBJECT, Type.OBJECT, Type.OBJECT, Type.OBJECT },
new String[] { "slIndex", "o", "meth", "tl", "arg1", "arg2",
"arg3", "arg4" }, "invoke", "com.lambda.Debugger.D",
patch, cpg);
D_invoke_4 = cpg.addMethodref(D_invoke_4Method);
D_invoke_5Method = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED, traceLine,
new Type[] { Type.INT, Type.OBJECT, Type.STRING, traceLine,
Type.OBJECT, Type.OBJECT, Type.OBJECT, Type.OBJECT,
Type.OBJECT }, new String[] { "slIndex", "o", "meth",
"tl", "arg1", "arg2", "arg3", "arg4", "arg5" },
"invoke", "com.lambda.Debugger.D", patch, cpg);
D_invoke_5 = cpg.addMethodref(D_invoke_5Method);
MethodGen D_invoke_6Method = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED, traceLine,
new Type[] { Type.INT, Type.OBJECT, Type.STRING, traceLine,
Type.OBJECT, Type.OBJECT, Type.OBJECT, Type.OBJECT,
Type.OBJECT, Type.OBJECT }, new String[] { "slIndex",
"o", "meth", "tl", "arg1", "arg2", "arg3", "arg4",
"arg5", "arg6" }, "invoke", "com.lambda.Debugger.D",
patch, cpg);
D_invoke_6 = cpg.addMethodref(D_invoke_6Method);
MethodGen D_invoke_7Method = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED, traceLine,
new Type[] { Type.INT, Type.OBJECT, Type.STRING, traceLine,
Type.OBJECT, Type.OBJECT, Type.OBJECT, Type.OBJECT,
Type.OBJECT, Type.OBJECT, Type.OBJECT }, new String[] {
"slIndex", "o", "meth", "tl", "arg1", "arg2", "arg3",
"arg4", "arg5", "arg6", "arg7" }, "invoke",
"com.lambda.Debugger.D", patch, cpg);
D_invoke_7 = cpg.addMethodref(D_invoke_7Method);
MethodGen D_invoke_8Method = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED, traceLine,
new Type[] { Type.INT, Type.OBJECT, Type.STRING, traceLine,
Type.OBJECT, Type.OBJECT, Type.OBJECT, Type.OBJECT,
Type.OBJECT, Type.OBJECT, Type.OBJECT, Type.OBJECT },
new String[] { "slIndex", "o", "meth", "tl", "arg1", "arg2",
"arg3", "arg4", "arg5", "arg6", "arg7", "arg8" },
"invoke", "com.lambda.Debugger.D", patch, cpg);
D_invoke_8 = cpg.addMethodref(D_invoke_8Method);
MethodGen D_invoke_9Method = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED, traceLine,
new Type[] { Type.INT, Type.OBJECT, Type.STRING, traceLine,
Type.OBJECT, Type.OBJECT, Type.OBJECT, Type.OBJECT,
Type.OBJECT, Type.OBJECT, Type.OBJECT, Type.OBJECT,
Type.OBJECT }, new String[] { "slIndex", "o", "meth",
"tl", "arg1", "arg2", "arg3", "arg4", "arg5", "arg6",
"arg7", "arg8", "arg9" }, "invoke",
"com.lambda.Debugger.D", patch, cpg);
D_invoke_9 = cpg.addMethodref(D_invoke_9Method);
MethodGen D_invoke_10Method = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED, traceLine,
new Type[] { Type.INT, Type.OBJECT, Type.STRING, traceLine,
Type.OBJECT, Type.OBJECT, Type.OBJECT, Type.OBJECT,
Type.OBJECT, Type.OBJECT, Type.OBJECT, Type.OBJECT,
Type.OBJECT, Type.OBJECT }, new String[] { "slIndex",
"o", "meth", "tl", "arg1", "arg2", "arg3", "arg4",
"arg5", "arg6", "arg7", "arg8", "arg9", "arg10" },
"invoke", "com.lambda.Debugger.D", patch, cpg);
D_invoke_10 = cpg.addMethodref(D_invoke_10Method);
D_newObj_0Method = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED, traceLine,
new Type[] { Type.INT, Type.OBJECT, traceLine }, new String[] {
"slIndex", "o", "tl" }, "newObj",
"com.lambda.Debugger.D", patch, cpg);
D_newObj_0 = cpg.addMethodref(D_newObj_0Method);
D_newObj_1Method = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED, traceLine,
new Type[] { Type.INT, Type.OBJECT, traceLine, Type.OBJECT },
new String[] { "slIndex", "o", "tl", "arg1" }, "newObj",
"com.lambda.Debugger.D", patch, cpg);
D_newObj_1 = cpg.addMethodref(D_newObj_1Method);
D_newObj_2Method = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED, traceLine,
new Type[] { Type.INT, Type.OBJECT, traceLine, Type.OBJECT,
Type.OBJECT }, new String[] { "slIndex", "o", "tl",
"arg1", "arg2" }, "newObj", "com.lambda.Debugger.D",
patch, cpg);
D_newObj_2 = cpg.addMethodref(D_newObj_2Method);
D_newObj_3Method = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED, traceLine,
new Type[] { Type.INT, Type.OBJECT, traceLine, Type.OBJECT,
Type.OBJECT, Type.OBJECT }, new String[] { "slIndex",
"o", "tl", "arg1", "arg2", "arg3" }, "newObj",
"com.lambda.Debugger.D", patch, cpg);
D_newObj_3 = cpg.addMethodref(D_newObj_3Method);
D_newObj_4Method = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED, traceLine,
new Type[] { Type.INT, Type.OBJECT, traceLine, Type.OBJECT,
Type.OBJECT, Type.OBJECT, Type.OBJECT }, new String[] {
"slIndex", "o", "tl", "arg1", "arg2", "arg3", "arg4" },
"newObj", "com.lambda.Debugger.D", patch, cpg);
D_newObj_4 = cpg.addMethodref(D_newObj_4Method);
D_newObj_5Method = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED, traceLine,
new Type[] { Type.INT, Type.OBJECT, traceLine, Type.OBJECT,
Type.OBJECT, Type.OBJECT, Type.OBJECT, Type.OBJECT },
new String[] { "slIndex", "o", "tl", "arg1", "arg2", "arg3",
"arg4", "arg5" }, "newObj", "com.lambda.Debugger.D",
patch, cpg);
D_newObj_5 = cpg.addMethodref(D_newObj_5Method);
MethodGen D_newObj_6Method = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED, traceLine,
new Type[] { Type.INT, Type.OBJECT, traceLine, Type.OBJECT,
Type.OBJECT, Type.OBJECT, Type.OBJECT, Type.OBJECT,
Type.OBJECT }, new String[] { "slIndex", "o", "tl",
"arg1", "arg2", "arg3", "arg4", "arg5", "arg6" },
"newObj", "com.lambda.Debugger.D", patch, cpg);
D_newObj_6 = cpg.addMethodref(D_newObj_6Method);
MethodGen D_newObj_7Method = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED, traceLine,
new Type[] { Type.INT, Type.OBJECT, traceLine, Type.OBJECT,
Type.OBJECT, Type.OBJECT, Type.OBJECT, Type.OBJECT,
Type.OBJECT, Type.OBJECT }, new String[] { "slIndex",
"o", "tl", "arg1", "arg2", "arg3", "arg4", "arg5",
"arg6", "arg7" }, "newObj", "com.lambda.Debugger.D",
patch, cpg);
D_newObj_7 = cpg.addMethodref(D_newObj_7Method);
MethodGen D_newObj_8Method = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED, traceLine,
new Type[] { Type.INT, Type.OBJECT, traceLine, Type.OBJECT,
Type.OBJECT, Type.OBJECT, Type.OBJECT, Type.OBJECT,
Type.OBJECT, Type.OBJECT, Type.OBJECT }, new String[] {
"slIndex", "o", "tl", "arg1", "arg2", "arg3", "arg4",
"arg5", "arg6", "arg7", "arg8" }, "newObj",
"com.lambda.Debugger.D", patch, cpg);
D_newObj_8 = cpg.addMethodref(D_newObj_8Method);
MethodGen D_newObj_9Method = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED, traceLine,
new Type[] { Type.INT, Type.OBJECT, traceLine, Type.OBJECT,
Type.OBJECT, Type.OBJECT, Type.OBJECT, Type.OBJECT,
Type.OBJECT, Type.OBJECT, Type.OBJECT, Type.OBJECT },
new String[] { "slIndex", "o", "tl", "arg1", "arg2", "arg3",
"arg4", "arg5", "arg6", "arg7", "arg8", "arg9" },
"newObj", "com.lambda.Debugger.D", patch, cpg);
D_newObj_9 = cpg.addMethodref(D_newObj_9Method);
MethodGen D_newObj_10Method = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED, traceLine,
new Type[] { Type.INT, Type.OBJECT, traceLine, Type.OBJECT,
Type.OBJECT, Type.OBJECT, Type.OBJECT, Type.OBJECT,
Type.OBJECT, Type.OBJECT, Type.OBJECT, Type.OBJECT,
Type.OBJECT }, new String[] { "slIndex", "o", "tl",
"arg1", "arg2", "arg3", "arg4", "arg5", "arg6", "arg7",
"arg8", "arg9", "arg10" }, "newObj",
"com.lambda.Debugger.D", patch, cpg);
D_newObj_10 = cpg.addMethodref(D_newObj_10Method);
D_returnMarkerMethod = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED, Type.VOID,
new Type[] { Type.INT, traceLine }, new String[] { "slIndex",
"tl" }, "returnMarker", "com.lambda.Debugger.D", patch,
cpg);
D_returnMarker_0 = cpg.addMethodref(D_returnMarkerMethod);
D_returnMarker_1Method = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED, Type.VOID,
new Type[] { Type.OBJECT, Type.INT, traceLine }, new String[] {
"rv", "slIndex", "tl" },
// INVERTED ARGS
"returnMarker", "com.lambda.Debugger.D", patch, cpg);
D_returnMarker_1 = cpg.addMethodref(D_returnMarker_1Method);
// void newObj(String slIndex, int line, Object o)
D_gettingLock_Method = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED, Type.VOID,
new Type[] { Type.INT, Type.OBJECT, traceLine }, new String[] {
"slIndex", "o", "tl" }, "gettingLock",
"com.lambda.Debugger.D", patch, cpg);
D_gettingLock = cpg.addMethodref(D_gettingLock_Method);
D_gotLock_Method = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED, Type.VOID,
new Type[] { Type.INT, Type.OBJECT, traceLine }, new String[] {
"slIndex", "o", "tl" }, "gotLock",
"com.lambda.Debugger.D", patch, cpg);
D_gotLock = cpg.addMethodref(D_gotLock_Method);
D_releasingLock_Method = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED, Type.VOID,
new Type[] { Type.INT, Type.OBJECT, traceLine }, new String[] {
"slIndex", "o", "tl" }, "releasingLock",
"com.lambda.Debugger.D", patch, cpg);
D_releasingLock = cpg.addMethodref(D_releasingLock_Method);
D_startingWait_Method = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED, Type.VOID,
new Type[] { Type.INT, Type.OBJECT, traceLine }, new String[] {
"slIndex", "o", "tl" }, "startingWait",
"com.lambda.Debugger.D", patch, cpg);
D_startingWait = cpg.addMethodref(D_startingWait_Method);
D_endingWait_Method = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED, Type.VOID,
new Type[] { Type.INT, Type.OBJECT, traceLine }, new String[] {
"slIndex", "o", "tl" }, "endingWait",
"com.lambda.Debugger.D", patch, cpg);
D_endingWait = cpg.addMethodref(D_endingWait_Method);
D_startingJoin_Method = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED, Type.VOID,
new Type[] { Type.INT, Type.OBJECT, traceLine }, new String[] {
"slIndex", "o", "tl" }, "startingJoin",
"com.lambda.Debugger.D", patch, cpg);
D_startingJoin = cpg.addMethodref(D_startingJoin_Method);
D_endingJoin_Method = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED, Type.VOID,
new Type[] { Type.INT, Type.OBJECT, traceLine }, new String[] {
"slIndex", "o", "tl" }, "endingJoin",
"com.lambda.Debugger.D", patch, cpg);
D_endingJoin = cpg.addMethodref(D_endingJoin_Method);
}
static MethodGen D_ODB_declareVarMappingsMethod;
static int D_ODB_declareVarMappings;
static MethodGen D_gettingLock_Method = null;
static MethodGen D_gotLock_Method = null;
static MethodGen D_releasingLock_Method = null;
static MethodGen D_startingWait_Method = null;
static MethodGen D_endingWait_Method = null;
static MethodGen D_startingJoin_Method = null;
static MethodGen D_endingJoin_Method = null;
static MethodGen D_addUnparentedMethod = null;
static MethodGen D_addUnparentedMethod_1 = null;
static MethodGen D_invokeMethod = null;
static MethodGen D_changeMethod = null;
static MethodGen D_bindMethod = null;
static MethodGen D_newArrayMethod = null;
static MethodGen D_changeIVMethod = null;
static MethodGen D_changeArray1DMethod = null;
static MethodGen D_createShadowClassMethod = null;
static MethodGen D_createShadowClass1Method = null;
static MethodGen D_createShadowIntMethod = null;
static MethodGen D_createShadowShortMethod = null;
static MethodGen D_createShadowByteMethod = null;
static MethodGen D_createShadowCharMethod = null;
static MethodGen D_createShadowBooleanMethod = null;
static MethodGen D_createShadowFloatMethod = null;
static MethodGen D_createShadowLongMethod = null;
static MethodGen D_createShadowDoubleMethod = null;
static MethodGen D_returnValue_0Method = null;
static MethodGen D_returnValue_1Method = null;
static MethodGen D_returnNewMethod = null;
static MethodGen D_exitMethod = null;
static MethodGen D_invoke_0Method = null;
static MethodGen D_invoke_1Method = null;
static MethodGen D_invoke_2Method = null;
static MethodGen D_invoke_3Method = null;
static MethodGen D_invoke_4Method = null;
static MethodGen D_invoke_5Method = null;
static MethodGen D_newObj_0Method = null;
static MethodGen D_newObj_1Method = null;
static MethodGen D_newObj_2Method = null;
static MethodGen D_newObj_3Method = null;
static MethodGen D_newObj_4Method = null;
static MethodGen D_newObj_5Method = null;
static MethodGen D_athrowMethod = null;
static MethodGen D_catchMethod = null;
// static MethodGen D_stampMethod = null;
static MethodGen D_returnMarkerMethod = null;
static MethodGen D_returnMarker_1Method = null;
// static MethodGen D_newObjMethod = null;
static boolean warningPrinted = false;
public static void printCompilerFlag() {
if (warningPrinted)
return;
Debugger.println("\n******************** PLEASE COMPILE "
+ sourceFileName + " WITH -g FLAG! ********************");
warningPrinted = true;
}
// AspectJ:
// "Display1.java;spacewar/Debug.java[1k];coordination/Coordinator.java[2k];spacewar/RegistrySynchronization.java[3k]"
// Java: "Display.java"
static Vector slVector;
static int slIndex;
static Hashtable slTable;
static void reset() {
nMethods = 0;
processedCLINIT = false;
slVector = new Vector();
slIndex = 0;
slTable = new Hashtable();
}
static int buildFileLineN(String className, String sourceFileName, int line) {
if (line == -1)
return -1; // No source lines
String fl = buildFileLine(className, sourceFileName, line);
// Debugger.println("throw at "+ sourceFileName + line);
Integer i = (Integer) slTable.get(fl);
return i.intValue();
}
static String buildFileLine(String className, String sourceFileName,
int line) {
String fl = buildFileLine0(className, sourceFileName, line);
Integer i = (Integer) slTable.get(fl);
if (i == null) {
slTable.put(fl, new Integer(slIndex));
slVector.add(fl);
slIndex++;
}
return fl;
}
static String buildFileLine0(String className, String sourceFileName,
int line) {
int start0 = 0, start1 = 0;
int semi = sourceFileName.indexOf(";");
if (semi < 0)
return (className + ":" + sourceFileName + ":" + line); // Java
if (line < 0) {
if (!SILENT)
Debugger.println("Bad line number: " + sourceFileName + ":"
+ line);
return (className + ":UnknownFile.java:2"); // Java
}
Vector v = new Vector();
{
String fn0 = sourceFileName, fn;
while (semi > 0) {
semi = fn0.indexOf(";");
if (semi > 0) {
fn = fn0.substring(0, semi);
// fn1 = "spacewar/Debug.java[1k]"
fn0 = fn0.substring(semi + 1, fn0.length());
// fn0 = "coordination/Coordinator.java[2k];spacewar/..."
} else
fn = fn0;
v.add(fn);
}
}
String fn0, fn1 = null;
int line0 = -1;
for (int i = 0; i < v.size(); i++) {
fn0 = (String) v.elementAt(i);
if (fn0.endsWith("]")) {
int open = fn0.indexOf("[");
String startString = fn0.substring(open + 1, fn0.length() - 1);
// startString = "2k"
if (startString.endsWith("k"))
start0 = Integer.parseInt(startString.substring(0,
startString.length() - 1)) * 1000;
// start = 2000
else
// throw new DebuggerException("Unknown start line
// "+startString+" in " +sourceFileName);
throw new NullPointerException("Unknown start line "
+ startString + " in " + sourceFileName);
fn0 = fn0.substring(0, open);
// fn = "coordination/Coordinator.java"
} else
start0 = 0;
if (line >= start0) {
start1 = start0;
fn1 = fn0;
} else {
line0 = line - start1;
int slash = fn1.lastIndexOf("/");
if (slash > 0)
fn1 = fn1.substring(slash + 1, fn1.length());
// fn1 = "Coordinator.java"
// Debugger.println("AspectJ: " + sourceFileName + ":"+line+" ->
// " +fn1+":"+line0);
return (className + ":" + fn1 + ":" + line0);
}
}
line0 = line - start1;
int slash = fn1.lastIndexOf("/");
if (slash > 0)
fn1 = fn1.substring(slash + 1, fn1.length());
// fn1 = "Coordinator.java"
// Debugger.println("AspectJ: " + sourceFileName + ":"+line+" -> "
// +fn1+":"+line0);
return (className + ":" + fn1 + ":" + line0);
}
public static void verify(String className) {
Verifier v = VerifierFactory.getVerifier(className);
VerificationResult vr;
vr = v.doPass1();
if (vr != VerificationResult.VR_OK)
throw new DebuggerException("Verifier Error in: " + className);
vr = v.doPass2();
if (vr != VerificationResult.VR_OK)
throw new DebuggerException("Verifier Error in: " + className);
JavaClass jc = null;
try {
jc = Repository.lookupClass(className);
} catch (ClassNotFoundException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
for (int i = 0; i < jc.getMethods().length; i++) {
vr = v.doPass3a(i);
if (vr != VerificationResult.VR_OK) {
Debugger.println("" + vr);
throw new DebuggerException("Verifier Error in: " + className);
}
vr = v.doPass3b(i);
if (vr != VerificationResult.VR_OK) {
Debugger.println("" + vr);
throw new DebuggerException("Verifier Error in: " + className);
}
}
}
private static int getLineNumber(int pc) {
int line;
if (lineNumberTable == null)
return -1;
try {
line = lineNumberTable.getSourceLine(pc);
} catch (ArrayIndexOutOfBoundsException e) {
// Debugger.println("Bad pos in lineNumberTable for: "+pc+"
// instruction: " + ihs[pc]); // This sucks! Fix BCEL
line = -1;
}
return line;
}
private static HashMap classTable = new HashMap();
private static void insertGetClass(String className1, InstructionList patch) {
IFNONNULL branch2;
String varName = getClassVar(className1);
patch.append(factory.createGetStatic(className, varName, typeClass));
patch.append(new DUP());
patch.append(branch2 = new IFNONNULL(null));
patch.append(new POP());
patch.append(new PUSH(cpg, className1));
patch.append(factory.createInvoke("java.lang.Class", "forName",
typeClass, new Type[] { Type.STRING }, Constants.INVOKESTATIC));
patch.append(new DUP());
patch.append(factory.createPutStatic(className, varName, typeClass));
branch2.setTarget(patch.append(new NOP()));
}
private static String getClassVar(String className1) {
String varName = (String) classTable.get(className1);
if (varName == null) {
varName = "ODB_classVar_" + classTable.size();
classTable.put(className1, varName);
}
return varName;
}
static void createClassNameMethod(ClassGen classGen) {
InstructionFactory factory = new InstructionFactory(cpg);
InstructionList patch = new MyInstructionList();
MethodGen D_ODB_classNameMethod = new MethodGen(Constants.ACC_STATIC
| Constants.ACC_PUBLIC, Type.VOID, new Type[] {},
new String[] {}, "ODB_classNameMethod", className, patch, cpg);
Iterator it = classTable.keySet().iterator();
while (it.hasNext()) {
String className1 = (String) it.next();
String varName = (String) classTable.get(className1);
Field f = new FieldGen(Constants.ACC_STATIC | Constants.ACC_FINAL
| Constants.ACC_PRIVATE, typeClass, varName, cpg)
.getField();
classGen.addField(f);
/*
* patch.append(new PUSH(cpg, className1)); patch.append(
* factory.createInvoke( "java.lang.Class", "forName", typeClass,
* new Type[] { Type.STRING }, Constants.INVOKESTATIC));
* patch.append( factory.createPutStatic(className, varName,
* typeClass));
*/
}
patch.append(InstructionConstants.RETURN);
D_ODB_classNameMethod.setMaxStack();
classGen.addMethod(D_ODB_classNameMethod.getMethod());
patch.dispose();
}
}
class MyInstructionList extends InstructionList {
public InstructionHandle append(Instruction arg0) {
if (!Debugify.SILENT)
Debugger.println("\t" + arg0);
return super.append(arg0);
}
public BranchHandle append(BranchInstruction arg0) {
if (!Debugify.SILENT)
Debugger.println("\t" + arg0);
return super.append(arg0);
}
public InstructionHandle append(CompoundInstruction arg0) {
if (!Debugify.SILENT)
Debugger.println("\t" + arg0);
return super.append(arg0);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy