コード例 #1
0
 /// <summary>
 /// 如果是值类型, 则将值类型装箱后推送到计算栈
 /// </summary>
 /// <param name="il"></param>
 public static void BoxIfNeed(this ILGenerator il, Type type)
 {
     if (type.IsValueType)
     {
         il.Box(type);
     }
 }
コード例 #2
0
        /// <summary>
        /// Performs a boxing operation if the given type is a value type.
        /// </summary>
        /// <param name="il">The instance of <see cref="ILGenerator"/>.</param>
        /// <param name="type">The type.</param>
        /// <returns>The instance of <see cref="ILGenerator"/>.</returns>
        public static ILGenerator BoxIfNeeded(this ILGenerator il, Type type)
        {
            if (type.IsValueType)
            {
                il.Box(type);
            }

            return(il);
        }
コード例 #3
0
        public static ILGenerator BoxIfNeeded(this ILGenerator il, System.Type type)
        {
            if (type.GetTypeInfo().IsValueType)
            {
                il.Box(type);
            }

            return(il);
        }
コード例 #4
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="il"></param>
        /// <param name="source"></param>
        /// <param name="destination"></param>
        /// <returns></returns>
        public static ILGenerator Convert(this ILGenerator il, Type source, Type destination)
        {
            if (source == null)
            {
                throw new ArgumentNullException("source");
            }
            if (destination == null)
            {
                throw new ArgumentNullException("destination");
            }

            if (source == destination)
            {
                return(il);
            }

            if (source == typeof(Object) && destination.IsValueType)
            {
                return(il.Unbox_Any(destination));
            }
            if (source.IsValueType && destination == typeof(Object))
            {
                return(il.Box(destination));
            }

            // if (source.IsAssignableFrom(destination)) return this;
            // --> it doesn't work for int? -> int, cause int is assignable from int?

            var converter = LookUpConverter(source, destination);

            if (converter != null)             // not so beauty, but it's enough for internal code
            {
                // todo. implement invariant culture here
                if (converter is ConstructorInfo)
                {
                    return(il.Newobj((ConstructorInfo)converter));
                }
                // note the ClassCastException expected below in near future :)
                return(converter.IsVirtual ? il.Callvirt((MethodInfo)converter) : il.Call((MethodInfo)converter));
            }

            Func <ILGenerator, ILGenerator> emitter;

            if (CanGenerateConverter(source, destination, out emitter))
            {
                return(emitter(il));
            }

            return(il.Castclass(destination));
        }
コード例 #5
0
        /// <summary>
        /// 只读
        /// </summary>
        private static void CloneActionRead(Type type, ILGenerator generator, PropertyInfo property)
        {
            var method = typeof(BuilderHelper).GetMethod(nameof(BuilderHelper.CloneObject),
                                                         TConfig.Flags, null, new Type[] { typeof(object), typeof(object), typeof(bool) }, null);

            generator.GetValue(property, type);      //获取引用值

            generator.Emit(OpCodes.Ldarg_1);         // los
            generator.Emit(OpCodes.Castclass, type); //未使用泛类,要转化为指定type类型
            generator.Box(property);                 //值数据转引用数据

            {                                        //参数
                generator.Emit(OpCodes.Ldc_I4, 1);
            }
            generator.Emit(OpCodes.Call, method);//调用静态方法
        }
コード例 #6
0
        /// <summary>
        /// 只读
        /// </summary>
        private static void CloneFuncRead(Type type, ILGenerator generator, PropertyInfo property)
        {
            var method = typeof(BuilderHelper).GetMethod(nameof(BuilderHelper.CloneObject),
                                                         TConfig.Flags, null, new Type[] { typeof(object), typeof(object), typeof(bool) }, null);

            // Load initial object (parameter)          (currently 2 items on eval stack)
            generator.GetValue(property, type);//获取引用值

            // Load the new object on the eval stack... (currently 1 item on eval stack)
            generator.Emit(OpCodes.Ldloc_0);
            generator.Box(property); //值数据转引用数据

            {                        //参数
                generator.Emit(OpCodes.Ldc_I4, 1);
            }
            generator.Emit(OpCodes.Call, method);//调用静态方法
        }
コード例 #7
0
            public override void ReadValueAfter(ILGenerator ilGen)
            {
                if (ReadValueMethod != null)
                {
                    ilGen.Call(ReadValueMethod);

                    if (BeforeType != AfterType)
                    {
                        if (AfterType.IsValueType)
                        {
                            ilGen.Box(AfterType);
                        }

                        ilGen.CastClass(BeforeType);

                        if (BeforeType.IsValueType)
                        {
                            ilGen.UnboxAny(BeforeType);
                        }
                    }

                    return;
                }

                var methodName = GetReadValueMethodName(BeforeType);

                if (methodName != null)
                {
                    var method = typeof(IValueReader).GetMethod(methodName);

                    if (methodName == nameof(IValueReader.ReadNullable) && method.IsGenericMethodDefinition)
                    {
                        method = method.MakeGenericMethod(Nullable.GetUnderlyingType(BeforeType));
                    }

                    ilGen.Call(method);

                    return;
                }

                var valueInterfaceType = typeof(ValueInterface <>).MakeGenericType(BeforeType);

                var valueInterfaceReadValueMethod = valueInterfaceType.GetMethod(nameof(ValueInterface <object> .ReadValue), StaticDeclaredOnly);

                ilGen.Call(valueInterfaceReadValueMethod);
            }
