GetMethod() public method

public GetMethod ( string name ) : IKVM.Reflection.MethodInfo
name string
return IKVM.Reflection.MethodInfo
Exemplo n.º 1
0
        protected override void EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom)
        {
            using (Compiler.Local oldValue = ctx.GetLocalWithValue(expectedType, valueFrom))
                using (Compiler.Local token = new Compiler.Local(ctx, ctx.MapType(typeof(SubItemToken))))
                    using (Compiler.Local field = new Compiler.Local(ctx, ctx.MapType(typeof(int))))
                    {
                        ctx.LoadReaderWriter();
                        ctx.EmitCall(ctx.MapType(typeof(ProtoReader)).GetMethod("StartSubItem"));
                        ctx.StoreValue(token);

                        Compiler.CodeLabel next = ctx.DefineLabel(), processField = ctx.DefineLabel(), end = ctx.DefineLabel();

                        ctx.MarkLabel(next);

                        ctx.EmitBasicRead("ReadFieldHeader", ctx.MapType(typeof(int)));
                        ctx.CopyValue();
                        ctx.StoreValue(field);
                        ctx.LoadValue(Tag); // = 1 - process
                        ctx.BranchIfEqual(processField, true);
                        ctx.LoadValue(field);
                        ctx.LoadValue(1); // < 1 - exit
                        ctx.BranchIfLess(end, false);

                        // default: skip
                        ctx.LoadReaderWriter();
                        ctx.EmitCall(ctx.MapType(typeof(ProtoReader)).GetMethod("SkipField"));
                        ctx.Branch(next, true);

                        // process
                        ctx.MarkLabel(processField);
                        if (Tail.RequiresOldValue)
                        {
                            if (expectedType.IsValueType)
                            {
                                ctx.LoadAddress(oldValue, expectedType);
                                ctx.EmitCall(expectedType.GetMethod("GetValueOrDefault", Helpers.EmptyTypes));
                            }
                            else
                            {
                                ctx.LoadValue(oldValue);
                            }
                        }
                        Tail.EmitRead(ctx, null);
                        // note we demanded always returns a value
                        if (expectedType.IsValueType)
                        {
                            ctx.EmitCtor(expectedType, Tail.ExpectedType); // re-nullable<T> it
                        }
                        ctx.StoreValue(oldValue);
                        ctx.Branch(next, false);

                        // outro
                        ctx.MarkLabel(end);

                        ctx.LoadValue(token);
                        ctx.LoadReaderWriter();
                        ctx.EmitCall(ctx.MapType(typeof(ProtoReader)).GetMethod("EndSubItem"));
                        ctx.LoadValue(oldValue); // load the old value
                    }
        }
Exemplo n.º 2
0
    static InterlockedMethods()
    {
#if !WINRT
        Type type = JVM.Import(typeof(System.Threading.Interlocked));
        AddInt32             = type.GetMethod("Add", new Type[] { Types.Int32.MakeByRefType(), Types.Int32 });
        CompareExchangeInt32 = type.GetMethod("CompareExchange", new Type[] { Types.Int32.MakeByRefType(), Types.Int32, Types.Int32 });
        CompareExchangeInt64 = type.GetMethod("CompareExchange", new Type[] { Types.Int64.MakeByRefType(), Types.Int64, Types.Int64 });
        foreach (MethodInfo m in type.GetMethods())
        {
            if (m.IsGenericMethodDefinition)
            {
                switch (m.Name)
                {
                case "CompareExchange":
                    CompareExchangeOfT = m;
                    break;

                case "Exchange":
                    ExchangeOfT = m;
                    break;
                }
            }
        }
#else
        throw new NotImplementedException();
#endif
    }
Exemplo n.º 3
0
        bool AddDecimalSupport(Type t)
        {
            if (system_decimal != null)
            {
                return(true);
            }
            var corlib = GetMscorlib(t);

            system_decimal = new ProcessedType(t)
            {
                Assembly = corlib,
                // this is tracked because the linker (if enabled) needs to be aware of the requirement
                // but we do not want any code to be generated (it's referenced only from native/glue code)
                IsNativeReference = true,
                Methods           = new List <ProcessedMethod> (),
            };
            // we don't want to being everything from System.Decimal, but only the bits the support code can call
            var string_type          = corlib.Assembly.GetType("System.String");
            var iformatprovider_type = corlib.Assembly.GetType("System.IFormatProvider");
            var parse = t.GetMethod("Parse", new Type [] { string_type, iformatprovider_type });

            system_decimal.Methods.Add(new ProcessedMethod(parse, this));
            var tostring = t.GetMethod("ToString", new Type [] { iformatprovider_type });

            system_decimal.Methods.Add(new ProcessedMethod(tostring, this));
            AddExtraType(system_decimal);
            return(true);
        }
Exemplo n.º 4
0
        internal static MethodInfo GetInstanceMethod(Type declaringType, string name, Type[] types)
        {
            if (types == null) types = EmptyTypes;
#if PORTABLE
            MethodInfo method = declaringType.GetMethod(name, types);
            if (method != null && method.IsStatic) method = null;
            return method;
#else
            return declaringType.GetMethod(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,
                null, types, null);
#endif
        }
        public static ParseableSerializer TryCreate(Type type, TypeModel model)
        {
            if (type == null) throw new ArgumentNullException("type");
#if WINRT || PORTABLE || COREFX
            MethodInfo method = null;
            
#if WINRT || COREFX
            foreach (MethodInfo tmp in type.GetTypeInfo().GetDeclaredMethods("Parse"))
#else
            foreach (MethodInfo tmp in type.GetMethods(BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly))
#endif
            {
                ParameterInfo[] p;
                if (tmp.Name == "Parse" && tmp.IsPublic && tmp.IsStatic && tmp.DeclaringType == type && (p = tmp.GetParameters()) != null && p.Length == 1 && p[0].ParameterType == typeof(string))
                {
                    method = tmp;
                    break;
                }
            }
#else
            MethodInfo method = type.GetMethod("Parse",
                BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly,
                null, new Type[] { model.MapType(typeof(string)) }, null);
#endif
            if (method != null && method.ReturnType == type)
            {
                if (Helpers.IsValueType(type))
                {
                    MethodInfo toString = GetCustomToString(type);
                    if (toString == null || toString.ReturnType != model.MapType(typeof(string))) return null; // need custom ToString, fools
                }
                return new ParseableSerializer(method);
            }
            return null;
        }
Exemplo n.º 6
0
        public static ParseableSerializer TryCreate(Type type, TypeModel model)
        {
            if (type == null) throw new ArgumentNullException("type");
#if WINRT || PORTABLE || COREFX
            MethodInfo method = null;
            
#if WINRT || COREFX
            foreach (MethodInfo tmp in type.GetTypeInfo().GetDeclaredMethods("Parse"))
#else
            foreach (MethodInfo tmp in type.GetMethods(BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly))
#endif
            {
                ParameterInfo[] p;
                if (tmp.Name == "Parse" && tmp.IsPublic && tmp.IsStatic && tmp.DeclaringType == type && (p = tmp.GetParameters()) != null && p.Length == 1 && p[0].ParameterType == typeof(string))
                {
                    method = tmp;
                    break;
                }
            }
#else
            MethodInfo method = type.GetMethod("Parse",
                BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly,
                null, new Type[] { model.MapType(typeof(string)) }, null);
#endif
            if (method != null && method.ReturnType == type)
            {
                if (Helpers.IsValueType(type))
                {
                    MethodInfo toString = GetCustomToString(type);
                    if (toString == null || toString.ReturnType != model.MapType(typeof(string))) return null; // need custom ToString, fools
                }
                return new ParseableSerializer(method);
            }
            return null;
        }
Exemplo n.º 7
0
        private void EmitBeq(Compiler.CompilerContext ctx, Compiler.CodeLabel label, Type type)
        {
            switch (Helpers.GetTypeCode(type))
            {
            case ProtoTypeCode.Boolean:
            case ProtoTypeCode.Byte:
            case ProtoTypeCode.Char:
            case ProtoTypeCode.Double:
            case ProtoTypeCode.Int16:
            case ProtoTypeCode.Int32:
            case ProtoTypeCode.Int64:
            case ProtoTypeCode.SByte:
            case ProtoTypeCode.Single:
            case ProtoTypeCode.UInt16:
            case ProtoTypeCode.UInt32:
            case ProtoTypeCode.UInt64:
                ctx.BranchIfEqual(label, false);
                break;

            default:
                MethodInfo method = type.GetMethod("op_Equality", BindingFlags.Public | BindingFlags.Static,
                                                   null, new Type[] { type, type }, null);
                if (method == null || method.ReturnType != ctx.MapType(typeof(bool)))
                {
                    throw new InvalidOperationException("No suitable equality operator found for default-values of type: " + type.FullName);
                }
                ctx.EmitCall(method);
                ctx.BranchIfTrue(label, false);
                break;
            }
        }
Exemplo n.º 8
0
        private static void EmitConversion(CodeEmitter ilgen, Type converterType, string method)
        {
            CodeEmitterLocal converter = ilgen.UnsafeAllocTempLocal(converterType);

            ilgen.Emit(OpCodes.Ldloca, converter);
            ilgen.Emit(OpCodes.Call, converterType.GetMethod(method));
        }
