Exemplo n.º 1
0
		/// <summary>
		///   Emit the code needed to marshal back the local variables to by-ref parameters.
		/// </summary>
		protected void EmitManagedToNativeMarshallingForByRefParameters (ILGenerator generator, Type[] nativeParameterTypes, ByRefParameter[] byRefLocalVariables)
		{
			for (int i = 0; i < byRefLocalVariables.Length; i++) {
				LocalBuilder local = byRefLocalVariables [i].LocalBuilder;
				if (local == null) {
					continue;
				}

				this.EmitManagedToNativeMarshallingCast (generator, local, local.LocalType, i);
			}
		}
Exemplo n.º 2
0
        private Expression BuildMethodCall(MethodBase method, Type type, ParameterExpression targetParameterExpression, ParameterExpression argsParameterExpression)
        {
            Expression expression6;

            ParameterInfo[]        parameters = method.GetParameters();
            Expression[]           arguments  = new Expression[parameters.Length];
            IList <ByRefParameter> list       = new List <ByRefParameter>();

            for (int i = 0; i < parameters.Length; i++)
            {
                Expression    expression4;
                ParameterInfo info          = parameters[i];
                Type          parameterType = info.ParameterType;
                bool          flag          = false;
                if (parameterType.IsByRef)
                {
                    parameterType = parameterType.GetElementType();
                    flag          = true;
                }
                Expression index = Expression.Constant(i);
                Expression left  = Expression.ArrayIndex(argsParameterExpression, index);
                if (parameterType.IsValueType())
                {
                    BinaryExpression expression = Expression.Coalesce(left, Expression.New(parameterType));
                    expression4 = this.EnsureCastExpression(expression, parameterType);
                }
                else
                {
                    expression4 = this.EnsureCastExpression(left, parameterType);
                }
                if (flag)
                {
                    ParameterExpression expression5 = Expression.Variable(parameterType);
                    ByRefParameter      item        = new ByRefParameter {
                        Value    = expression4,
                        Variable = expression5,
                        IsOut    = info.IsOut
                    };
                    list.Add(item);
                    expression4 = expression5;
                }
                arguments[i] = expression4;
            }
            if (method.IsConstructor)
            {
                expression6 = Expression.New((ConstructorInfo)method, arguments);
            }
            else if (method.IsStatic)
            {
                expression6 = Expression.Call((MethodInfo)method, arguments);
            }
            else
            {
                expression6 = Expression.Call(this.EnsureCastExpression(targetParameterExpression, method.DeclaringType), (MethodInfo)method, arguments);
            }
            if (method is MethodInfo)
            {
                if (((MethodInfo)method).ReturnType != typeof(void))
                {
                    expression6 = this.EnsureCastExpression(expression6, type);
                }
                else
                {
                    expression6 = Expression.Block(expression6, Expression.Constant(null));
                }
            }
            else
            {
                expression6 = this.EnsureCastExpression(expression6, type);
            }
            if (list.Count <= 0)
            {
                return(expression6);
            }
            IList <ParameterExpression> list2 = new List <ParameterExpression>();
            IList <Expression>          list3 = new List <Expression>();

            foreach (ByRefParameter parameter in list)
            {
                if (!parameter.IsOut)
                {
                    list3.Add(Expression.Assign(parameter.Variable, parameter.Value));
                }
                list2.Add(parameter.Variable);
            }
            list3.Add(expression6);
            return(Expression.Block((IEnumerable <ParameterExpression>)list2, (IEnumerable <Expression>)list3));
        }
