private static MethodHandle buildSetter(Class arrayClass){ MethodHandle set = MethodHandles.arrayElementSetter(arrayClass); MethodHandle fallback = MethodHandles.explicitCastArguments(set, set.type().changeParameterType(0, Object.class)); fallback = MethodHandles.dropArguments(fallback, 3, int.class); MethodType reorderType = fallback.type(). insertParameterTypes(0, int.class). dropParameterTypes(4,5); fallback = MethodHandles.permuteArguments(fallback, reorderType, 1, 0, 3, 0); fallback = MethodHandles.foldArguments(fallback, normalizeIndex); fallback = MethodHandles.explicitCastArguments(fallback, set.type()); MethodHandle guard = MethodHandles.dropArguments(notNegative, 0, arrayClass); MethodHandle handle = MethodHandles.guardWithTest(guard, set, fallback); return handle; }
public static MethodHandle getJavaArraySetterMethodHandle(Class<?> arrayClass) { Class<?> arrayType = getJavaArrayType(arrayClass); return MethodHandles.arrayElementSetter(arrayType); }
/** * Returns a method handle to do an array store. * @param receiverClass Class of the array to store the value in * @return a MethodHandle that accepts the receiver as first argument, the index as second argument, * and the value to set as 3rd argument. Return value is undefined and should be ignored. */ static MethodHandle lookupArrayStore(Class<?> receiverClass) { if (receiverClass.isArray()) { return MethodHandles.arrayElementSetter(receiverClass); } else if (Map.class.isAssignableFrom(receiverClass)) { // maps allow access like mymap[key] return MAP_PUT; } else if (List.class.isAssignableFrom(receiverClass)) { return LIST_SET; } throw new IllegalArgumentException("Attempting to address a non-array type " + "[" + receiverClass.getCanonicalName() + "] as an array."); }
/** * Apply the chain of transforms and bind them to an array element set. The signature * at the endpoint must return void and receive the array type, int index, and array * element type. * * @return the full handle chain, bound to an array element set. */ public MethodHandle arraySet() { return invoke(MethodHandles.arrayElementSetter(type().parameterType(0))); }
gic = new GuardedInvocationComponent(MethodHandles.arrayElementSetter(declaredType)); isMap = false; } else if(List.class.isAssignableFrom(declaredType)) { isMap = true; } else if(clazz.isArray()) { gic = getClassGuardedInvocationComponent(MethodHandles.arrayElementSetter(clazz), callSiteType); isMap = false; } else if(List.class.isAssignableFrom(clazz)) {
case "set": checkArity(2); return MethodHandles.arrayElementSetter(invocation.receiverClass()); case "size": case "length":
gic = createInternalFilteredGuardedInvocationComponent(MethodHandles.arrayElementSetter(declaredType), linkerServices); collectionType = CollectionType.ARRAY; } else if(List.class.isAssignableFrom(declaredType)) { } else if(clazz.isArray()) { gic = getClassGuardedInvocationComponent(linkerServices.filterInternalObjects( MethodHandles.arrayElementSetter(clazz)), callSiteType); collectionType = CollectionType.ARRAY; } else if(List.class.isAssignableFrom(clazz)) {