Exemple #1
0
        private static ConstructorBuilder DefineThreadLocalType(DynamicTypeWrapper.FinishContext context, int opcodeIndex, MethodWrapper caller)
        {
            TypeWrapper  threadLocal = ClassLoaderWrapper.LoadClassCritical("ikvm.internal.IntrinsicThreadLocal");
            TypeBuilder  tb          = caller.DeclaringType.TypeAsBuilder.DefineNestedType("__<tls>_" + opcodeIndex, TypeAttributes.NestedPrivate | TypeAttributes.Sealed, threadLocal.TypeAsBaseType);
            FieldBuilder fb          = tb.DefineField("field", Types.Object, FieldAttributes.Private | FieldAttributes.Static);

            fb.SetCustomAttribute(new CustomAttributeBuilder(JVM.Import(typeof(ThreadStaticAttribute)).GetConstructor(Type.EmptyTypes), new object[0]));
            MethodBuilder mbGet = tb.DefineMethod("get", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.Final, Types.Object, Type.EmptyTypes);
            ILGenerator   ilgen = mbGet.GetILGenerator();

            ilgen.Emit(OpCodes.Ldsfld, fb);
            ilgen.Emit(OpCodes.Ret);
            MethodBuilder mbSet = tb.DefineMethod("set", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.Final, null, new Type[] { Types.Object });

            ilgen = mbSet.GetILGenerator();
            ilgen.Emit(OpCodes.Ldarg_1);
            ilgen.Emit(OpCodes.Stsfld, fb);
            ilgen.Emit(OpCodes.Ret);
            ConstructorBuilder cb        = tb.DefineConstructor(MethodAttributes.Assembly, CallingConventions.Standard, Type.EmptyTypes);
            CodeEmitter        ctorilgen = CodeEmitter.Create(cb);

            ctorilgen.Emit(OpCodes.Ldarg_0);
            MethodWrapper basector = threadLocal.GetMethodWrapper("<init>", "()V", false);

            basector.Link();
            basector.EmitCall(ctorilgen);
            ctorilgen.Emit(OpCodes.Ret);
            ctorilgen.DoEmit();
            context.RegisterPostFinishProc(delegate
            {
                threadLocal.Finish();
                tb.CreateType();
            });
            return(cb);
        }
Exemple #2
0
        private static ConstructorInfo AddConstructor(TypeBuilder tb, MethodWrapper defaultConstructor, ConstructorInfo serializationConstructor, bool callReadObject)
        {
            ConstructorBuilder ctor = tb.DefineConstructor(MethodAttributes.Family, CallingConventions.Standard, new Type[] { JVM.Import(typeof(SerializationInfo)), JVM.Import(typeof(StreamingContext)) });

            AttributeHelper.HideFromJava(ctor);
            ctor.AddDeclarativeSecurity(SecurityAction.Demand, psetSerializationFormatter);
            CodeEmitter ilgen = CodeEmitter.Create(ctor);

            ilgen.Emit(OpCodes.Ldarg_0);
            if (defaultConstructor != null)
            {
                defaultConstructor.EmitCall(ilgen);
            }
            else
            {
                ilgen.Emit(OpCodes.Ldarg_1);
                ilgen.Emit(OpCodes.Ldarg_2);
                ilgen.Emit(OpCodes.Call, serializationConstructor);
            }
            if (callReadObject)
            {
                ilgen.Emit(OpCodes.Ldarg_0);
                ilgen.Emit(OpCodes.Ldarg_1);
                TypeWrapper   serializationHelper = ClassLoaderWrapper.LoadClassCritical("ikvm.internal.Serialization");
                MethodWrapper mw = serializationHelper.GetMethodWrapper("readObject", "(Ljava.lang.Object;Lcli.System.Runtime.Serialization.SerializationInfo;)V", false);
                mw.Link();
                mw.EmitCall(ilgen);
            }
            ilgen.Emit(OpCodes.Ret);
            ilgen.DoEmit();
            return(ctor);
        }
