示例#1
0
        //
        // create a CallSite that returns an object that implements the
        // functional interface 'declType', containing a single method with the
        // signature 'declMethod'.  this interface method is a proxy that calls
        // the method 'implMethod' from class 'implClass'.
        //
        // 'captureParameters' may optionally specify any number of parameters,
        // which would be on the stack when 'invokedynamic' is executed.  these
        // parameters are captured by the callsite, and injected as the first
        // several parameters of 'implMethod' when the proxy is called.  the
        // parameter list for 'implMethod' should not include these parameters;
        // they are inserted by this method.
        //
        // callKind should be InvokeStatic, InvokeVirtual, or InvokeInterface,
        // and specifies the type of 'implMethod'.  if not InvokeStatic, it is
        // as if the first parameter in 'captureParameters' is 'declType'.
        //

        public JavaCallSite(JavaType declType, JavaMethodRef declMethod,
                            JavaType implClass, JavaMethodRef implMethod,
                            List <JavaFieldRef> captureParameters,
                            JavaMethodHandle.HandleKind callKind)
        {
            BootstrapMethod      = GetLambdaMetafactory();
            BootstrapMethodIndex = 0xFFFF;

            var invokedMethod = new JavaMethodRef();

            invokedMethod.Name       = declMethod.Name;
            invokedMethod.ReturnType = declType;
            invokedMethod.Parameters = new List <JavaFieldRef>();
            if (callKind != JavaMethodHandle.HandleKind.InvokeStatic)
            {
                invokedMethod.Parameters.Add(new JavaFieldRef("", implClass));
            }
            InvokedMethod = invokedMethod;

            var methodHandle = new JavaMethodHandle();

            methodHandle.Class             = implClass;
            methodHandle.Method            = implMethod;
            methodHandle.Kind              = callKind;
            methodHandle.IsInterfaceMethod =
                (callKind == JavaMethodHandle.HandleKind.InvokeInterface);

            JavaMethodType castMethod = new JavaMethodType(declMethod.ReturnType, null);

            castMethod.Parameters = new List <JavaFieldRef>();
            for (int i = 0; i < implMethod.Parameters.Count; i++)
            {
                JavaType castParameterType = declMethod.Parameters[i].Type;
                if (castParameterType.Equals(JavaType.ObjectType))
                {
                    var implParameterType = implMethod.Parameters[i].Type;
                    castParameterType = implParameterType.Wrapper ?? implParameterType;
                }
                castMethod.Parameters.Add(new JavaFieldRef("", castParameterType));
            }

            BootstrapArgs = new object[3];
            // arg#0 (aka 'samMethodType') specifies the signature, minus the name,
            // of the method in the functional interface.  note that the name was
            // already inserted into 'InvokedMethod', above
            BootstrapArgs[0] =
                new JavaMethodType(declMethod.ReturnType, declMethod.Parameters);
            // arg#1 (aka 'implMethod') specifies the name and signature of the
            // method that provides the actual implementation for the interface
            BootstrapArgs[1] = methodHandle;
            // arg#2 (aka 'instantiatedMethodType') specifies optional conversions
            // on the parameters passed to the 'invokeinterface' instructions.
            // in particular, boxing of primitives to standard wrapper types, or
            // casting generic java.lang.Object to a more restricted type.
            BootstrapArgs[2] =
                new JavaMethodType(castMethod.ReturnType, castMethod.Parameters);

            if (captureParameters != null)
            {
                invokedMethod.Parameters.AddRange(captureParameters);
                var newParameters = new List <JavaFieldRef>(captureParameters);
                newParameters.AddRange(implMethod.Parameters);
                methodHandle.Method = new JavaMethodRef(
                    implMethod.Name, implMethod.ReturnType, newParameters);
            }
        }
示例#2
0
        public ushort ConstMethodType(JavaMethodType vMethodType)
        {
            ushort descriptorIndex = ConstUtf8(vMethodType.ToDescriptor());

            return((ushort)constants.Put(new JavaConstant.MethodType(descriptorIndex), Where));
        }