Refine search
@Override public void visitLineNumber(final int line, final Label start) { if (lineNumberTable == null) { lineNumberTable = new ByteVector(); } ++lineNumberTableLength; lineNumberTable.putShort(start.bytecodeOffset); lineNumberTable.putShort(line); }
@Override public void visitIincInsn(final int var, final int increment) { lastBytecodeOffset = code.length; // Add the instruction to the bytecode of the method. if ((var > 255) || (increment > 127) || (increment < -128)) { code.putByte(Constants.WIDE).put12(Opcodes.IINC, var).putShort(increment); } else { code.putByte(Opcodes.IINC).put11(var, increment); } // If needed, update the maximum stack size and number of locals, and stack map frames. if (currentBasicBlock != null && (compute == COMPUTE_ALL_FRAMES || compute == COMPUTE_INSERTED_FRAMES)) { currentBasicBlock.frame.execute(Opcodes.IINC, var, null, null); } if (compute != COMPUTE_NOTHING) { int currentMaxLocals = var + 1; if (currentMaxLocals > maxLocals) { maxLocals = currentMaxLocals; } } }
/** * Puts this symbol table's BootstrapMethods attribute in the given ByteVector. This includes the * 6 attribute header bytes and the num_bootstrap_methods value. * * @param output where the JVMS BootstrapMethods attribute must be put. */ void putBootstrapMethods(final ByteVector output) { if (bootstrapMethods != null) { output .putShort(addConstantUtf8(Constants.BOOTSTRAP_METHODS)) .putInt(bootstrapMethods.length + 2) .putShort(bootstrapMethodCount) .putByteArray(bootstrapMethods.data, 0, bootstrapMethods.length); } }
/** * Puts this symbol table's constant_pool array in the given ByteVector, preceded by the * constant_pool_count value. * * @param output where the JVMS ClassFile's constant_pool array must be put. */ void putConstantPool(final ByteVector output) { output.putShort(constantPoolCount).putByteArray(constantPool.data, 0, constantPool.length); }
/** * Puts the type_path JVMS structure corresponding to the given TypePath into the given * ByteVector. * * @param typePath a TypePath instance, or {@literal null} for empty paths. * @param output where the type path must be put. */ static void put(final TypePath typePath, final ByteVector output) { if (typePath == null) { output.putByte(0); } else { int length = typePath.typePathContainer[typePath.typePathOffset] * 2 + 1; output.putByteArray(typePath.typePathContainer, typePath.typePathOffset, length); } } }
ByteVector out = new ByteVector(size); out.putInt(0xCAFEBABE).putInt(version); out.putShort(index).putByteArray(pool.data, 0, pool.length); int mask = Opcodes.ACC_DEPRECATED | ACC_SYNTHETIC_ATTRIBUTE | ((access & ACC_SYNTHETIC_ATTRIBUTE) / TO_ACC_SYNTHETIC); out.putShort(access & ~mask).putShort(name).putShort(superName); out.putShort(interfaceCount); for (int i = 0; i < interfaceCount; ++i) { out.putShort(interfaces[i]); out.putShort(nbFields); fb = firstField; while (fb != null) { out.putShort(nbMethods); mb = firstMethod; while (mb != null) { out.putShort(attributeCount); if (bootstrapMethods != null) { out.putShort(newUTF8("BootstrapMethods")); out.putInt(bootstrapMethods.length + 2).putShort( bootstrapMethodsCount); out.putByteArray(bootstrapMethods.data, 0, bootstrapMethods.length); out.putShort(newUTF8("Signature")).putInt(2).putShort(signature); out.putShort(newUTF8("SourceFile")).putInt(2).putShort(sourceFile);
ByteVector result = new ByteVector(size); result.putInt(0xCAFEBABE).putInt(version); symbolTable.putConstantPool(result); int mask = (version & 0xFFFF) < Opcodes.V1_5 ? Opcodes.ACC_SYNTHETIC : 0; result.putShort(accessFlags & ~mask).putShort(thisClass).putShort(superClass); result.putShort(interfaceCount); for (int i = 0; i < interfaceCount; ++i) { result.putShort(interfaces[i]); result.putShort(fieldsCount); fieldWriter = firstField; while (fieldWriter != null) { result.putShort(methodsCount); boolean hasFrames = false; boolean hasAsmInstructions = false; result.putShort(attributesCount); if (innerClasses != null) { result .putShort(symbolTable.addConstantUtf8(Constants.INNER_CLASSES)) .putInt(innerClasses.length + 2) .putShort(numberOfInnerClasses) .putByteArray(innerClasses.data, 0, innerClasses.length); .putShort(symbolTable.addConstantUtf8(Constants.ENCLOSING_METHOD)) .putInt(4) .putShort(enclosingClassIndex) .putShort(enclosingMethodIndex);
@Override public void visitLookupSwitchInsn(final Label dflt, final int[] keys, final Label[] labels) { lastBytecodeOffset = code.length; // Add the instruction to the bytecode of the method. code.putByte(Opcodes.LOOKUPSWITCH).putByteArray(null, 0, (4 - code.length % 4) % 4); dflt.put(code, lastBytecodeOffset, true); code.putInt(labels.length); for (int i = 0; i < labels.length; ++i) { code.putInt(keys[i]); labels[i].put(code, lastBytecodeOffset, true); } // If needed, update the maximum stack size and number of locals, and stack map frames. visitSwitchInsn(dflt, labels); }
@Override public void visitIntInsn(final int opcode, final int operand) { lastBytecodeOffset = code.length; // Add the instruction to the bytecode of the method. if (opcode == Opcodes.SIPUSH) { code.put12(opcode, operand); } else { // BIPUSH or NEWARRAY code.put11(opcode, operand); } // If needed, update the maximum stack size and number of locals, and stack map frames. if (currentBasicBlock != null) { if (compute == COMPUTE_ALL_FRAMES || compute == COMPUTE_INSERTED_FRAMES) { currentBasicBlock.frame.execute(opcode, operand, null, null); } else if (opcode != Opcodes.NEWARRAY) { // The stack size delta is 1 for BIPUSH or SIPUSH, and 0 for NEWARRAY. int size = relativeStackSize + 1; if (size > maxRelativeStackSize) { maxRelativeStackSize = size; } relativeStackSize = size; } } }
case METHOD_TYPE_PARAMETER: case METHOD_FORMAL_PARAMETER: output.putShort(targetTypeAndInfo >>> 16); break; case FIELD: case METHOD_RETURN: case METHOD_RECEIVER: output.putByte(targetTypeAndInfo >>> 24); break; case CAST: case CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT: case METHOD_REFERENCE_TYPE_ARGUMENT: output.putInt(targetTypeAndInfo); break; case CLASS_EXTENDS: case CONSTRUCTOR_REFERENCE: case METHOD_REFERENCE: output.put12(targetTypeAndInfo >>> 24, (targetTypeAndInfo & 0xFFFF00) >> 8); break; default:
annotationWriter == null ? 0 : annotationWriter.computeAnnotationsSize(null) - 8; output.putShort(attributeNameIndex); output.putInt(attributeLength); output.putByte(annotableParameterCount); for (int i = 0; i < annotableParameterCount; ++i) { AnnotationWriter annotationWriter = annotationWriters[i]; annotationWriter = annotationWriter.previousAnnotation; output.putShort(numAnnotations); annotationWriter = firstAnnotation; while (annotationWriter != null) { output.putByteArray( annotationWriter.annotation.data, 0, annotationWriter.annotation.length); annotationWriter = annotationWriter.nextAnnotation;
@Override public void visitEnum(final String name, final String descriptor, final String value) { // Case of an element_value with an enum_const_value field. // See https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.16.1. ++numElementValuePairs; if (useNamedValues) { annotation.putShort(symbolTable.addConstantUtf8(name)); } annotation .put12('e', symbolTable.addConstantUtf8(descriptor)) .putShort(symbolTable.addConstantUtf8(value)); }
ByteVector output = new ByteVector(typePathLength); output.putByte(0); int typePathIndex = 0; while (typePathIndex < typePathLength) { char c = typePath.charAt(typePathIndex++); if (c == '[') { output.put11(ARRAY_ELEMENT, 0); } else if (c == '.') { output.put11(INNER_TYPE, 0); } else if (c == '*') { output.put11(WILDCARD_BOUND, 0); } else if (c >= '0' && c <= '9') { int typeArg = c - '0'; output.put11(TYPE_ARGUMENT, typeArg); } else { throw new IllegalArgumentException();
bootstrapMethods = this.bootstrapMethods = new ByteVector(); bootstrapMethods.putShort(newHandle(bsm.tag, bsm.owner, bsm.name, bsm.desc)); bootstrapMethods.putShort(argsLength); bootstrapMethods.putShort(newConst(bsmArg)); result = new Item(bootstrapMethodIndex); result.set(position, hashCode); put(result);
/** * Adds a CONSTANT_Utf8_info to the constant pool of this symbol table. Does nothing if the * constant pool already contains a similar item. * * @param value a string. * @return a new or already existing Symbol with the given value. */ int addConstantUtf8(final String value) { int hashCode = hash(Symbol.CONSTANT_UTF8_TAG, value); Entry entry = get(hashCode); while (entry != null) { if (entry.tag == Symbol.CONSTANT_UTF8_TAG && entry.hashCode == hashCode && entry.value.equals(value)) { return entry.index; } entry = entry.next; } constantPool.putByte(Symbol.CONSTANT_UTF8_TAG).putUTF8(value); return put(new Entry(constantPoolCount++, Symbol.CONSTANT_UTF8_TAG, value, hashCode)).index; }
/** * Adds a CONSTANT_Long_info or CONSTANT_Double_info to the constant pool of this symbol table. * Does nothing if the constant pool already contains a similar item. * * @param tag one of {@link Symbol#CONSTANT_LONG_TAG} or {@link Symbol#CONSTANT_DOUBLE_TAG}. * @param value a long or double. * @return a constant pool constant with the given tag and primitive values. */ private Symbol addConstantLongOrDouble(final int tag, final long value) { int hashCode = hash(tag, value); Entry entry = get(hashCode); while (entry != null) { if (entry.tag == tag && entry.hashCode == hashCode && entry.data == value) { return entry; } entry = entry.next; } int index = constantPoolCount; constantPool.putByte(tag).putLong(value); constantPoolCount += 2; return put(new Entry(index, tag, value, hashCode)); }
ByteVector typeAnnotation = new ByteVector(); typeAnnotation.putByte(typeRef >>> 24).putShort(start.length); for (int i = 0; i < start.length; ++i) { typeAnnotation .putShort(start[i].bytecodeOffset) .putShort(end[i].bytecodeOffset - start[i].bytecodeOffset) .putShort(index[i]); typeAnnotation.putShort(symbolTable.addConstantUtf8(descriptor)).putShort(0); if (visible) { return lastCodeRuntimeVisibleTypeAnnotation =
/** * 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; }
/** * Adds a double to the constant pool of the class being build. Does nothing * if the constant pool already contains a similar item. * * @param value * the double value. * @return a new or already existing double item. */ Item newDouble(final double value) { key.set(value); Item result = get(key); if (result == null) { pool.putByte(DOUBLE).putLong(key.longVal); result = new Item(index, key); index += 2; put(result); } return result; }