Ejemplo n.º 1
0
 /// <summary>
 /// The JVM is resolving a CONSTANT_MethodHandle CP entry.  And it wants our help.
 /// It will make an up-call to this method.  (Do not change the name or signature.)
 /// The type argument is a Class for field requests and a MethodType for non-fields.
 /// <para>
 /// Recent versions of the JVM may also pass a resolved MemberName for the type.
 /// In that case, the name is ignored and may be null.
 /// </para>
 /// </summary>
 internal static MethodHandle LinkMethodHandleConstant(Class callerClass, int refKind, Class defc, String name, Object type)
 {
     try
     {
         Lookup lookup = IMPL_LOOKUP.@in(callerClass);
         assert(RefKindIsValid(refKind));
         return(lookup.linkMethodHandleConstant((sbyte)refKind, defc, name, type));
     }
     catch (IllegalAccessException ex)
     {
         Throwable cause = ex.InnerException;
         if (cause is AbstractMethodError)
         {
             throw (AbstractMethodError)cause;
         }
         else
         {
             Error err = new IllegalAccessError(ex.Message);
             throw InitCauseFrom(err, ex);
         }
     }
     catch (NoSuchMethodException ex)
     {
         Error err = new NoSuchMethodError(ex.Message);
         throw InitCauseFrom(err, ex);
     }
     catch (NoSuchFieldException ex)
     {
         Error err = new NoSuchFieldError(ex.Message);
         throw InitCauseFrom(err, ex);
     }
     catch (ReflectiveOperationException ex)
     {
         Error err = new IncompatibleClassChangeError();
         throw InitCauseFrom(err, ex);
     }
 }
Ejemplo n.º 2
0
        // 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);
        }