Beispiel #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;
        }
Beispiel #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);
                }
            }
        }
Beispiel #3
0
        public void PushArguments(ParameterInfo[] methodParameters, ILGenerator IL, bool isStatic)
        {
            ParameterInfo[] parameters     = methodParameters ?? Array.Empty <ParameterInfo>();
            int             parameterCount = parameters.Length;

            // object[] args = new object[size];
            IL.Emit(OpCodes.Ldc_I4, parameterCount);
            IL.Emit(OpCodes.Newarr, typeof(object));
            IL.Emit(OpCodes.Stloc_S, 0);

            if (parameterCount == 0)
            {
                IL.Emit(OpCodes.Ldloc_S, 0);
                return;
            }

            // Populate the object array with the list of arguments
            int index            = 0;
            int argumentPosition = 1;

            foreach (ParameterInfo param in parameters)
            {
                System.Type parameterType = param.ParameterType.IsByRef ? param.ParameterType.GetElementType() : param.ParameterType;
                // args[N] = argumentN (pseudocode)
                IL.Emit(OpCodes.Ldloc_S, 0);
                IL.Emit(OpCodes.Ldc_I4, index);

                // Zero out the [out] parameters
                if (param.IsOut)
                {
                    IL.Emit(OpCodes.Ldnull);
                    IL.Emit(OpCodes.Stelem_Ref);
                    argumentPosition++;
                    index++;
                    continue;
                }

                IL.Emit(OpCodes.Ldarg, argumentPosition);

                if (param.ParameterType.IsByRef)
                {
                    var unboxedType = param.ParameterType.GetElementType();
                    if (Nullable.GetUnderlyingType(unboxedType) != null)
                    {
                        IL.Emit(OpCodes.Ldobj, unboxedType);
                    }
                    else if (OpCodesMap.TryGetLdindOpCode(unboxedType, out var ldind))
                    {
                        IL.Emit(ldind);
                    }
                    else
                    {
                        IL.Emit(OpCodes.Ldind_Ref);
                    }
                }

                if (parameterType.IsValueType || param.ParameterType.IsByRef || parameterType.IsGenericParameter)
                {
                    IL.Emit(OpCodes.Box, parameterType);
                }

                IL.Emit(OpCodes.Stelem_Ref);

                index++;
                argumentPosition++;
            }
            IL.Emit(OpCodes.Ldloc_S, 0);
        }