Exemplo n.º 9
0
        private static MethodInfo GetCustomToString(Type type)

        {
#if WINRT
            foreach (MethodInfo method in type.GetTypeInfo().GetDeclaredMethods("ToString"))

            {
                if (method.IsPublic && !method.IsStatic && method.GetParameters().Length == 0)
                {
                    return(method);
                }
            }

            return(null);
#elif PORTABLE
            MethodInfo method = Helpers.GetInstanceMethod(type, "ToString", Helpers.EmptyTypes);

            if (method == null || !method.IsPublic || method.IsStatic || method.DeclaringType != type)
            {
                return(null);
            }

            return(method);
#else
            return(type.GetMethod("ToString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly,

                                  null, Helpers.EmptyTypes, null));
#endif
        }
Exemplo n.º 10
0
        internal static MethodInfo GetStaticMethod(Type declaringType, string name, Type[] parameterTypes)
        {
#if PORTABLE
            throw new InvalidOperationException("Unable to GetMethod with ParameterTypes in PCL version");
#else
            return(declaringType.GetMethod(name, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, parameterTypes, null));
#endif
        }
Exemplo n.º 11
0
            public override void Emit(CodeGen g, Operator op)
            {
                Type dt = g.TypeMapper.MapType(typeof(Delegate));

                g.IL.Emit(OpCodes.Call, (MethodInfo)dt.GetMethod("Remove", BindingFlags.Public | BindingFlags.Static, null,
                                                                 new Type[] { dt, dt }, null));
                g.IL.Emit(OpCodes.Castclass, ReturnType);
            }
Exemplo n.º 12
0
        internal static MethodInfo GetInstanceMethod(Type declaringType, string name, Type[] types)
        {
            if (types == null)
            {
                types = EmptyTypes;
            }
#if PORTABLE || COREFX
            MethodInfo method = declaringType.GetMethod(name, types);
            if (method != null && method.IsStatic)
            {
                method = null;
            }
            return(method);
#else
            return(declaringType.GetMethod(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,
                                           null, types, null));
#endif
        }
Exemplo n.º 13
0
        internal static MethodInfo GetStaticMethod(Type declaringType, string name, Type[] parameterTypes)
        {
#if PORTABLE
            foreach (MethodInfo method in declaringType.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic))
            {
                if (method.Name == name && IsMatch(method.GetParameters(), parameterTypes)) return method;
            }
            return null;
#else
            return declaringType.GetMethod(name, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, parameterTypes, null);
#endif
        }
Exemplo n.º 14
0
        protected override void EmitWrite(ProtoBuf.Compiler.CompilerContext ctx, ProtoBuf.Compiler.Local valueFrom)
        {
            // int i and T[] arr
            using (Compiler.Local arr = ctx.GetLocalWithValue(arrayType, valueFrom))
                using (Compiler.Local i = new ProtoBuf.Compiler.Local(ctx, ctx.MapType(typeof(int))))
                {
                    bool writePacked       = (options & OPTIONS_WritePacked) != 0;
                    bool fixedLengthPacked = writePacked && CanUsePackedPrefix();

                    using (Compiler.Local token = (writePacked && !fixedLengthPacked) ? new Compiler.Local(ctx, ctx.MapType(typeof(SubItemToken))) : null)
                    {
                        Type mappedWriter = ctx.MapType(typeof(ProtoWriter));
                        if (writePacked)
                        {
                            ctx.LoadValue(fieldNumber);
                            ctx.LoadValue((int)WireType.String);
                            ctx.LoadReaderWriter();
                            ctx.EmitCall(mappedWriter.GetMethod("WriteFieldHeader"));

                            if (fixedLengthPacked)
                            {
                                // write directly - no need for buffering
                                ctx.LoadLength(arr, false);
                                ctx.LoadValue((int)packedWireType);
                                ctx.LoadReaderWriter();
                                ctx.EmitCall(mappedWriter.GetMethod("WritePackedPrefix"));
                            }
                            else
                            {
                                ctx.LoadValue(arr);
                                ctx.LoadReaderWriter();
                                ctx.EmitCall(mappedWriter.GetMethod("StartSubItem"));
                                ctx.StoreValue(token);
                            }

                            ctx.LoadValue(fieldNumber);
                            ctx.LoadReaderWriter();
                            ctx.EmitCall(mappedWriter.GetMethod("SetPackedField"));
                        }
                        EmitWriteArrayLoop(ctx, i, arr);

                        if (writePacked)
                        {
                            if (fixedLengthPacked)
                            {
                                ctx.LoadValue(fieldNumber);
                                ctx.LoadReaderWriter();
                                ctx.EmitCall(mappedWriter.GetMethod("ClearPackedField"));
                            }
                            else
                            {
                                ctx.LoadValue(token);
                                ctx.LoadReaderWriter();
                                ctx.EmitCall(mappedWriter.GetMethod("EndSubItem"));
                            }
                        }
                    }
                }
        }
Exemplo n.º 15
0
        protected override void EmitWrite(ProtoBuf.Compiler.CompilerContext ctx, ProtoBuf.Compiler.Local valueFrom)
        {
            // int i and T[] arr
            using (Compiler.Local arr = ctx.GetLocalWithValue(arrayType, valueFrom))
                using (Compiler.Local i = new ProtoBuf.Compiler.Local(ctx, ctx.MapType(typeof(int))))
                {
                    bool writePacked = (options & OPTIONS_WritePacked) != 0;
                    using (Compiler.Local token = writePacked ? new Compiler.Local(ctx, ctx.MapType(typeof(SubItemToken))) : null)
                    {
                        Type mappedWriter = ctx.MapType(typeof(ProtoWriter));
                        if (writePacked)
                        {
                            ctx.LoadValue(fieldNumber);
                            ctx.LoadValue((int)WireType.String);
                            ctx.LoadReaderWriter();
                            ctx.EmitCall(mappedWriter.GetMethod("WriteFieldHeader"));

                            ctx.LoadValue(arr);
                            ctx.LoadReaderWriter();
                            ctx.EmitCall(mappedWriter.GetMethod("StartSubItem"));
                            ctx.StoreValue(token);

                            ctx.LoadValue(fieldNumber);
                            ctx.LoadReaderWriter();
                            ctx.EmitCall(mappedWriter.GetMethod("SetPackedField"));
                        }
                        EmitWriteArrayLoop(ctx, i, arr);

                        if (writePacked)
                        {
                            ctx.LoadValue(token);
                            ctx.LoadReaderWriter();
                            ctx.EmitCall(mappedWriter.GetMethod("EndSubItem"));
                        }
                    }
                }
        }
Exemplo n.º 16
0
 static MethodInfo GetMethod(string assembly, string typeName, string method)
 {
     foreach (Assembly asm in universe.GetAssemblies())
     {
         if (asm.GetName().Name.Equals(assembly, StringComparison.OrdinalIgnoreCase))
         {
             Type type = asm.GetType(typeName);
             if (type != null)
             {
                 return(type.GetMethod(method, BindingFlags.Public | BindingFlags.Static));
             }
         }
     }
     return(null);
 }
Exemplo n.º 17
0
        bool TryGetImplementedMethod(Type type, string name, Type[] paramTypes, out MethodInfo result)
        {
            var dotName = "." + name;

            foreach (var m in type.GetMethods(_memberFlags))
            {
                if (!m.Name.EndsWith(dotName))
                    continue;

                result = type.GetMethod(m.Name, _memberFlags, _binder, paramTypes, null);
                if (result != null)
                    return true;
            }

            return TryGetInterfaceMethod(type, name, paramTypes, out result);
        }
Exemplo n.º 18
0
        private static MethodInfo GetCustomToString(Type type)
        {
#if WINRT
            foreach (MethodInfo method in type.GetTypeInfo().GetDeclaredMethods("ToString"))
            {
                if (method.IsPublic && !method.IsStatic && method.GetParameters().Length == 0) return method;
            }
            return null;
#elif PORTABLE || COREFX
            MethodInfo method = Helpers.GetInstanceMethod(type, "ToString", Helpers.EmptyTypes);
            if (method == null || !method.IsPublic || method.IsStatic || method.DeclaringType != type) return null;
            return method;
#else

            return type.GetMethod("ToString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly,
                        null, Helpers.EmptyTypes, null);
#endif
        }
        private static MethodInfo GetCustomToString(Type type)
        {
            // ## 苦竹 屏蔽 ##
//#if WINRT
//            foreach (MethodInfo method in type.GetTypeInfo().GetDeclaredMethods("ToString"))
//            {
//                if (method.IsPublic && !method.IsStatic && method.GetParameters().Length == 0) return method;
//            }
//            return null;
//#elif PORTABLE || COREFX
//            MethodInfo method = Helpers.GetInstanceMethod(type, "ToString", Helpers.EmptyTypes);
//            if (method == null || !method.IsPublic || method.IsStatic || method.DeclaringType != type) return null;
//            return method;
//#else

            return(type.GetMethod("ToString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly,
                                  null, Helpers.EmptyTypes, null));
//#endif
        }
        bool AddDateTimeSupport(Type t)
        {
            if (system_datetime != null)
            {
                return(true);
            }

            var corlib = GetMscorlib(t);

            system_datetime = new ProcessedType(t)
            {
                Assembly = corlib,
                // this is tracked because the linker (if enabled) needs to be aware of the requirement
                // but we do not want any code to be generated (it's referenced only from native/glue code)
                IsNativeReference = true,
                Methods           = new List <ProcessedMethod> (),
                Properties        = new List <ProcessedProperty> (),
                Constructors      = new List <ProcessedConstructor> (),
            };
            var ticks = t.GetProperty("Ticks");

            system_datetime.Properties.Add(new ProcessedProperty(ticks, this, system_datetime));

            var kind = t.GetProperty("Kind");

            system_datetime.Properties.Add(new ProcessedProperty(kind, this, system_datetime));

            var dtk          = corlib.Assembly.GetType("System.DateTimeKind");
            var longT        = corlib.Assembly.GetType("System.Int64");
            var ctorLongKind = t.GetConstructor(new Type [] { longT, dtk });

            system_datetime.Constructors.Add(new ProcessedConstructor(ctorLongKind, this, system_datetime));

            var toUniversalTime = t.GetMethod("ToUniversalTime");

            system_datetime.Methods.Add(new ProcessedMethod(toUniversalTime, this, system_datetime));

            AddExtraType(system_datetime);
            return(true);
        }
Exemplo n.º 21
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);
        }
Exemplo n.º 22
0
        private void WriteGetKeyImpl(TypeBuilder type, bool hasInheritance, SerializerPair[] methodPairs, Compiler.CompilerContext.ILVersion ilVersion, string assemblyName, out ILGenerator il, out int knownTypesCategory, out FieldBuilder knownTypes, out Type knownTypesLookupType)
        {

            il = Override(type, "GetKeyImpl");
            Compiler.CompilerContext ctx = new Compiler.CompilerContext(il, false, false, methodPairs, this, ilVersion, assemblyName, MapType(typeof(System.Type), true));
            
            if (types.Count <= KnownTypes_ArrayCutoff)
            {
                knownTypesCategory = KnownTypes_Array;
                knownTypesLookupType = MapType(typeof(System.Type[]), true);
            }
            else
            {
#if NO_GENERICS
                knownTypesLookupType = null;
#else
                knownTypesLookupType = MapType(typeof(System.Collections.Generic.Dictionary<System.Type, int>), false);
#endif
                if (knownTypesLookupType == null)
                {
                    knownTypesLookupType = MapType(typeof(Hashtable), true);
                    knownTypesCategory = KnownTypes_Hashtable;
                }
                else
                {
                    knownTypesCategory = KnownTypes_Dictionary;
                }
            }
            knownTypes = type.DefineField("knownTypes", knownTypesLookupType, FieldAttributes.Private | FieldAttributes.InitOnly | FieldAttributes.Static);

            switch (knownTypesCategory)
            {
                case KnownTypes_Array:
                    {
                        il.Emit(OpCodes.Ldsfld, knownTypes);
                        il.Emit(OpCodes.Ldarg_1);
                        // note that Array.IndexOf is not supported under CF
                        il.EmitCall(OpCodes.Callvirt, MapType(typeof(IList)).GetMethod(
                            "IndexOf", new Type[] { MapType(typeof(object)) }), null);
                        if (hasInheritance)
                        {
                            il.DeclareLocal(MapType(typeof(int))); // loc-0
                            il.Emit(OpCodes.Dup);
                            il.Emit(OpCodes.Stloc_0);

                            BasicList getKeyLabels = new BasicList();
                            int lastKey = -1;
                            for (int i = 0; i < methodPairs.Length; i++)
                            {
                                if (methodPairs[i].MetaKey == methodPairs[i].BaseKey) break;
                                if (lastKey == methodPairs[i].BaseKey)
                                {   // add the last label again
                                    getKeyLabels.Add(getKeyLabels[getKeyLabels.Count - 1]);
                                }
                                else
                                {   // add a new unique label
                                    getKeyLabels.Add(ctx.DefineLabel());
                                    lastKey = methodPairs[i].BaseKey;
                                }
                            }
                            Compiler.CodeLabel[] subtypeLabels = new Compiler.CodeLabel[getKeyLabels.Count];
                            getKeyLabels.CopyTo(subtypeLabels, 0);

                            ctx.Switch(subtypeLabels);
                            il.Emit(OpCodes.Ldloc_0); // not a sub-type; use the original value
                            il.Emit(OpCodes.Ret);

                            lastKey = -1;
                            // now output the different branches per sub-type (not derived type)
                            for (int i = subtypeLabels.Length - 1; i >= 0; i--)
                            {
                                if (lastKey != methodPairs[i].BaseKey)
                                {
                                    lastKey = methodPairs[i].BaseKey;
                                    // find the actual base-index for this base-key (i.e. the index of
                                    // the base-type)
                                    int keyIndex = -1;
                                    for (int j = subtypeLabels.Length; j < methodPairs.Length; j++)
                                    {
                                        if (methodPairs[j].BaseKey == lastKey && methodPairs[j].MetaKey == lastKey)
                                        {
                                            keyIndex = j;
                                            break;
                                        }
                                    }
                                    ctx.MarkLabel(subtypeLabels[i]);
                                    Compiler.CompilerContext.LoadValue(il, keyIndex);
                                    il.Emit(OpCodes.Ret);
                                }
                            }
                        }
                        else
                        {
                            il.Emit(OpCodes.Ret);
                        }
                    }
                    break;
                case KnownTypes_Dictionary:
                    {
                        LocalBuilder result = il.DeclareLocal(MapType(typeof(int)));
                        Label otherwise = il.DefineLabel();
                        il.Emit(OpCodes.Ldsfld, knownTypes);
                        il.Emit(OpCodes.Ldarg_1);
                        il.Emit(OpCodes.Ldloca_S, result);
                        il.EmitCall(OpCodes.Callvirt, knownTypesLookupType.GetMethod("TryGetValue", BindingFlags.Instance | BindingFlags.Public), null);
                        il.Emit(OpCodes.Brfalse_S, otherwise);
                        il.Emit(OpCodes.Ldloc_S, result);
                        il.Emit(OpCodes.Ret);
                        il.MarkLabel(otherwise);
                        il.Emit(OpCodes.Ldc_I4_M1);
                        il.Emit(OpCodes.Ret);
                    }
                    break;
                case KnownTypes_Hashtable:
                    {
                        Label otherwise = il.DefineLabel();
                        il.Emit(OpCodes.Ldsfld, knownTypes);
                        il.Emit(OpCodes.Ldarg_1);
                        il.EmitCall(OpCodes.Callvirt, knownTypesLookupType.GetProperty("Item").GetGetMethod(), null);
                        il.Emit(OpCodes.Dup);
                        il.Emit(OpCodes.Brfalse_S, otherwise);
#if FX11
                        il.Emit(OpCodes.Unbox, MapType(typeof(int)));
                        il.Emit(OpCodes.Ldobj, MapType(typeof(int)));
#else
                        if (ilVersion == Compiler.CompilerContext.ILVersion.Net1)
                        {
                            il.Emit(OpCodes.Unbox, MapType(typeof(int)));
                            il.Emit(OpCodes.Ldobj, MapType(typeof(int)));
                        }
                        else
                        {
                            il.Emit(OpCodes.Unbox_Any, MapType(typeof(int)));
                        }
#endif
                        il.Emit(OpCodes.Ret);
                        il.MarkLabel(otherwise);
                        il.Emit(OpCodes.Pop);
                        il.Emit(OpCodes.Ldc_I4_M1);
                        il.Emit(OpCodes.Ret);
                    }
                    break;
                default:
                    throw new InvalidOperationException();
            }
        }
Exemplo n.º 23
0
 internal void WriteNullCheckedTail(Type type, IProtoSerializer tail, Compiler.Local valueFrom)
 {
     if (type.IsValueType)
     {
         Type underlyingType = null;
     #if !FX11
         underlyingType = Helpers.GetUnderlyingType(type);
     #endif
         if (underlyingType == null)
         { // not a nullable T; can invoke directly
             tail.EmitWrite(this, valueFrom);
         }
         else
         { // nullable T; check HasValue
             using (Compiler.Local valOrNull = GetLocalWithValue(type, valueFrom))
             {
                 LoadAddress(valOrNull, type);
                 LoadValue(type.GetProperty("HasValue"));
                 CodeLabel @end = DefineLabel();
                 BranchIfFalse(@end, false);
                 LoadAddress(valOrNull, type);
                 EmitCall(type.GetMethod("GetValueOrDefault", Helpers.EmptyTypes));
                 tail.EmitWrite(this, null);
                 MarkLabel(@end);
             }
         }
     }
     else
     { // ref-type; do a null-check
         LoadValue(valueFrom);
         CopyValue();
         CodeLabel hasVal = DefineLabel(), @end = DefineLabel();
         BranchIfTrue(hasVal, true);
         DiscardValue();
         Branch(@end, false);
         MarkLabel(hasVal);
         tail.EmitWrite(this, null);
         MarkLabel(@end);
     }
 }
