protected byte CreateLocalsForByRefParams(byte paramArrayIndex, MethodBase invocationInfo)
        {
            byte numberOfByRefParams = 0;

            ParameterInfo[] parameters = invocationInfo.GetParameters();
            for (int i = 0, count = ParamTypes.Length; i < count; ++i)
            {
                Type paramType = ParamTypes[i];
                if (paramType.IsByRef)
                {
                    Type type = paramType.GetElementType();
                    Gen.DeclareLocal(type);
                    if (!parameters[i].IsOut)                     // no initialization necessary is 'out' parameter
                    {
                        Gen.Emit(OpCodes.Ldarg, (short)paramArrayIndex);
                        Gen.Emit(OpCodes.Ldc_I4, i);
                        Gen.Emit(OpCodes.Ldelem_Ref);
                        if (type == typeof(object))
                        {
                            Gen.Emit(type.IsValueType ? OpCodes.Unbox_Any : OpCodes.Castclass, type);
                        }
                        stloc_s(numberOfByRefParams);
                    }
                    numberOfByRefParams++;
                }
            }
            return(numberOfByRefParams);
        }
        protected internal override Delegate CreateDelegate()
        {
            bool handleInnerStruct = ShouldHandleInnerStruct;

            if (handleInnerStruct)
            {
                Gen.Emit(OpCodes.Ldarg_0);                 // load arg-0 (this)
                Gen.DeclareLocal(TargetType);              // TargetType tmpStr
                LoadInnerStructToLocal(0);                 // tmpStr = ((ValueTypeHolder)this)).Value
                Gen.DeclareLocal(typeof(object));          // object result;
            }
            else if (!IsStatic)
            {
                Gen.Emit(OpCodes.Ldarg_0);                 // load arg-0 (this)
                Gen.Emit(OpCodes.Castclass, TargetType);   // (TargetType)this
            }
            if (MemberInfo is FieldInfo field)
            {
                if (field.DeclaringType.IsEnum)                 // special enum handling as ldsfld does not support enums
                {
                    Gen.Emit(OpCodes.Ldc_I4, (int)field.GetValue(field.DeclaringType));
                }
                else
                {
                    Gen.Emit(field.IsStatic ? OpCodes.Ldsfld : OpCodes.Ldfld, field);                      // (this|tmpStr).field OR TargetType.field
                }
                if (field.FieldType.IsValueType)
                {
                    Gen.Emit(OpCodes.Box, field.FieldType);                     // (object)<stack>
                }
            }
            else
            {
                PropertyInfo prop      = (PropertyInfo)MemberInfo;
                MethodInfo   getMethod = prop.GetGetMethod(true);
                Gen.Emit(getMethod.IsStatic || IsTargetTypeStruct ? OpCodes.Call : OpCodes.Callvirt, getMethod);                 // (this|tmpStr).prop OR TargetType.prop
                if (prop.PropertyType.IsValueType)
                {
                    Gen.Emit(OpCodes.Box, prop.PropertyType);                     // (object)<stack>
                }
            }
            if (handleInnerStruct)
            {
                Gen.Emit(OpCodes.Stloc_1);                  // resultLocal = <stack>
                StoreLocalToInnerStruct(0);                 // ((ValueTypeHolder)this)).Value = tmpStr
                Gen.Emit(OpCodes.Ldloc_1);                  // push resultLocal
            }
            Gen.Emit(OpCodes.Ret);
            return(Method.CreateDelegate(typeof(MemberGetter)));
        }
        protected internal override Delegate CreateDelegate()
        {
            MethodInfo method                = (MethodInfo)MemberInfo;
            const byte paramArrayIndex       = 1;
            bool       hasReturnType         = method.ReturnType != typeof(void);
            byte       startUsableLocalIndex = 0;

            if (HasRefParam)
            {
                startUsableLocalIndex = CreateLocalsForByRefParams(paramArrayIndex, method);
                // create by_ref_locals from argument array
                Gen.DeclareLocal(hasReturnType ? method.ReturnType : typeof(object));                 // T result;
                GenerateInvocation(method, paramArrayIndex, (byte)(startUsableLocalIndex + 1));
                if (hasReturnType)
                {
                    stloc_s(startUsableLocalIndex);                     // result = <stack>;
                }
                AssignByRefParamsToArray(paramArrayIndex);              // store by_ref_locals back to argument array
            }
            else
            {
                Gen.DeclareLocal(hasReturnType ? method.ReturnType : typeof(object));                 // T result;
                GenerateInvocation(method, paramArrayIndex, (byte)(startUsableLocalIndex + 1));
                if (hasReturnType)
                {
                    stloc_s(startUsableLocalIndex);                     // result = <stack>;
                }
            }
            if (ShouldHandleInnerStruct)
            {
                StoreLocalToInnerStruct((short)(startUsableLocalIndex + 1));                  // ((ValueTypeHolder)this)).Value = tmpStr;
            }
            if (hasReturnType)
            {
                Gen.Emit(OpCodes.Ldloc, (short)startUsableLocalIndex);                 // push result;
                if (method.ReturnType.IsValueType)
                {
                    Gen.Emit(OpCodes.Box, method.ReturnType);                     // box result;
                }
            }
            else
            {
                Gen.Emit(OpCodes.Ldnull);                 // load null
            }
            Gen.Emit(OpCodes.Ret);
            return(Method.CreateDelegate(typeof(MethodInvoker)));
        }
 protected void GenerateInvocation(MethodInfo methodInfo, byte paramArrayIndex, byte structLocalPosition)
 {
     if (!IsStatic)
     {
         Gen.Emit(OpCodes.Ldarg_0);                 // load arg-0 (this/null);
         if (ShouldHandleInnerStruct)
         {
             Gen.DeclareLocal(TargetType);                     // TargetType tmpStr;
             LoadInnerStructToLocal(structLocalPosition);      // tmpStr = ((ValueTypeHolder)this)).Value;
         }
         else
         {
             Gen.Emit(OpCodes.Castclass, TargetType);                     // (TargetType)arg-0;
         }
     }
     PushParamsOrLocalsToStack(paramArrayIndex);                                                        // push arguments and by_ref_locals
     Gen.Emit(methodInfo.IsStatic || IsTargetTypeStruct ? OpCodes.Call : OpCodes.Callvirt, methodInfo); // call OR callvirt
 }
