@Test(dataProvider = "flags") public void systemLoadLibraryTest(final boolean publicLookup) { final CallSite cs1 = createGetMethodCallSite(publicLookup, "loadLibrary"); final CallSite cs2 = createCallSite(publicLookup, CALL, MethodType.methodType(void.class, Object.class, Object.class, String.class)); try { final Object method = cs1.getTarget().invoke(StaticClass.forClass(System.class)); cs2.getTarget().invoke(method, StaticClass.forClass(System.class), "foo"); throw new RuntimeException("should not reach here in any case!"); } catch (final Throwable th) { if (publicLookup) { Assert.assertTrue(th instanceof IllegalAccessError); } else { Assert.assertTrue(th instanceof AccessControlException); } } }
/** * Generate test with an invokedynamic, a static bootstrap method with an extra arg that is a * MethodHandle of kind invoke interface. The target method is a method into an interface * that is shadowed by another definition into a sub interfaces. */ private void generateMethodTest7(ClassVisitor cv) { MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "test7", "()V", null, null); MethodType mt = MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class, MethodHandle.class); Handle bootstrap = new Handle(Opcodes.H_INVOKESTATIC, Type.getInternalName(InvokeCustom.class), "bsmCreateCallCallingtargetMethodTest8", mt.toMethodDescriptorString(), false); mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(InvokeCustom.class)); mv.visitInsn(Opcodes.DUP); mv.visitMethodInsn( Opcodes.INVOKESPECIAL, Type.getInternalName(InvokeCustom.class), "<init>", "()V", false); mv.visitInvokeDynamicInsn("targetMethodTest8", "(Linvokecustom/J;)V", bootstrap, new Handle(Opcodes.H_INVOKEINTERFACE, Type.getInternalName(J.class), "targetMethodTest8", "()V", true)); mv.visitInsn(Opcodes.RETURN); mv.visitMaxs(-1, -1); }
@Test public void prelinkTransformerTest() throws Throwable { final DynamicLinkerFactory factory = newDynamicLinkerFactory(true); final boolean[] reachedPrelinkTransformer = { false }; factory.setPrelinkTransformer((final GuardedInvocation inv, final LinkRequest linkRequest, final LinkerServices linkerServices) -> { reachedPrelinkTransformer[0] = true; // just identity transformer! return inv; }); final MethodType mt = MethodType.methodType(Object.class, Object.class, String.class); final DynamicLinker linker = factory.createLinker(); final CallSite cs = linker.link(new SimpleRelinkableCallSite(new CallSiteDescriptor( MethodHandles.publicLookup(), GET_PROPERTY, mt))); Assert.assertFalse(reachedPrelinkTransformer[0]); Assert.assertEquals(cs.getTarget().invoke(new Object(), "class"), Object.class); Assert.assertTrue(reachedPrelinkTransformer[0]); }
static void testOnePermutation(MethodHandle mh, int[] perm, Object[] args) throws Throwable { MethodType mt = mh.type(); MethodType pmt = methodType(mt.returnType(), unpermuteArgs(perm, mt.parameterArray(), Class[].class)); if (VERBOSE) System.out.println(Arrays.toString(perm)); testCases += 1; if (DRY_RUN) return; Object res = permuteArguments(mh, pmt, perm).invokeWithArguments(unpermuteArgs(perm, args)); String str = String.valueOf(res); if (!Arrays.toString(args).equals(str)) { System.out.println(Arrays.toString(perm)+" "+str+" *** WRONG ***"); } }
public void testInvokePolymorphicWithAllTypes() { try { MethodHandle mth = MethodHandles.lookup() .findStatic( InvokePolymorphic.class, "testWithAllTypes", MethodType.methodType( void.class, boolean.class, char.class, short.class, int.class, long.class, float.class, double.class, String.class, Object.class)); mth.invokeExact(false,'h', (short) 56, 72, Integer.MAX_VALUE + 42l, 0.56f, 100.0d, "hello", (Object) "goodbye"); } catch (Throwable t) { t.printStackTrace(); } }
@Override boolean isApplicable(final MethodType callSiteType, final SingleDynamicMethod method) { final MethodType methodType = method.getMethodType(); final int methodArity = methodType.parameterCount(); if(methodArity != callSiteType.parameterCount()) { return false; } // 0th arg is receiver; it doesn't matter for overload // resolution. for(int i = 1; i < methodArity; ++i) { if(!TypeUtilities.isSubtype(callSiteType.parameterType(i), methodType.parameterType(i))) { return false; } } return true; }
@Test public void testReturnFromArg() throws Throwable { MethodHandles.Lookup l = MethodHandles.lookup(); MethodHandle consumeIdentity = dropArguments( identity(String.class), 1, int.class, int.class); MethodHandle consumeVoid = l.findStatic( PermuteArgsReturnVoidTest.class, "consumeVoid", MethodType.methodType(void.class, String.class, int.class, int.class)); MethodHandle f = MethodHandles.foldArguments(consumeIdentity, consumeVoid); MethodHandle p = MethodHandles.permuteArguments(f, MethodType.methodType(String.class, String.class, int.class, int.class), 0, 2, 1); String s = (String) p.invoke("IN", 0, 0); Assert.assertEquals(s.getClass(), String.class); Assert.assertEquals(s, "IN"); }
@Test public static void testCountedLoopVoidInit() throws Throwable { MethodHandle fit5 = MethodHandles.constant(int.class, 5); for (int i = 0; i < 8; i++) { MethodHandle zero = MethodHandles.zero(void.class); MethodHandle init = fit5; MethodHandle body = Counted.MH_printHello; boolean useNull = (i & 1) != 0, addInitArg = (i & 2) != 0, addBodyArg = (i & 4) != 0; if (useNull) zero = null; if (addInitArg) init = MethodHandles.dropArguments(init, 0, int.class); if (addBodyArg) body = MethodHandles.dropArguments(body, 1, int.class); System.out.println("testCountedLoopVoidInit i="+i+" : "+Arrays.asList(init, zero, body)); MethodHandle loop = MethodHandles.countedLoop(init, zero, body); MethodType expectedType = Counted.MT_countedPrinting; if (addInitArg || addBodyArg) expectedType = expectedType.insertParameterTypes(0, int.class); assertEquals(expectedType, loop.type()); if (addInitArg || addBodyArg) loop.invoke(99); else loop.invoke(); } }
/** * Routine used to obtain a randomly generated method type. * * @param arity Arity of returned method type. * @return MethodType generated randomly. */ public static MethodType randomMethodTypeGenerator(int arity) { final Class<?>[] CLASSES = { Object.class, int.class, boolean.class, byte.class, short.class, char.class, long.class, float.class, double.class }; if (arity > MAX_ARITY) { throw new IllegalArgumentException( String.format("Arity should not exceed %d!", MAX_ARITY)); } List<Class<?>> list = randomClasses(CLASSES, arity); list = getParams(list, false, arity); int i = RNG.nextInt(CLASSES.length + 1); Class<?> rtype = i == CLASSES.length ? void.class : CLASSES[i]; return MethodType.methodType(rtype, list); }
public BoxedIntegersWithReverseComparator() { try { MethodHandles.Lookup l = MethodHandles.lookup(); MethodType cmpt = MethodType.methodType( int.class, Object[].class, Object[].class, Comparator.class); MethodType cmprt = MethodType.methodType( int.class, Object[].class, int.class, int.class, Object[].class, int.class, int.class, Comparator.class); eqc = l.findStatic(Arrays.class, "equals", cmpt.changeReturnType(boolean.class)); eqcr = l.findStatic(Arrays.class, "equals", cmprt.changeReturnType(boolean.class)); cmpc = l.findStatic(Arrays.class, "compare", cmpt); cmpcr = l.findStatic(Arrays.class, "compare", cmprt); mismatchc = l.findStatic(Arrays.class, "mismatch", cmpt); mismatchcr = l.findStatic(Arrays.class, "mismatch", cmprt); } catch (Exception e) { throw new Error(e); } }
Compiler getCompiler(final FunctionNode functionNode, final MethodType actualCallSiteType, final ScriptObject runtimeScope, final Map<Integer, Type> invalidatedProgramPoints, final int[] continuationEntryPoints) { final TypeMap typeMap = typeMap(actualCallSiteType); final Type[] paramTypes = typeMap == null ? null : typeMap.getParameterTypes(functionNodeId); final Object typeInformationFile = OptimisticTypesPersistence.getLocationDescriptor(source, functionNodeId, paramTypes); final Context context = Context.getContextTrusted(); return new Compiler( context, context.getEnv(), getInstallerForNewCode(), functionNode.getSource(), // source context.getErrorManager(), isStrict() | functionNode.isStrict(), // is strict true, // is on demand this, // compiledFunction, i.e. this RecompilableScriptFunctionData typeMap, // type map getEffectiveInvalidatedProgramPoints(invalidatedProgramPoints, typeInformationFile), // invalidated program points typeInformationFile, continuationEntryPoints, // continuation entry points runtimeScope); // runtime scope }
@Override public void setTarget(final MethodHandle newTarget) { final MethodType type = type(); final boolean isVoid = type.returnType() == void.class; final Class<?> newSelfType = newTarget.type().parameterType(0); MethodHandle selfFilter = MH.bindTo(PROFILEENTRY, this); if (newSelfType != Object.class) { // new target uses a more precise 'self' type than Object.class. We need to // convert the filter type. Note that the profileEntry method returns "self" // argument "as is" and so the cast introduced will succeed for any type. final MethodType selfFilterType = MethodType.methodType(newSelfType, newSelfType); selfFilter = selfFilter.asType(selfFilterType); } MethodHandle methodHandle = MH.filterArguments(newTarget, 0, selfFilter); if (isVoid) { methodHandle = MH.filterReturnValue(methodHandle, MH.bindTo(PROFILEVOIDEXIT, this)); } else { final MethodType filter = MH.type(type.returnType(), type.returnType()); methodHandle = MH.filterReturnValue(methodHandle, MH.asType(MH.bindTo(PROFILEEXIT, this), filter)); } super.setTarget(methodHandle); }
@Override MethodType getGenericType() { // We need to ask the code for its generic type. We can't just rely on this function data's arity, as it's not // actually correct for lots of built-ins. E.g. ECMAScript 5.1 section 15.5.3.2 prescribes that // Script.fromCharCode([char0[, char1[, ...]]]) has a declared arity of 1 even though it's a variable arity // method. int max = 0; for(final CompiledFunction fn: code) { final MethodType t = fn.type(); if(ScriptFunctionData.isVarArg(t)) { // 2 for (callee, this, args[]) return MethodType.genericMethodType(2, true); } final int paramCount = t.parameterCount() - (ScriptFunctionData.needsCallee(t) ? 1 : 0); if(paramCount > max) { max = paramCount; } } // +1 for callee return MethodType.genericMethodType(max + 1); }
MethodHandle createConverter(final Class<?> sourceType, final Class<?> targetType) throws Exception { final MethodType type = MethodType.methodType(targetType, sourceType); final MethodHandle identity = IDENTITY_CONVERSION.asType(type); MethodHandle last = identity; boolean cacheable = true; for(int i = factories.length; i-- > 0;) { final GuardedTypeConversion next = factories[i].convertToType(sourceType, targetType); if(next != null) { cacheable = cacheable && next.isCacheable(); final GuardedInvocation conversionInvocation = next.getConversionInvocation(); conversionInvocation.assertType(type); last = conversionInvocation.compose(last); } } if(last == identity) { return IDENTITY_CONVERSION; } if(cacheable) { return last; } throw new NotCacheableConverter(last); }
private static MethodHandle spreadGuardArguments(final MethodHandle guard, final MethodType descType) { final MethodType guardType = guard.type(); final int guardParamCount = guardType.parameterCount(); final int descParamCount = descType.parameterCount(); final int spreadCount = guardParamCount - descParamCount + 1; if (spreadCount <= 0) { // Guard doesn't dip into the varargs return guard; } final MethodHandle arrayConvertingGuard; // If the last parameter type of the guard is an array, then it is already itself a guard for a vararg apply // invocation. We must filter the last argument with toApplyArgs otherwise deeper levels of nesting will fail // with ClassCastException of NativeArray to Object[]. if(guardType.parameterType(guardParamCount - 1).isArray()) { arrayConvertingGuard = MH.filterArguments(guard, guardParamCount - 1, NativeFunction.TO_APPLY_ARGS); } else { arrayConvertingGuard = guard; } return ScriptObject.adaptHandleToVarArgCallSite(arrayConvertingGuard, descParamCount); }
@Override public void setTarget(final MethodHandle newTarget) { if (!getNashornDescriptor().isTraceEnterExit()) { super.setTarget(newTarget); return; } final MethodType type = type(); final boolean isVoid = type.returnType() == void.class; MethodHandle traceMethodHandle = isVoid ? TRACEVOID : TRACEOBJECT; traceMethodHandle = MH.bindTo(traceMethodHandle, this); traceMethodHandle = MH.bindTo(traceMethodHandle, newTarget); traceMethodHandle = MH.asCollector(traceMethodHandle, Object[].class, type.parameterCount()); traceMethodHandle = MH.asType(traceMethodHandle, type); super.setTarget(traceMethodHandle); }
/** * Generate test with an invokedynamic, a static bootstrap method with extra args and no arg * to the target method. */ private void generateMethodTest3(ClassVisitor cv) { MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "test3", "()V", null, null); MethodType mt = MethodType.methodType( CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class, int.class, long.class, float.class, double.class); Handle bootstrap = new Handle( Opcodes.H_INVOKESTATIC, Type.getInternalName(InvokeCustom.class), "bsmLookupStaticWithExtraArgs", mt.toMethodDescriptorString(), false); mv.visitInvokeDynamicInsn("targetMethodTest3", "()V", bootstrap, new Integer(1), new Long(123456789), new Float(123.456), new Double(123456.789123)); mv.visitInsn(Opcodes.RETURN); mv.visitMaxs(-1, -1); }
static void run(StackWalker walker) { MethodHandles.Lookup lookup = MethodHandles.lookup(); MethodHandle handle = null; try { handle = lookup.findStatic(C2.class, "call", MethodType.methodType(void.class, StackWalker.class)); handle.invoke(walker); } catch(Throwable t) { throw new RuntimeException(t); } }
@Test(dataProvider = "flags") public void systemGetPropertyTest(final boolean publicLookup) { final CallSite cs1 = createGetMethodCallSite(publicLookup, "getProperty"); final CallSite cs2 = createCallSite(publicLookup, CALL, MethodType.methodType(String.class, Object.class, Object.class, String.class)); try { final Object method = cs1.getTarget().invoke(StaticClass.forClass(System.class)); cs2.getTarget().invoke(method, StaticClass.forClass(System.class), "java.home"); throw new RuntimeException("should not reach here in any case!"); } catch (final Throwable th) { Assert.assertTrue(th instanceof SecurityException); } }
/** * Generate test with an invokedynamic, a static bootstrap method with an extra arg that is a * MethodHandle of kind put static. The method handle write a static field in a class and then * print its value. */ private void generateMethodTest11(ClassVisitor cv) { MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "test11", "()V", null, null); MethodType mt = MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class, MethodHandle.class); Handle bootstrap = new Handle(Opcodes.H_INVOKESTATIC, Type.getInternalName(InvokeCustom.class), "bsmCreateCallCallingtargetMethod", mt.toMethodDescriptorString(), false); mv.visitLdcInsn("Write static field"); mv.visitInvokeDynamicInsn("staticField1", "(Ljava/lang/String;)V", bootstrap, new Handle(Opcodes.H_PUTSTATIC, Type.getInternalName(InvokeCustom.class), "staticField1", "Ljava/lang/String;", false)); mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;"); mv.visitFieldInsn(Opcodes.GETSTATIC, Type.getInternalName(InvokeCustom.class), "staticField1", "Ljava/lang/String;"); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false); mv.visitInsn(Opcodes.RETURN); mv.visitMaxs(-1, -1); }
/** * Generate test with an invokedynamic, a static bootstrap method with an extra arg that is a * MethodHandle of kind put instance. The method handle write an instance field in a class and * then print its value. */ private void generateMethodTest13(ClassVisitor cv) { MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "test13", "()V", null, null); MethodType mt = MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class, MethodHandle.class); Handle bootstrap = new Handle(Opcodes.H_INVOKESTATIC, Type.getInternalName(InvokeCustom.class), "bsmCreateCallCallingtargetMethod", mt.toMethodDescriptorString(), false); mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(InvokeCustom.class)); mv.visitInsn(Opcodes.DUP); mv.visitMethodInsn( Opcodes.INVOKESPECIAL, Type.getInternalName(InvokeCustom.class), "<init>", "()V", false); mv.visitVarInsn(Opcodes.ASTORE, 0); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitLdcInsn("Write instance field"); mv.visitInvokeDynamicInsn("instanceField1", "(Linvokecustom/InvokeCustom;Ljava/lang/String;)V", bootstrap, new Handle(Opcodes.H_PUTFIELD, Type.getInternalName(InvokeCustom.class), "instanceField1", "Ljava/lang/String;", false)); mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;"); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitFieldInsn(Opcodes.GETFIELD, Type.getInternalName(InvokeCustom.class), "instanceField1", "Ljava/lang/String;"); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false); mv.visitInsn(Opcodes.RETURN); mv.visitMaxs(-1, -1); }
public static void main(String[] args) throws Throwable { // Build an interface invoke and then invoke it on something // that doesn't implement the interface to test the // raiseException path. MethodHandle target = MethodHandles.lookup().findVirtual(intf.class, "target", MethodType.methodType(Object.class)); try { target.invoke(new Object()); } catch (ClassCastException cce) { // everything is ok System.out.println("got expected ClassCastException"); } }
private MethodHandle createRelinkAndInvokeMethod(final RelinkableCallSite callSite, final int relinkCount) { // Make a bound MH of invoke() for this linker and call site final MethodHandle boundRelinker = MethodHandles.insertArguments(RELINK, 0, this, callSite, Integer.valueOf( relinkCount)); // Make a MH that gathers all arguments to the invocation into an Object[] final MethodType type = callSite.getDescriptor().getMethodType(); final MethodHandle collectingRelinker = boundRelinker.asCollector(Object[].class, type.parameterCount()); return MethodHandles.foldArguments(MethodHandles.exactInvoker(type), collectingRelinker.asType( type.changeReturnType(MethodHandle.class))); }
@Test public void testDropArgumentsToMatch() throws Throwable { MethodHandle cat = lookup().findVirtual(String.class, "concat", methodType(String.class, String.class)); MethodType bigType = cat.type().insertParameterTypes(0, String.class, String.class, int.class); MethodHandle d0 = MethodHandles.dropArgumentsToMatch(cat, 0, bigType.parameterList(), 3); assertEquals("xy",(String)d0.invokeExact("m", "n", 1, "x", "y")); MethodHandle d1 = MethodHandles.dropArgumentsToMatch(cat, 0, bigType.parameterList(), 0); assertEquals("mn",(String)d1.invokeExact("m", "n", 1, "x", "y")); MethodHandle d2 = MethodHandles.dropArgumentsToMatch(cat, 1, bigType.parameterList(), 4); assertEquals("xy",(String)d2.invokeExact("x", "b", "c", 1, "a", "y")); }
static MethodHandle changeArgTypes(MethodHandle target, int beg, int end, Class<?> argType) { MethodType targetType = target.type(); end = Math.min(end, targetType.parameterCount()); ArrayList<Class<?>> argTypes = new ArrayList<>(targetType.parameterList()); Collections.fill(argTypes.subList(beg, end), argType); MethodType ttype2 = MethodType.methodType(targetType.returnType(), argTypes); return target.asType(ttype2); }
public void testInvokePolymorphicRange() { MethodType mt = MethodType.methodType(String.class, byte.class, char.class, short.class, float.class, double.class, long.class, Integer.class, int.class, String.class); MethodHandles.Lookup lk = MethodHandles.lookup(); try { MethodHandle mh = lk.findVirtual(getClass(), "buildString", mt); System.out.println( mh.invoke(this, (byte) 2, 'a', (short) 0xFFFF, 1.1f, 2.24d, 12345678L, null, 1, "string")); } catch (Throwable t) { t.printStackTrace(); } }
public MethodHandle testInvokePolymorphicWithConstructor() { MethodHandle mh = null; MethodType mt = MethodType.methodType(void.class); MethodHandles.Lookup lk = MethodHandles.lookup(); try { mh = lk.findConstructor(Data.class, mt); System.out.println(mh.invoke().getClass() == Data.class); } catch (Throwable t) { t.printStackTrace(); } return mh; }
public static void main(String[] args) throws Throwable { Test8015436 testObj = new Test8015436(); testObj.someMethod(); testObj.defaultMethod(DEFAULT_MTD_INVOKED_DIRECTLY); MethodHandles.Lookup lookup = MethodHandles.lookup(); MethodType mt = MethodType.methodType(void.class, String.class); MethodHandle mh = lookup.findVirtual(Test8015436.class, "defaultMethod", mt); mh.invokeExact(testObj, DEFAULT_MTD_INVOKED_MH); }
public static String testCallSiteGetTargetSnippet(int i) throws Exception { ConstantCallSite site; MethodHandles.Lookup lookup = MethodHandles.lookup(); switch (i) { case 1: site = GraalDirectives.opaque(new ConstantCallSite(lookup.findVirtual(String.class, "replace", MethodType.methodType(String.class, char.class, char.class)))); break; default: site = GraalDirectives.opaque(new ConstantCallSite(lookup.findStatic(java.util.Arrays.class, "asList", MethodType.methodType(java.util.List.class, Object[].class)))); } return site.getTarget().toString(); }
final CompiledFunction getBestConstructor(final MethodType callSiteType, final ScriptObject runtimeScope, final Collection<CompiledFunction> forbidden) { if (!isConstructor()) { throw typeError("not.a.constructor", toSource()); } // Constructor call sites don't have a "this", but getBest is meant to operate on "callee, this, ..." style final CompiledFunction cf = getBest(callSiteType.insertParameterTypes(1, Object.class), runtimeScope, forbidden); return cf; }
@BeforeMethod public void setUp() throws Exception { rtype = void.class; ptypes = new Class<?>[] { int.class, String.class }; mt_viS = MethodType.methodType(void.class, int.class, String.class); mt_OO = MethodType.methodType(Object.class, Object.class); mt_OO2 = MethodType.methodType(Object.class, Object.class, Object.class); mt_vv = MethodType.methodType(void.class); mt_Vv = MethodType.methodType(Void.class); mt_Ov = MethodType.methodType(Object.class); mt_iSI = MethodType.methodType(int.class, String.class, Integer.class); mt_ISi = MethodType.methodType(Integer.class, String.class, int.class); mt_ISI = MethodType.methodType(Integer.class, String.class, Integer.class); mt_iSi = MethodType.methodType(int.class, String.class, int.class); compareTo = String.class.getDeclaredMethod("compareTo", String.class); mt_viO = MethodType.methodType(void.class, int.class, Object.class); mt_iO2 = MethodType.methodType(int.class, Object.class, Object.class); mt_OOi = MethodType.methodType(Object.class, Object.class, int.class); mt_iOi = MethodType.methodType(int.class, Object.class, int.class); mt_VIO = MethodType.methodType(Void.class, Integer.class, Object.class); mt_IO2 = MethodType.methodType(Integer.class, Object.class, Object.class); mt_OOI = MethodType.methodType(Object.class, Object.class, Integer.class); mt_IOI = MethodType.methodType(Integer.class, Object.class, Integer.class); mt_VIS = MethodType.methodType(Void.class, Integer.class, String.class); mt_vOiSzA = MethodType.methodType(void.class, Object.class, int.class, String.class, boolean.class, Object[].class); mt_OO99 = MethodType.genericMethodType(99); GALLERY = new MethodType[] { mt_viS, mt_OO, mt_OO2, mt_vv, mt_Vv, mt_Ov, mt_iSI, mt_ISi, mt_ISI, mt_iSi, mt_viO, mt_iO2, mt_OOi, mt_iOi, mt_VIO, mt_IO2, mt_OOI, mt_IOI, mt_VIS, mt_vOiSzA, mt_OO99 }; }
MethodType asMethodType() { Class<?>[] parameters = new Class<?>[objects + prims]; for(int i = 0; i < objects; i++) { parameters[i] = Object.class; } for(int i = 0; i < prims; i++) { parameters[objects + i] = long.class; } return MethodType.methodType(void.class, parameters); }
@Test public void test252() throws Throwable { final int ARITY = 252; System.out.println("test"+ARITY); Object[] a = testArgs(ARITY); Object r0 = hashArguments(a); Object r; r = hashArguments_252( // <editor-fold defaultstate="collapsed" desc="a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], ..."> a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], a[0x05], a[0x06], a[0x07], a[0x08], a[0x09], a[0x0A], a[0x0B], a[0x0C], a[0x0D], a[0x0E], a[0x0F], a[0x10], a[0x11], a[0x12], a[0x13], a[0x14], a[0x15], a[0x16], a[0x17], a[0x18], a[0x19], a[0x1A], a[0x1B], a[0x1C], a[0x1D], a[0x1E], a[0x1F], a[0x20], a[0x21], a[0x22], a[0x23], a[0x24], a[0x25], a[0x26], a[0x27], a[0x28], a[0x29], a[0x2A], a[0x2B], a[0x2C], a[0x2D], a[0x2E], a[0x2F], a[0x30], a[0x31], a[0x32], a[0x33], a[0x34], a[0x35], a[0x36], a[0x37], a[0x38], a[0x39], a[0x3A], a[0x3B], a[0x3C], a[0x3D], a[0x3E], a[0x3F], a[0x40], a[0x41], a[0x42], a[0x43], a[0x44], a[0x45], a[0x46], a[0x47], a[0x48], a[0x49], a[0x4A], a[0x4B], a[0x4C], a[0x4D], a[0x4E], a[0x4F], a[0x50], a[0x51], a[0x52], a[0x53], a[0x54], a[0x55], a[0x56], a[0x57], a[0x58], a[0x59], a[0x5A], a[0x5B], a[0x5C], a[0x5D], a[0x5E], a[0x5F], a[0x60], a[0x61], a[0x62], a[0x63], a[0x64], a[0x65], a[0x66], a[0x67], a[0x68], a[0x69], a[0x6A], a[0x6B], a[0x6C], a[0x6D], a[0x6E], a[0x6F], a[0x70], a[0x71], a[0x72], a[0x73], a[0x74], a[0x75], a[0x76], a[0x77], a[0x78], a[0x79], a[0x7A], a[0x7B], a[0x7C], a[0x7D], a[0x7E], a[0x7F], a[0x80], a[0x81], a[0x82], a[0x83], a[0x84], a[0x85], a[0x86], a[0x87], a[0x88], a[0x89], a[0x8A], a[0x8B], a[0x8C], a[0x8D], a[0x8E], a[0x8F], a[0x90], a[0x91], a[0x92], a[0x93], a[0x94], a[0x95], a[0x96], a[0x97], a[0x98], a[0x99], a[0x9A], a[0x9B], a[0x9C], a[0x9D], a[0x9E], a[0x9F], a[0xA0], a[0xA1], a[0xA2], a[0xA3], a[0xA4], a[0xA5], a[0xA6], a[0xA7], a[0xA8], a[0xA9], a[0xAA], a[0xAB], a[0xAC], a[0xAD], a[0xAE], a[0xAF], a[0xB0], a[0xB1], a[0xB2], a[0xB3], a[0xB4], a[0xB5], a[0xB6], a[0xB7], a[0xB8], a[0xB9], a[0xBA], a[0xBB], a[0xBC], a[0xBD], a[0xBE], a[0xBF], a[0xC0], a[0xC1], a[0xC2], a[0xC3], a[0xC4], a[0xC5], a[0xC6], a[0xC7], a[0xC8], a[0xC9], a[0xCA], a[0xCB], a[0xCC], a[0xCD], a[0xCE], a[0xCF], a[0xD0], a[0xD1], a[0xD2], a[0xD3], a[0xD4], a[0xD5], a[0xD6], a[0xD7], a[0xD8], a[0xD9], a[0xDA], a[0xDB], a[0xDC], a[0xDD], a[0xDE], a[0xDF], a[0xE0], a[0xE1], a[0xE2], a[0xE3], a[0xE4], a[0xE5], a[0xE6], a[0xE7], a[0xE8], a[0xE9], a[0xEA], a[0xEB], a[0xEC], a[0xED], a[0xEE], a[0xEF], a[0xF0], a[0xF1], a[0xF2], a[0xF3], a[0xF4], a[0xF5], a[0xF6], a[0xF7], // </editor-fold> a[0xF8], a[0xF9], a[0xFA], a[0xFB]); // hashArguments_252 assertEquals(r0, r); MethodType mt = MethodType.genericMethodType(ARITY); MethodHandle mh = MethodHandles.lookup().findStatic(BigArityTest.class, "hashArguments_"+ARITY, mt); test252(mh, a, r0); MethodHandle mh_CA = MH_hashArguments_VA.asFixedArity().asCollector(Object[].class, ARITY); test252(mh_CA, a, r0); MethodHandle mh_a = MethodHandles.lookup().findStatic(BigArityTest.class, "hashArguments_"+ARITY+"_a", MT_A).asCollector(1, Object[].class, ARITY-2); test252(mh_a, a, r0); }
private static GuardedInvocation createClassNotFoundInvocation(final CallSiteDescriptor desc) { // If NativeJavaPackage is invoked either as a constructor or as a function, throw a ClassNotFoundException as // we can assume the user attempted to instantiate a non-existent class. final MethodType type = desc.getMethodType(); return new GuardedInvocation( MH.dropArguments(CLASS_NOT_FOUND, 1, type.parameterList().subList(1, type.parameterCount())), type.parameterType(0) == NativeJavaPackage.class ? null : TYPE_GUARD); }
@Test public void testHasWrappers() { System.out.println("hasWrappers"); MethodType[] instances = {mt_viS, mt_OO2, mt_vv, mt_Ov, mt_iSI, mt_ISi, mt_ISI, mt_iSi}; boolean[] expResults = {false, false, false, false, true, true, true, false}; for (int i = 0; i < instances.length; i++) { System.out.println(" hasWrappers "+instances[i]); boolean result = instances[i].hasWrappers(); assertEquals("#"+i, expResults[i], result); } }
/** * Given a method handle and an expected return type, perform return value filtering * according to the optimistic type coercion rules * @param mh method handle * @param expectedReturnType expected return type * @param programPoint program point * @return filtered method */ public static MethodHandle filterOptimisticReturnValue(final MethodHandle mh, final Class<?> expectedReturnType, final int programPoint) { if(!isValid(programPoint)) { return mh; } final MethodType type = mh.type(); final Class<?> actualReturnType = type.returnType(); if(TypeUtilities.isConvertibleWithoutLoss(actualReturnType, expectedReturnType)) { return mh; } final MethodHandle guard = getOptimisticTypeGuard(expectedReturnType, actualReturnType); return guard == null ? mh : MH.filterReturnValue(mh, MH.insertArguments(guard, guard.type().parameterCount() - 1, programPoint)); }
/** * Add code with specific call site type. It will adapt the type of the looked up method handle to fit the call site * type. This is necessary because even if we request a specialization that takes an "int" parameter, we might end * up getting one that takes a "double" etc. because of internal function logic causes widening (e.g. assignment of * a wider value to the parameter variable). However, we use the method handle type for matching subsequent lookups * for the same specialization, so we must adapt the handle to the expected type. * @param fnInit the function * @param callSiteType the call site type * @return the compiled function object, with its type matching that of the call site type. */ private CompiledFunction addCode(final FunctionInitializer fnInit, final MethodType callSiteType) { if (isVariableArity()) { return addCode(lookup(fnInit, true), fnInit.getInvalidatedProgramPoints(), callSiteType, fnInit.getFlags()); } final MethodHandle handle = lookup(fnInit, true); final MethodType fromType = handle.type(); MethodType toType = needsCallee(fromType) ? callSiteType.changeParameterType(0, ScriptFunction.class) : callSiteType.dropParameterTypes(0, 1); toType = toType.changeReturnType(fromType.returnType()); final int toCount = toType.parameterCount(); final int fromCount = fromType.parameterCount(); final int minCount = Math.min(fromCount, toCount); for(int i = 0; i < minCount; ++i) { final Class<?> fromParam = fromType.parameterType(i); final Class<?> toParam = toType.parameterType(i); // If method has an Object parameter, but call site had String, preserve it as Object. No need to narrow it // artificially. Note that this is related to how CompiledFunction.matchesCallSite() works, specifically // the fact that various reference types compare to equal (see "fnType.isEquivalentTo(csType)" there). if (fromParam != toParam && !fromParam.isPrimitive() && !toParam.isPrimitive()) { assert fromParam.isAssignableFrom(toParam); toType = toType.changeParameterType(i, fromParam); } } if (fromCount > toCount) { toType = toType.appendParameterTypes(fromType.parameterList().subList(toCount, fromCount)); } else if (fromCount < toCount) { toType = toType.dropParameterTypes(fromCount, toCount); } return addCode(lookup(fnInit, false).asType(toType), fnInit.getInvalidatedProgramPoints(), callSiteType, fnInit.getFlags()); }
private static NashornCallSiteDescriptor get(final MethodHandles.Lookup lookup, final Operation operation, final MethodType methodType, final int flags) { final NashornCallSiteDescriptor csd = new NashornCallSiteDescriptor(lookup, operation, methodType, flags); // Many of these call site descriptors are identical (e.g. every getter for a property color will be // "GET_PROPERTY:color(Object)Object", so it makes sense canonicalizing them. Make an exception for // optimistic call site descriptors, as they also carry a program point making them unique. if (csd.isOptimistic()) { return csd; } final NashornCallSiteDescriptor canonical = canonicals.get(lookup.lookupClass()).putIfAbsent(csd, csd); return canonical != null ? canonical : csd; }
static MethodHandle findStatic(Class<?> cls, String name, MethodType mt) { try { return MethodHandles.lookup().findStatic(cls, name, mt); } catch (Exception e) { throw new Error(e); } }
public void testAltStdSer() throws Throwable { MethodHandle fooMH = MethodHandles.lookup().findStatic(SerializedLambdaTest.class, "foo", predicateMT); // Alt metafactory, serializable target, no FLAG_SERIALIZABLE: not serializable CallSite cs = LambdaMetafactory.altMetafactory(MethodHandles.lookup(), "test", MethodType.methodType(SerPredicate.class), predicateMT, fooMH, stringPredicateMT, 0); assertNotSerial((SerPredicate<String>) cs.getTarget().invokeExact(), fooAsserter); // Alt metafactory, serializable marker, no FLAG_SERIALIZABLE: not serializable cs = LambdaMetafactory.altMetafactory(MethodHandles.lookup(), "test", MethodType.methodType(Predicate.class), predicateMT, fooMH, stringPredicateMT, LambdaMetafactory.FLAG_MARKERS, 1, Serializable.class); assertNotSerial((Predicate<String>) cs.getTarget().invokeExact(), fooAsserter); }