예제 #1
0
        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;
        }
예제 #2
0
        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);
                }
            }
        }