From 0d00484c77c4997cd3a23603da6b7dc617a669b3 Mon Sep 17 00:00:00 2001 From: amosshi Date: Sun, 15 Dec 2019 16:53:38 -0800 Subject: [PATCH] #4 Classfile - Refactor the wide opcode parser --- .../format/classfile/Opcode.java | 89 +++++++++---------- 1 file changed, 43 insertions(+), 46 deletions(-) diff --git a/FormatCLASS/src/main/java/org/freeinternals/format/classfile/Opcode.java b/FormatCLASS/src/main/java/org/freeinternals/format/classfile/Opcode.java index ce7b9fd..af837bb 100755 --- a/FormatCLASS/src/main/java/org/freeinternals/format/classfile/Opcode.java +++ b/FormatCLASS/src/main/java/org/freeinternals/format/classfile/Opcode.java @@ -1639,7 +1639,7 @@ protected InstructionParsed parse(final int curPos, final PosDataInputStream pdi protected InstructionParsed parse(final int curPos, final PosDataInputStream pdis) throws IOException { InstructionParsed parsed = new InstructionParsed(curPos, this.code); parsed.cpIndex = pdis.readUnsignedShort(); - + // Skip 2 zero bytes BytesTool.skipBytes(pdis, 2); parsed.opCodeText = this.name(); @@ -1753,6 +1753,27 @@ protected InstructionParsed parse(final int curPos, final PosDataInputStream pdi * TODO - Refactor this method */ wide(196) { + private List WIDE_SINGLE_OPCODES = new ArrayList() { + { + add(Opcode.Instruction.iload.code); + add(Opcode.Instruction.lload.code); + add(Opcode.Instruction.fload.code); + add(Opcode.Instruction.dload.code); + add(Opcode.Instruction.aload.code); + add(Opcode.Instruction.istore.code); + add(Opcode.Instruction.lstore.code); + add(Opcode.Instruction.fstore.code); + add(Opcode.Instruction.dstore.code); + add(Opcode.Instruction.astore.code); + add(Opcode.Instruction.ret.code); + } + }; + + /** + * The target opcode for the {@link Instruction#wide} instruction. + */ + private int wide_opcode; + @Override protected InstructionParsed parse(final int curPos, final PosDataInputStream pdis) throws IOException { InstructionParsed parsed = new InstructionParsed(curPos, this.code); @@ -1760,50 +1781,34 @@ protected InstructionParsed parse(final int curPos, final PosDataInputStream pdi return parsed; } + @Override + String getName() { + return getWideName(Opcode.Instruction.valueOf(this.wide_opcode).name()); + } + + /** + * Get the name with "wide " prefix. Only applied for {@link #wide}. + * + * @return opcode name with "wide " prefix + */ + String getWideName(String s) { + return Instruction.wide.name() + " " + s; + } + private String getText_wide(final PosDataInputStream pdis) throws IOException { - final int opcode = pdis.readUnsignedByte(); + this.wide_opcode = pdis.readUnsignedByte(); String opCodeText; int shortValue; int shortValue2; - if (opcode == Opcode.Instruction.iload.code) { - shortValue = pdis.readUnsignedShort(); - opCodeText = String.format(FORMAT_OPCODE_NUMBER, Instruction.getWideName(Opcode.Instruction.iload.name()), shortValue); - } else if (opcode == Opcode.Instruction.lload.code) { - shortValue = pdis.readUnsignedShort(); - opCodeText = String.format(FORMAT_OPCODE_NUMBER, Instruction.getWideName(Opcode.Instruction.lload.name()), shortValue); - } else if (opcode == Opcode.Instruction.fload.code) { - shortValue = pdis.readUnsignedShort(); - opCodeText = String.format(FORMAT_OPCODE_NUMBER, Instruction.getWideName(Opcode.Instruction.fload.name()), shortValue); - } else if (opcode == Opcode.Instruction.dload.code) { - shortValue = pdis.readUnsignedShort(); - opCodeText = String.format(FORMAT_OPCODE_NUMBER, Instruction.getWideName(Opcode.Instruction.dload.name()), shortValue); - } else if (opcode == Opcode.Instruction.aload.code) { + if (this.WIDE_SINGLE_OPCODES.contains(this.wide_opcode)) { shortValue = pdis.readUnsignedShort(); - opCodeText = String.format(FORMAT_OPCODE_NUMBER, Instruction.getWideName(Opcode.Instruction.aload.name()), shortValue); - } else if (opcode == Opcode.Instruction.istore.code) { - shortValue = pdis.readUnsignedShort(); - opCodeText = String.format(FORMAT_OPCODE_NUMBER, Instruction.getWideName(Opcode.Instruction.istore.name()), shortValue); - } else if (opcode == Opcode.Instruction.lstore.code) { - shortValue = pdis.readUnsignedShort(); - opCodeText = String.format(FORMAT_OPCODE_NUMBER, Instruction.getWideName(Opcode.Instruction.lstore.name()), shortValue); - } else if (opcode == Opcode.Instruction.fstore.code) { - shortValue = pdis.readUnsignedShort(); - opCodeText = String.format(FORMAT_OPCODE_NUMBER, Instruction.getWideName(Opcode.Instruction.fstore.name()), shortValue); - } else if (opcode == Opcode.Instruction.dstore.code) { - shortValue = pdis.readUnsignedShort(); - opCodeText = String.format(FORMAT_OPCODE_NUMBER, Instruction.getWideName(Opcode.Instruction.dstore.name()), shortValue); - } else if (opcode == Opcode.Instruction.astore.code) { - shortValue = pdis.readUnsignedShort(); - opCodeText = String.format(FORMAT_OPCODE_NUMBER, Instruction.getWideName(Opcode.Instruction.astore.name()), shortValue); - } else if (opcode == Opcode.Instruction.iinc.code) { + opCodeText = String.format(FORMAT_OPCODE_NUMBER, getWideName(Opcode.Instruction.valueOf(this.wide_opcode).name()), shortValue); + } else if (this.wide_opcode == Opcode.Instruction.iinc.code) { shortValue = pdis.readUnsignedShort(); shortValue2 = pdis.readUnsignedShort(); - opCodeText = String.format(FORMAT_OPCODE_LOCAL_IINC, Instruction.getWideName(Opcode.Instruction.iinc.name()), shortValue, shortValue2); - } else if (opcode == Opcode.Instruction.ret.code) { - shortValue = pdis.readUnsignedShort(); - opCodeText = String.format(FORMAT_OPCODE_NUMBER, Instruction.getWideName(Opcode.Instruction.ret.name()), shortValue); + opCodeText = String.format(FORMAT_OPCODE_LOCAL_IINC, getWideName(Opcode.Instruction.iinc.name()), shortValue, shortValue2); } else { opCodeText = String.format("%s [Unknown opcode]", Opcode.Instruction.wide.name()); } @@ -1920,6 +1925,7 @@ protected InstructionParsed parse(final int curPos, final PosDataInputStream pdi * @see #new_ * @see #instanceof_ * @see #reserved + * @see #wide */ String getName() { String name = super.name(); @@ -1934,15 +1940,6 @@ String getName() { return name; } - /** - * Get the name with "wide " prefix. Only applied for {@link #wide}. - * - * @return opcode name with "wide " prefix - */ - static String getWideName(String s) { - return Instruction.wide.name() + " " + s; - } - /** * Get Opcode name. * @@ -2170,7 +2167,7 @@ public static class InstructionParsed { * @see Instruction#getName() */ public final String opCodeName; - + /** * Text of the {@link #opCode}. In case {@link #opCode} is * {@link Instruction#wide}, the {@link #opCodeText} contains the