/** * Write the ClassFile to the Stream * * @param os the stream to write to. */ public synchronized void write(OutputStream os) throws IOException { DataOutputStream dos = new DataOutputStream(os); try { dos.writeInt(MAGIC); dos.writeShort(MINOR); dos.writeShort(MAJOR); writeConstantPool(dos); if (debug()) System.err.println("access: " + accessFlags); dos.writeShort(accessFlags); dos.writeShort(thisClass.getConstantPoolIndex()); dos.writeShort(superClass.getConstantPoolIndex()); writeInterfaces(dos); writeFields(dos); writeMethods(dos); writeAttributes(dos); dos.close(); // all done! } catch (IOException ioe) { System.err.println("Bad IO"); } catch (Exception e) { System.err.println("Oops"); } }
private int getOrInsertClass(int nameIndex) throws IOException { int classIndex = constantPool.lookForClass(nameIndex); if (classIndex == -1) { classIndex = constantPool.poolSize() + 1; ClassConstant classConstant = new ClassConstant(nameIndex); constantPool.add(classConstant); classConstant.serializeToStream(constantStream); } return classIndex; }
/** * Returns the given type in form of a loaded type. The value is loaded from the written class's * constant pool. * * @param fixedValue The type to return from the method. * @return An implementation for the given {@code fixedValue}. */ public static AssignerConfigurable value(TypeDescription fixedValue) { return new ForPoolValue( ClassConstant.of(fixedValue), TypeDescription.CLASS, Assigner.DEFAULT, Assigner.Typing.STATIC); }
public void visitClassConstant(Clazz clazz, ClassConstant classConstant) { if (shouldBeMarkedAsUsed(classConstant)) { markAsUsed(classConstant); markConstant(clazz, classConstant.u2nameIndex); // Mark the referenced class itself. classConstant.referencedClassAccept(this); } }
@Override public Size apply( MethodVisitor methodVisitor, Context implementationContext, MethodDescription instrumentedMethod) { return ForOriginType.this.apply( methodVisitor, implementationContext, instrumentedMethod, TypeDescription.CLASS.asGenericType(), ClassConstant.of(originType)); }
@Override public MethodDelegationBinder.ParameterBinding<?> bind( AnnotationDescription.Loadable<Origin> annotation, MethodDescription source, ParameterDescription target, Implementation.Target implementationTarget, Assigner assigner) { TypeDescription parameterType = target.getType().asErasure(); if (parameterType.represents(Class.class)) { return new MethodDelegationBinder.ParameterBinding.Anonymous( ClassConstant.of(implementationTarget.getOriginType())); } else if (parameterType.represents(Method.class)) { return new MethodDelegationBinder.ParameterBinding.Anonymous( annotation.loadSilent().cache() ? MethodConstant.forMethod(source.asDefined()).cached() : MethodConstant.forMethod(source.asDefined())); } else if (parameterType.represents(String.class)) { return new MethodDelegationBinder.ParameterBinding.Anonymous( new TextConstant(source.toString())); } else if (parameterType.represents(int.class)) { return new MethodDelegationBinder.ParameterBinding.Anonymous( IntegerConstant.forValue(source.getModifiers())); } else if (parameterType.equals(JavaType.METHOD_HANDLE.getTypeStub())) { return new MethodDelegationBinder.ParameterBinding.Anonymous( MethodHandleConstant.of(source.asDefined())); } else if (parameterType.equals(JavaType.METHOD_TYPE.getTypeStub())) { return new MethodDelegationBinder.ParameterBinding.Anonymous( MethodTypeConstant.of(source.asDefined())); } else { throw new IllegalStateException( "The " + target + " method's " + target.getIndex() + " parameter is annotated with a Origin annotation with an argument not representing a Class," + " Method, String, int, MethodType or MethodHandle type"); } }
/** * Returns a fixed value from any intercepted method. The fixed value is stored in the constant * pool if this is possible. Java is capable of storing any primitive value, {@link String} values * and {@link Class} references in the constant pool. Since Java 7, {@code MethodHandle} as well * as {@code MethodType} references are also supported. Alternatively, the fixed value is stored * in a static field. * * <p>When a value is stored in the class's constant pool, its identity is lost. If an object's * identity is important, the {@link FixedValue#reference(Object)} method should be used instead. * * @param fixedValue The fixed value to return from the method. * @return An implementation for the given {@code fixedValue}. */ public static AssignerConfigurable value(Object fixedValue) { Class<?> type = fixedValue.getClass(); if (type == String.class) { return new ForPoolValue( new TextConstant((String) fixedValue), TypeDescription.STRING, Assigner.DEFAULT, Assigner.Typing.STATIC); } else if (type == Class.class) { return new ForPoolValue( ClassConstant.of(new TypeDescription.ForLoadedType((Class<?>) fixedValue)), TypeDescription.CLASS, Assigner.DEFAULT, Assigner.Typing.STATIC); } else if (type == Boolean.class) { return new ForPoolValue( IntegerConstant.forValue((Boolean) fixedValue), new TypeDescription.ForLoadedType(boolean.class), Assigner.DEFAULT, Assigner.Typing.STATIC); } else if (type == Byte.class) { return new ForPoolValue( IntegerConstant.forValue((Byte) fixedValue), new TypeDescription.ForLoadedType(byte.class), Assigner.DEFAULT, Assigner.Typing.STATIC); } else if (type == Short.class) { return new ForPoolValue( IntegerConstant.forValue((Short) fixedValue), new TypeDescription.ForLoadedType(short.class), Assigner.DEFAULT, Assigner.Typing.STATIC); } else if (type == Character.class) { return new ForPoolValue( IntegerConstant.forValue((Character) fixedValue), new TypeDescription.ForLoadedType(char.class), Assigner.DEFAULT, Assigner.Typing.STATIC); } else if (type == Integer.class) { return new ForPoolValue( IntegerConstant.forValue((Integer) fixedValue), new TypeDescription.ForLoadedType(int.class), Assigner.DEFAULT, Assigner.Typing.STATIC); } else if (type == Long.class) { return new ForPoolValue( LongConstant.forValue((Long) fixedValue), new TypeDescription.ForLoadedType(long.class), Assigner.DEFAULT, Assigner.Typing.STATIC); } else if (type == Float.class) { return new ForPoolValue( FloatConstant.forValue((Float) fixedValue), new TypeDescription.ForLoadedType(float.class), Assigner.DEFAULT, Assigner.Typing.STATIC); } else if (type == Double.class) { return new ForPoolValue( DoubleConstant.forValue((Double) fixedValue), new TypeDescription.ForLoadedType(double.class), Assigner.DEFAULT, Assigner.Typing.STATIC); } else if (JavaType.METHOD_HANDLE.getTypeStub().isAssignableFrom(type)) { return new ForPoolValue( MethodHandleConstant.of(JavaInstance.MethodHandle.of(fixedValue)), new TypeDescription.ForLoadedType(type), Assigner.DEFAULT, Assigner.Typing.STATIC); } else if (JavaType.METHOD_TYPE.getTypeStub().represents(type)) { return new ForPoolValue( MethodTypeConstant.of(JavaInstance.MethodType.of(fixedValue)), new TypeDescription.ForLoadedType(type), Assigner.DEFAULT, Assigner.Typing.STATIC); } else { return reference(fixedValue); } }
public void outAClzzConstant(AClzzConstant node) { String s = (String) mProductions.removeLast(); mProductions.addLast(ClassConstant.v(s)); }
public void countConstantReferences() { if (catchType != null) catchType.incReference(); }
public boolean searchForString(String str) { for (ClassConstant<Integer> i : stringIndices) { if (((String) constants[i.get() - 1].get()).contains(str)) return true; } return false; }
public void visitClassConstant(Clazz clazz, ClassConstant classConstant) { // Let the visitor visit the class referenced in the class constant. classConstant.referencedClassAccept(classVisitor); }