private static OpCode GetStindInstruction(System.Type parameterType) { if (parameterType.IsByRef) { OpCode stindOpCode; if(OpCodesMap.TryGetStindOpCode(parameterType.GetElementType(), out stindOpCode)) { return stindOpCode; } } return OpCodes.Stind_Ref; }
private static void SaveRefArguments(ILGenerator IL, ParameterInfo[] parameters) { // Save the arguments returned from the handler method IL.Emit(OpCodes.Ldloc_1); IL.Emit(OpCodes.Call, getArguments); IL.Emit(OpCodes.Stloc_0); foreach (ParameterInfo param in parameters) { string typeName = param.ParameterType.Name; bool isRef = param.ParameterType.IsByRef && typeName.EndsWith("&"); if (!isRef) { continue; } // Load the destination address IL.Emit(OpCodes.Ldarg, param.Position + 1); // Load the argument value IL.Emit(OpCodes.Ldloc_0); IL.Emit(OpCodes.Ldc_I4, param.Position); IL.Emit(OpCodes.Ldelem_Ref); System.Type unboxedType = param.ParameterType.GetElementType(); IL.Emit(OpCodes.Unbox_Any, unboxedType); if (Nullable.GetUnderlyingType(unboxedType) != null) { IL.Emit(OpCodes.Stobj, unboxedType); } else if (OpCodesMap.TryGetStindOpCode(param.ParameterType.GetElementType(), out var stind)) { IL.Emit(stind); } else { IL.Emit(OpCodes.Stind_Ref); } } }