⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bytecodedisplay.java

📁 Java Bytecode Editor 是一个 JAVA 的字节码反汇编和修改器。它可以很方便的修改已经编译成 Class 文件的 JAVA 文件。
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
    }

    private void updateHistory(int offset) {

        BrowserServices services = detailPane.getBrowserServices();
        TreePath treePath = services.getBrowserComponent().getTreePane().getTree().getSelectionPath();

        BrowserHistory history = services.getBrowserComponent().getHistory();
        history.updateHistory(treePath, new Integer(offset));
    }

    private void setupTextLayouts() {

        lineHeight = 0;
        currentHeight = 0f;
        currentWidth = 0f;
        textLines.clear();
        lines.clear();
        textLayouts = null;
        offsetToLine.clear();
        lineToLink.clear();


        byte[] code = codeAttribute.getCode();

        try {
            java.util.List instructions = ByteCodeReader.readByteCode(code);

            calculateOffsetWidth(instructions);

            Iterator it = instructions.iterator();
            AbstractInstruction currentInstruction;
            while (it.hasNext()) {
                currentInstruction = (AbstractInstruction)it.next();
                addInstructionToDocument(currentInstruction);
            }
            textLayouts = new TextLayout[lines.size()];
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        setPreferredSize(new Dimension((int)currentWidth + 2 * MARGIN_X, (int)currentHeight + 2 * MARGIN_Y));
    }

    private void calculateOffsetWidth(java.util.List instructions) {

        int numberOfInstructions = instructions.size();

        if (numberOfInstructions > 0) {
            AbstractInstruction lastInstruction = (AbstractInstruction)instructions.get(numberOfInstructions - 1);
            offsetWidth = String.valueOf(lastInstruction.getOffset()).length();
        } else {
            offsetWidth = 1;
        }
        StringBuffer buffer = new StringBuffer(offsetWidth);
        for (int i = 0; i  < offsetWidth; i++) {
            buffer.append(' ');
        }
        offsetBlank = buffer.toString();
    }


    private void addInstructionToDocument(AbstractInstruction instruction) {

        int offset = instruction.getOffset();

        addOffsetReference(offset);

        appendString(getPaddedValue(offset, offsetWidth),
                STYLE_OFFSET);

        appendString(" " + instruction.getOpcodeVerbose(),
                STYLE_INSTRUCTION);

        addOpcodeSpecificInfo(instruction);

        newLine();

    }

    private void addOffsetReference(int offset) {

        offsetToLine.put(new Integer(offset),
                new Integer(getCurrentLine()));
    }

    private void addOpcodeSpecificInfo(AbstractInstruction instruction) {

        if (instruction instanceof ImmediateByteInstruction) {
            addImmediateByteSpecificInfo((ImmediateByteInstruction)instruction);
        } else if (instruction instanceof ImmediateShortInstruction) {
            addImmediateShortSpecificInfo((ImmediateShortInstruction)instruction);
        } else if (instruction instanceof ImmediateIntInstruction) {
            addImmediateIntSpecificInfo((ImmediateIntInstruction)instruction);
        } else if (instruction instanceof BranchInstruction) {
            addBranchSpecificInfo((BranchInstruction)instruction);
        } else if (instruction instanceof TableSwitchInstruction) {
            addTableSwitchSpecificInfo((TableSwitchInstruction)instruction);
        } else if (instruction instanceof LookupSwitchInstruction) {
            addLookupSwitchSpecificInfo((LookupSwitchInstruction)instruction);
        }
    }

    private void addImmediateByteSpecificInfo(ImmediateByteInstruction instruction) {

        int opcode = instruction.getOpcode();
        int sourceOffset = instruction.getOffset();
        int immediateByte = instruction.getImmediateByte();

        if (opcode == Opcodes.OPCODE_LDC) {
            addConstantPoolLink(immediateByte, sourceOffset);
        } else if (opcode == Opcodes.OPCODE_NEWARRAY) {
            String verbose = OpcodesUtil.getArrayTypeVerbose(immediateByte);
            appendString(" " + immediateByte + " (" + verbose + ")",
                    STYLE_IMMEDIATE_VALUE);

        } else {
            appendString(" " + immediateByte,
                    STYLE_IMMEDIATE_VALUE);

            if (instruction instanceof IncrementInstruction) {
                appendString(" by", STYLE_NORMAL);
                appendString(" " + ((IncrementInstruction)instruction).getIncrementConst(),
                        STYLE_IMMEDIATE_VALUE);
            }
        }
    }

    private void addImmediateShortSpecificInfo(ImmediateShortInstruction instruction) {

        int opcode = instruction.getOpcode();
        int sourceOffset = instruction.getOffset();
        int immediateShort = instruction.getImmediateShort();

        if (opcode == Opcodes.OPCODE_SIPUSH) {
            appendString(" " + immediateShort,
                    STYLE_IMMEDIATE_VALUE);
        } else {
            addConstantPoolLink(immediateShort, sourceOffset);

            if (instruction instanceof InvokeInterfaceInstruction) {
                appendString(" count " + ((InvokeInterfaceInstruction)instruction).getCount(),
                        STYLE_IMMEDIATE_VALUE);

            } else if (instruction instanceof MultianewarrayInstruction) {
                appendString(" dim " + ((MultianewarrayInstruction)instruction).getDimensions(),
                        STYLE_IMMEDIATE_VALUE);

            }
        }

    }

    private void addImmediateIntSpecificInfo(ImmediateIntInstruction instruction) {

        int immediateInt = instruction.getImmediateInt();
        int sourceOffset = instruction.getOffset();

        addConstantPoolLink(immediateInt, sourceOffset);

    }

    private void addBranchSpecificInfo(BranchInstruction instruction) {

        int branchOffset = instruction.getBranchOffset();
        int instructionOffset = instruction.getOffset();

        addOffsetLink(branchOffset, instructionOffset);

    }

    private void addTableSwitchSpecificInfo(TableSwitchInstruction instruction) {

        int instructionOffset = instruction.getOffset();
        int lowByte = instruction.getLowByte();
        int highByte = instruction.getHighByte();
        int[] jumpOffsets = instruction.getJumpOffsets();

        appendString(" " + lowByte + " to " + highByte, STYLE_IMMEDIATE_VALUE);
        newLine();

        for (int i = 0; i <= highByte - lowByte; i++) {
            appendString(offsetBlank + TAB_STRING + (i + lowByte) + ": ", STYLE_IMMEDIATE_VALUE);
            addOffsetLink(jumpOffsets[i], instructionOffset);
            newLine();

        }
        appendString(offsetBlank + TAB_STRING + "default: ", STYLE_IMMEDIATE_VALUE);
        addOffsetLink(instruction.getDefaultOffset(), instructionOffset);

    }

    private void addLookupSwitchSpecificInfo(LookupSwitchInstruction instruction) {

        int instructionOffset = instruction.getOffset();
        java.util.List matchOffsetPairs = instruction.getMatchOffsetPairs();
        int matchOffsetPairsCount = matchOffsetPairs.size();

        appendString(" " + matchOffsetPairsCount, STYLE_IMMEDIATE_VALUE);
        newLine();

        MatchOffsetPair matchOffsetPairEntry;
        for (int i = 0; i < matchOffsetPairsCount; i++) {
            matchOffsetPairEntry = (MatchOffsetPair)matchOffsetPairs.get(i);
            appendString(offsetBlank + TAB_STRING + matchOffsetPairEntry.getMatch() + ": ",
                    STYLE_IMMEDIATE_VALUE);
            addOffsetLink(matchOffsetPairEntry.getOffset(), instructionOffset);
            newLine();

        }
        appendString(offsetBlank + TAB_STRING + "default: ", STYLE_IMMEDIATE_VALUE);
        addOffsetLink(instruction.getDefaultOffset(), instructionOffset);

    }

    private void addConstantPoolLink(int constantPoolIndex, int sourceOffset) {

        appendString(" ", STYLE_NORMAL);
        int startCharIndex = getCurrentCharIndex();
        appendString("#" + constantPoolIndex, STYLE_LINK);
        int endCharIndex = getCurrentCharIndex();
        lineToLink.put(new Integer(getCurrentLine()), new ConstantPoolLink(startCharIndex, endCharIndex, sourceOffset, constantPoolIndex));

        try {
            String name = classFile.getConstantPoolEntryName(constantPoolIndex);
            if (name.length() > 0) {
                appendString(" <" + name + ">", STYLE_SMALL);
            }
        } catch (InvalidByteCodeException ex) {
        }
    }

    private void addOffsetLink(int branchOffset, int sourceOffset) {

        int targetOffset = branchOffset + sourceOffset;

        appendString(" ", STYLE_NORMAL);
        int startCharIndex = getCurrentCharIndex();
        appendString(String.valueOf(targetOffset), STYLE_LINK);
        int endCharIndex = getCurrentCharIndex();
        lineToLink.put(new Integer(getCurrentLine()), new OffsetLink(startCharIndex, endCharIndex, sourceOffset, targetOffset));

        appendString(" (" + (branchOffset > 0 ? "+" : "") + String.valueOf(branchOffset) + ")",
                STYLE_IMMEDIATE_VALUE);
    }

    private int getCurrentCharIndex() {

        Iterator it = currentLineCache.iterator();
        int offset = 0;
        while (it.hasNext()) {
            LineCacheEntry entry = (LineCacheEntry)it.next();
            offset += entry.text.length();
        }
        return offset;
    }

    private int getCurrentLine() {
        return lines.size();
    }

    private void appendString(String text, Map attributes) {
        currentLineCache.add(new LineCacheEntry(text, attributes));
    }

    private void newLine() {

        String text = getCurrentLineText();
        AttributedString attrString = new AttributedString(text, STYLE_BASE);
        Iterator it = currentLineCache.iterator();
        int startCharIndex = 0;
        while (it.hasNext()) {
            LineCacheEntry entry = (LineCacheEntry)it.next();
            int endCharIndex = startCharIndex + entry.text.length();
            attrString.addAttributes(entry.attributes, startCharIndex, endCharIndex);
            startCharIndex = endCharIndex;
        }
        lines.add(attrString);
        textLines.add(text);
        
        if (lineHeight == 0) {
            TextLayout textLayout = new TextLayout(attrString.getIterator(), frc);
            lineHeight = (int)(textLayout.getAscent() + textLayout.getDescent() + textLayout.getLeading());
            ascent = (int)textLayout.getAscent();
            textLayout = new TextLayout("0", STYLE_BASE, frc);
            characterWidth = (int)textLayout.getAdvance();
        }
        currentHeight += lineHeight;
        currentWidth = Math.max(currentWidth, characterWidth * text.length());

        currentLineCache.clear();
    }

    private String getCurrentLineText() {

        StringBuffer buffer = new StringBuffer(getCurrentLineLength());
        Iterator it = currentLineCache.iterator();
        while (it.hasNext()) {
            LineCacheEntry entry = (LineCacheEntry)it.next();
            buffer.append(entry.text);
        }
        return buffer.toString();
    }

    private int getCurrentLineLength() {

        int length = 0;
        Iterator it = currentLineCache.iterator();
        while (it.hasNext()) {
            LineCacheEntry entry = (LineCacheEntry)it.next();
            length += entry.text.length();
        }
        return length;
    }

    private static class LineCacheEntry {

        private String text;
        private Map attributes;

        private LineCacheEntry(String text, Map attributes) {
            this.text = text;
            this.attributes = attributes;
        }
    }

    private static class BytecodeLink {

        private int startCharIndex;
        private int endCharIndex;
        protected int sourceOffset;

        private BytecodeLink(int startCharIndex, int endCharIndex, int sourceOffset) {
            this.startCharIndex = startCharIndex;
            this.endCharIndex = endCharIndex;
            this.sourceOffset = sourceOffset;
        }
    }

    private static class ConstantPoolLink extends BytecodeLink {

        private int cpIndex;

        private ConstantPoolLink(int startCharIndex, int endCharIndex, int sourceOffset, int cpIndex) {
            super(startCharIndex, endCharIndex, sourceOffset);
            this.cpIndex = cpIndex;
        }

    }

    private static class OffsetLink extends BytecodeLink {

        private int targetOffset;

        private OffsetLink(int startCharIndex, int endCharIndex, int sourceOffset, int targetOffset) {
            super(startCharIndex, endCharIndex, sourceOffset);
            this.targetOffset = targetOffset;
        }

    }

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -