return null; ByteVector bv = new ByteVector(); bv.putByte(typeRef >>> 24).putShort(start.length); for (int i = 0; i < start.length; ++i) { bv.putShort(start[i].position) .putShort(end[i].position - start[i].position) .putShort(index[i]); bv.putByte(0); } else { int length = typePath.b[typePath.offset] * 2 + 1; bv.putByteArray(typePath.b, typePath.offset, length); bv.putShort(cw.newUTF8(desc)).putShort(0); AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv, bv.length - 2);
@Override public final void visitSource(final String file, final String debug) { if (file != null) { sourceFile = newUTF8(file); } if (debug != null) { sourceDebug = new ByteVector().encodeUTF8(debug, 0, Integer.MAX_VALUE); } }
/** * Puts a byte into this byte vector. The byte vector is automatically * enlarged if necessary. * * @param b * a byte. * @return this byte vector. */ public ByteVector putByte(final int b) { int length = this.length; if (length + 1 > data.length) { enlarge(1); } data[length++] = (byte) b; this.length = length; return this; }
@Override public void visitLineNumber(final int line, final Label start) { if (lineNumber == null) { lineNumber = new ByteVector(); } ++lineNumberCount; lineNumber.putShort(start.position); lineNumber.putShort(line); }
/** * Adds a long to the constant pool of the class being build. Does nothing * if the constant pool already contains a similar item. * * @param value * the long value. * @return a new or already existing long item. */ Item newLong(final long value) { key.set(value); Item result = get(key); if (result == null) { pool.putByte(LONG).putLong(value); result = new Item(index, key); index += 2; put(result); } return result; }
@Override public void visitTableSwitchInsn(final int min, final int max, final Label dflt, final Label... labels) { lastCodeOffset = code.length; // adds the instruction to the bytecode of the method int source = code.length; code.putByte(Opcodes.TABLESWITCH); code.putByteArray(null, 0, (4 - code.length % 4) % 4); dflt.put(this, code, source, true); code.putInt(min).putInt(max); for (int i = 0; i < labels.length; ++i) { labels[i].put(this, code, source, true); } // updates currentBlock visitSwitchInsn(dflt, labels); }
@Override public void visitIincInsn(final int var, final int increment) { lastCodeOffset = code.length; if (currentBlock != null) { if (compute == FRAMES) { currentBlock.frame.execute(Opcodes.IINC, var, null, null); } } if (compute != NOTHING) { // updates max locals int n = var + 1; if (n > maxLocals) { maxLocals = n; } } // adds the instruction to the bytecode of the method if ((var > 255) || (increment > 127) || (increment < -128)) { code.putByte(196 /* WIDE */).put12(Opcodes.IINC, var) .putShort(increment); } else { code.putByte(Opcodes.IINC).put11(var, increment); } }
/** * Puts the annotations of this annotation writer list into the given byte * vector. * * @param out * where the annotations must be put. */ void put(final ByteVector out) { int n = 0; int size = 2; AnnotationWriter aw = this; AnnotationWriter last = null; while (aw != null) { ++n; size += aw.bv.length; aw.visitEnd(); // in case user forgot to call visitEnd aw.prev = last; last = aw; aw = aw.next; } out.putInt(size); out.putShort(n); aw = last; while (aw != null) { out.putByteArray(aw.bv.data, 0, aw.bv.length); aw = aw.prev; } }
@Override public void visitIntInsn(final int opcode, final int operand) { lastCodeOffset = code.length; // Label currentBlock = this.currentBlock; if (currentBlock != null) { if (compute == FRAMES) { currentBlock.frame.execute(opcode, operand, null, null); } else if (opcode != Opcodes.NEWARRAY) { // updates current and max stack sizes only for NEWARRAY // (stack size variation = 0 for BIPUSH or SIPUSH) int size = stackSize + 1; if (size > maxStackSize) { maxStackSize = size; } stackSize = size; } } // adds the instruction to the bytecode of the method if (opcode == Opcodes.SIPUSH) { code.put12(opcode, operand); } else { // BIPUSH or NEWARRAY code.put11(opcode, operand); } }
ByteVector out = new ByteVector(n); out.putByte(0); for (int i = 0; i < n;) { char c = typePath.charAt(i++); if (c == '[') { out.put11(ARRAY_ELEMENT, 0); } else if (c == '.') { out.put11(INNER_TYPE, 0); } else if (c == '*') { out.put11(WILDCARD_BOUND, 0); } else if (c >= '0' && c <= '9') { int typeArg = c - '0'; i += 1; out.put11(TYPE_ARGUMENT, typeArg);
enlarge(2 + charLength); } else { length = len; return encodeUTF8(s, i, 65535);
/** * Adds an integer to the constant pool of the class being build. Does * nothing if the constant pool already contains a similar item. * * @param value * the int value. * @return a new or already existing int item. */ Item newInteger(final int value) { key.set(value); Item result = get(key); if (result == null) { pool.putByte(INT).putInt(value); result = new Item(index++, key); put(result); } return result; }
@Override public void visitMultiANewArrayInsn(final String desc, final int dims) { lastCodeOffset = code.length; Item i = cw.newClassItem(desc); // Label currentBlock = this.currentBlock; if (currentBlock != null) { if (compute == FRAMES) { currentBlock.frame.execute(Opcodes.MULTIANEWARRAY, dims, cw, i); } else { // updates current stack size (max stack size unchanged because // stack size variation always negative or null) stackSize += 1 - dims; } } // adds the instruction to the bytecode of the method code.put12(Opcodes.MULTIANEWARRAY, i.index).putByte(dims); }
ByteVector bootstrapMethods = new ByteVector(attrSize + 62); bootstrapMethods.putByteArray(b, u + 10, attrSize - 2); classWriter.bootstrapMethodsCount = boostrapMethodCount; classWriter.bootstrapMethods = bootstrapMethods;
/** * Adds an UTF8 string to the constant pool of the class being build. Does * nothing if the constant pool already contains a similar item. <i>This * method is intended for {@link Attribute} sub classes, and is normally not * needed by class generators or adapters.</i> * * @param value * the String value. * @return the index of a new or already existing UTF8 item. */ public int newUTF8(final String value) { key.set(UTF8, value, null, null); Item result = get(key); if (result == null) { pool.putByte(UTF8).putUTF8(value); result = new Item(index++, key); put(result); } return result.index; }