/** * Represents the supplied {@code java.lang.Module} as an instance of this class and validates that the * supplied instance really represents a Java {@code Module}. * * @param module The module to represent. * @return A representation of the supplied Java module. */ public static JavaModule of(Object module) { if (!JavaType.MODULE.getTypeStub().isInstance(module)) { throw new IllegalArgumentException("Not a Java module: " + module); } return new JavaModule(module); }
/** * Returns a method type representation of a loaded {@code MethodType} object. * * @param methodType A method type object to represent as a {@link JavaConstant}. * @return The method type represented as a {@link MethodType}. */ public static MethodType ofLoaded(Object methodType) { if (!JavaType.METHOD_TYPE.getTypeStub().isInstance(methodType)) { throw new IllegalArgumentException("Expected method type object: " + methodType); } return of(DISPATCHER.returnType(methodType), DISPATCHER.parameterArray(methodType)); }
/** * Creates class injector that defines a class using a method handle lookup. * * @param lookup The {@code java.lang.invoke.MethodHandles$Lookup} instance to use. * @return An appropriate class injector. */ public static UsingLookup of(Object lookup) { if (!DISPATCHER.isAlive()) { throw new IllegalStateException("The current VM does not support class definition via method handle lookups"); } else if (!JavaType.METHOD_HANDLES_LOOKUP.getTypeStub().isInstance(lookup)) { throw new IllegalArgumentException("Not a method handle lookup: " + lookup); } else if ((DISPATCHER.lookupModes(lookup) & PACKAGE_LOOKUP) == 0) { throw new IllegalArgumentException("Lookup does not imply package-access: " + lookup); } return new UsingLookup(DISPATCHER.dropLookupMode(lookup, Opcodes.ACC_PRIVATE)); }
@Override public InvokeDynamic as(TypeDescription typeDescription) { if (!typeDescription.asBoxed().isInstance(value)) { throw new IllegalArgumentException(value + " is not of type " + typeDescription); } return new InvokeDynamic(bootstrapMethod, handleArguments, invocationProvider.appendArgument(new InvocationProvider.ArgumentProvider.ForInstance(value, typeDescription)), terminationHandler, assigner, typing); }
/** * Delegates any intercepted method to invoke a non-{@code static} method that is declared by the supplied type's instance or any * of its super types. To be considered a valid delegation target, a method must be visible and accessible to the instrumented type. * This is the case if the method's declaring type is either public or in the same package as the instrumented type and if the method * is either public or non-private and in the same package as the instrumented type. Private methods can only be used as * a delegation target if the delegation is targeting the instrumented type. * * @param target The target instance for the delegation. * @param type The most specific type of which {@code target} should be considered. Must be a super type of the target's actual type. * @param fieldName The name of the field that is holding the {@code target} instance. * @param methodGraphCompiler The method graph compiler to use. * @return A method delegation that redirects method calls to a static method of the supplied type. */ public MethodDelegation to(Object target, Type type, String fieldName, MethodGraph.Compiler methodGraphCompiler) { TypeDescription.Generic typeDescription = TypeDefinition.Sort.describe(type); if (!typeDescription.asErasure().isInstance(target)) { throw new IllegalArgumentException(target + " is not an instance of " + type); } return new MethodDelegation(new ImplementationDelegate.ForField.WithInstance(fieldName, methodGraphCompiler, parameterBinders, matcher, target, typeDescription), parameterBinders, ambiguityResolver, bindingResolver); }
} else if (argument instanceof TypeDescription && ((TypeDescription) argument).isPrimitive()) { argument = JavaConstant.Dynamic.ofPrimitiveType((TypeDescription) argument); } else if (JavaType.METHOD_HANDLE.getTypeStub().isInstance(argument)) { argument = JavaConstant.MethodHandle.ofLoaded(argument); } else if (JavaType.METHOD_TYPE.getTypeStub().isInstance(argument)) { argument = JavaConstant.MethodType.ofLoaded(argument);
/** * Creates a method handles representation of a loaded method handle which is analyzed using the given lookup context. * A method handle can only be analyzed on virtual machines that support the corresponding API (Java 7+). For virtual machines before Java 8+, * a method handle instance can only be analyzed by taking advantage of private APIs what might require a access context. * * @param methodHandle The loaded method handle to represent. * @param lookup The lookup object to use for analyzing the method handle. * @return A representation of the loaded method handle */ public static MethodHandle ofLoaded(Object methodHandle, Object lookup) { if (!JavaType.METHOD_HANDLE.getTypeStub().isInstance(methodHandle)) { throw new IllegalArgumentException("Expected method handle object: " + methodHandle); } else if (!JavaType.METHOD_HANDLES_LOOKUP.getTypeStub().isInstance(lookup)) { throw new IllegalArgumentException("Expected method handle lookup object: " + lookup); } Dispatcher dispatcher = DISPATCHER.initialize(); Object methodHandleInfo = dispatcher.reveal(lookup, methodHandle); Object methodType = dispatcher.getMethodType(methodHandleInfo); return new MethodHandle(HandleType.of(dispatcher.getReferenceKind(methodHandleInfo)), TypeDescription.ForLoadedType.of(dispatcher.getDeclaringClass(methodHandleInfo)), dispatcher.getName(methodHandleInfo), TypeDescription.ForLoadedType.of(dispatcher.returnType(methodType)), new TypeList.ForLoadedTypes(dispatcher.parameterArray(methodType))); }
} else if (argument instanceof TypeDescription && ((TypeDescription) argument).isPrimitive()) { argument = ofPrimitiveType((TypeDescription) argument); } else if (JavaType.METHOD_HANDLE.getTypeStub().isInstance(argument)) { argument = MethodHandle.ofLoaded(argument); } else if (JavaType.METHOD_TYPE.getTypeStub().isInstance(argument)) { argument = MethodType.ofLoaded(argument);
} else if (argument instanceof TypeDescription && ((TypeDescription) argument).isPrimitive()) { argument = ofPrimitiveType((TypeDescription) argument); } else if (JavaType.METHOD_HANDLE.getTypeStub().isInstance(argument)) { argument = MethodHandle.ofLoaded(argument); } else if (JavaType.METHOD_TYPE.getTypeStub().isInstance(argument)) { argument = MethodType.ofLoaded(argument);
} else if (value instanceof Enum<?>) { return new ForEnumerationValue(new EnumerationDescription.ForLoadedEnumeration((Enum<?>) value)); } else if (JavaType.METHOD_HANDLE.getTypeStub().isInstance(value)) { return new ForJavaConstant(JavaConstant.MethodHandle.ofLoaded(value)); } else if (JavaType.METHOD_TYPE.getTypeStub().isInstance(value)) { return new ForJavaConstant(JavaConstant.MethodType.ofLoaded(value)); } else {
} else if (value instanceof Class) { return new ForStackManipulation(ClassConstant.of(TypeDescription.ForLoadedType.of((Class<?>) value)), Class.class); } else if (JavaType.METHOD_HANDLE.getTypeStub().isInstance(value)) { return new ForStackManipulation(new JavaConstantValue(JavaConstant.MethodHandle.ofLoaded(value)), JavaType.METHOD_HANDLE.getTypeStub()); } else if (JavaType.METHOD_TYPE.getTypeStub().isInstance(value)) { return new ForStackManipulation(new JavaConstantValue(JavaConstant.MethodType.ofLoaded(value)), JavaType.METHOD_TYPE.getTypeStub()); } else if (value instanceof Enum<?>) {
stackManipulation = ClassConstant.of((TypeDescription) value); suppliedType = TypeDescription.CLASS; } else if (JavaType.METHOD_HANDLE.getTypeStub().isInstance(value)) { stackManipulation = new JavaConstantValue(JavaConstant.MethodHandle.ofLoaded(value)); suppliedType = JavaType.METHOD_HANDLE.getTypeStub(); stackManipulation = new JavaConstantValue((JavaConstant.MethodHandle) value); suppliedType = JavaType.METHOD_HANDLE.getTypeStub(); } else if (JavaType.METHOD_TYPE.getTypeStub().isInstance(value)) { stackManipulation = new JavaConstantValue(JavaConstant.MethodType.ofLoaded(value)); suppliedType = JavaType.METHOD_HANDLE.getTypeStub();