/* * insertGapCore0w() can handle a long code sequence more than 32K. * It guarantees that the length of the inserted gap (NOPs) is equal to * gapLength. No other NOPs except some NOPs following TABLESWITCH or * LOOKUPSWITCH will not be inserted. * * Note: currentPos might be moved. * * @param where It must indicate the first byte of an opcode. * @param newWhere It contains the updated index of the position where a gap * is inserted and the length of the gap. * It must not be null. */ private byte[] insertGapCore0w( byte[] code, int where, int gapLength, boolean exclusive, ExceptionTable etable, CodeAttribute ca, Gap newWhere) throws BadBytecode { if (gapLength <= 0) return code; ArrayList jumps = makeJumpList(code, code.length); Pointers pointers = new Pointers(currentPos, mark, where, etable, ca); byte[] r = insertGap2w(code, where, gapLength, exclusive, jumps, pointers); currentPos = pointers.cursor; mark = pointers.mark; int where2 = pointers.mark0; if (where2 == currentPos && !exclusive) currentPos += gapLength; if (exclusive) where2 -= gapLength; newWhere.position = where2; newWhere.length = gapLength; return r; }
/** * Inserts an inclusive or exclusive gap in front of the instruction at the given index <code>pos * </code>. Branch offsets and the exception table in the method body are also updated. The * inserted gap is filled with NOP. The gap length may be extended to a multiple of 4. * * <p>Suppose that the instruction at the given index is at the beginning of a block statement. If * the gap is inclusive, then it is included within that block. If the gap is exclusive, then it * is excluded from that block. * * <p>The index at which the gap is actually inserted might be different from pos since some other * bytes might be inserted at other positions (e.g. to change <code>GOTO</code> to <code>GOTO_W * </code>). The index is available from the <code>Gap</code> object returned by this method. * * <p>Suppose that the gap is inserted at the position of the next instruction that would be * returned by <code>next()</code> (not the last instruction returned by the last call to <code> * next()</code>). The next instruction returned by <code>next()</code> after the gap is inserted * is still the same instruction. It is not <code>NOP</code> at the first byte of the inserted * gap. * * @param pos the index at which a gap is inserted. * @param length gap length. * @param exclusive true if exclusive, otherwise false. * @return the position and the length of the inserted gap. * @since 3.11 */ public Gap insertGapAt(int pos, int length, boolean exclusive) throws BadBytecode { /** cursorPos indicates the next bytecode whichever exclusive is true or false. */ Gap gap = new Gap(); if (length <= 0) { gap.position = pos; gap.length = 0; return gap; } byte[] c; int length2; if (bytecode.length + length > Short.MAX_VALUE) { // currentPos might change after calling insertGapCore0w(). c = insertGapCore0w( bytecode, pos, length, exclusive, get().getExceptionTable(), codeAttr, gap); pos = gap.position; length2 = length; // == gap.length } else { int cur = currentPos; c = insertGapCore0(bytecode, pos, length, exclusive, get().getExceptionTable(), codeAttr); // insertGapCore0() never changes pos. length2 = c.length - bytecode.length; gap.position = pos; gap.length = length2; if (cur >= pos) currentPos = cur + length2; if (mark > pos || (mark == pos && exclusive)) mark += length2; } codeAttr.setCode(c); bytecode = c; endPos = getCodeLength(); updateCursors(pos, length2); return gap; }