/** * Renders disassembled instructions into the code table, starting at the specified row and * instruction address. * * @param instructions A list of instructions to render into the table. * @param row The table row to start at. * @param address The code address to start at. */ private void renderInstructions(Iterable<WAMInstruction> instructions, int row, int address) { for (WAMInstruction instruction : instructions) { WAMLabel label = instruction.getLabel(); labeledTable.put(ADDRESS, row, String.format("%08X", address)); labeledTable.put(LABEL, row, (label == null) ? "" : (label.toPrettyString() + ":")); labeledTable.put(MNEMONIC, row, instruction.getMnemonic().getPretty()); int fieldMask = instruction.getMnemonic().getFieldMask(); String arg = ""; for (int i = 2; i < 32; i = i * 2) { if ((fieldMask & i) != 0) { if (!"".equals(arg)) { arg += ", "; } switch (i) { case 2: arg += Integer.toString(instruction.getReg1()); break; case 4: arg += Integer.toString(instruction.getReg2()); break; case 8: FunctorName fn = instruction.getFn(); if (fn != null) { arg += fn.getName() + "/" + fn.getArity(); } break; case 16: WAMLabel target1 = instruction.getTarget1(); if (target1 != null) { arg += target1.getName() + "/" + target1.getArity() + "_" + target1.getId(); } break; } } } labeledTable.put(ARG_1, row, arg); row++; address += instruction.sizeof(); } }
/** * Should be notified every time byte-code is added to the machine. * * @param codeBuffer A buffer containing the byte-code. * @param start The start offset within the buffer of the new code. * @param length The length of the new code. * @param interner The machines interner to lookup interned names with. * @param codeView The machines code view to find interned names matching addresses. */ public void onCodeUpdate( ByteBuffer codeBuffer, int start, int length, VariableAndFunctorInterner interner, WAMCodeView codeView) { log.fine( "public void onCodeUpdate(ByteBuffer codeBuffer, int start = " + start + ", int length = " + length + ", VariableAndFunctorInterner interner, WAMCodeView codeView): called"); // Take a copy of the new bytecode. copyAndResizeCodeBuffer(codeBuffer, start, length); // Disassemble the new area of byte code. SizeableList<WAMInstruction> instructions = WAMInstruction.disassemble(start, length, this.codeBuffer, interner, codeView); // Figure out where to start writing the disassembled code into the table. Map.Entry<Integer, Integer> entry = addressToRow.floorEntry(start); int firstRow = (entry == null) ? 0 : (entry.getValue() + 1); int address = start; int row = firstRow; // Build the mapping between addresses and rows. for (WAMInstruction instruction : instructions) { addressToRow.put(address, row); rowToAddress.add(row, address); row++; address += instruction.sizeof(); } // Render the instructions into the table to be displayed. renderInstructions(instructions, firstRow, start); }