/** * Puts two bytes and one short into the constant pool. * * @param b1 * a byte. * @param b2 * another byte. * @param s * a short. */ private void put112(final int b1, final int b2, final int s) { pool.put11(b1, b2).putShort(s); } }
/** * Puts one byte and two shorts into the constant pool. * * @param b * a byte. * @param s1 * a short. * @param s2 * another short. */ private void put122(final int b, final int s1, final int s2) { pool.put12(b, s1).putShort(s2); }
localVarType.putShort(start.position) .putShort(end.position - start.position) .putShort(cw.newUTF8(name)).putShort(cw.newUTF8(signature)) .putShort(index); localVar.putShort(start.position) .putShort(end.position - start.position) .putShort(cw.newUTF8(name)).putShort(cw.newUTF8(desc)) .putShort(index); if (compute != NOTHING) {
@Override public final void visitInnerClass(final String name, final String outerName, final String innerName, final int access) { if (innerClasses == null) { innerClasses = new ByteVector(); } // Sec. 4.7.6 of the JVMS states "Every CONSTANT_Class_info entry in the // constant_pool table which represents a class or interface C that is // not a package member must have exactly one corresponding entry in the // classes array". To avoid duplicates we keep track in the intVal field // of the Item of each CONSTANT_Class_info entry C whether an inner // class entry has already been added for C (this field is unused for // class entries, and changing its value does not change the hashcode // and equality tests). If so we store the index of this inner class // entry (plus one) in intVal. This hack allows duplicate detection in // O(1) time. Item nameItem = newClassItem(name); if (nameItem.intVal == 0) { ++innerClassesCount; innerClasses.putShort(nameItem.index); innerClasses.putShort(outerName == null ? 0 : newClass(outerName)); innerClasses.putShort(innerName == null ? 0 : newUTF8(innerName)); innerClasses.putShort(access); nameItem.intVal = innerClassesCount; } else { // Compare the inner classes entry nameItem.intVal - 1 with the // arguments of this method and throw an exception if there is a // difference? } }
@Override public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) { if (!ClassReader.ANNOTATIONS) { return null; } ByteVector bv = new ByteVector(); // write type, and reserve space for values count bv.putShort(cw.newUTF8(desc)).putShort(0); AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv, 2); if (visible) { aw.next = anns; anns = aw; } else { aw.next = ianns; ianns = aw; } return aw; }
@Override public AnnotationVisitor visitAnnotation(final String name, final String desc) { ++size; if (named) { bv.putShort(cw.newUTF8(name)); } // write tag and type, and reserve space for values count bv.put12('@', cw.newUTF8(desc)).putShort(0); return new AnnotationWriter(cw, true, bv, bv, bv.length - 2); }
@Override public final AnnotationVisitor visitAnnotation(final String desc, final boolean visible) { if (!ClassReader.ANNOTATIONS) { return null; } ByteVector bv = new ByteVector(); // write type, and reserve space for values count bv.putShort(newUTF8(desc)).putShort(0); AnnotationWriter aw = new AnnotationWriter(this, true, bv, bv, 2); if (visible) { aw.next = anns; anns = aw; } else { aw.next = ianns; ianns = aw; } return aw; }
@Override public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) { if (!ClassReader.ANNOTATIONS) { return null; } ByteVector bv = new ByteVector(); // write type, and reserve space for values count bv.putShort(cw.newUTF8(desc)).putShort(0); AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv, 2); if (visible) { aw.next = anns; anns = aw; } else { aw.next = ianns; ianns = aw; } return aw; }
@Override public final AnnotationVisitor visitTypeAnnotation(int typeRef, TypePath typePath, final String desc, final boolean visible) { if (!ClassReader.ANNOTATIONS) { return null; } ByteVector bv = new ByteVector(); // write target_type and target_info AnnotationWriter.putTarget(typeRef, typePath, bv); // write type, and reserve space for values count bv.putShort(newUTF8(desc)).putShort(0); AnnotationWriter aw = new AnnotationWriter(this, true, bv, bv, bv.length - 2); if (visible) { aw.next = tanns; tanns = aw; } else { aw.next = itanns; itanns = aw; } return aw; }
@Override public AnnotationVisitor visitInsnAnnotation(int typeRef, TypePath typePath, String desc, boolean visible) { if (!ClassReader.ANNOTATIONS) { return null; } ByteVector bv = new ByteVector(); // write target_type and target_info typeRef = (typeRef & 0xFF0000FF) | (lastCodeOffset << 8); AnnotationWriter.putTarget(typeRef, typePath, bv); // write type, and reserve space for values count bv.putShort(cw.newUTF8(desc)).putShort(0); AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv, bv.length - 2); if (visible) { aw.next = ctanns; ctanns = aw; } else { aw.next = ictanns; ictanns = aw; } return aw; }
@Override public AnnotationVisitor visitTypeAnnotation(final int typeRef, final TypePath typePath, final String desc, final boolean visible) { if (!ClassReader.ANNOTATIONS) { return null; } ByteVector bv = new ByteVector(); // write target_type and target_info AnnotationWriter.putTarget(typeRef, typePath, bv); // write type, and reserve space for values count bv.putShort(cw.newUTF8(desc)).putShort(0); AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv, bv.length - 2); if (visible) { aw.next = tanns; tanns = aw; } else { aw.next = itanns; itanns = aw; } return aw; }
@Override public AnnotationVisitor visitTypeAnnotation(final int typeRef, final TypePath typePath, final String desc, final boolean visible) { if (!ClassReader.ANNOTATIONS) { return null; } ByteVector bv = new ByteVector(); // write target_type and target_info AnnotationWriter.putTarget(typeRef, typePath, bv); // write type, and reserve space for values count bv.putShort(cw.newUTF8(desc)).putShort(0); AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv, bv.length - 2); if (visible) { aw.next = tanns; tanns = aw; } else { aw.next = itanns; itanns = aw; } return aw; }
@Override public AnnotationVisitor visitTryCatchAnnotation(int typeRef, TypePath typePath, String desc, boolean visible) { if (!ClassReader.ANNOTATIONS) { return null; } ByteVector bv = new ByteVector(); // write target_type and target_info AnnotationWriter.putTarget(typeRef, typePath, bv); // write type, and reserve space for values count bv.putShort(cw.newUTF8(desc)).putShort(0); AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv, bv.length - 2); if (visible) { aw.next = ctanns; ctanns = aw; } else { aw.next = ictanns; ictanns = aw; } return aw; }
@Override public AnnotationVisitor visitArray(final String name) { ++size; if (named) { bv.putShort(cw.newUTF8(name)); } // write tag, and reserve space for array size bv.put12('[', 0); return new AnnotationWriter(cw, false, bv, bv, bv.length - 2); }
/** * 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 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); } }