Exemple #3
0
        private static void AddReadResolve(DynamicTypeWrapper wrapper, TypeBuilder tb)
        {
            MethodWrapper mw = wrapper.GetMethodWrapper("readResolve", "()Ljava.lang.Object;", false);

            if (mw != null && !wrapper.IsSubTypeOf(iobjectreference))
            {
                tb.AddInterfaceImplementation(JVM.Import(typeof(IObjectReference)));
                MethodBuilder getRealObject = tb.DefineMethod("IObjectReference.GetRealObject", MethodAttributes.Private | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.Final,
                                                              Types.Object, new Type[] { JVM.Import(typeof(StreamingContext)) });
                getRealObject.SetCustomAttribute(securityCriticalAttribute);
                AttributeHelper.HideFromJava(getRealObject);
                tb.DefineMethodOverride(getRealObject, JVM.Import(typeof(IObjectReference)).GetMethod("GetRealObject"));
                CodeEmitter ilgen = CodeEmitter.Create(getRealObject);
                mw.Link();
                if (!wrapper.IsFinal)
                {
                    // readResolve is only applicable if it exists on the actual type of the object, so if we're a subclass don't call it
                    ilgen.Emit(OpCodes.Ldarg_0);
                    ilgen.Emit(OpCodes.Callvirt, Compiler.getTypeMethod);
                    ilgen.Emit(OpCodes.Ldtoken, wrapper.TypeAsBaseType);
                    ilgen.Emit(OpCodes.Call, Compiler.getTypeFromHandleMethod);
                    CodeEmitterLabel label = ilgen.DefineLabel();
                    ilgen.Emit(OpCodes.Beq_S, label);
                    ilgen.Emit(OpCodes.Ldarg_0);
                    ilgen.Emit(OpCodes.Ret);
                    ilgen.MarkLabel(label);
                }
                ilgen.Emit(OpCodes.Ldarg_0);
                mw.EmitCall(ilgen);
                ilgen.Emit(OpCodes.Ret);
                ilgen.DoEmit();
            }
        }
        private static MethodBuilder AddConstructor(TypeBuilder tb, MethodWrapper defaultConstructor, MethodBase serializationConstructor, bool callReadObject)
        {
            MethodBuilder ctor = ReflectUtil.DefineConstructor(tb, MethodAttributes.Family, new Type[] { JVM.Import(typeof(SerializationInfo)), JVM.Import(typeof(StreamingContext)) });

            AttributeHelper.HideFromJava(ctor);
            CodeEmitter ilgen = CodeEmitter.Create(ctor);

            ilgen.Emit(OpCodes.Ldarg_0);
            if (defaultConstructor != null)
            {
                defaultConstructor.EmitCall(ilgen);
            }
            else
            {
                ilgen.Emit(OpCodes.Ldarg_1);
                ilgen.Emit(OpCodes.Ldarg_2);
                ilgen.Emit(OpCodes.Call, serializationConstructor);
            }
            if (callReadObject)
            {
                ilgen.Emit(OpCodes.Ldarg_0);
                ilgen.Emit(OpCodes.Ldarg_1);
                TypeWrapper   serializationHelper = ClassLoaderWrapper.LoadClassCritical("ikvm.internal.Serialization");
                MethodWrapper mw = serializationHelper.GetMethodWrapper("readObject", "(Ljava.lang.Object;Lcli.System.Runtime.Serialization.SerializationInfo;)V", false);
                mw.Link();
                mw.EmitCall(ilgen);
            }
            ilgen.Emit(OpCodes.Ret);
            ilgen.DoEmit();
            return(ctor);
        }
Exemple #5
0
        internal static void AddGetObjectData(TypeBuilder tb)
        {
            string name = tb.IsSealed
                                ? "System.Runtime.Serialization.ISerializable.GetObjectData"
                                : "GetObjectData";
            MethodAttributes attr = tb.IsSealed
                                ? MethodAttributes.Private | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.Final
                                : MethodAttributes.Family | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.CheckAccessOnOverride;

            tb.AddInterfaceImplementation(JVM.Import(typeof(ISerializable)));
            MethodBuilder getObjectData = tb.DefineMethod(name, attr, null,
                                                          new Type[] { JVM.Import(typeof(SerializationInfo)), JVM.Import(typeof(StreamingContext)) });

            getObjectData.SetCustomAttribute(securityCriticalAttribute);
            AttributeHelper.HideFromJava(getObjectData);
            //TODO: We need to review this for .NET Core
            //getObjectData.AddDeclarativeSecurity(SecurityAction.Demand, psetSerializationFormatter);
            tb.DefineMethodOverride(getObjectData, JVM.Import(typeof(ISerializable)).GetMethod("GetObjectData"));
            CodeEmitter ilgen = CodeEmitter.Create(getObjectData);

            ilgen.Emit(OpCodes.Ldarg_0);
            ilgen.Emit(OpCodes.Ldarg_1);
            TypeWrapper   serializationHelper = ClassLoaderWrapper.LoadClassCritical("ikvm.internal.Serialization");
            MethodWrapper mw = serializationHelper.GetMethodWrapper("writeObject", "(Ljava.lang.Object;Lcli.System.Runtime.Serialization.SerializationInfo;)V", false);

            mw.Link();
            mw.EmitCall(ilgen);
            ilgen.Emit(OpCodes.Ret);
            ilgen.DoEmit();
        }
Exemple #6
0
 internal static void EmitUnbox(CodeEmitter ilgen, TypeWrapper tw)
 {
     if (tw == PrimitiveTypeWrapper.BYTE)
     {
         javaLangByte.EmitCheckcast(ilgen);
         byteValue.EmitCall(ilgen);
     }
     else if (tw == PrimitiveTypeWrapper.BOOLEAN)
     {
         javaLangBoolean.EmitCheckcast(ilgen);
         booleanValue.EmitCall(ilgen);
     }
     else if (tw == PrimitiveTypeWrapper.SHORT)
     {
         javaLangShort.EmitCheckcast(ilgen);
         shortValue.EmitCall(ilgen);
     }
     else if (tw == PrimitiveTypeWrapper.CHAR)
     {
         javaLangCharacter.EmitCheckcast(ilgen);
         charValue.EmitCall(ilgen);
     }
     else if (tw == PrimitiveTypeWrapper.INT)
     {
         javaLangInteger.EmitCheckcast(ilgen);
         intValue.EmitCall(ilgen);
     }
     else if (tw == PrimitiveTypeWrapper.FLOAT)
     {
         javaLangFloat.EmitCheckcast(ilgen);
         floatValue.EmitCall(ilgen);
     }
     else if (tw == PrimitiveTypeWrapper.LONG)
     {
         javaLangLong.EmitCheckcast(ilgen);
         longValue.EmitCall(ilgen);
     }
     else if (tw == PrimitiveTypeWrapper.DOUBLE)
     {
         javaLangDouble.EmitCheckcast(ilgen);
         doubleValue.EmitCall(ilgen);
     }
     else
     {
         throw new InvalidOperationException();
     }
 }
        private static void AddReadResolve(TypeWrapper wrapper)
        {
            MethodWrapper mw = wrapper.GetMethodWrapper("readResolve", "()Ljava.lang.Object;", false);

            if (mw != null && !wrapper.IsSubTypeOf(iobjectreference))
            {
                TypeBuilder tb = wrapper.TypeAsBuilder;
                tb.AddInterfaceImplementation(JVM.Import(typeof(IObjectReference)));
                MethodBuilder getRealObject = tb.DefineMethod("IObjectReference.GetRealObject", MethodAttributes.Private | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.Final,
                                                              Types.Object, new Type[] { JVM.Import(typeof(StreamingContext)) });
                getRealObject.SetCustomAttribute(securityCriticalAttribute);
                AttributeHelper.HideFromJava(getRealObject);
                tb.DefineMethodOverride(getRealObject, JVM.Import(typeof(IObjectReference)).GetMethod("GetRealObject"));
                CodeEmitter ilgen = CodeEmitter.Create(getRealObject);
                mw.Link();
                ilgen.Emit(OpCodes.Ldarg_0);
                mw.EmitCall(ilgen);
                ilgen.Emit(OpCodes.Ret);
            }
        }
Exemple #8
0
    private static void DoEmit(DynamicTypeWrapper.FinishContext context, TypeWrapper wrapper, CodeEmitter ilgen, FieldWrapper field)
    {
        ConstructorBuilder cb;
        bool exists;

        lock (map)
        {
            exists = map.TryGetValue(field, out cb);
        }
        if (!exists)
        {
            // note that we don't need to lock here, because we're running as part of FinishCore, which is already protected by a lock
            TypeWrapper arfuTypeWrapper = ClassLoaderWrapper.LoadClassCritical("ikvm.internal.IntrinsicAtomicReferenceFieldUpdater");
            TypeBuilder tb = wrapper.TypeAsBuilder.DefineNestedType("__<ARFU>_" + field.Name + field.Signature.Replace('.', '/'), TypeAttributes.NestedPrivate | TypeAttributes.Sealed, arfuTypeWrapper.TypeAsBaseType);
            EmitCompareAndSet("compareAndSet", tb, field.GetField());
            EmitGet(tb, field.GetField());
            EmitSet("set", tb, field.GetField());

            cb = tb.DefineConstructor(MethodAttributes.Assembly, CallingConventions.Standard, Type.EmptyTypes);
            lock (map)
            {
                map.Add(field, cb);
            }
            CodeEmitter ctorilgen = CodeEmitter.Create(cb);
            ctorilgen.Emit(OpCodes.Ldarg_0);
            MethodWrapper basector = arfuTypeWrapper.GetMethodWrapper("<init>", "()V", false);
            basector.Link();
            basector.EmitCall(ctorilgen);
            ctorilgen.Emit(OpCodes.Ret);
            ctorilgen.DoEmit();
            context.RegisterPostFinishProc(delegate
            {
                arfuTypeWrapper.Finish();
                tb.CreateType();
            });
        }
        ilgen.Emit(OpCodes.Pop);
        ilgen.Emit(OpCodes.Pop);
        ilgen.Emit(OpCodes.Pop);
        ilgen.Emit(OpCodes.Newobj, cb);
    }
Exemple #9
0
        internal void Emit(ClassLoaderWrapper loader, CodeEmitter ilgen)
        {
            if (Type != "static" || Class == null || Name == null || Sig == null)
            {
                throw new NotImplementedException();
            }
            Type[] redirParamTypes = loader.ArgTypeListFromSig(Sig);
            for (int i = 0; i < redirParamTypes.Length; i++)
            {
                ilgen.EmitLdarg(i);
            }
            // HACK if the class name contains a comma, we assume it is a .NET type
            if (Class.IndexOf(',') >= 0)
            {
#if NETSTANDARD
                Class = Class.Replace("mscorlib", Universe.CoreLibName);
#endif
                Type       type = StaticCompiler.Universe.GetType(Class, true);
                MethodInfo mi   = type.GetMethod(Name, redirParamTypes);
                if (mi == null)
                {
                    throw new InvalidOperationException();
                }
                ilgen.Emit(OpCodes.Call, mi);
            }
            else
            {
                TypeWrapper   tw = loader.LoadClassByDottedName(Class);
                MethodWrapper mw = tw.GetMethodWrapper(Name, Sig, false);
                if (mw == null)
                {
                    throw new InvalidOperationException();
                }
                mw.Link();
                mw.EmitCall(ilgen);
            }
            // TODO we may need a cast here (or a stack to return type conversion)
            ilgen.Emit(OpCodes.Ret);
        }
Exemple #10
0
 internal static void EmitBox(CodeEmitter ilgen, TypeWrapper tw)
 {
     if (tw == PrimitiveTypeWrapper.BYTE)
     {
         valueOfByte.EmitCall(ilgen);
     }
     else if (tw == PrimitiveTypeWrapper.BOOLEAN)
     {
         valueOfBoolean.EmitCall(ilgen);
     }
     else if (tw == PrimitiveTypeWrapper.SHORT)
     {
         valueOfShort.EmitCall(ilgen);
     }
     else if (tw == PrimitiveTypeWrapper.CHAR)
     {
         valueOfCharacter.EmitCall(ilgen);
     }
     else if (tw == PrimitiveTypeWrapper.INT)
     {
         valueOfInteger.EmitCall(ilgen);
     }
     else if (tw == PrimitiveTypeWrapper.FLOAT)
     {
         valueOfFloat.EmitCall(ilgen);
     }
     else if (tw == PrimitiveTypeWrapper.LONG)
     {
         valueOfLong.EmitCall(ilgen);
     }
     else if (tw == PrimitiveTypeWrapper.DOUBLE)
     {
         valueOfDouble.EmitCall(ilgen);
     }
     else
     {
         throw new InvalidOperationException();
     }
 }
Exemple #11
0
 private static bool Reflection_getCallerClass(EmitIntrinsicContext eic)
 {
     if (eic.Caller.HasCallerID)
     {
         int arg = eic.Caller.GetParametersForDefineMethod().Length - 1;
         if (!eic.Caller.IsStatic)
         {
             arg++;
         }
         eic.Emitter.EmitLdarg(arg);
         MethodWrapper mw;
         if (MatchInvokeStatic(eic, 1, "java.lang.ClassLoader", "getClassLoader", "(Ljava.lang.Class;)Ljava.lang.ClassLoader;"))
         {
             eic.PatchOpCode(1, NormalizedByteCode.__nop);
             mw = [email protected]("getCallerClassLoader", "()Ljava.lang.ClassLoader;", false);
         }
         else
         {
             mw = [email protected]("getCallerClass", "()Ljava.lang.Class;", false);
         }
         mw.Link();
         mw.EmitCallvirt(eic.Emitter);
         return(true);
     }
     else if (DynamicTypeWrapper.RequiresDynamicReflectionCallerClass(eic.ClassFile.Name, eic.Caller.Name, eic.Caller.Signature))
     {
         // since the non-intrinsic version of Reflection.getCallerClass() always throws an exception, we have to redirect to the dynamic version
         MethodWrapper getCallerClass = ClassLoaderWrapper.LoadClassCritical("sun.reflect.Reflection").GetMethodWrapper("getCallerClass", "(I)Ljava.lang.Class;", false);
         getCallerClass.Link();
         eic.Emitter.EmitLdc_I4(2);
         getCallerClass.EmitCall(eic.Emitter);
         return(true);
     }
     else
     {
         StaticCompiler.IssueMessage(Message.ReflectionCallerClassRequiresCallerID, eic.ClassFile.Name, eic.Caller.Name, eic.Caller.Signature);
     }
     return(false);
 }
        private static void AddGetObjectData(TypeWrapper wrapper)
        {
            TypeBuilder tb = wrapper.TypeAsBuilder;

            tb.AddInterfaceImplementation(JVM.Import(typeof(ISerializable)));
            MethodBuilder getObjectData = tb.DefineMethod("GetObjectData", MethodAttributes.Family | MethodAttributes.Virtual | MethodAttributes.NewSlot, null,
                                                          new Type[] { JVM.Import(typeof(SerializationInfo)), JVM.Import(typeof(StreamingContext)) });

            getObjectData.SetCustomAttribute(securityCriticalAttribute);
            AttributeHelper.HideFromJava(getObjectData);
            getObjectData.AddDeclarativeSecurity(SecurityAction.Demand, psetSerializationFormatter);
            tb.DefineMethodOverride(getObjectData, JVM.Import(typeof(ISerializable)).GetMethod("GetObjectData"));
            CodeEmitter ilgen = CodeEmitter.Create(getObjectData);

            ilgen.Emit(OpCodes.Ldarg_0);
            ilgen.Emit(OpCodes.Ldarg_1);
            TypeWrapper   serializationHelper = ClassLoaderWrapper.LoadClassCritical("ikvm.internal.Serialization");
            MethodWrapper mw = serializationHelper.GetMethodWrapper("writeObject", "(Ljava.lang.Object;Lcli.System.Runtime.Serialization.SerializationInfo;)V", false);

            mw.Link();
            mw.EmitCall(ilgen);
            ilgen.Emit(OpCodes.Ret);
        }
Exemple #13
0
 internal sealed override void Generate(CodeGenContext context, CodeEmitter ilgen)
 {
     Debug.Assert(Name != null);
     if (Name == ".ctor")
     {
         Debug.Assert(Class == null && type != null);
         Type[]          argTypes = context.ClassLoader.ArgTypeListFromSig(Sig);
         ConstructorInfo ci       = StaticCompiler.GetTypeForMapXml(context.ClassLoader, type).GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, CallingConventions.Standard, argTypes, null);
         if (ci == null)
         {
             throw new InvalidOperationException("Missing .ctor: " + type + "..ctor" + Sig);
         }
         ilgen.Emit(opcode, ci);
     }
     else
     {
         Debug.Assert(Class == null ^ type == null);
         if (Class != null)
         {
             Debug.Assert(Sig != null);
             MethodWrapper method = context.ClassLoader.LoadClassByDottedName(Class).GetMethodWrapper(Name, Sig, false);
             if (method == null)
             {
                 throw new InvalidOperationException("method not found: " + Class + "." + Name + Sig);
             }
             method.Link();
             // TODO this code is part of what Compiler.CastInterfaceArgs (in compiler.cs) does,
             // it would be nice if we could avoid this duplication...
             TypeWrapper[] argTypeWrappers = method.GetParameters();
             for (int i = 0; i < argTypeWrappers.Length; i++)
             {
                 if (argTypeWrappers[i].IsGhost)
                 {
                     CodeEmitterLocal[] temps = new CodeEmitterLocal[argTypeWrappers.Length + (method.IsStatic ? 0 : 1)];
                     for (int j = temps.Length - 1; j >= 0; j--)
                     {
                         TypeWrapper tw;
                         if (method.IsStatic)
                         {
                             tw = argTypeWrappers[j];
                         }
                         else
                         {
                             if (j == 0)
                             {
                                 tw = method.DeclaringType;
                             }
                             else
                             {
                                 tw = argTypeWrappers[j - 1];
                             }
                         }
                         if (tw.IsGhost)
                         {
                             tw.EmitConvStackTypeToSignatureType(ilgen, null);
                         }
                         temps[j] = ilgen.DeclareLocal(tw.TypeAsSignatureType);
                         ilgen.Emit(OpCodes.Stloc, temps[j]);
                     }
                     for (int j = 0; j < temps.Length; j++)
                     {
                         ilgen.Emit(OpCodes.Ldloc, temps[j]);
                     }
                     break;
                 }
             }
             if (opcode.Value == OpCodes.Call.Value)
             {
                 method.EmitCall(ilgen);
             }
             else if (opcode.Value == OpCodes.Callvirt.Value)
             {
                 method.EmitCallvirt(ilgen);
             }
             else if (opcode.Value == OpCodes.Newobj.Value)
             {
                 method.EmitNewobj(ilgen);
             }
             else
             {
                 // ldftn or ldvirtftn
                 ilgen.Emit(opcode, (MethodInfo)method.GetMethod());
             }
         }
         else
         {
             Type[] argTypes;
             if (Sig.StartsWith("("))
             {
                 argTypes = context.ClassLoader.ArgTypeListFromSig(Sig);
             }
             else if (Sig == "")
             {
                 argTypes = Type.EmptyTypes;
             }
             else
             {
                 string[] types = Sig.Split(';');
                 argTypes = new Type[types.Length];
                 for (int i = 0; i < types.Length; i++)
                 {
                     argTypes[i] = StaticCompiler.GetTypeForMapXml(context.ClassLoader, types[i]);
                 }
             }
             MethodInfo mi = StaticCompiler.GetTypeForMapXml(context.ClassLoader, type).GetMethod(Name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static, null, argTypes, null);
             if (mi == null)
             {
                 throw new InvalidOperationException("Missing method: " + type + "." + Name + Sig);
             }
             ilgen.Emit(opcode, mi);
         }
     }
 }
