📄 sourcecodeparser.java
字号:
type = scanner.token();
if (scanner.nextToken() != Number_Integer) {
exception(scanner, "dimesion.number.expected.here");
}
i = parseInteger(scanner.token());
operands[1] = Util.getBytes(i, 1); // dimension
operands[0] = Util.getBytes(cpl.addClass(type), 2);
codeLength = 4;
op = new Attribute_Code.Opcode(offset, opinfo.opcode, operands);
scanner.nextToken();
break;
case Constants.WIDE:
isWide = true;
codeLength = 1;
op = new Attribute_Code.Opcode(offset, opinfo.opcode, operands);
scanner.nextToken();
break;
case Constants.IINC:
// like :iinc t(3) -1 or iinc 3 -1
operands = new byte[2][];
scanner.nextToken();
if (scanner.tokenType() == Number_Integer) {
i = parseInteger(scanner.token());
} else {
if (scanner.nextToken() != SBracket_Left) {
exception(scanner, "'('.expected.here");
}
if (scanner.nextToken() != Number_Integer) {
exception(scanner, "local.variable.index.expected.here");
}
i = parseInteger(scanner.token());
if (scanner.nextToken() != SBracket_Right) {
exception(scanner, "')'.expected.here");
}
}
scanner.nextToken();
if (scanner.tokenType() != Number_Integer) {
exception(scanner, "increment.amount.expected.here");
}
j = parseInteger(scanner.token());
if (isWide == true) {
operands[0] = Util.getBytes(i, 2);
operands[1] = Util.getBytes(j, 2);
codeLength = 5;
} else {
operands[0] = Util.getBytes(i, 1);
operands[1] = Util.getBytes(j, 1);
codeLength = 3;
}
op = new Attribute_Code.Opcode(offset, opinfo.opcode, operands);
scanner.nextToken();
break;
case Constants.ALOAD:
case Constants.ASTORE:
case Constants.DLOAD:
case Constants.DSTORE:
case Constants.FLOAD:
case Constants.FSTORE:
case Constants.ILOAD:
case Constants.ISTORE:
case Constants.LLOAD:
case Constants.LSTORE:
case Constants.RET:
// like:istore a(8) or istore 8
operands = new byte[1][];
scanner.nextToken();
if (scanner.tokenType() == Number_Integer) {
i = parseInteger(scanner.token());
} else {
if (scanner.nextToken() != SBracket_Left) {
exception(scanner, "'('.expected.here");
}
if (scanner.nextToken() != Number_Integer) {
exception(scanner, "local.variable.index.expected.here");
}
i = parseInteger(scanner.token());
if (scanner.nextToken() != SBracket_Right) {
exception(scanner, "')'.expected.here");
}
}
if (isWide == true) {
operands[0] = Util.getBytes(i, 2);
codeLength = 2;
isWide = false;
} else {
operands[0] = Util.getBytes(i, 1);
codeLength = 2;
}
op = new Attribute_Code.Opcode(offset, opinfo.opcode, operands);
scanner.nextToken();
break;
case Constants.GOTO:
case Constants.IFEQ:
case Constants.IFGE:
case Constants.IFGT:
case Constants.IFLE:
case Constants.IFLT:
case Constants.JSR:
case Constants.IFNE:
case Constants.IFNONNULL:
case Constants.IFNULL:
case Constants.IF_ACMPEQ:
case Constants.IF_ACMPNE:
case Constants.IF_ICMPEQ:
case Constants.IF_ICMPGE:
case Constants.IF_ICMPGT:
case Constants.IF_ICMPLE:
case Constants.IF_ICMPLT:
case Constants.IF_ICMPNE:
case Constants.GOTO_W:
case Constants.JSR_W:
scanner.nextToken();
operands = new byte[1][];
codeLength = 3;
op = new OpcodeWrapper(offset, opinfo.opcode, operands, scanner.token());
toUpdate.add(op);
scanner.nextToken();
break;
case Constants.BIPUSH:
default:
operands = new byte[opinfo.operandsCount][];
for (i = 0; i < opinfo.operandsCount; i++) {
if (scanner.nextToken() != Number_Integer) {
exception(scanner, "number.expected.here");
}
operands[i] = Util.getBytes(parseInteger(scanner.token()), opinfo.operandsLength[i]);
codeLength = codeLength + opinfo.operandsLength[i];
}
scanner.nextToken();
codeLength++;
op = new Attribute_Code.Opcode(offset, opinfo.opcode, operands);
}
break;
}
case Attribute:
break;
default:
exception(scanner, "label.name.or.instructions.expected.here");
}
offset = offset + codeLength;
codes.add(op);
if (record) {
labelMap.put(label, op);
label = null;
}
record = false;
operands = null;
codeLength = 0;
}
updateLabelLinks(labelMap, toUpdate);
return new LabeledInstructions((Attribute_Code.Opcode[]) codes.toArray(new Attribute_Code.Opcode[codes.size()]), labelMap, offset);
}
private void updateLabelLinks(Hashtable labels, ArrayList toUpdate) throws GrammerException {
OpcodeWrapper op;
ArrayList list;
String label;
int counter;
byte[][] operands;
for (int i = 0; i < toUpdate.size(); i++) {
op = (OpcodeWrapper) toUpdate.get(i);
operands = op.operands;
switch (op.opcode) {
case Constants.TABLESWITCH:
list = (ArrayList) op.info;
counter = operands.length;
operands[1] = Util.getBytes(getOffset((String) list.get(0), labels, false) - op.offset, 4);// default value
counter = 1;
for (int j = 4; j < operands.length; j++) {
operands[j] = Util.getBytes(getOffset((String) list.get(counter++), labels, false) - op.offset, 4);
}
break;
case Constants.LOOKUPSWITCH:
list = (ArrayList) op.info;
counter = operands.length;
operands[1] = Util.getBytes(getOffset((String) list.get(0), labels, false) - op.offset, 4);// default value
counter = 1;
for (int j = 4; j < operands.length; j++) {
operands[j] = Util.getBytes(getOffset((String) list.get(counter++), labels, false) - op.offset, 4);
j++;
}
break;
case Constants.GOTO:
case Constants.IFEQ:
case Constants.IFGE:
case Constants.IFGT:
case Constants.IFLE:
case Constants.IFLT:
case Constants.JSR:
case Constants.IFNE:
case Constants.IFNONNULL:
case Constants.IFNULL:
case Constants.IF_ACMPEQ:
case Constants.IF_ACMPNE:
case Constants.IF_ICMPEQ:
case Constants.IF_ICMPGE:
case Constants.IF_ICMPGT:
case Constants.IF_ICMPLE:
case Constants.IF_ICMPLT:
case Constants.IF_ICMPNE:
label = (String) op.info;
operands[0] = Util.getBytes(getOffset(label, labels, false) - op.offset, 2);
break;
case Constants.GOTO_W:
case Constants.JSR_W:
label = (String) op.info;
operands[0] = Util.getBytes(getOffset(label, labels, false) - op.offset, 4);
break;
}
}
}
/**
* parse method declaration, and the throws clause , if any.
* @param method
* @throws ParsingException
*/
private void parseMethodSignature(Method method, ArrayList attributes) throws ParsingException, GrammerException {
int acc = 0;
String methodName, retType;
StringBuffer para = new StringBuffer(15);
while (scanner.tokenType() == AccessFlag) {
acc = acc | Util.getAccessFlag_Method(scanner.token());
scanner.nextToken();
}
retType = scanner.token();
scanner.nextToken();
methodName = scanner.token();
scanner.nextToken();
if (scanner.tokenType() != SBracket_Left) {
exception(scanner, "'('.expected.here");
}
scanner.nextToken();
if (scanner.tokenType() == SBracket_Right) {
//void paras
para.append("");
} else {
while (scanner.tokenType() != EOF && scanner.tokenType() != SBracket_Right) {
para = para.append(scanner.token());
if (scanner.nextToken() == Comma) {
para.append(',');
scanner.nextToken();
}
}
//validate the next token
if (scanner.tokenType() != SBracket_Right) {
throw new ParsingException(scanner.getOffset(), "')'.expected.here");
}
}
retType = Util.toInnerType(retType);
method.descriptor_index = cpl.addUtf8("(" + Util.toInnerParameterTypes(para.toString()) + ")" + retType);
method.name_index = cpl.addUtf8(methodName);
method.access_flags = acc;
scanner.nextToken();
// throws clause, if any
if ("throws".equals(scanner.token()) == true) {
IntegerArray thr = new IntegerArray(4);
while (scanner.tokenType() != Bracket_Left && scanner.tokenType() != EOF) {
scanner.nextToken();
thr.add(cpl.addClass(scanner.token()));
scanner.nextToken();
if (scanner.tokenType() != Bracket_Left && scanner.tokenType() != Comma) {
exception(scanner, "invalid.throw.clause");
}
}
Attribute att = new Attribute_Exceptions(2 + 2 * thr.getAll().length, thr.getAll().length, thr.getAll());
att.attribute_name_index = cpl.addUtf8("Exceptions");
attributes.add(att);
} else if (scanner.tokenType() == Bracket_Left) {
} else {
exception(scanner, "'{'.expected.here");
}
scanner.nextToken();
}
/**
* like:jce.TestClass this start=line0, end=line0, index=0
* @param s
* @param map
* @throws ParsingException
* @throws GrammerException
*/
private Attribute_LocalVariableTable parseLocalVariableTable(String s, Hashtable map) throws ParsingException, GrammerException {
Scanner sc;
sc = Scanner.partialScanner(scanner.getContent(), scanner.getOffset() + 1, scanner.getLength() - 2, scanner.getColumnNumberStart() + 1,
scanner.getLineNumberStart());
ArrayList lvts = new ArrayList();
String type, name, index;
int start, end;
sc.nextToken();
if (sc.nextToken() != Colon) {
exception(sc, "':'.expected");
}
sc.nextToken();
while (sc.tokenType() != EOF) {
type = sc.token();
sc.nextToken();
name = sc.token();
sc.nextToken();
if ("start".equals(sc.token()) == false) {
exception(sc, "'start'.expected.here");
}
if (sc.nextToken() != Equal) {
exception(sc, "'='.expected.here");
}
sc.nextToken();
start = getOffset(sc.token(), map, false);
if (sc.nextToken() != Comma) {
exception(sc, "','.expected.here");
}
sc.nextToken();
if ("end".equals(sc.token()) == false) {
exception(sc, "'end'.expected.here");
}
if (sc.nextToken() != Equal) {
exception(sc, "'='.expected.here");
}
sc.nextToken();
end = getOffset(sc.token(), map, true);
if (sc.nextToken() != Comma) {
exception(sc, "','.expected.here");
}
sc.nextToken();
if ("index".equals(sc.token()) == false) {
exception(sc, "'index'.expected.here");
}
if (sc.nextToken() != Equal) {
exception(sc, "'='.expected.here");
}
if (sc.nextToken() != Number_Integer) {
exception(sc, "local.variable.index.expected.here");
}
index = sc.token();
lvts.add(new Attribute_LocalVariableTable.LocalVariable(start, end - start, cpl.addUtf8(name), cpl.addUtf8(Util.toInnerType(type)),
parseInteger(index)));
sc.nextToken();
}
Attribute_LocalVariableTable.LocalVariable[] lvs = (Attribute_LocalVariableTable.LocalVariable[]) lvts
.toArray(new Attribute_LocalVariableTable.LocalVariable[lvts.size()]);
Attribute_LocalVariableTable lvt = new Attribute_LocalVariableTable(10 * lvs.length + 2, lvs.length, lvs);
lvt.attribute_name_index = cpl.addUtf8("LocalVariableTable");
return lvt;
}
/**
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -