protected internal override Delegate CreateDelegate()
        {
            MemberInfo member = CallInfo.MemberInfo;

            if (member == null)
            {
                member            = LookupUtils.GetMember(CallInfo);
                CallInfo.IsStatic = member.IsStatic();
            }
            bool handleInnerStruct = CallInfo.ShouldHandleInnerStruct;

            if (handleInnerStruct)
            {
                Generator.ldarg_0                               // load arg-0 (this)
                .DeclareLocal(CallInfo.TargetType);             // TargetType tmpStr
                LoadInnerStructToLocal(0);                      // tmpStr = ((ValueTypeHolder)this)).Value
                Generator.DeclareLocal(Constants.ObjectType);   // object result;
            }
            else if (!CallInfo.IsStatic)
            {
                Generator.ldarg_0                               // load arg-0 (this)
                .castclass(CallInfo.TargetType);                // (TargetType)this
            }

            if (member.MemberType == MemberTypes.Field)
            {
                var field = member as FieldInfo;

                if (field.DeclaringType.IsEnum)                  // special enum handling as ldsfld does not support enums
                {
                    Generator.ldc_i4((int)field.GetValue(field.DeclaringType))
                    .boxIfValueType(field.FieldType);
                }
                else
                {
                    Generator.ldfld(field.IsStatic, field)                              // (this|tmpStr).field OR TargetType.field
                    .boxIfValueType(field.FieldType);                                   // (object)<stack>
                }
            }
            else
            {
                var        prop      = member as PropertyInfo;
                MethodInfo getMethod = LookupUtils.GetPropertyGetMethod(prop, CallInfo);
                Generator.call(getMethod.IsStatic || CallInfo.IsTargetTypeStruct, getMethod) // (this|tmpStr).prop OR TargetType.prop
                .boxIfValueType(prop.PropertyType);                                          // (object)<stack>
            }

            if (handleInnerStruct)
            {
                Generator.stloc_1.end();        // resultLocal = <stack>
                StoreLocalToInnerStruct(0);     // ((ValueTypeHolder)this)).Value = tmpStr
                Generator.ldloc_1.end();        // push resultLocal
            }

            Generator.ret();

            return(Method.CreateDelegate(typeof(MemberGetter)));
        }
        protected internal override Delegate CreateDelegate()
        {
            MemberInfo member = CallInfo.MemberInfo;

            if (member == null)
            {
                member            = LookupUtils.GetMember(CallInfo);
                CallInfo.IsStatic = member.IsStatic();
            }
            bool handleInnerStruct = CallInfo.ShouldHandleInnerStruct;

            if (CallInfo.IsStatic)
            {
                Generator.ldarg_1.end();                                                                        // load value-to-be-set
            }
            else
            {
                Generator.ldarg_0.end();                                                                        // load arg-0 (this)
                if (handleInnerStruct)
                {
                    Generator.DeclareLocal(CallInfo.TargetType);                        // TargetType tmpStr
                    LoadInnerStructToLocal(0);                                          // tmpStr = ((ValueTypeHolder)this)).Value;
                    Generator.ldarg_1.end();                                            // load value-to-be-set;
                }
                else
                {
                    Generator.castclass(CallInfo.TargetType)                            // (TargetType)this
                    .ldarg_1.end();                                                     // load value-to-be-set;
                }
            }

            Generator.CastFromObject(member.Type());                            // unbox | cast value-to-be-set
            if (member.MemberType == MemberTypes.Field)
            {
                var field = member as FieldInfo;
                Generator.stfld(field.IsStatic, field);                         // (this|tmpStr).field = value-to-be-set;
            }
            else
            {
                var        prop      = member as PropertyInfo;
                MethodInfo setMethod = LookupUtils.GetPropertySetMethod(prop, CallInfo);
                Generator.call(setMethod.IsStatic || CallInfo.IsTargetTypeStruct, setMethod); // (this|tmpStr).set_Prop(value-to-be-set);
            }

            if (handleInnerStruct)
            {
                StoreLocalToInnerStruct(0); // ((ValueTypeHolder)this)).Value = tmpStr
            }

            Generator.ret();

            return(Method.CreateDelegate(typeof(MemberSetter)));
        }
Beispiel #3
0
        protected internal override Delegate CreateDelegate()
        {
            var method = (MethodInfo)CallInfo.MemberInfo ?? LookupUtils.GetMethod(CallInfo);

            CallInfo.IsStatic = method.IsStatic;
            const byte paramArrayIndex = 1;
            bool       hasReturnType   = method.ReturnType != Constants.VoidType;

            byte startUsableLocalIndex = 0;

            if (CallInfo.HasRefParam)
            {
                startUsableLocalIndex = CreateLocalsForByRefParams(paramArrayIndex, method);
                // create by_ref_locals from argument array
                Generator.DeclareLocal(hasReturnType
                                                                ? method.ReturnType
                                                                : Constants.ObjectType);  // T result;
                GenerateInvocation(method, paramArrayIndex, (byte)(startUsableLocalIndex + 1));
                if (hasReturnType)
                {
                    Generator.stloc(startUsableLocalIndex);                  // result = <stack>;
                }
                AssignByRefParamsToArray(paramArrayIndex);                   // store by_ref_locals back to argument array
            }
            else
            {
                Generator.DeclareLocal(hasReturnType
                                                                ? method.ReturnType
                                                                : Constants.ObjectType);  // T result;
                GenerateInvocation(method, paramArrayIndex, (byte)(startUsableLocalIndex + 1));
                if (hasReturnType)
                {
                    Generator.stloc(startUsableLocalIndex);                       // result = <stack>;
                }
            }

            if (CallInfo.ShouldHandleInnerStruct)
            {
                StoreLocalToInnerStruct((byte)(startUsableLocalIndex + 1));                    // ((ValueTypeHolder)this)).Value = tmpStr;
            }
            if (hasReturnType)
            {
                Generator.ldloc(startUsableLocalIndex)                   // push result;
                .boxIfValueType(method.ReturnType);                      // box result;
            }
            else
            {
                Generator.ldnull.end();                 // load null
            }
            Generator.ret();

            return(Method.CreateDelegate(typeof(MethodInvoker)));
        }
Beispiel #4
0
        protected internal override Delegate CreateDelegate()
        {
            if (CallInfo.IsTargetTypeStruct && CallInfo.HasNoParam) // no-arg struct needs special initialization
            {
                Generator.DeclareLocal(CallInfo.TargetType);        // TargetType tmp
                Generator.ldloca_s(0)                               // &tmp
                .initobj(CallInfo.TargetType)                       // init_obj(&tmp)
                .ldloc_0.end();                                     // load tmp
            }
            else if (CallInfo.TargetType.IsArray)
            {
                Generator.ldarg_0                                           // load args[] (method arguments)
                .ldc_i4_0                                                   // load 0
                .ldelem_ref                                                 // load args[0] (length)
                .unbox_any(typeof(int))                                     // unbox stack
                .newarr(CallInfo.TargetType.GetElementType());              // new T[args[0]]
            }
            else
            {
                ConstructorInfo ctorInfo = LookupUtils.GetConstructor(CallInfo);
                byte            startUsableLocalIndex = 0;
                if (CallInfo.HasRefParam)
                {
                    startUsableLocalIndex = CreateLocalsForByRefParams(0, ctorInfo); // create by_ref_locals from argument array
                    Generator.DeclareLocal(CallInfo.TargetType);                     // TargetType tmp;
                }

                PushParamsOrLocalsToStack(0);               // push arguments and by_ref_locals
                Generator.newobj(ctorInfo);                 // ctor (<stack>)

                if (CallInfo.HasRefParam)
                {
                    Generator.stloc(startUsableLocalIndex); // tmp = <stack>;
                    AssignByRefParamsToArray(0);            // store by_ref_locals back to argument array
                    Generator.ldloc(startUsableLocalIndex); // tmp
                }
            }
            Generator.boxIfValueType(CallInfo.TargetType)
            .ret();                                         // return (box)<stack>;
            return(Method.CreateDelegate(typeof(ConstructorInvoker)));
        }