protected internal override Delegate CreateDelegate() { /* * Type elementType = TargetType.GetElementType(); * Generator * .ldarg_0 // load array * .castclass(TargetType) // (T[])array * .ldarg_1 // load index * .ldarg_2 // load value * .CastFromObject(elementType) // (unbox | cast) value * .stelem(elementType) // array[index] = value * .ret(); * return Method.CreateDelegate(typeof(ArrayElementSetter)); */ Type elementType = TargetType.GetElementType(); Gen.Emit(OpCodes.Ldarg_0); Gen.Emit(OpCodes.Castclass, TargetType); Gen.Emit(OpCodes.Ldarg_1); Gen.Emit(OpCodes.Ldarg_2); if (elementType == typeof(object)) { Gen.Emit(elementType.IsValueType ? OpCodes.Unbox_Any : OpCodes.Castclass, elementType); } Gen.Emit(OpCodes.Stelem, elementType); Gen.Emit(OpCodes.Ret); return(Method.CreateDelegate(typeof(ArrayElementSetter))); }
protected internal override Delegate CreateDelegate() { Type elementType = TargetType.GetElementType(); Gen.Emit(OpCodes.Ldarg_0); Gen.Emit(OpCodes.Castclass, TargetType); Gen.Emit(OpCodes.Ldarg_1); Gen.Emit(OpCodes.Ldelem, elementType); if (TargetType.IsValueType) { Gen.Emit(OpCodes.Box, TargetType); } Gen.Emit(OpCodes.Ret); return(Method.CreateDelegate(typeof(ArrayElementGetter))); }
protected internal override Delegate CreateDelegate() { if (ReflectionUtils.IsTargetTypeStruct(TargetType) && ReflectionUtils.IsEmptyTypeList(ParameterTypes)) { // No-arg struct needs special initialization Emit.DeclareLocal(TargetType); // TargetType tmp Emit.ldloca_s(0) // &tmp .initobj(TargetType) // init_obj(&tmp) .ldloc_0.end(); // load tmp } else if (TargetType.IsArray) { Emit.ldarg_0 // load args[] (method arguments) .ldc_i4_0 // load 0 .ldelem_ref // load args[0] (length) .unbox_any(typeof(int)) // unbox stack .newarr(TargetType.GetElementType()); // new T[args[0]] } else { ConstructorInfo ctorInfo = TargetType.GetConstructor(Flags, null, ParameterTypes, null); byte startUsableLocalIndex = 0; if (ReflectionUtils.HasRefParam(ParameterTypes)) { startUsableLocalIndex = CreateLocalsForByRefParams(0, ctorInfo); // create by_ref_locals from argument array Emit.DeclareLocal(TargetType); // TargetType tmp; } PushParamsOrLocalsToStack(0); // push arguments and by_ref_locals Emit.newobj(ctorInfo); // ctor (<stack>) if (ReflectionUtils.HasRefParam(ParameterTypes)) { Emit.stloc(startUsableLocalIndex); // tmp = <stack>; AssignByRefParamsToArray(0); // store by_ref_locals back to argument array Emit.ldloc(startUsableLocalIndex); // tmp } } Emit.boxIfValueType(TargetType) .ret(); // return (box)<stack>; return(Method.CreateDelegate(typeof(ConstructorInvoker))); }
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))); }