Beispiel #5
0
        protected internal override Delegate CreateDelegate()
        {
            bool handleInnerStruct = ShouldHandleInnerStruct;

            if (!IsStatic)
            {
                Gen.Emit(OpCodes.Ldarg_0);                        // load arg-0 (this)
                if (handleInnerStruct)
                {
                    Gen.DeclareLocal(TargetType);                     // TargetType tmpStr
                    LoadInnerStructToLocal(0);                        // tmpStr = ((ValueTypeHolder)this)).Value;
                }
                else
                {
                    Gen.Emit(OpCodes.Castclass, TargetType);                     // (TargetType)this
                }
            }
            Gen.Emit(OpCodes.Ldarg_1);                           // load value-to-be-set;

            Type type = MemberInfo.Type();

            if (type != typeof(object))
            {
                Gen.Emit(type.IsValueType ? OpCodes.Unbox_Any : OpCodes.Castclass, type);
            }
            if (MemberInfo is FieldInfo field)
            {
                Gen.Emit(field.IsStatic ? OpCodes.Stsfld : OpCodes.Stfld, field);                 // (this|tmpStr).field = value-to-be-set;
            }
            else
            {
                PropertyInfo prop      = (PropertyInfo)MemberInfo;
                MethodInfo   setMethod = prop.GetSetMethod(true);
                Gen.Emit(setMethod.IsStatic || IsTargetTypeStruct ? OpCodes.Call : OpCodes.Callvirt, setMethod);                 // (this|tmpStr).set_Prop(value-to-be-set);
            }
            if (handleInnerStruct)
            {
                StoreLocalToInnerStruct(0);                 // ((ValueTypeHolder)this)).Value = tmpStr
            }
            Gen.Emit(OpCodes.Ret);
            return(Method.CreateDelegate(typeof(MemberSetter)));
        }
 protected internal override Delegate CreateDelegate()
 {
     if (IsTargetTypeStruct && HasNoParam)          // no-arg struct needs special initialization
     {
         Gen.DeclareLocal(TargetType);              // TargetType tmp
         Gen.Emit(OpCodes.Ldloca_S, (byte)0);       // &tmp
         Gen.Emit(OpCodes.Initobj, TargetType);     // init_obj(&tmp)
         Gen.Emit(OpCodes.Ldloc_0);                 // load tmp
     }
     else if (TargetType.IsArray)
     {
         Gen.Emit(OpCodes.Ldarg_0);                             // load args[] (method arguments)
         Gen.Emit(OpCodes.Ldc_I4_0);                            // load 0
         Gen.Emit(OpCodes.Ldelem_Ref);                          // load args[0] (length)
         Gen.Emit(OpCodes.Unbox_Any, typeof(int));              // unbox stack
         Gen.Emit(OpCodes.Newarr, TargetType.GetElementType()); // new T[args[0]]
     }
     else
     {
         ConstructorInfo ctorInfo = (ConstructorInfo)MemberInfo;
         byte            startUsableLocalIndex = 0;
         if (HasRefParam)
         {
             startUsableLocalIndex = CreateLocalsForByRefParams(0, ctorInfo); // create by_ref_locals from argument array
             Gen.DeclareLocal(TargetType);                                    // TargetType tmp;
         }
         PushParamsOrLocalsToStack(0);                                        // push arguments and by_ref_locals
         Gen.Emit(OpCodes.Newobj, ctorInfo);                                  // ctor (<stack>)
         if (HasRefParam)
         {
             stloc_s(startUsableLocalIndex);                        // tmp = <stack>;
             AssignByRefParamsToArray(0);                           // store by_ref_locals back to argument array
             Gen.Emit(OpCodes.Ldloc, (short)startUsableLocalIndex); // tmp
         }
     }
     if (TargetType.IsValueType)
     {
         Gen.Emit(OpCodes.Box, TargetType);
     }
     Gen.Emit(OpCodes.Ret);             // return (box)<stack>;
     return(Method.CreateDelegate(typeof(ConstructorInvoker)));
 }
Beispiel #7
0
        protected internal override Delegate CreateDelegate()
        {
            bool handleInnerStruct = ShouldHandleInnerStruct;

            if (handleInnerStruct)
            {
                Gen.Emit(OpCodes.Ldarg_1);                            // load arg-1 (target)
                Gen.DeclareLocal(TargetType);                         // TargetType localStr;
                Gen.Emit(OpCodes.Castclass, typeof(ValueTypeHolder)); // (ValueTypeHolder)wrappedStruct
                Gen.Emit(OpCodes.Callvirt, StructGetMethod);          // <stack>.get_Value()
                Gen.Emit(OpCodes.Unbox_Any, TargetType);              // unbox <stack>
                Gen.Emit(OpCodes.Stloc_0);                            // localStr = <stack>
            }
            for (int i = 0, count = Sources.Count; i < count; ++i)
            {
                if (handleInnerStruct)
                {
                    Gen.Emit(OpCodes.Ldloca_S, (byte)0);                      // load &localStr
                }
                else
                {
                    Gen.Emit(OpCodes.Ldarg_1);
                    Gen.Emit(OpCodes.Castclass, TargetType);                      // ((TargetType)target)
                }
                Gen.Emit(OpCodes.Ldarg_0);
                Gen.Emit(OpCodes.Castclass, SourceType);
                GenerateGetMemberValue(Sources[i]);
                GenerateSetMemberValue(Targets[i]);
            }
            if (handleInnerStruct)
            {
                StoreLocalToInnerStruct(1, 0);                     // ((ValueTypeHolder)this)).Value = tmpStr
            }
            Gen.Emit(OpCodes.Ret);
            return(Method.CreateDelegate(typeof(ObjectMapper)));
        }
Beispiel #8
0
        protected internal override Delegate CreateDelegate()
        {
            bool handleInnerStruct = ShouldHandleInnerStruct;

            if (!IsStatic)
            {
                Gen.Emit(OpCodes.Ldarg_0);                  // load arg-0 (this)
                if (handleInnerStruct)
                {
                    Gen.DeclareLocal(TargetType);                         // TargetType tmpStr
                    Gen.Emit(OpCodes.Castclass, typeof(ValueTypeHolder)); // (ValueTypeHolder)wrappedStruct
                    Gen.Emit(OpCodes.Callvirt, StructGetMethod);          // <stack>.get_Value()
                    Gen.Emit(OpCodes.Unbox_Any, TargetType);              // unbox <stack>
                    Gen.Emit(OpCodes.Stloc_0);                            // localStr = <stack>
                }
                else
                {
                    Gen.Emit(OpCodes.Castclass, TargetType);                     // (TargetType)this
                }
            }
            IList <MemberInfo> members = Members;

            for (int i = 0, count = members.Count; i < count; ++i)
            {
                MemberInfo method = members[i];

                if (method == null)
                {
                    continue;
                }
                if (method is FieldInfo field)
                {
                    if (!field.IsStatic)
                    {
                        if (handleInnerStruct)
                        {
                            Gen.Emit(OpCodes.Ldloca_S, (byte)0);
                        }
                        else if (i != count - 1)
                        {
                            Gen.Emit(OpCodes.Dup);
                        }
                    }
                    Gen.Emit(OpCodes.Ldarg_1);
                    Gen.Emit(OpCodes.Ldc_I4, i);
                    Gen.Emit(OpCodes.Ldelem_Ref);
                    if (field.FieldType != typeof(object))
                    {
                        Gen.Emit(field.FieldType.IsValueType ? OpCodes.Unbox_Any : OpCodes.Castclass, field.FieldType);
                    }
                    Gen.Emit(field.IsStatic ? OpCodes.Stsfld : OpCodes.Stfld, field);                     // (this|tmpStr).field = value-to-be-set
                }
                else
                {
                    PropertyInfo property  = (PropertyInfo)method;
                    MethodInfo   setMethod = property.GetSetMethod(true) ?? throw new MemberAccessException(TargetType.FullName + "." + property.Name);
                    if (!setMethod.IsStatic)
                    {
                        if (handleInnerStruct)
                        {
                            Gen.Emit(OpCodes.Ldloca_S, (byte)0);
                        }
                        else if (i != count - 1)
                        {
                            Gen.Emit(OpCodes.Dup);
                        }
                    }
                    Gen.Emit(OpCodes.Ldarg_1);
                    Gen.Emit(OpCodes.Ldc_I4, i);
                    Gen.Emit(OpCodes.Ldelem_Ref);
                    if (property.PropertyType != typeof(object))
                    {
                        Gen.Emit(property.PropertyType.IsValueType ? OpCodes.Unbox_Any : OpCodes.Castclass, property.PropertyType);
                    }
                    Gen.Emit(setMethod.IsStatic || IsTargetTypeStruct ? OpCodes.Call : OpCodes.Callvirt, setMethod);                      // (this|tmpStr).set_Prop(value-to-be-set)
                }
            }
            if (handleInnerStruct)
            {
                StoreLocalToInnerStruct(0);                   // ((ValueTypeHolder)this)).Value = tmpStr
            }
            //Gen.Emit(OpCodes.Ldnull); // load null
            Gen.Emit(OpCodes.Ret);
            return(Method.CreateDelegate(typeof(MultiSetter)));
        }