Exemplo n.º 3
0
		/// <summary>
		///   Genenerate optimized IL for stacking parameters :
		///   - For the third or fourth parameter, use the short OpCode
		///   - For all the parameters left, use the long OpCode
		/// </summary>
		protected static void EmitParametersLoadingOnStack (ILGenerator generator, Type[] parameterTypes, Type[] nativeParameterTypes, ByRefParameter[] byRefLocalVariables, int parameterOffset)
		{
			for (int i = 0; i < parameterTypes.Length; i++) {
				// For by-ref type, loads the local variable
				// Otherwise, loads the argument (wrapped or not)
				Type parameterType = parameterTypes [i];
				if (parameterType.IsByRef) {
					generator.Emit (OpCodes.Ldloca, byRefLocalVariables [i].LocalBuilder);
				} else {
                    EmitLoadArgument (generator, i + parameterOffset);

					// For wrapped type (interface or Id subclass)
					if (TypeHelper.NeedWrapping (parameterType)) {
						MethodInfo wrapInstance = EmitInfos.OBJECTIVECRUNTIME_GETINSTANCE.MakeGenericMethod (new[] {parameterType});
						generator.Emit (OpCodes.Call, wrapInstance);
					} else {
						EmitHelper.CastValueType (generator, nativeParameterTypes [i], parameterTypes [i]);
					}
				}
			}
		}
Exemplo n.º 4
0
		/// <summary>
		///   For by-ref parameters passed as reference (without [out] attribute), we first set the value of local variables
		/// </summary>
		protected void EmitNativeToManagedMarshallingForByRefParameters (ILGenerator generator, Type[] nativeParameterTypes, ByRefParameter[] byRefLocalVariables)
		{
			for (int i = 0; i < byRefLocalVariables.Length; i++) {
				ByRefParameter parameter = byRefLocalVariables [i];
				if (parameter.LocalBuilder == null || parameter.IsOut) {
					continue;
				}

				Type localType = parameter.LocalBuilder.LocalType;

				EmitLoadArgument (generator, i + 2);
				this.EmitNativeToManagedMarshallingCast (generator, localType);
				generator.Emit (OpCodes.Stloc, parameter.LocalBuilder);
			}
		}
Exemplo n.º 5
0
		/// <summary>
		///   Emit local variable for each by-ref parameters. These variables will hold the result until the marshalling occurs.
		/// </summary>
		protected static ByRefParameter[] CreateLocalVariableForByRefParameters (ILGenerator generator, ParameterInfo[] parameterInfos)
		{
			ByRefParameter[] byrefLocals = new ByRefParameter[parameterInfos.Length];
			for (int i = 0; i < parameterInfos.Length; i++) {
				Type parameterType = parameterInfos [i].ParameterType;

				// For by-ref type, create a local variable and store it
				if (!parameterType.IsByRef) {
					continue;
				}

				// Create the local variable of the de-referenced type
				byrefLocals [i].LocalBuilder = generator.DeclareLocal (parameterType.GetElementType ());
				byrefLocals [i].IsOut = parameterInfos [i].IsOut;
			}
			return byrefLocals;
		}
Exemplo n.º 6
0
        private void AddBasicMethodTargets(MethodTracker method)
        {
            List<Parameter> parameters = new List<Parameter>();
            int argIndex = 0;
            ArgBuilder instanceBuilder;
            if (!method.IsStatic) {
                parameters.Add(new Parameter(method.DeclaringType));
                instanceBuilder = new SimpleArgBuilder(argIndex++, parameters[0]);
            } else {
                instanceBuilder = new NullArgBuilder();
            }

            List<ArgBuilder> argBuilders = new List<ArgBuilder>();
            List<ArgBuilder> defaultBuilders = new List<ArgBuilder>();
            bool hasByRef = false;

            foreach (ParameterInfo pi in method.GetParameters()) {
                if (pi.ParameterType == typeof(ICallerContext)) {
                    argBuilders.Add(new ContextArgBuilder());
                    continue;
                }

                if (pi.DefaultValue != DBNull.Value) {
                    defaultBuilders.Add(new DefaultArgBuilder(pi.ParameterType, pi.DefaultValue));
                } else if (defaultBuilders.Count > 0) {
                    // If we get a bad method with non-contiguous default values, then just use the contiguous list
                    defaultBuilders.Clear();
                }

                if (pi.ParameterType.IsByRef) {
                    hasByRef = true;
                    Parameter param = new ByRefParameter(pi.ParameterType.GetElementType(), pi.IsOut && !pi.IsIn);
                    parameters.Add(param);
                    argBuilders.Add(new ReferenceArgBuilder(argIndex++, param));
                } else {
                    Parameter param = new Parameter(pi.ParameterType);
                    parameters.Add(param);
                    argBuilders.Add(new SimpleArgBuilder(argIndex++, param));
                }
            }

            ReturnBuilder returnBuilder = new ReturnBuilder(CompilerHelpers.GetReturnType(method.Method));

            for (int i = 1; i < defaultBuilders.Count + 1; i++) {
                List<ArgBuilder> defaultArgBuilders = argBuilders.GetRange(0, argBuilders.Count - i);
                defaultArgBuilders.AddRange(defaultBuilders.GetRange(defaultBuilders.Count - i, i));
                AddTarget(new MethodTarget(method, parameters.GetRange(0, parameters.Count - i),
                    instanceBuilder, defaultArgBuilders, returnBuilder));
            }

            if (hasByRef) AddSimpleTarget(MakeByRefReducedMethodTarget(method, parameters, instanceBuilder, argBuilders));
            AddSimpleTarget(new MethodTarget(method, parameters, instanceBuilder, argBuilders, returnBuilder));
        }
        private Expression BuildMethodCall(MethodBase method, Type type, ParameterExpression?targetParameterExpression, ParameterExpression argsParameterExpression)
        {
            ParameterInfo[] parametersInfo = method.GetParameters();

            Expression[]           argsExpression;
            IList <ByRefParameter> refParameterMap;

            if (parametersInfo.Length == 0)
            {
                argsExpression  = new Expression[0];
                refParameterMap = new ByRefParameter[0];
            }
            else
            {
                argsExpression  = new Expression[parametersInfo.Length];
                refParameterMap = new List <ByRefParameter>();

                for (int i = 0; i < parametersInfo.Length; i++)
                {
                    ParameterInfo parameter     = parametersInfo[i];
                    Type          parameterType = parameter.ParameterType;
                    bool          isByRef       = false;
                    if (parameterType.IsByRef)
                    {
                        parameterType = parameterType.GetElementType();
                        isByRef       = true;
                    }

                    Expression indexExpression = Expression.Constant(i);

                    Expression paramAccessorExpression = Expression.ArrayIndex(argsParameterExpression, indexExpression);

                    Expression argExpression = EnsureCastExpression(paramAccessorExpression, parameterType, !isByRef);

                    if (isByRef)
                    {
                        ParameterExpression variable = Expression.Variable(parameterType);
                        refParameterMap.Add(new ByRefParameter(argExpression, variable, parameter.IsOut));

                        argExpression = variable;
                    }

                    argsExpression[i] = argExpression;
                }
            }

            Expression callExpression;

            if (method.IsConstructor)
            {
                callExpression = Expression.New((ConstructorInfo)method, argsExpression);
            }
            else if (method.IsStatic)
            {
                callExpression = Expression.Call((MethodInfo)method, argsExpression);
            }
            else
            {
                Expression readParameter = EnsureCastExpression(targetParameterExpression !, method.DeclaringType);

                callExpression = Expression.Call(readParameter, (MethodInfo)method, argsExpression);
            }

            if (method is MethodInfo m)
            {
                if (m.ReturnType != typeof(void))
                {
                    callExpression = EnsureCastExpression(callExpression, type);
                }
                else
                {
                    callExpression = Expression.Block(callExpression, Expression.Constant(null));
                }
            }
            else
            {
                callExpression = EnsureCastExpression(callExpression, type);
            }

            if (refParameterMap.Count > 0)
            {
                IList <ParameterExpression> variableExpressions = new List <ParameterExpression>();
                IList <Expression>          bodyExpressions     = new List <Expression>();
                foreach (ByRefParameter p in refParameterMap)
                {
                    if (!p.IsOut)
                    {
                        bodyExpressions.Add(Expression.Assign(p.Variable, p.Value));
                    }

                    variableExpressions.Add(p.Variable);
                }

                bodyExpressions.Add(callExpression);

                callExpression = Expression.Block(variableExpressions, bodyExpressions);
            }

            return(callExpression);
        }