SimpleMetadataReader(Resource resource, @Nullable ClassLoader classLoader) throws IOException { InputStream is = new BufferedInputStream(resource.getInputStream()); ClassReader classReader; try { classReader = new ClassReader(is); } catch (IllegalArgumentException ex) { throw new NestedIOException("ASM ClassReader failed to parse class file - " + "probably due to a new Java class file version that isn't supported yet: " + resource, ex); } finally { is.close(); } AnnotationMetadataReadingVisitor visitor = new AnnotationMetadataReadingVisitor(classLoader); classReader.accept(visitor, ClassReader.SKIP_DEBUG); this.annotationMetadata = visitor; // (since AnnotationMetadataReadingVisitor extends ClassMetadataReadingVisitor) this.classMetadata = visitor; this.resource = resource; }
final int maxStack = readUnsignedShort(currentOffset); final int maxLocals = readUnsignedShort(currentOffset + 2); final int codeLength = readInt(currentOffset + 4); currentOffset += 8; case Constants.IFNULL: case Constants.IFNONNULL: createLabel(bytecodeOffset + readShort(currentOffset + 1), labels); currentOffset += 3; break; case Constants.ASM_IFNULL: case Constants.ASM_IFNONNULL: createLabel(bytecodeOffset + readUnsignedShort(currentOffset + 1), labels); currentOffset += 3; break; case Constants.JSR_W: case Constants.ASM_GOTO_W: createLabel(bytecodeOffset + readInt(currentOffset + 1), labels); currentOffset += 5; break; createLabel(bytecodeOffset + readInt(currentOffset), labels); int numTableEntries = readInt(currentOffset + 8) - readInt(currentOffset + 4) + 1; currentOffset += 12; createLabel(bytecodeOffset + readInt(currentOffset), labels); currentOffset += 4;
int accessFlags = readUnsignedShort(currentOffset); String thisClass = readClass(currentOffset + 2, charBuffer); String superClass = readClass(currentOffset + 4, charBuffer); String[] interfaces = new String[readUnsignedShort(currentOffset + 6)]; currentOffset += 8; for (int i = 0; i < interfaces.length; ++i) { interfaces[i] = readClass(currentOffset, charBuffer); currentOffset += 2; int currentAttributeOffset = getFirstAttributeOffset(); for (int i = readUnsignedShort(currentAttributeOffset - 2); i > 0; --i) { String attributeName = readUTF8(currentAttributeOffset, charBuffer); int attributeLength = readInt(currentAttributeOffset + 2); currentAttributeOffset += 6; sourceFile = readUTF8(currentAttributeOffset, charBuffer); } else if (Constants.INNER_CLASSES.equals(attributeName)) { innerClassesOffset = currentAttributeOffset; enclosingMethodOffset = currentAttributeOffset; } else if (Constants.NEST_HOST.equals(attributeName)) { nestHostClass = readClass(currentAttributeOffset, charBuffer); } else if (Constants.NEST_MEMBERS.equals(attributeName)) { nestMembersOffset = currentAttributeOffset; } else if (Constants.SIGNATURE.equals(attributeName)) { signature = readUTF8(currentAttributeOffset, charBuffer); } else if (Constants.RUNTIME_VISIBLE_ANNOTATIONS.equals(attributeName)) { runtimeVisibleAnnotationsOffset = currentAttributeOffset;
int currentAttributeOffset = getFirstAttributeOffset(); int[] currentBootstrapMethodOffsets = null; for (int i = readUnsignedShort(currentAttributeOffset - 2); i > 0; --i) { String attributeName = readUTF8(currentAttributeOffset, charBuffer); int attributeLength = readInt(currentAttributeOffset + 2); currentAttributeOffset += 6; if (Constants.BOOTSTRAP_METHODS.equals(attributeName)) { currentBootstrapMethodOffsets = new int[readUnsignedShort(currentAttributeOffset)]; 4 + readUnsignedShort(currentBootstrapMethodOffset + 2) * 2;
break; case Frame.ITEM_OBJECT: frame[index] = readClass(currentOffset, charBuffer); currentOffset += 2; break; case Frame.ITEM_UNINITIALIZED: frame[index] = createLabel(readUnsignedShort(currentOffset), labels); currentOffset += 2; break;
offsetDelta = frameType - Frame.SAME_LOCALS_1_STACK_ITEM_FRAME; currentOffset = readVerificationTypeInfo( currentOffset, context.currentFrameStackTypes, 0, charBuffer, labels); context.currentFrameType = Opcodes.F_SAME1; context.currentFrameStackCount = 1; } else if (frameType >= Frame.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED) { offsetDelta = readUnsignedShort(currentOffset); currentOffset += 2; if (frameType == Frame.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED) { currentOffset = readVerificationTypeInfo( currentOffset, context.currentFrameStackTypes, 0, charBuffer, labels); context.currentFrameType = Opcodes.F_SAME1; for (int k = frameType - Frame.SAME_FRAME_EXTENDED; k > 0; k--) { currentOffset = readVerificationTypeInfo( currentOffset, context.currentFrameLocalTypes, local++, charBuffer, labels); context.currentFrameStackCount = 0; } else { final int numberOfLocals = readUnsignedShort(currentOffset); currentOffset += 2; context.currentFrameType = Opcodes.F_FULL; for (int local = 0; local < numberOfLocals; ++local) { currentOffset = readVerificationTypeInfo(
int constantPoolOffset = classReader.getItem(1) - 1; int constantPoolLength = classReader.header - constantPoolOffset; constantPoolCount = classReader.getItemCount(); constantPool = new ByteVector(constantPoolLength); constantPool.putByteArray(inputBytes, constantPoolOffset, constantPoolLength); char[] charBuffer = new char[classReader.getMaxStringLength()]; boolean hasBootstrapMethods = false; int itemIndex = 1; while (itemIndex < constantPoolCount) { int itemOffset = classReader.getItem(itemIndex); int itemTag = inputBytes[itemOffset - 1]; int nameAndTypeItemOffset; case Symbol.CONSTANT_INTERFACE_METHODREF_TAG: nameAndTypeItemOffset = classReader.getItem(classReader.readUnsignedShort(itemOffset + 2)); addConstantMemberReference( itemIndex, itemTag, classReader.readClass(itemOffset, charBuffer), classReader.readUTF8(nameAndTypeItemOffset, charBuffer), classReader.readUTF8(nameAndTypeItemOffset + 2, charBuffer)); break; case Symbol.CONSTANT_INTEGER_TAG: case Symbol.CONSTANT_FLOAT_TAG: addConstantIntegerOrFloat(itemIndex, itemTag, classReader.readInt(itemOffset)); break; case Symbol.CONSTANT_NAME_AND_TYPE_TAG:
accept(classVisitor, new Attribute[0], parsingOptions); int accessFlags = readUnsignedShort(currentOffset); String thisClass = readClass(currentOffset + 2, charBuffer); String superClass = readClass(currentOffset + 4, charBuffer); String[] interfaces = new String[readUnsignedShort(currentOffset + 6)]; currentOffset += 8; for (int i = 0; i < interfaces.length; ++i) { int numAnnotations = readUnsignedShort(runtimeVisibleAnnotationsOffset); int currentAnnotationOffset = runtimeVisibleAnnotationsOffset + 2; while (numAnnotations-- > 0) { int numAnnotations = readUnsignedShort(runtimeInvisibleAnnotationsOffset); int currentAnnotationOffset = runtimeInvisibleAnnotationsOffset + 2; while (numAnnotations-- > 0) { int numAnnotations = readUnsignedShort(runtimeVisibleTypeAnnotationsOffset); int currentAnnotationOffset = runtimeVisibleTypeAnnotationsOffset + 2; while (numAnnotations-- > 0) { String annotationDescriptor = readUTF8(currentAnnotationOffset, charBuffer); currentAnnotationOffset += 2; int fieldsCount = readUnsignedShort(currentOffset); currentOffset += 2; while (fieldsCount-- > 0) { currentOffset = readField(classVisitor, context, currentOffset);
/** * Makes the given visitor visit the JVMS ClassFile structure passed to the constructor of this * {@link ClassReader}. * * @param classVisitor the visitor that must visit this class. * @param parsingOptions the options to use to parse this class. One or more of {@link * #SKIP_CODE}, {@link #SKIP_DEBUG}, {@link #SKIP_FRAMES} or {@link #EXPAND_FRAMES}. */ public void accept(final ClassVisitor classVisitor, final int parsingOptions) { accept(classVisitor, new Attribute[0], parsingOptions); }
int[] typeAnnotationsOffsets = new int[readUnsignedShort(currentOffset)]; currentOffset += 2; int targetType = readInt(currentOffset); switch (targetType >>> 24) { case TypeReference.LOCAL_VARIABLE: int tableLength = readUnsignedShort(currentOffset + 1); currentOffset += 3; while (tableLength-- > 0) { int startPc = readUnsignedShort(currentOffset); int length = readUnsignedShort(currentOffset + 2); createLabel(startPc, context.currentMethodLabels); createLabel(startPc + length, context.currentMethodLabels); int pathLength = readByte(currentOffset); if ((targetType >>> 24) == TypeReference.EXCEPTION_PARAMETER) { String annotationDescriptor = readUTF8(currentOffset, charBuffer); currentOffset += 2; readElementValues( methodVisitor.visitTryCatchAnnotation( targetType & 0xFFFFFF00, path, annotationDescriptor, visible), readElementValues( /* annotationVisitor = */ null, currentOffset, /* named = */ true, charBuffer);
final int maxStack = readUnsignedShort(currentOffset); final int maxLocals = readUnsignedShort(currentOffset + 2); final int codeLength = readInt(currentOffset + 4); currentOffset += 8; createLabel(bytecodeOffset + readInt(currentOffset), labels); int numTableEntries = readInt(currentOffset + 8) - readInt(currentOffset + 4) + 1; currentOffset += 12; createLabel(bytecodeOffset + readInt(currentOffset), labels); currentOffset += 4; int attributesCount = readUnsignedShort(currentOffset); currentOffset += 2; while (attributesCount-- > 0) { String attributeName = readUTF8(currentOffset, charBuffer); int attributeLength = readInt(currentOffset + 2); currentOffset += 6; int localVariableTableLength = readUnsignedShort(currentLocalVariableTableOffset); currentLocalVariableTableOffset += 2; while (localVariableTableLength-- > 0) { int startPc = readUnsignedShort(currentLocalVariableTableOffset); createDebugLabel(startPc, labels); int length = readUnsignedShort(currentLocalVariableTableOffset + 2); createDebugLabel(startPc + length, labels); int lineNumberTableLength = readUnsignedShort(currentLineNumberTableOffset);
ClassReader cr = new ClassReader(new DataInputStream(jar.getInputStream(jarEntry))); if (cr.getSuperName().equals("io/gomint/plugin/Plugin")) { final AtomicReference<String> name = new AtomicReference<>(); final AtomicReference<PluginVersion> version = new AtomicReference<>(); final AtomicReference<String> startup = new AtomicReference<>(StartupPriority.STARTUP.name()); cr.accept(new ClassVisitor(Opcodes.ASM7) { @Override public AnnotationVisitor visitAnnotation(String descriptor, boolean visible) { meta.setDepends(depends.get()); meta.setSoftDepends(softDepends.get()); meta.setMainClass(cr.getClassName().replace("/", ".")); } else { AtomicInteger neededArguments = new AtomicInteger(); cr.accept(new ClassVisitor(Opcodes.ASM7) { @Override public AnnotationVisitor visitAnnotation(String descriptor, boolean visible) { meta.getInjectionCommands().add(cr.getClassName().replace("/", "."));
String className = ClassNameReader.getClassName(new ClassReader(b)); ProtectionDomain protectionDomain = getProtectionDomain(); synchronized (classLoader) { // just in case
int currentOffset = typeAnnotationOffset; int targetType = readInt(typeAnnotationOffset); switch (targetType >>> 24) { case TypeReference.CLASS_TYPE_PARAMETER: case TypeReference.RESOURCE_VARIABLE: targetType &= 0xFF000000; int tableLength = readUnsignedShort(currentOffset + 1); currentOffset += 3; context.currentLocalVariableAnnotationRangeStarts = new Label[tableLength]; context.currentLocalVariableAnnotationRangeIndices = new int[tableLength]; for (int i = 0; i < tableLength; ++i) { int startPc = readUnsignedShort(currentOffset); int length = readUnsignedShort(currentOffset + 2); int index = readUnsignedShort(currentOffset + 4); currentOffset += 6; context.currentLocalVariableAnnotationRangeStarts[i] = createLabel(startPc, context.currentMethodLabels); context.currentLocalVariableAnnotationRangeEnds[i] = createLabel(startPc + length, context.currentMethodLabels); context.currentLocalVariableAnnotationRangeIndices[i] = index; int pathLength = readByte(currentOffset); context.currentTypeAnnotationTargetPath = pathLength == 0 ? null : new TypePath(b, currentOffset);
@Override @SuppressWarnings("unchecked") public void afterPropertiesSet() throws Exception { byte[] bytes = FileCopyUtils.copyToByteArray(this.resource.getInputStream()); String className = new ClassReader(bytes).getClassName().replace("/", "."); Class<?> factoryClass = this.classLoader.defineClass(className, bytes); try { this.target = ((CompilationResultFactory<T>) factoryClass.newInstance()).getResult(); this.method = findFactoryMethod(factoryClass); } catch (InstantiationException | IllegalAccessException e) { throw new IllegalArgumentException("failed to load Function byte code", e); } }
int constantPoolOffset = classReader.getItem(1) - 1; int constantPoolLength = classReader.header - constantPoolOffset; constantPoolCount = classReader.getItemCount(); constantPool = new ByteVector(constantPoolLength); constantPool.putByteArray(inputBytes, constantPoolOffset, constantPoolLength); char[] charBuffer = new char[classReader.getMaxStringLength()]; boolean hasBootstrapMethods = false; int itemIndex = 1; while (itemIndex < constantPoolCount) { int itemOffset = classReader.getItem(itemIndex); int itemTag = inputBytes[itemOffset - 1]; int nameAndTypeItemOffset; case Symbol.CONSTANT_INTERFACE_METHODREF_TAG: nameAndTypeItemOffset = classReader.getItem(classReader.readUnsignedShort(itemOffset + 2)); addConstantMemberReference( itemIndex, itemTag, classReader.readClass(itemOffset, charBuffer), classReader.readUTF8(nameAndTypeItemOffset, charBuffer), classReader.readUTF8(nameAndTypeItemOffset + 2, charBuffer)); break; case Symbol.CONSTANT_INTEGER_TAG: case Symbol.CONSTANT_FLOAT_TAG: addConstantIntegerOrFloat(itemIndex, itemTag, classReader.readInt(itemOffset)); break; case Symbol.CONSTANT_NAME_AND_TYPE_TAG:
int currentAttributeOffset = classReader.getFirstAttributeOffset(); for (int i = classReader.readUnsignedShort(currentAttributeOffset - 2); i > 0; --i) { String attributeName = classReader.readUTF8(currentAttributeOffset, charBuffer); if (Constants.BOOTSTRAP_METHODS.equals(attributeName)) { bootstrapMethodCount = classReader.readUnsignedShort(currentAttributeOffset + 6); break; currentAttributeOffset += 6 + classReader.readInt(currentAttributeOffset + 2); int bootstrapMethodsLength = classReader.readInt(currentAttributeOffset + 2) - 2; bootstrapMethods = new ByteVector(bootstrapMethodsLength); bootstrapMethods.putByteArray(inputBytes, bootstrapMethodsOffset, bootstrapMethodsLength); for (int i = 0; i < bootstrapMethodCount; i++) { int offset = currentOffset - bootstrapMethodsOffset; int bootstrapMethodRef = classReader.readUnsignedShort(currentOffset); currentOffset += 2; int numBootstrapArguments = classReader.readUnsignedShort(currentOffset); currentOffset += 2; int hashCode = classReader.readConst(bootstrapMethodRef, charBuffer).hashCode(); while (numBootstrapArguments-- > 0) { int bootstrapArgument = classReader.readUnsignedShort(currentOffset); currentOffset += 2; hashCode ^= classReader.readConst(bootstrapArgument, charBuffer).hashCode();
/** * Makes the given visitor visit the JVMS ClassFile structure passed to the constructor of this * {@link ClassReader}. * * @param classVisitor the visitor that must visit this class. * @param parsingOptions the options to use to parse this class. One or more of {@link * #SKIP_CODE}, {@link #SKIP_DEBUG}, {@link #SKIP_FRAMES} or {@link #EXPAND_FRAMES}. */ public void accept(final ClassVisitor classVisitor, final int parsingOptions) { accept(classVisitor, new Attribute[0], parsingOptions); }
int[] typeAnnotationsOffsets = new int[readUnsignedShort(currentOffset)]; currentOffset += 2; int targetType = readInt(currentOffset); switch (targetType >>> 24) { case TypeReference.LOCAL_VARIABLE: int tableLength = readUnsignedShort(currentOffset + 1); currentOffset += 3; while (tableLength-- > 0) { int startPc = readUnsignedShort(currentOffset); int length = readUnsignedShort(currentOffset + 2); createLabel(startPc, context.currentMethodLabels); createLabel(startPc + length, context.currentMethodLabels); int pathLength = readByte(currentOffset); if ((targetType >>> 24) == TypeReference.EXCEPTION_PARAMETER) { String annotationDescriptor = readUTF8(currentOffset, charBuffer); currentOffset += 2; readElementValues( methodVisitor.visitTryCatchAnnotation( targetType & 0xFFFFFF00, path, annotationDescriptor, visible), readElementValues( /* annotationVisitor = */ null, currentOffset, /* named = */ true, charBuffer);
String className = ClassNameReader.getClassName(new ClassReader(b)); ProtectionDomain protectionDomain = getProtectionDomain(); synchronized (classLoader) { // just in case