📄 jasmparser.java
字号:
/*
*
*/
package ee.ioc.cs.jbe.browser.codeedit;
import java.util.ArrayList;
import org.apache.bcel.generic.*;
import org.gjt.jclasslib.bytecode.OpcodesUtil;
public class JAsmParser {
/*
* Parses the input code and returns an instructionlist, but also has a
* sideeffect: it updates the constant pool on the fly to have the required
* constants in the constant pool.
*/
private JAsmParseException parseException = new JAsmParseException();
public InstructionList parse(String code, ConstantPoolGen cpg)
throws JAsmParseException {
code = code.replaceAll("\r", "");
String[] codeLines = code.split("\n");
if (codeLines.length == 1 && codeLines[0].equals("")) {
return new InstructionList();
}
InstructionList instructions = new InstructionList();
ArrayList<InstructionHandle> instructionHandleList = new ArrayList<InstructionHandle> ();
ArrayList<TempSwitchData> lookupSwitches = new ArrayList<TempSwitchData>();
ArrayList<TempSwitchData> tableSwitches = new ArrayList<TempSwitchData>();
ArrayList<BranchPair> branches = new ArrayList<BranchPair>();
InstructionHandle ih;
String[] instrElems;
int codeLength = countLines(codeLines);
// InstructionHandle[] iha = new InstructionHandle[strt.countTokens()];
int labels = 0;
int switchMode = 0; // 0- normal , 1- tableswitch, 2 - lookupswitch
String fullInstr;
String instrName;
TempSwitchData tempSwitch = new TempSwitchData();
for (int i = 0; i < codeLines.length; i++) {
fullInstr = codeLines[i];
//switchmode, 1 denoting tableswitch, 2 lookupswitch
if (beginsWithWhitespace(fullInstr) && switchMode == 1) {
boolean isDefault = isDefaultLine(fullInstr.trim());
if (isDefault) {
int target = getLookupTarget(fullInstr.trim(), labels,
codeLength);
tempSwitch.getBranchPairs().add(
new BranchPair(-1, target));
} else {
int target = getTableArg(fullInstr.trim(), labels, codeLength);
tempSwitch.getBranchPairs().add(
new BranchPair(tempSwitch.getInitialLab(), target));
tempSwitch.incInitialLab();
}
} else if (beginsWithWhitespace(fullInstr) && switchMode == 2) {
int target = getLookupTarget(fullInstr.trim(), labels,
codeLength);
int value = getLookupSource(fullInstr.trim(), labels);
tempSwitch.getBranchPairs().add(new BranchPair(value, target));
} else if (beginsWithWhitespace(fullInstr)) {
parseException.addError(JAsmParseException.WHITESPACE_ERROR,
fullInstr, labels-1);
} else {
if (switchMode == 1) {
TABLESWITCH ts = new TABLESWITCH();
ih = instructions.append(ts);
instructionHandleList.add(ih);
tempSwitch.setHandle(ih);
tableSwitches.add(tempSwitch);
labels++;
switchMode = 0;
} else if (switchMode == 2) {
LOOKUPSWITCH ls = new LOOKUPSWITCH();
ih = instructions.append(ls);
instructionHandleList.add(ih);
tempSwitch.setHandle(ih);
lookupSwitches.add(tempSwitch);
labels++;
switchMode = 0;
}
instrElems = fullInstr.split(" ");
instrName = instrElems[0].toLowerCase().trim();
if (instrName.equals("bipush")) {
byte arg = getSingleByteArg(instrElems, labels);
ih = instructions.append(new BIPUSH(arg));
instructionHandleList.add(ih);
labels++;
} else if (instrName.equals("sipush")) {
short arg = getSingleShortArg(instrElems, labels);
ih = instructions.append(new SIPUSH(arg));
instructionHandleList.add(ih);
labels++;
} else if (instrName.equals("iinc")) {
int arg1 = 0;
int arg2 = 0;
try {
arg1 = Integer.parseInt(instrElems[1]);
arg2 = Integer.parseInt(instrElems[2]);
} catch (NumberFormatException nfe) {
parseException.addError(
JAsmParseException.INT_REQUIRED, instrElems[0],
labels);
} catch (ArrayIndexOutOfBoundsException aobe) {
parseException.addError(
JAsmParseException.MISSING_ARGUMENTS,
instrElems[0], labels);
}
ih = instructions.append(new IINC(arg1, arg2));
instructionHandleList.add(ih);
labels++;
}
/*
* Class and object operations.
*/
else if (instrName.equals("anewarray")) {
int arg = getClassConstRef(instrElems, cpg, labels);
ih = instructions.append(new ANEWARRAY(arg));
instructionHandleList.add(ih);
labels++;
} else if (instrName.equals("checkcast")) {
int arg = getClassConstRef(instrElems, cpg, labels);
ih = instructions.append(new CHECKCAST(arg));
instructionHandleList.add(ih);
labels++;
} else if (instrName.equals("instanceof")) {
int arg = getClassConstRef(instrElems, cpg, labels);
ih = instructions.append(new INSTANCEOF(arg));
instructionHandleList.add(ih);
labels++;
} else if (instrName.equals("new")) {
int arg = getClassConstRef(instrElems, cpg, labels);
ih = instructions.append(new NEW(arg));
instructionHandleList.add(ih);
labels++;
}
/*
* Invoke instructions
*/
else if (instrName.equals("invokevirtual")) {
int arg = getMethodConstRef(instrElems, cpg, labels);
ih = instructions.append(new INVOKEVIRTUAL(arg));
instructionHandleList.add(ih);
labels++;
} else if (instrName.equals("invokestatic")) {
int arg = getMethodConstRef(instrElems, cpg, labels);
ih = instructions.append(new INVOKESTATIC(arg));
instructionHandleList.add(ih);
labels++;
} else if (instrName.equals("invokespecial")) {
int arg = getMethodConstRef(instrElems, cpg, labels);
ih = instructions.append(new INVOKESPECIAL(arg));
instructionHandleList.add(ih);
labels++;
} else if (instrName.equals("invokeinterface")) {
int arg1 = Integer.parseInt(instrElems[1]);
int arg2 = Integer.parseInt(instrElems[1]);
ih = instructions.append(new INVOKEINTERFACE(arg1, arg2));
instructionHandleList.add(ih);
labels++;
}
/*
* Field instructions
*/
else if (instrName.equals("getstatic")) {
int arg = getFieldConstRef(instrElems, cpg, labels);
ih = instructions.append(new GETSTATIC(arg));
instructionHandleList.add(ih);
labels++;
} else if (instrName.equals("getfield")) {
int arg = getFieldConstRef(instrElems, cpg, labels);
ih = instructions.append(new GETFIELD(arg));
instructionHandleList.add(ih);
labels++;
} else if (instrName.equals("putstatic")) {
int arg = getFieldConstRef(instrElems, cpg, labels);
ih = instructions.append(new PUTSTATIC(arg));
instructionHandleList.add(ih);
labels++;
} else if (instrName.equals("putfield")) {
int arg = getFieldConstRef(instrElems, cpg, labels);
ih = instructions.append(new PUTFIELD(arg));
instructionHandleList.add(ih);
labels++;
}
/*
* Newarray instructions
*/
else if (instrName.equals("newarray")) {
byte arg = getArrayRef(instrElems, labels);
ih = instructions.append(new NEWARRAY(arg));
instructionHandleList.add(ih);
labels++;
}
else if (instrName.equals("multianewarray")) {
short dim = 1;
int arg = 0;
try {
dim = Short.parseShort(instrElems[2]);
} catch (NumberFormatException nfe) {
parseException.addError(
JAsmParseException.SHORT_REQUIRED,
instrElems[0], labels);
} catch (ArrayIndexOutOfBoundsException aobe) {
parseException.addError(
JAsmParseException.MISSING_ARGUMENTS,
instrElems[0], labels);
}
try {
arg = Integer.parseInt(instrElems[1]);
} catch (NumberFormatException nfe) {
String classN = instrElems[1];
arg = cpg.addClass(classN);
} catch (ArrayIndexOutOfBoundsException aobe) {
parseException.addError(
JAsmParseException.MISSING_ARGUMENTS,
instrElems[0], labels);
}
ih = instructions.append(new MULTIANEWARRAY(arg, dim));
instructionHandleList.add(ih);
labels++;
}
/*
* Load constant instructions
*/
else if (instrName.equals("ldc")) {
int arg = getConstRef4ldc(instrElems, cpg, labels);
ih = instructions.append(new LDC(arg));
instructionHandleList.add(ih);
labels++;
} else if (instrName.equals("ldc_w")) {
int arg = getConstRef4ldc(instrElems, cpg, labels);
ih = instructions.append(new LDC_W(arg));
instructionHandleList.add(ih);
labels++;
} else if (instrName.equals("ldc2_w")) {
int arg = getConstRefldc2_w(instrElems, cpg, labels);
ih = instructions.append(new LDC2_W(arg));
instructionHandleList.add(ih);
labels++;
}
/*
* Local Variable instructions
*/
else if (instrName.equals("ret")) {
int arg = getSingleIntArg(instrElems, labels);
ih = instructions.append(new RET(arg));
instructionHandleList.add(ih);
labels++;
} else if (instrName.equals("aload")) {
int arg = getSingleIntArg(instrElems, labels);
ih = instructions.append(new ALOAD(arg));
instructionHandleList.add(ih);
labels++;
} else if (instrName.equals("astore")) {
int arg = getSingleIntArg(instrElems, labels);
ih = instructions.append(new ASTORE(arg));
instructionHandleList.add(ih);
labels++;
} else if (instrName.equals("dload")) {
int arg = getSingleIntArg(instrElems, labels);
ih = instructions.append(new DLOAD(arg));
instructionHandleList.add(ih);
labels++;
} else if (instrName.equals("dstore")) {
int arg = getSingleIntArg(instrElems, labels);
ih = instructions.append(new DSTORE(arg));
instructionHandleList.add(ih);
labels++;
} else if (instrName.equals("fload")) {
int arg = getSingleIntArg(instrElems, labels);
ih = instructions.append(new FLOAD(arg));
instructionHandleList.add(ih);
labels++;
} else if (instrName.equals("fstore")) {
int arg = getSingleIntArg(instrElems, labels);
ih = instructions.append(new FSTORE(arg));
instructionHandleList.add(ih);
labels++;
} else if (instrName.equals("iload")) {
int arg = getSingleIntArg(instrElems, labels);
ih = instructions.append(new ILOAD(arg));
instructionHandleList.add(ih);
labels++;
} else if (instrName.equals("istore")) {
int arg = getSingleIntArg(instrElems, labels);
ih = instructions.append(new ISTORE(arg));
instructionHandleList.add(ih);
labels++;
} else if (instrName.equals("lload")) {
int arg = getSingleIntArg(instrElems, labels);
ih = instructions.append(new LLOAD(arg));
instructionHandleList.add(ih);
labels++;
} else if (instrName.equals("lstore")) {
int arg = getSingleIntArg(instrElems, labels);
ih = instructions.append(new LSTORE(arg));
instructionHandleList.add(ih);
labels++;
}
/*
* Switch instructions
*/
else if (instrName.equals("tableswitch")) {
switchMode = 1;
int arg = getSingleIntArg(instrElems, labels);
tempSwitch = new TempSwitchData(2, arg);
} else if (instrName.equals("lookupswitch")) {
switchMode = 2;
tempSwitch = new TempSwitchData(1);
}
/*
* 0 parameter instructions
*/
else if (instrName.equals("aaload")) {
ih = instructions.append(new AALOAD());
instructionHandleList.add(ih);
labels++;
} else if (instrName.equals("aastore")) {
ih = instructions.append(new AASTORE());
instructionHandleList.add(ih);
labels++;
} else if (instrName.equals("aconst_null")) {
ih = instructions.append(new ACONST_NULL());
instructionHandleList.add(ih);
labels++;
} else if (instrName.equals("aload_0")) {
ih = instructions.append(new ALOAD(0));
instructionHandleList.add(ih);
labels++;
} else if (instrName.equals("aload_1")) {
ih = instructions.append(new ALOAD(1));
instructionHandleList.add(ih);
labels++;
} else if (instrName.equals("aload_2")) {
ih = instructions.append(new ALOAD(2));
instructionHandleList.add(ih);
labels++;
} else if (instrName.equals("aload_3")) {
ih = instructions.append(new ALOAD(3));
instructionHandleList.add(ih);
labels++;
} else if (instrName.equals("areturn")) {
ih = instructions.append(new ARETURN());
instructionHandleList.add(ih);
labels++;
} else if (instrName.equals("arraylength")) {
ih = instructions.append(new ARRAYLENGTH());
instructionHandleList.add(ih);
labels++;
} else if (instrName.equals("astore_0")) {
ih = instructions.append(new ASTORE(0));
instructionHandleList.add(ih);
labels++;
} else if (instrName.equals("astore_1")) {
ih = instructions.append(new ASTORE(1));
instructionHandleList.add(ih);
labels++;
} else if (instrName.equals("astore_2")) {
ih = instructions.append(new ASTORE(2));
instructionHandleList.add(ih);
labels++;
} else if (instrName.equals("astore_3")) {
ih = instructions.append(new ASTORE(3));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -