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() { 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))); }