Exemplo n.º 24
0
        private void DoIt()
        {
            AssemblyName aname = new AssemblyName();

            aname.Name = Path.GetFileNameWithoutExtension(outFile);
            if (culture != null)
            {
                aname.CultureInfo = new CultureInfo(culture);
            }

            string fileName = Path.GetFileName(outFile);

            AssemblyBuilder ab;

            /*
             * Emit Manifest
             * */

            if (isTemplateFile)
            {
                aname = ReadCustomAttributesFromTemplateFile(templateFile, aname);
            }

            if (!String.IsNullOrEmpty(title))
            {
                AddCattr(typeof(System.Reflection.AssemblyTitleAttribute), title);
            }
            if (!String.IsNullOrEmpty(description))
            {
                AddCattr(typeof(System.Reflection.AssemblyDescriptionAttribute), description);
            }
            if (!String.IsNullOrEmpty(company))
            {
                AddCattr(typeof(System.Reflection.AssemblyCompanyAttribute), company);
            }
            if (!String.IsNullOrEmpty(product))
            {
                AddCattr(typeof(System.Reflection.AssemblyProductAttribute), product);
            }
            if (!String.IsNullOrEmpty(copyright))
            {
                AddCattr(typeof(System.Reflection.AssemblyCopyrightAttribute), copyright);
            }
            if (!String.IsNullOrEmpty(trademark))
            {
                AddCattr(typeof(System.Reflection.AssemblyTrademarkAttribute), trademark);
            }

            SetKeyPair(aname);

            if (fileName != outFile)
            {
                ab = universe.DefineDynamicAssembly(aname, AssemblyBuilderAccess.Save, Path.GetDirectoryName(outFile));
            }
            else
            {
                ab = universe.DefineDynamicAssembly(aname, AssemblyBuilderAccess.Save);
            }

            foreach (CustomAttributeBuilder cb in cattrs)
            {
                ab.SetCustomAttribute(cb);
            }

            /*
             * Emit modules
             */

            foreach (ModuleInfo mod in inputFiles)
            {
                if (mod.target != null)
                {
                    File.Copy(mod.fileName, mod.target, true);
                    mod.fileName = mod.target;
                }

                bool isAssembly = false;
                try {
                    AssemblyName.GetAssemblyName(mod.fileName);
                    isAssembly = true;
                }
                catch (Exception) {
                }

                if (isAssembly)
                {
                    ReportWarning(1020, "Ignoring included assembly '" + mod.fileName + "'");
                }
                else
                {
                    ab.__AddModule(universe.OpenRawModule(mod.fileName));
                }
            }

            /*
             * Set entry point
             */

            if (entryPoint != null)
            {
                string mainClass  = entryPoint.Substring(0, entryPoint.LastIndexOf('.'));
                string mainMethod = entryPoint.Substring(entryPoint.LastIndexOf('.') + 1);

                MethodInfo mainMethodInfo = null;

                try {
                    IKVM.Reflection.Type mainType = ab.GetType(mainClass);
                    if (mainType != null)
                    {
                        mainMethodInfo = mainType.GetMethod(mainMethod);
                    }
                }
                catch (Exception ex) {
                    Console.WriteLine(ex);
                }
                if (mainMethodInfo != null)
                {
                    ab.SetEntryPoint(mainMethodInfo);
                }
                else
                {
                    Report(1037, "Unable to find the entry point method '" + entryPoint + "'");
                }
            }

            /*
             * Emit resources
             */

            ab.DefineVersionInfoResource();

            if (win32IconFile != null)
            {
                try {
                    ab.__DefineIconResource(File.ReadAllBytes(win32IconFile));
                }
                catch (Exception ex) {
                    Report(1031, "Error reading icon '" + win32IconFile + "' --" + ex);
                }
            }

            if (win32ResFile != null)
            {
                try {
                    ab.DefineUnmanagedResource(win32ResFile);
                }
                catch (Exception ex) {
                    Report(1019, "Metadata failure creating assembly -- " + ex);
                }
            }

            ModuleBuilder mainModule = null;

            foreach (ResourceInfo res in resources)
            {
                if (res.name == null)
                {
                    res.name = Path.GetFileName(res.fileName);
                }

                foreach (ResourceInfo res2 in resources)
                {
                    if ((res != res2) && (res.name == res2.name))
                    {
                        Report(1046, String.Format("Resource identifier '{0}' has already been used in this assembly", res.name));
                    }
                }

                if (res.isEmbedded)
                {
                    if (mainModule == null)
                    {
                        mainModule = ab.DefineDynamicModule(fileName, fileName, false);
                    }

                    Stream stream = new MemoryStream(File.ReadAllBytes(res.fileName));

                    mainModule.DefineManifestResource(res.name, stream, res.isPrivate ? ResourceAttributes.Private : ResourceAttributes.Public);
                }
                else
                {
                    if (res.target != null)
                    {
                        File.Copy(res.fileName, res.target, true);
                        res.fileName = res.target;
                    }

                    // AddResourceFile must receive a file name and not a path.
                    // Drop directory and give warning if we have a path.
                    var resourceFileName = Path.GetFileName(res.fileName);
                    if (Path.GetDirectoryName(res.fileName) != null || Path.IsPathRooted(res.fileName))
                    {
                        ReportWarning(99999,
                                      String.Format("Path '{0}' in the resource name is not supported. Using just file name '{1}'",
                                                    res.fileName,
                                                    resourceFileName));
                    }

                    ab.AddResourceFile(res.name, resourceFileName,
                                       res.isPrivate ? ResourceAttributes.Private : ResourceAttributes.Public);
                }
            }

            PortableExecutableKinds pekind = PortableExecutableKinds.ILOnly;
            ImageFileMachine        machine;

            switch (platform)
            {
            case Platform.X86:
                pekind |= PortableExecutableKinds.Required32Bit;
                machine = ImageFileMachine.I386;
                break;

            case Platform.X64:
                pekind |= PortableExecutableKinds.PE32Plus;
                machine = ImageFileMachine.AMD64;
                break;

            case Platform.IA64:
                machine = ImageFileMachine.IA64;
                break;

            case Platform.AnyCPU32Preferred:
                pekind |= PortableExecutableKinds.Preferred32Bit;
                machine = ImageFileMachine.I386;
                break;

            case Platform.Arm:
                machine = ImageFileMachine.ARM;
                break;

            case Platform.AnyCPU:
            default:
                machine = ImageFileMachine.I386;
                break;
            }

            try {
                ab.Save(fileName, pekind, machine);
            }
            catch (Exception ex) {
                Report(1019, "Metadata failure creating assembly -- " + ex);
            }
        }
Exemplo n.º 25
0
 private void WriteConstructors(TypeBuilder type, ref int index, SerializerPair[] methodPairs, ref ILGenerator il, int knownTypesCategory, FieldBuilder knownTypes, Type knownTypesLookupType, Compiler.CompilerContext ctx)
 {
     type.DefineDefaultConstructor(MethodAttributes.Public);
     il = type.DefineTypeInitializer().GetILGenerator();
     switch (knownTypesCategory)
     {
         case KnownTypes_Array:
             {
                 Compiler.CompilerContext.LoadValue(il, types.Count);
                 il.Emit(OpCodes.Newarr, ctx.MapType(typeof(System.Type)));
                 index = 0;
                 foreach (SerializerPair pair in methodPairs)
                 {
                     il.Emit(OpCodes.Dup);
                     Compiler.CompilerContext.LoadValue(il, index);
                     il.Emit(OpCodes.Ldtoken, pair.Type.Type);
                     il.EmitCall(OpCodes.Call, ctx.MapType(typeof(System.Type)).GetMethod("GetTypeFromHandle"), null);
                     il.Emit(OpCodes.Stelem_Ref);
                     index++;
                 }
                 il.Emit(OpCodes.Stsfld, knownTypes);
                 il.Emit(OpCodes.Ret);
             }
             break;
         case KnownTypes_Dictionary:
             {
                 Compiler.CompilerContext.LoadValue(il, types.Count);
                 //LocalBuilder loc = il.DeclareLocal(knownTypesLookupType);
                 il.Emit(OpCodes.Newobj, knownTypesLookupType.GetConstructor(new Type[] { MapType(typeof(int)) }));
                 il.Emit(OpCodes.Stsfld, knownTypes);
                 int typeIndex = 0;
                 foreach (SerializerPair pair in methodPairs)
                 {
                     il.Emit(OpCodes.Ldsfld, knownTypes);
                     il.Emit(OpCodes.Ldtoken, pair.Type.Type);
                     il.EmitCall(OpCodes.Call, ctx.MapType(typeof(System.Type)).GetMethod("GetTypeFromHandle"), null);
                     int keyIndex = typeIndex++, lastKey = pair.BaseKey;
                     if (lastKey != pair.MetaKey) // not a base-type; need to give the index of the base-type
                     {
                         keyIndex = -1; // assume epic fail
                         for (int j = 0; j < methodPairs.Length; j++)
                         {
                             if (methodPairs[j].BaseKey == lastKey && methodPairs[j].MetaKey == lastKey)
                             {
                                 keyIndex = j;
                                 break;
                             }
                         }
                     }
                     Compiler.CompilerContext.LoadValue(il, keyIndex);
                     il.EmitCall(OpCodes.Callvirt, knownTypesLookupType.GetMethod("Add", new Type[] { MapType(typeof(System.Type)), MapType(typeof(int)) }), null);
                 }
                 il.Emit(OpCodes.Ret);
             }
             break;
         case KnownTypes_Hashtable:
             {
                 Compiler.CompilerContext.LoadValue(il, types.Count);
                 il.Emit(OpCodes.Newobj, knownTypesLookupType.GetConstructor(new Type[] { MapType(typeof(int)) }));
                 il.Emit(OpCodes.Stsfld, knownTypes);
                 int typeIndex = 0;
                 foreach (SerializerPair pair in methodPairs)
                 {
                     il.Emit(OpCodes.Ldsfld, knownTypes);
                     il.Emit(OpCodes.Ldtoken, pair.Type.Type);
                     il.EmitCall(OpCodes.Call, ctx.MapType(typeof(System.Type)).GetMethod("GetTypeFromHandle"), null);
                     int keyIndex = typeIndex++, lastKey = pair.BaseKey;
                     if (lastKey != pair.MetaKey) // not a base-type; need to give the index of the base-type
                     {
                         keyIndex = -1; // assume epic fail
                         for (int j = 0; j < methodPairs.Length; j++)
                         {
                             if (methodPairs[j].BaseKey == lastKey && methodPairs[j].MetaKey == lastKey)
                             {
                                 keyIndex = j;
                                 break;
                             }
                         }
                     }
                     Compiler.CompilerContext.LoadValue(il, keyIndex);
                     il.Emit(OpCodes.Box, MapType(typeof(int)));
                     il.EmitCall(OpCodes.Callvirt, knownTypesLookupType.GetMethod("Add", new Type[] { MapType(typeof(object)), MapType(typeof(object)) }), null);
                 }
                 il.Emit(OpCodes.Ret);
             }
             break;
         default:
             throw new InvalidOperationException();
     }
 }
Exemplo n.º 26
0
        internal static MethodInfo GetInstanceMethod(Type declaringType, string name, Type[] types)
        {
            if(types == null) types = EmptyTypes;
#if PORTABLE
            MethodInfo method = declaringType.GetMethod(name, types);
            if (method != null && method.IsStatic) method = null;
            return method;
#else
            return declaringType.GetMethod(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,
                null, types, null);
#endif
        }
Exemplo n.º 27
0
 internal static MethodInfo GetStaticMethod(Type declaringType, string name)
 {
     return(declaringType.GetMethod(name, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic));
 }
Exemplo n.º 28
0
        private static void LoadAll()
        {
            // Types
            function  = Load(typeof(TotemFunction));
            value     = Load(typeof(TotemValue));
            tstring   = Load(typeof(TotemString));
            arguments = Load(typeof(TotemArguments));
            parameter = Load(typeof(TotemParameter));
            @bool     = Load(typeof(TotemBool));
            map       = Load(typeof(TotemMap));
            array     = Load(typeof(TotemArray));
            scope     = Load(typeof(TotemFunction.ScopeWrapper));

            arr_parameters = Load(typeof(TotemParameter[]));
            sys_bool       = Load(typeof(bool));

            // Methods
            value_val = Load(typeof(TotemValue)).GetProperty("ByTotemValue").GetGetMethod();

            function_run       = Load(typeof(TotemFunction)).GetMethod("TotemRun", r.BindingFlags.NonPublic | r.BindingFlags.Instance);
            execute            = Load(typeof(TotemValue)).GetMethod("Execute");
            function_ctor      = Load(typeof(TotemFunction)).GetConstructor(r.BindingFlags.NonPublic | r.BindingFlags.Instance, null, new IKType[] { Load(typeof(TotemScope)), Load(typeof(string)), Load(typeof(TotemParameter[])) }, null);
            function_local_set = Load(typeof(TotemFunction)).GetMethod("LocalSet", r.BindingFlags.NonPublic | r.BindingFlags.Instance);
            function_local_get = Load(typeof(TotemFunction)).GetMethod("LocalGet", r.BindingFlags.NonPublic | r.BindingFlags.Instance);
            function_local_dec = Load(typeof(TotemFunction)).GetMethod("LocalDec", r.BindingFlags.NonPublic | r.BindingFlags.Instance);
            function_env       = Load(typeof(TotemFunction)).GetProperty("Scope", r.BindingFlags.NonPublic | r.BindingFlags.Instance).GetGetMethod(true);

            arguments_ctor = Load(typeof(TotemArguments)).GetConstructor(IKType.EmptyTypes);
            arguments_add  = Load(typeof(TotemArguments)).GetMethod("Add", r.BindingFlags.Public | r.BindingFlags.Instance | r.BindingFlags.DeclaredOnly);

            number_ctor_long = Load(typeof(TotemNumber)).GetConstructor(new IKType[] { Load(typeof(long)) });

            string_ctor = Load(typeof(TotemString)).GetConstructor(new IKType[] { Load(typeof(string)) });

            parameter_ctor = Load(typeof(TotemParameter)).GetConstructor(new IKType[] { Load(typeof(string)), Load(typeof(TotemValue)) });

            undefined = Load(typeof(TotemValue)).GetProperty("Undefined").GetGetMethod();
            @null     = Load(typeof(TotemValue)).GetProperty("Null").GetGetMethod();

            value_add        = Load(typeof(TotemValue)).GetMethod("op_Addition", r.BindingFlags.Static | r.BindingFlags.Public);
            value_sub        = Load(typeof(TotemValue)).GetMethod("op_Subtraction", r.BindingFlags.Static | r.BindingFlags.Public);
            value_mul        = Load(typeof(TotemValue)).GetMethod("op_Multiply", r.BindingFlags.Static | r.BindingFlags.Public);
            value_div        = Load(typeof(TotemValue)).GetMethod("op_Division", r.BindingFlags.Static | r.BindingFlags.Public);
            value_eq         = Load(typeof(TotemValue)).GetMethod("op_Equality", r.BindingFlags.Static | r.BindingFlags.Public);
            value_neq        = Load(typeof(TotemValue)).GetMethod("op_Inequality", r.BindingFlags.Static | r.BindingFlags.Public);
            value_lt         = Load(typeof(TotemValue)).GetMethod("op_LessThan", r.BindingFlags.Static | r.BindingFlags.Public);
            value_gt         = Load(typeof(TotemValue)).GetMethod("op_GreaterThan", r.BindingFlags.Static | r.BindingFlags.Public);
            value_lte        = Load(typeof(TotemValue)).GetMethod("op_LessThanOrEqual", r.BindingFlags.Static | r.BindingFlags.Public);
            value_gte        = Load(typeof(TotemValue)).GetMethod("op_GreaterThanOrEqual", r.BindingFlags.Static | r.BindingFlags.Public);
            value_incr       = Load(typeof(TotemValue)).GetMethod("op_Increment", r.BindingFlags.Static | r.BindingFlags.Public);
            value_decr       = Load(typeof(TotemValue)).GetMethod("op_Decrement", r.BindingFlags.Static | r.BindingFlags.Public);
            value_istrue     = Load(typeof(TotemValue)).GetMethod("op_Explicit", r.BindingFlags.Static | r.BindingFlags.Public, null, r.CallingConventions.Standard, new IKType[] { Load(typeof(TotemValue)) }, null);
            value_lookup_get = Load(typeof(TotemValue)).GetProperty("Item", value, new IKType[] { value }).GetGetMethod();
            value_lookup_set = Load(typeof(TotemValue)).GetProperty("Item", value, new IKType[] { value }).GetSetMethod();

            scope_ctor = Load(typeof(TotemFunction.ScopeWrapper)).GetConstructor(new IKType[] { Load(typeof(TotemFunction)) });

            dispose = Load(typeof(IDisposable)).GetMethod("Dispose");

            get_prop = Load(typeof(TotemValue)).GetMethod("GetProp");
            set_prop = Load(typeof(TotemValue)).GetMethod("SetProp");

            bool_ctor = Load(typeof(TotemBool)).GetConstructor(new IKType[] { Load(typeof(bool)) });

            map_ctor = map.GetConstructor(IKType.EmptyTypes);
            map_add  = map.GetMethod("AddItem");

            array_ctor = array.GetConstructor(IKType.EmptyTypes);
            array_add  = array.GetMethod("AddItem");
        }
Exemplo n.º 29
0
 internal static MethodInfo GetStaticMethod(Type declaringType, string name, Type[] parameterTypes)
 {
     return(declaringType.GetMethod(name, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, parameterTypes, null));
 }
        private void WriteConstructors(TypeBuilder type, ref int index, SerializerPair[] methodPairs, ref ILGenerator il, int knownTypesCategory, FieldBuilder knownTypes, Type knownTypesLookupType, Compiler.CompilerContext ctx)
        {
            type.DefineDefaultConstructor(MethodAttributes.Public);
            il = type.DefineTypeInitializer().GetILGenerator();
            switch (knownTypesCategory)
            {
            case KnownTypes_Array:
            {
                Compiler.CompilerContext.LoadValue(il, _types.Count);
                il.Emit(OpCodes.Newarr, ctx.MapType(typeof(System.Type)));
                index = 0;
                foreach (SerializerPair pair in methodPairs)
                {
                    il.Emit(OpCodes.Dup);
                    Compiler.CompilerContext.LoadValue(il, index);
                    il.Emit(OpCodes.Ldtoken, pair.Type.Type);
                    il.EmitCall(OpCodes.Call, ctx.MapType(typeof(System.Type)).GetMethod("GetTypeFromHandle"), null);
                    il.Emit(OpCodes.Stelem_Ref);
                    index++;
                }
                il.Emit(OpCodes.Stsfld, knownTypes);
                il.Emit(OpCodes.Ret);
            }
            break;

            case KnownTypes_Dictionary:
            {
                Compiler.CompilerContext.LoadValue(il, _types.Count);
                //LocalBuilder loc = il.DeclareLocal(knownTypesLookupType);
                il.Emit(OpCodes.Newobj, knownTypesLookupType.GetConstructor(new Type[] { MapType(typeof(int)) }));
                il.Emit(OpCodes.Stsfld, knownTypes);
                int typeIndex = 0;
                foreach (SerializerPair pair in methodPairs)
                {
                    il.Emit(OpCodes.Ldsfld, knownTypes);
                    il.Emit(OpCodes.Ldtoken, pair.Type.Type);
                    il.EmitCall(OpCodes.Call, ctx.MapType(typeof(System.Type)).GetMethod("GetTypeFromHandle"), null);
                    int keyIndex = typeIndex++, lastKey = pair.BaseKey;
                    if (lastKey != pair.MetaKey) // not a base-type; need to give the index of the base-type
                    {
                        keyIndex = -1;           // assume epic fail
                        for (int j = 0; j < methodPairs.Length; j++)
                        {
                            if (methodPairs[j].BaseKey == lastKey && methodPairs[j].MetaKey == lastKey)
                            {
                                keyIndex = j;
                                break;
                            }
                        }
                    }
                    Compiler.CompilerContext.LoadValue(il, keyIndex);
                    il.EmitCall(OpCodes.Callvirt, knownTypesLookupType.GetMethod("Add", new Type[] { MapType(typeof(System.Type)), MapType(typeof(int)) }), null);
                }
                il.Emit(OpCodes.Ret);
            }
            break;

            case KnownTypes_Hashtable:
            {
                Compiler.CompilerContext.LoadValue(il, _types.Count);
                il.Emit(OpCodes.Newobj, knownTypesLookupType.GetConstructor(new Type[] { MapType(typeof(int)) }));
                il.Emit(OpCodes.Stsfld, knownTypes);
                int typeIndex = 0;
                foreach (SerializerPair pair in methodPairs)
                {
                    il.Emit(OpCodes.Ldsfld, knownTypes);
                    il.Emit(OpCodes.Ldtoken, pair.Type.Type);
                    il.EmitCall(OpCodes.Call, ctx.MapType(typeof(System.Type)).GetMethod("GetTypeFromHandle"), null);
                    int keyIndex = typeIndex++, lastKey = pair.BaseKey;
                    if (lastKey != pair.MetaKey) // not a base-type; need to give the index of the base-type
                    {
                        keyIndex = -1;           // assume epic fail
                        for (int j = 0; j < methodPairs.Length; j++)
                        {
                            if (methodPairs[j].BaseKey == lastKey && methodPairs[j].MetaKey == lastKey)
                            {
                                keyIndex = j;
                                break;
                            }
                        }
                    }
                    Compiler.CompilerContext.LoadValue(il, keyIndex);
                    il.Emit(OpCodes.Box, MapType(typeof(int)));
                    il.EmitCall(OpCodes.Callvirt, knownTypesLookupType.GetMethod("Add", new Type[] { MapType(typeof(object)), MapType(typeof(object)) }), null);
                }
                il.Emit(OpCodes.Ret);
            }
            break;

            default:
                throw new InvalidOperationException();
            }
        }
        private void WriteGetKeyImpl(TypeBuilder type, bool hasInheritance, SerializerPair[] methodPairs, Compiler.CompilerContext.ILVersion ilVersion, string assemblyName, out ILGenerator il, out int knownTypesCategory, out FieldBuilder knownTypes, out Type knownTypesLookupType)
        {
            var genInfo = Override(type, "GetKeyImpl");

            il = genInfo.GetILGenerator();
            Compiler.CompilerContext ctx = new Compiler.CompilerContext(genInfo, false, false, methodPairs, this, ilVersion, assemblyName, MapType(typeof(System.Type), true));

            if (_types.Count <= KnownTypes_ArrayCutoff)
            {
                knownTypesCategory   = KnownTypes_Array;
                knownTypesLookupType = MapType(typeof(System.Type[]), true);
            }
            else
            {
#if NO_GENERICS
                knownTypesLookupType = null;
#else
                knownTypesLookupType = MapType(typeof(System.Collections.Generic.Dictionary <System.Type, int>), false);
#endif
                if (knownTypesLookupType == null)
                {
                    knownTypesLookupType = MapType(typeof(Hashtable), true);
                    knownTypesCategory   = KnownTypes_Hashtable;
                }
                else
                {
                    knownTypesCategory = KnownTypes_Dictionary;
                }
            }
            knownTypes = type.DefineField("knownTypes", knownTypesLookupType, FieldAttributes.Private | FieldAttributes.InitOnly | FieldAttributes.Static);

            switch (knownTypesCategory)
            {
            case KnownTypes_Array:
            {
                il.Emit(OpCodes.Ldsfld, knownTypes);
                il.Emit(OpCodes.Ldarg_1);
                // note that Array.IndexOf is not supported under CF
                il.EmitCall(OpCodes.Callvirt, MapType(typeof(IList)).GetMethod(
                                "IndexOf", new Type[] { MapType(typeof(object)) }), null);
                if (hasInheritance)
                {
                    il.DeclareLocal(MapType(typeof(int)));         // loc-0
                    il.Emit(OpCodes.Dup);
                    il.Emit(OpCodes.Stloc_0);

                    BasicList getKeyLabels = new BasicList();
                    int       lastKey      = -1;
                    for (int i = 0; i < methodPairs.Length; i++)
                    {
                        if (methodPairs[i].MetaKey == methodPairs[i].BaseKey)
                        {
                            break;
                        }
                        if (lastKey == methodPairs[i].BaseKey)
                        {           // add the last label again
                            getKeyLabels.Add(getKeyLabels[getKeyLabels.Count - 1]);
                        }
                        else
                        {           // add a new unique label
                            getKeyLabels.Add(ctx.DefineLabel());
                            lastKey = methodPairs[i].BaseKey;
                        }
                    }
                    Compiler.CodeLabel[] subtypeLabels = new Compiler.CodeLabel[getKeyLabels.Count];
                    getKeyLabels.CopyTo(subtypeLabels, 0);

                    ctx.Switch(subtypeLabels);
                    il.Emit(OpCodes.Ldloc_0);         // not a sub-type; use the original value
                    il.Emit(OpCodes.Ret);

                    lastKey = -1;
                    // now output the different branches per sub-type (not derived type)
                    for (int i = subtypeLabels.Length - 1; i >= 0; i--)
                    {
                        if (lastKey != methodPairs[i].BaseKey)
                        {
                            lastKey = methodPairs[i].BaseKey;
                            // find the actual base-index for this base-key (i.e. the index of
                            // the base-type)
                            int keyIndex = -1;
                            for (int j = subtypeLabels.Length; j < methodPairs.Length; j++)
                            {
                                if (methodPairs[j].BaseKey == lastKey && methodPairs[j].MetaKey == lastKey)
                                {
                                    keyIndex = j;
                                    break;
                                }
                            }
                            ctx.MarkLabel(subtypeLabels[i]);
                            Compiler.CompilerContext.LoadValue(il, keyIndex);
                            il.Emit(OpCodes.Ret);
                        }
                    }
                }
                else
                {
                    il.Emit(OpCodes.Ret);
                }
            }
            break;

            case KnownTypes_Dictionary:
            {
                LocalBuilder result    = il.DeclareLocal(MapType(typeof(int)));
                Label        otherwise = il.DefineLabel();
                il.Emit(OpCodes.Ldsfld, knownTypes);
                il.Emit(OpCodes.Ldarg_1);
                il.Emit(OpCodes.Ldloca_S, result);
                il.EmitCall(OpCodes.Callvirt, knownTypesLookupType.GetMethod("TryGetValue", BindingFlags.Instance | BindingFlags.Public), null);
                il.Emit(OpCodes.Brfalse_S, otherwise);
                il.Emit(OpCodes.Ldloc_S, result);
                il.Emit(OpCodes.Ret);
                il.MarkLabel(otherwise);
                il.Emit(OpCodes.Ldc_I4_M1);
                il.Emit(OpCodes.Ret);
            }
            break;

            case KnownTypes_Hashtable:
            {
                Label otherwise = il.DefineLabel();
                il.Emit(OpCodes.Ldsfld, knownTypes);
                il.Emit(OpCodes.Ldarg_1);
                il.EmitCall(OpCodes.Callvirt, knownTypesLookupType.GetProperty("Item").GetGetMethod(), null);
                il.Emit(OpCodes.Dup);
                il.Emit(OpCodes.Brfalse_S, otherwise);
#if FX11
                il.Emit(OpCodes.Unbox, MapType(typeof(int)));
                il.Emit(OpCodes.Ldobj, MapType(typeof(int)));
#else
                if (ilVersion == Compiler.CompilerContext.ILVersion.Net1)
                {
                    il.Emit(OpCodes.Unbox, MapType(typeof(int)));
                    il.Emit(OpCodes.Ldobj, MapType(typeof(int)));
                }
                else
                {
                    il.Emit(OpCodes.Unbox_Any, MapType(typeof(int)));
                }
#endif
                il.Emit(OpCodes.Ret);
                il.MarkLabel(otherwise);
                il.Emit(OpCodes.Pop);
                il.Emit(OpCodes.Ldc_I4_M1);
                il.Emit(OpCodes.Ret);
            }
            break;

            default:
                throw new InvalidOperationException();
            }
        }
Exemplo n.º 32
0
 internal static MethodInfo GetStaticMethod(Type declaringType, string name, Type[] parameterTypes)
 {
    return declaringType.GetMethod(name, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, parameterTypes, null);
 }
Exemplo n.º 33
0
        internal void ReadNullCheckedTail(Type type, IProtoSerializer tail, Compiler.Local valueFrom)
        {
            #if !FX11
            Type underlyingType;

            if (type.IsValueType && (underlyingType = Helpers.GetUnderlyingType(type)) != null)
            {
                if(tail.RequiresOldValue)
                {
                    // we expect the input value to be in valueFrom; need to unpack it from T?
                    using (Local loc = GetLocalWithValue(type, valueFrom))
                    {
                        LoadAddress(loc, type);
                        EmitCall(type.GetMethod("GetValueOrDefault", Helpers.EmptyTypes));
                    }
                }
                else
                {
                    Helpers.DebugAssert(valueFrom == null); // not expecting a valueFrom in this case
                }
                tail.EmitRead(this, null); // either unwrapped on the stack or not provided
                if (tail.ReturnsValue)
                {
                    // now re-wrap the value
                    EmitCtor(type, underlyingType);
                }
                return;
            }
            #endif
            // either a ref-type of a non-nullable struct; treat "as is", even if null
            // (the type-serializer will handle the null case; it needs to allow null
            // inputs to perform the correct type of subclass creation)
            tail.EmitRead(this, valueFrom);
        }
Exemplo n.º 34
0
			internal DelegateInnerClassTypeWrapper(string name, Type delegateType)
				: base(Modifiers.Public | Modifiers.Interface | Modifiers.Abstract, name, null)
			{
#if STATIC_COMPILER || STUB_GENERATOR
				this.fakeType = FakeTypes.GetDelegateType(delegateType);
#elif !FIRST_PASS
				this.fakeType = typeof([email protected]<>).MakeGenericType(delegateType);
#endif
				MethodInfo invoke = delegateType.GetMethod("Invoke");
				ParameterInfo[] parameters = invoke.GetParameters();
				TypeWrapper[] argTypeWrappers = new TypeWrapper[parameters.Length];
				System.Text.StringBuilder sb = new System.Text.StringBuilder("(");
				MemberFlags flags = MemberFlags.None;
				for (int i = 0; i < parameters.Length; i++)
				{
					Type parameterType = parameters[i].ParameterType;
					if (parameterType.IsByRef)
					{
						flags |= MemberFlags.DelegateInvokeWithByRefParameter;
						parameterType = ArrayTypeWrapper.MakeArrayType(parameterType.GetElementType(), 1);
					}
					argTypeWrappers[i] = ClassLoaderWrapper.GetWrapperFromType(parameterType);
					sb.Append(argTypeWrappers[i].SigName);
				}
				TypeWrapper returnType = ClassLoaderWrapper.GetWrapperFromType(invoke.ReturnType);
				sb.Append(")").Append(returnType.SigName);
				MethodWrapper invokeMethod = new DynamicOnlyMethodWrapper(this, "Invoke", sb.ToString(), returnType, argTypeWrappers, flags);
				SetMethods(new MethodWrapper[] { invokeMethod });
				SetFields(FieldWrapper.EmptyArray);
			}
Exemplo n.º 35
0
 internal void EmitBasicRead(Type helperType, string methodName, Type expectedType)
 {
     MethodInfo method = helperType.GetMethod(
         methodName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);
     if (method == null || method.ReturnType != expectedType
         || method.GetParameters().Length != 1) throw new ArgumentException("methodName");
     LoadReaderWriter();
     EmitCall(method);
 }
Exemplo n.º 36
0
 internal static MethodInfo GetStaticMethod(Type declaringType, string name)
 {
     return declaringType.GetMethod(name, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
 }
Exemplo n.º 37
0
 internal void EmitWrite(Type helperType, string methodName, Compiler.Local valueFrom)
 {
     if (Helpers.IsNullOrEmpty(methodName)) throw new ArgumentNullException("methodName");
     MethodInfo method = helperType.GetMethod(
         methodName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);
     if (method == null || method.ReturnType != MapType(typeof(void))) throw new ArgumentException("methodName");
     LoadValue(valueFrom);
     LoadReaderWriter();
     EmitCall(method);
 }
Exemplo n.º 38
0
		internal static string GetDelegateInvokeStubName(Type delegateType)
		{
			MethodInfo delegateInvoke = delegateType.GetMethod("Invoke");
			ParameterInfo[] parameters = delegateInvoke.GetParameters();
			string name = null;
			for (int i = 0; i < parameters.Length; i++)
			{
				if (parameters[i].ParameterType.IsByRef)
				{
					name = (name ?? "<Invoke>") + "_" + i;
				}
			}
			return name ?? "Invoke";
		}
Exemplo n.º 39
0
        protected override void EmitRead(ProtoBuf.Compiler.CompilerContext ctx, ProtoBuf.Compiler.Local valueFrom)
        {
            Type listType;

#if NO_GENERICS
            listType = typeof(BasicList);
#else
            listType = ctx.MapType(typeof(System.Collections.Generic.List <>)).MakeGenericType(itemType);
#endif
            Type expected = ExpectedType;
            using (Compiler.Local oldArr = AppendToCollection ? ctx.GetLocalWithValue(expected, valueFrom) : null)
                using (Compiler.Local newArr = new Compiler.Local(ctx, expected))
                    using (Compiler.Local list = new Compiler.Local(ctx, listType))
                    {
                        ctx.EmitCtor(listType);
                        ctx.StoreValue(list);
                        ListDecorator.EmitReadList(ctx, list, Tail, listType.GetMethod("Add"), packedWireType, false);

                        // leave this "using" here, as it can share the "FieldNumber" local with EmitReadList
                        using (Compiler.Local oldLen = AppendToCollection ? new ProtoBuf.Compiler.Local(ctx, ctx.MapType(typeof(int))) : null) {
                            Type[] copyToArrayInt32Args = new Type[] { ctx.MapType(typeof(Array)), ctx.MapType(typeof(int)) };

                            if (AppendToCollection)
                            {
                                ctx.LoadLength(oldArr, true);
                                ctx.CopyValue();
                                ctx.StoreValue(oldLen);

                                ctx.LoadAddress(list, listType);
                                ctx.LoadValue(listType.GetProperty("Count"));
                                ctx.Add();
                                ctx.CreateArray(itemType, null); // length is on the stack
                                ctx.StoreValue(newArr);

                                ctx.LoadValue(oldLen);
                                Compiler.CodeLabel nothingToCopy = ctx.DefineLabel();
                                ctx.BranchIfFalse(nothingToCopy, true);
                                ctx.LoadValue(oldArr);
                                ctx.LoadValue(newArr);
                                ctx.LoadValue(0); // index in target

                                ctx.EmitCall(expected.GetMethod("CopyTo", copyToArrayInt32Args));
                                ctx.MarkLabel(nothingToCopy);

                                ctx.LoadValue(list);
                                ctx.LoadValue(newArr);
                                ctx.LoadValue(oldLen);
                            }
                            else
                            {
                                ctx.LoadAddress(list, listType);
                                ctx.LoadValue(listType.GetProperty("Count"));
                                ctx.CreateArray(itemType, null);
                                ctx.StoreValue(newArr);

                                ctx.LoadAddress(list, listType);
                                ctx.LoadValue(newArr);
                                ctx.LoadValue(0);
                            }

                            copyToArrayInt32Args[0] = expected; // // prefer: CopyTo(T[], int)
                            MethodInfo copyTo = listType.GetMethod("CopyTo", copyToArrayInt32Args);
                            if (copyTo == null)
                            { // fallback: CopyTo(Array, int)
                                copyToArrayInt32Args[1] = ctx.MapType(typeof(Array));
                                copyTo = listType.GetMethod("CopyTo", copyToArrayInt32Args);
                            }
                            ctx.EmitCall(copyTo);
                        }
                        ctx.LoadValue(newArr);
                    }
        }
Exemplo n.º 40
0
        private void EmitBeq(Compiler.CompilerContext ctx, Compiler.CodeLabel label, Type type)
        {
            switch (Helpers.GetTypeCode(type))
            {
                case ProtoTypeCode.Boolean:
                case ProtoTypeCode.Byte:
                case ProtoTypeCode.Char:
                case ProtoTypeCode.Double:
                case ProtoTypeCode.Int16:
                case ProtoTypeCode.Int32:
                case ProtoTypeCode.Int64:
                case ProtoTypeCode.SByte:
                case ProtoTypeCode.Single:
                case ProtoTypeCode.UInt16:
                case ProtoTypeCode.UInt32:
                case ProtoTypeCode.UInt64:
                    ctx.BranchIfEqual(label, false);
                    break;

                default:
                    MethodInfo method = type.GetMethod("op_Equality", BindingFlags.Public | BindingFlags.Static,
                        null, new Type[] { type, type}, null);
                    if (method == null || method.ReturnType != ctx.MapType(typeof(bool)))
                    {
                        throw new InvalidOperationException("No suitable equality operator found for default-values of type: " + type.FullName);
                    }
                    ctx.EmitCall(method);
                    ctx.BranchIfTrue(label, false);
                    break;
            }
        }
Exemplo n.º 41
0
        public void OutlineType()
        {
            bool first;

            OutlineAttributes();
            o.Write(GetTypeVisibility(t));

            if (t.IsClass && !t.IsSubclassOf(type_multicast_delegate))
            {
                if (t.IsSealed)
                {
                    o.Write(t.IsAbstract ? " static" : " sealed");
                }
                else if (t.IsAbstract)
                {
                    o.Write(" abstract");
                }
            }

            o.Write(" ");
            o.Write(GetTypeKind(t));
            o.Write(" ");

            Type [] interfaces = (Type [])Comparer.Sort(TypeGetInterfaces(t, declared_only));
            Type    parent     = t.BaseType;

            if (t.IsSubclassOf(type_multicast_delegate))
            {
                MethodInfo method;

                method = t.GetMethod("Invoke");

                o.Write(FormatType(method.ReturnType));
                o.Write(" ");
                o.Write(GetTypeName(t));
                o.Write(" (");
                OutlineParams(method.GetParameters());
                o.Write(")");

                WriteGenericConstraints(t.GetGenericArguments());

                o.WriteLine(";");
                return;
            }

            o.Write(GetTypeName(t));
            if (((parent != null && parent != type_object && parent != type_value_type) || interfaces.Length != 0) && !t.IsEnum)
            {
                first = true;
                o.Write(" : ");

                if (parent != null && parent != type_object && parent != type_value_type)
                {
                    o.Write(FormatType(parent));
                    first = false;
                }

                foreach (Type intf in interfaces)
                {
                    if (!first)
                    {
                        o.Write(", ");
                    }
                    first = false;

                    o.Write(FormatType(intf));
                }
            }

            if (t.IsEnum)
            {
                Type underlyingType = t.GetEnumUnderlyingType();
                if (underlyingType != type_int)
                {
                    o.Write(" : {0}", FormatType(underlyingType));
                }
            }
            WriteGenericConstraints(t.GetGenericArguments());
            o.WriteLine(" {");
            o.Indent++;

            if (t.IsEnum)
            {
                bool is_first = true;
                foreach (FieldInfo fi in t.GetFields(BindingFlags.Public | BindingFlags.Static))
                {
                    if (!is_first)
                    {
                        o.WriteLine(",");
                    }
                    is_first = false;
                    o.Write(fi.Name);
                }
                o.WriteLine();
                o.Indent--; o.WriteLine("}");
                return;
            }

            first = true;

            foreach (ConstructorInfo ci in t.GetConstructors(DefaultFlags))
            {
                if (!ShowMember(ci))
                {
                    continue;
                }

                if (first)
                {
                    o.WriteLine();
                }
                first = false;

                OutlineMemberAttribute(ci);
                OutlineConstructor(ci);

                o.WriteLine();
            }


            first = true;

            foreach (MethodInfo m in Comparer.Sort(t.GetMethods(DefaultFlags)))
            {
                if (!ShowMember(m))
                {
                    continue;
                }

                if ((m.Attributes & MethodAttributes.SpecialName) != 0)
                {
                    continue;
                }

                if (first)
                {
                    o.WriteLine();
                }
                first = false;

                OutlineMemberAttribute(m);
                OutlineMethod(m);

                o.WriteLine();
            }

            first = true;

            foreach (MethodInfo m in t.GetMethods(DefaultFlags))
            {
                if (!ShowMember(m))
                {
                    continue;
                }

                if ((m.Attributes & MethodAttributes.SpecialName) == 0)
                {
                    continue;
                }
                if (!(m.Name.StartsWith("op_")))
                {
                    continue;
                }

                if (first)
                {
                    o.WriteLine();
                }
                first = false;

                OutlineMemberAttribute(m);
                OutlineOperator(m);

                o.WriteLine();
            }

            first = true;

            foreach (PropertyInfo pi in Comparer.Sort(t.GetProperties(DefaultFlags)))
            {
                if (!((pi.CanRead && ShowMember(pi.GetGetMethod(true))) ||
                      (pi.CanWrite && ShowMember(pi.GetSetMethod(true)))))
                {
                    continue;
                }

                if (first)
                {
                    o.WriteLine();
                }
                first = false;

                OutlineMemberAttribute(pi);
                OutlineProperty(pi);

                o.WriteLine();
            }

            first = true;

            foreach (FieldInfo fi in t.GetFields(DefaultFlags))
            {
                if (!ShowMember(fi))
                {
                    continue;
                }

                if (first)
                {
                    o.WriteLine();
                }
                first = false;

                OutlineMemberAttribute(fi);
                OutlineField(fi);

                o.WriteLine();
            }

            first = true;

            foreach (EventInfo ei in Comparer.Sort(t.GetEvents(DefaultFlags)))
            {
                if (!ShowMember(ei.GetAddMethod(true)))
                {
                    continue;
                }

                if (first)
                {
                    o.WriteLine();
                }
                first = false;

                OutlineMemberAttribute(ei);
                OutlineEvent(ei);

                o.WriteLine();
            }

            first = true;

            foreach (Type ntype in Comparer.Sort(t.GetNestedTypes(DefaultFlags)))
            {
                if (!ShowMember(ntype))
                {
                    continue;
                }

                if (first)
                {
                    o.WriteLine();
                }
                first = false;

#if STATIC
                new Outline(universe, mscorlib, ntype, o, declared_only, show_private, filter_obsolete).OutlineType();
#else
                new Outline(ntype, o, declared_only, show_private, filter_obsolete).OutlineType();
#endif
            }

            o.Indent--; o.WriteLine("}");
        }
Exemplo n.º 42
0
 internal static MethodInfo GetInstanceMethod(Type declaringType, string name)
 {
     return declaringType.GetMethod(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
 }
Exemplo n.º 43
0
		private static bool IsDelegate(Type type)
		{
			// HACK non-public delegates do not get the special treatment (because they are likely to refer to
			// non-public types in the arg list and they're not really useful anyway)
			// NOTE we don't have to check in what assembly the type lives, because this is a DotNetTypeWrapper,
			// we know that it is a different assembly.
			if (!type.IsAbstract && type.IsSubclassOf(Types.MulticastDelegate) && type.IsVisible)
			{
				MethodInfo invoke = type.GetMethod("Invoke");
				if (invoke != null)
				{
					foreach (ParameterInfo p in invoke.GetParameters())
					{
						// we don't support delegates with pointer parameters
						if (IsPointerType(p.ParameterType))
						{
							return false;
						}
					}
					return !IsPointerType(invoke.ReturnType);
				}
			}
			return false;
		}
Exemplo n.º 44
0
        protected override void EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom)
        {
            using (ctx.StartDebugBlockAuto(this))
            {
                using (Compiler.Local oldValue = ctx.GetLocalWithValueForEmitRead(this, valueFrom))
                {
                    Compiler.Local tempLocal = null;
                    Compiler.Local valueForTail;
                    Debug.Assert(Tail.RequiresOldValue || Tail.EmitReadReturnsValue);
                    if (Tail.RequiresOldValue)
                    {
                        if (_expectedType.IsValueType)
                        {
                            tempLocal = ctx.Local(Tail.ExpectedType);
                            ctx.LoadAddress(oldValue, _expectedType);
                            ctx.EmitCall(_expectedType.GetMethod("GetValueOrDefault", Helpers.EmptyTypes));
                            ctx.StoreValue(tempLocal);
                            valueForTail = tempLocal;
                        }
                        else
                        {
                            valueForTail = oldValue;
                        }
                    }
                    else
                    {
                        valueForTail = null;
                    }

                    // valueForTail contains:
                    // null: when not required old value
                    // oldValue local: when reference type
                    // tempLocal: when nullable value type

                    Tail.EmitRead(ctx, valueForTail);

                    if (_expectedType.IsValueType)
                    {
                        if (!Tail.EmitReadReturnsValue)
                        {
                            ctx.LoadValue(tempLocal);
                        }
                        // note we demanded always returns a value
                        ctx.EmitCtor(_expectedType, Tail.ExpectedType); // re-nullable<T> it
                    }

                    if (Tail.EmitReadReturnsValue || _expectedType.IsValueType)
                    {
                        ctx.StoreValue(oldValue);
                    }

                    if (EmitReadReturnsValue)
                    {
                        ctx.LoadValue(oldValue);
                    }

                    if (!tempLocal.IsNullRef())
                    {
                        tempLocal.Dispose();
                    }
                }
            }
        }