private String parseInst(Instruction inst, int offset, Map<Integer, Integer> labels) throws ConstantPoolException { StringBuffer tmp = new StringBuffer(); StringBuilder tmp2 = new StringBuilder(); ParseVisitor parseVisitor = new ParseVisitorM6(labels, tmp2); // System.out.println(inst.toString()); tmp.append("(" + offset + " ("); if (labels.containsKey(inst.getPC())) { String label = "TAG_" + labels.get(inst.getPC()); tagTable.put(label, new Integer(offset)); tmp2.append(";;at " + label); } tmp.append(inst.accept(parseVisitor, null)).append("))"); // round the line length to multiple of 8. if (!tmp2.equals("")) { int pos = 20; while (pos <= tmp.length()) { pos += 20; } int bc = pos - tmp.length(); for (int j = 0; j < bc; j++) { tmp.append(" "); } tmp.append(tmp2); } return tmp.toString().trim(); }
/** * This method processes the MethodInfo given in the constructor. It is necessary to call this * method before querying this method. * * @param constant_pool The constant pool element from the M6Class object representing the outer * class from which this method is taken from. */ public void processMethod() throws ConstantPoolException, DescriptorException { /* The name of the method */ if (debug) { System.out.println("\nProcessing method: " + name + "Parameters: " + params); } /* Process the code attribute */ if (cai != null && !no_method_body) { LinkedHashMap<Integer, Integer> labels = new LinkedHashMap<>(); LabelsVisitor labelsVisitor = new LabelsVisitor(); for (Instruction inst : cai.getInstructions()) { for (int offset : inst.accept(labelsVisitor, null)) { int label = inst.getPC() + offset; if (!labels.containsKey(label)) { labels.put(label, labels.size()); } } } for (Code_attribute.Exception_data e : cai.exception_table) { if (!labels.containsKey(e.start_pc)) { labels.put(e.start_pc, labels.size()); } if (!labels.containsKey(e.end_pc)) { labels.put(e.end_pc, labels.size()); } if (!labels.containsKey(e.handler_pc)) { labels.put(e.handler_pc, labels.size()); } } int offset = 0; int li = 0; // index in linenumber table // get the parsed code part for (Instruction instr : cai.getInstructions()) { if (lnt != null && li < lnt.line_number_table.length && lnt.line_number_table[li].start_pc == instr.getPC()) { m6instructions.add("; " + "line_number #" + lnt.line_number_table[li].line_number); li++; } String resultStr = parseInst(instr, offset, labels); if (resultStr != null) { m6instructions.add(resultStr); offset = offset + instr.length(); } } // resolve any tag to absolute offsets. resolveTagInCode(); // add an end marker to the code. m6instructions.add("(endofcode " + code_length + ")"); } processed = true; }
@Override public String visitBranch(Instruction instr, int offset, Void p) { StringBuilder sb = new StringBuilder(); return sb.append(instr.getMnemonic()) .append(' ') .append(label(instr.getPC(), offset)) .toString(); }
@Override public String visitTableSwitch( Instruction instr, int default_, int low, int high, int[] offsets, Void p) { StringBuilder sb = new StringBuilder(); sb.append(instr.getMnemonic()) // the opcode .append(" (tableswitchinfo ") .append(label(instr.getPC(), default_)) // the default target .append(" (") .append(low) .append(" . ") .append(high) .append(") ("); for (int i = 0; i < high - low + 1; i++) { sb.append(label(instr.getPC(), offsets[i])).append(' '); } sb.setCharAt(sb.length() - 1, ')'); return sb.append(")").toString(); }
@Override public String visitLookupSwitch( Instruction instr, int default_, int npairs, int[] matches, int[] offsets, Void p) { StringBuilder sb = new StringBuilder(); sb.append(instr.getMnemonic()) // the opcode .append(" (lookupswitchinfo ") .append(label(instr.getPC(), default_)) // the default target .append(' ') .append(npairs) // the pair count .append(" ("); for (int i = 0; i < npairs; i++) { sb.append('(') .append(matches[i]) .append(" . ") .append(label(instr.getPC(), offsets[i])) .append(") "); } sb.setCharAt(sb.length() - 1, ')'); return sb.append(")").toString(); }