コード例 #8
0
 public override CodeNode VisitSkipAssignmentIfMissingValue(SkipAssignmentIfMissingValueNode node)
 {
     if (!_InFieldAssignment)
     {
         throw new InvalidOperationException("SkipAssignmentIfMissingValueNode must be in a FieldAssignmentNode");
     }
     ILGen.Ldloca(_FieldLocal);
     ILGen.Ldc(node.MissingValue, node.MissingValue.GetType());
     //BUG: Revisit this.  The purpose of constrained is so you don't have to do different codegen for valuetype vs. reference type
     if (_FieldLocal.LocalType.IsValueType)
     {
         ILGen.Box(_FieldLocal.LocalType);
     }
     ILGen.Constrained(_FieldLocal.LocalType);
     // TODO: if (!node.AllowMissingValue) { do the next two lines... }
     ILGen.Callvirt(typeof(object).GetMethod("Equals", typeof(object)));
     ILGen.Brtrue(_SkipAssignmentLabel);
     return(node);
 }
コード例 #9
0
            public override void WriteValueAfter(ILGenerator ilGen)
            {
                if (WriteValueMethod != null)
                {
                    if (BeforeType != AfterType)
                    {
                        if (BeforeType.IsValueType)
                        {
                            ilGen.Box(BeforeType);
                        }

                        ilGen.CastClass(AfterType);

                        if (AfterType.IsValueType)
                        {
                            ilGen.UnboxAny(AfterType);
                        }
                    }

                    ilGen.Call(WriteValueMethod);

                    return;
                }

                var methodName = GetWriteValueMethodName(BeforeType);

                if (methodName != null)
                {
                    ilGen.Call(typeof(IValueWriter).GetMethod(methodName));

                    return;
                }

                var valueInterfaceType = typeof(ValueInterface <>).MakeGenericType(BeforeType);

                var valueInterfaceWriteValueMethod = valueInterfaceType.GetMethod(nameof(ValueInterface <object> .WriteValue), StaticDeclaredOnly);

                ilGen.Call(valueInterfaceWriteValueMethod);
            }
コード例 #10
0
 public static ILGenerator Box <T>(this ILGenerator generator) where T : struct => generator.Box(typeof(T));
コード例 #11
0
ファイル: ILGenHelpers.cs プロジェクト: opony/LinqToStdf
 public static void Box <T>(this ILGenerator ilgen)
 {
     ilgen.Box(typeof(T));
 }
コード例 #12
0
 public void EmitAppendToStringBuilder(ILGenerator gen, LocalBuilder?_, LocalBuilder?__, CsvColumnAttribute?attribute) => gen
 .Box <TEnum>()
 .Callvirt <StringBuilder>("Append", typeof(object));
コード例 #13
0
 /// <summary>
 /// 转化参数到类型,获取参数值,返回引用数据(指定类型时,调用转化)
 /// </summary>
 internal static void GetValue(this ILGenerator generator, PropertyInfo property, Type type)
 {
     generator.Emit(OpCodes.Ldarg_0);
     generator.Emit(OpCodes.Castclass, type); //未使用泛类,要转化为指定type类型
     generator.Box(property);                 //值数据转引用数据
 }
コード例 #14
0
        private void EmitStructConverter(ILGenerator il, Type inType, Type outType)
        {
            var casted    = il.DeclareLocal(inType);
            var converted = il.DeclareLocal(outType);
            var v2        = il.DeclareLocal(objectType);

            var inPropMap    = inType.GetProperties().ToDictionary(x => x.Name.ToLower());
            var outCtor      = outType.GetConstructors().OrderByDescending(x => x.GetParameters().Length).First();
            var ctorParamMap = outCtor
                               .GetParameters()
                               .Select(outParam =>
            {
                var outParamKey = outParam.Name.ToLower();
                return(new { outParam, inProp = inPropMap.ContainsKey(outParamKey) ? inPropMap[outParamKey] : null });
            })
                               .ToArray();

            var invalidParamTransitions = ctorParamMap.Where(x => x.inProp == null).ToArray();

            if (invalidParamTransitions.Length > 0)
            {
                throw new Exception($"Can't serialize this kind of struct. Need to know how to map next ctor params: {string.Join(", ", invalidParamTransitions.Select(x => x.outParam.Name))}");
            }


            il.Ldarg(1);
            il.Unbox_Any(inType);
            il.Stloc(casted);

            il.Ldloca(converted);

            foreach (var ctorParamPair in ctorParamMap)
            {
                var inItem      = ctorParamPair.inProp;
                var outItem     = ctorParamPair.outParam;
                var inItemType  = inItem.PropertyType;
                var outItemType = outItem.ParameterType;
                if (inItemType == outItemType)
                {
                    il.Ldloca(casted);
                    il.Call(inItem.GetMethod);
                }
                else
                {
                    il.Ldsfld(ConverterStorage.InstanceFieldInfo);
                    il.Ldtoken(inItemType);
                    il.Call(typeOfMethodInfo);
                    il.Ldtoken(outItemType);
                    il.Call(typeOfMethodInfo);
                    il.Callvirt(ConverterStorage.GetImplementationFieldInfo);
                    il.Ldloca(casted);
                    il.Call(inItem.GetMethod);
                    il.Callvirt(convertMethodInfo);
                    il.Castclass(outItemType);
                }
            }

            il.Call(outCtor);

            il.Ldloc(converted);
            il.Box(outType);
            il.Stloc(v2);

            var brLabel = il.DefineLabel();

            il.BrS(brLabel);
            il.MarkLabel(brLabel);

            il.Ldloc(v2);
            il.Ret();
        }