// this implements the upcall from the JVM, MethodHandleNatives.makeDynamicCallSite: internal static CallSite MakeSite(MethodHandle bootstrapMethod, String name, MethodType type, Object info, Class callerClass) // Callee information: // Extra arguments for BSM, if any: // Caller information: { MethodHandles.Lookup caller = IMPL_LOOKUP.@in(callerClass); CallSite site; try { Object binding; info = MaybeReBox(info); if (info == null) { binding = bootstrapMethod.invoke(caller, name, type); } else if (!info.GetType().IsArray) { binding = bootstrapMethod.invoke(caller, name, type, info); } else { Object[] argv = (Object[])info; MaybeReBoxElements(argv); switch (argv.Length) { case 0: binding = bootstrapMethod.invoke(caller, name, type); break; case 1: binding = bootstrapMethod.invoke(caller, name, type, argv[0]); break; case 2: binding = bootstrapMethod.invoke(caller, name, type, argv[0], argv[1]); break; case 3: binding = bootstrapMethod.invoke(caller, name, type, argv[0], argv[1], argv[2]); break; case 4: binding = bootstrapMethod.invoke(caller, name, type, argv[0], argv[1], argv[2], argv[3]); break; case 5: binding = bootstrapMethod.invoke(caller, name, type, argv[0], argv[1], argv[2], argv[3], argv[4]); break; case 6: binding = bootstrapMethod.invoke(caller, name, type, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]); break; default: const int NON_SPREAD_ARG_COUNT = 3; // (caller, name, type) if (NON_SPREAD_ARG_COUNT + argv.Length > MethodType.MAX_MH_ARITY) { throw new BootstrapMethodError("too many bootstrap method arguments"); } MethodType bsmType = bootstrapMethod.Type(); MethodType invocationType = MethodType.GenericMethodType(NON_SPREAD_ARG_COUNT + argv.Length); MethodHandle typedBSM = bootstrapMethod.AsType(invocationType); MethodHandle spreader = invocationType.Invokers().SpreadInvoker(NON_SPREAD_ARG_COUNT); binding = spreader.invokeExact(typedBSM, (Object)caller, (Object)name, (Object)type, argv); break; } } //System.out.println("BSM for "+name+type+" => "+binding); if (binding is CallSite) { site = (CallSite)binding; } else { throw new ClassCastException("bootstrap method failed to produce a CallSite"); } if (!site.Target.Type().Equals(type)) { throw WrongTargetType(site.Target, type); } } catch (Throwable ex) { BootstrapMethodError bex; if (ex is BootstrapMethodError) { bex = (BootstrapMethodError)ex; } else { bex = new BootstrapMethodError("call site initialization exception", ex); } throw bex; } return(site); }