Exemple #14
0
 internal void Call(MethodWrapper mw)
 {
     mw.EmitCall(ilgen);
 }
    /**
     * Emit an invoke for the given name, using the MemberName directly.
     */
    void emitStaticInvoke(MemberName member, Name name)
    {
        // push arguments
        emitPushArguments(name);

        // invocation
        if (member.isMethod())
        {
            if (IsMethodHandleLinkTo(member))
            {
                MethodType    mt   = member.getMethodType();
                TypeWrapper[] args = new TypeWrapper[mt.parameterCount()];
                for (int j = 0; j < args.Length; j++)
                {
                    args[j] = TypeWrapper.FromClass(mt.parameterType(j));
                    args[j].Finish();
                }
                TypeWrapper ret = TypeWrapper.FromClass(mt.returnType());
                ret.Finish();
                Compiler.MethodHandleMethodWrapper.EmitLinkToCall(ilgen, args, ret);
                ret.EmitConvSignatureTypeToStackType(ilgen);
            }
            else if (IsMethodHandleInvokeBasic(member))
            {
                EmitInvokeBasic(member.getMethodType());
            }
            else
            {
                switch (member.getReferenceKind())
                {
                case MethodHandleNatives.Constants.REF_invokeInterface:
                case MethodHandleNatives.Constants.REF_invokeSpecial:
                case MethodHandleNatives.Constants.REF_invokeStatic:
                case MethodHandleNatives.Constants.REF_invokeVirtual:
                    break;

                default:
                    throw new BailoutException(Bailout.UnsupportedRefKind, member);
                }
                MethodWrapper mw = GetMethodWrapper(member);
                if (!IsStaticallyInvocable(mw))
                {
                    throw new BailoutException(Bailout.NotStaticallyInvocable, member);
                }
                mw.Link();
                mw.DeclaringType.Finish();
                mw.ResolveMethod();
                if (mw.HasCallerID)
                {
                    EmitConstant(DynamicCallerIDProvider.Instance);
                    ilgen.Emit(OpCodes.Call, ByteCodeHelperMethods.DynamicCallerID);
                }
                if (mw.IsStatic || member.getReferenceKind() == MethodHandleNatives.Constants.REF_invokeSpecial)
                {
                    mw.EmitCall(ilgen);
                }
                else
                {
                    mw.EmitCallvirt(ilgen);
                }
                mw.ReturnType.EmitConvSignatureTypeToStackType(ilgen);
            }
        }
        else if (member.isField())
        {
            FieldWrapper fw = GetFieldWrapper(member);
            if (!IsStaticallyInvocable(fw))
            {
                throw new BailoutException(Bailout.NotStaticallyInvocable, member);
            }
            fw.Link();
            fw.DeclaringType.Finish();
            fw.ResolveField();
            switch (member.getReferenceKind())
            {
            case MethodHandleNatives.Constants.REF_getField:
            case MethodHandleNatives.Constants.REF_getStatic:
                fw.EmitGet(ilgen);
                fw.FieldTypeWrapper.EmitConvSignatureTypeToStackType(ilgen);
                break;

            case MethodHandleNatives.Constants.REF_putField:
            case MethodHandleNatives.Constants.REF_putStatic:
                fw.EmitSet(ilgen);
                break;

            default:
                throw new BailoutException(Bailout.UnsupportedRefKind, member);
            }
        }
        else
        {
            throw new BailoutException(Bailout.NotStaticallyInvocable, member);
        }
    }