/** * Does a human-friendly dump of this instance. * * @param out {@code non-null;} where to dump * @param prefix {@code non-null;} prefix to attach to each line of output * @param verbose whether to be verbose; verbose output includes lines for zero-size instructions * and explicit constant pool indices */ public void debugPrint(Writer out, String prefix, boolean verbose) { IndentingWriter iw = new IndentingWriter(out, 0, prefix); int sz = size(); try { for (int i = 0; i < sz; i++) { DalvInsn insn = (DalvInsn) get0(i); String s; if ((insn.codeSize() != 0) || verbose) { s = insn.listingString("", 0, verbose); } else { s = null; } if (s != null) { iw.write(s); } } iw.flush(); } catch (IOException ex) { throw new RuntimeException(ex); } }
/** * Gets the size of the outgoing arguments area required by this method. This is equal to the * largest argument word count of any method referred to by this instance. * * @return {@code >= 0;} the required outgoing arguments size */ public int getOutsSize() { int sz = size(); int result = 0; for (int i = 0; i < sz; i++) { DalvInsn insn = (DalvInsn) get0(i); if (!(insn instanceof CstInsn)) { continue; } Constant cst = ((CstInsn) insn).getConstant(); if (!(cst instanceof CstBaseMethodRef)) { continue; } boolean isStatic = (insn.getOpcode().getFamily() == DalvOps.INVOKE_STATIC); int count = ((CstBaseMethodRef) cst).getParameterWordCount(isStatic); if (count > result) { result = count; } } return result; }
/** * Extracts and returns the source position information out of an instruction list. * * @param insns {@code non-null;} instructions to convert * @param howMuch how much information should be included; one of the static constants defined by * this class * @return {@code non-null;} the positions list */ public static PositionList make(DalvInsnList insns, int howMuch) { switch (howMuch) { case NONE: { return EMPTY; } case LINES: case IMPORTANT: { // Valid. break; } default: { throw new IllegalArgumentException("bogus howMuch"); } } SourcePosition noInfo = SourcePosition.NO_INFO; SourcePosition cur = noInfo; int sz = insns.size(); PositionList.Entry[] arr = new PositionList.Entry[sz]; boolean lastWasTarget = false; int at = 0; for (int i = 0; i < sz; i++) { DalvInsn insn = insns.get(i); if (insn instanceof CodeAddress) { lastWasTarget = true; ; continue; } SourcePosition pos = insn.getPosition(); if (pos.equals(noInfo) || pos.sameLine(cur)) { continue; } if ((howMuch == IMPORTANT) && !lastWasTarget) { continue; } cur = pos; arr[at] = new PositionList.Entry(insn.getAddress(), pos); at++; lastWasTarget = false; } PositionList result = new PositionList(at); for (int i = 0; i < at; i++) { result.set(i, arr[i]); } result.setImmutable(); return result; }
/** * Gets the size of this instance, in 16-bit code units. This will only return a meaningful result * if the instructions in this instance all have valid addresses. * * @return {@code >= 0;} the size */ public int codeSize() { int sz = size(); if (sz == 0) { return 0; } DalvInsn last = get(sz - 1); return last.getNextAddress(); }
/** * Writes all the instructions in this instance to the given output destination. * * @param out {@code non-null;} where to write to */ public void writeTo(AnnotatedOutput out) { int startCursor = out.getCursor(); int sz = size(); if (out.annotates()) { boolean verbose = out.isVerbose(); for (int i = 0; i < sz; i++) { DalvInsn insn = (DalvInsn) get0(i); int codeBytes = insn.codeSize() * 2; String s; if ((codeBytes != 0) || verbose) { s = insn.listingString(" ", out.getAnnotationWidth(), true); } else { s = null; } if (s != null) { out.annotate(codeBytes, s); } else if (codeBytes != 0) { out.annotate(codeBytes, ""); } } } for (int i = 0; i < sz; i++) { DalvInsn insn = (DalvInsn) get0(i); try { insn.writeTo(out); } catch (RuntimeException ex) { throw ExceptionWithContext.withContext(ex, "...while writing " + insn); } } // Sanity check of the amount written. int written = (out.getCursor() - startCursor) / 2; if (written != codeSize()) { throw new RuntimeException( "write length mismatch; expected " + codeSize() + " but actually wrote " + written); } }