void LoadInputParametersIntoLocals(ParameterInfo[] parameters, LocalBuilder[] parameterLocals, ArgBuilder inputParametersArg, out int inputParameterCount) { inputParameterCount = 0; for (int i = 0; i < parameterLocals.Length; i++) { if (ServiceReflector.FlowsIn(parameters[i])) { Type parameterType = parameterLocals[i].LocalType; ilg.LoadArrayElement(inputParametersArg, inputParameterCount); if (!parameterType.IsValueType) { ilg.ConvertValue(TypeOfObject, parameterType); ilg.Store(parameterLocals[i]); } else { ilg.Dup(); ilg.If(); ilg.ConvertValue(TypeOfObject, parameterType); ilg.Store(parameterLocals[i]); ilg.Else(); ilg.Pop(); ilg.LoadZeroValueIntoLocal(parameterType, parameterLocals[i]); ilg.EndIf(); } inputParameterCount++; } } }
private void CreateInArgs() { var parameters = MethodBase.GetParameters(); int inCount = 0; foreach (var param in parameters) { if (ServiceReflector.FlowsIn(param)) { inCount++; } } if (inCount == Args.Length) // All parameters are InArgs so do nothing and fallback to returning Args { return; } _inArgs = new object[inCount]; int inPos = 0; for (int argPos = 0; argPos < parameters.Length; argPos++) { if (ServiceReflector.FlowsIn(parameters[argPos])) { _inArgs[inPos] = Args[argPos]; inPos++; } } Fx.Assert((inPos - 1) != (inCount), $"Incorrect number of arguments put into _inArgs array, expected {inCount} and copied {inPos - 1}"); }
void LoadZeroValueInputParametersIntoLocals(ParameterInfo[] parameters, LocalBuilder[] parameterLocals) { for (int i = 0; i < parameterLocals.Length; i++) { if (ServiceReflector.FlowsIn(parameters[i])) { ilg.LoadZeroValueIntoLocal(parameterLocals[i].LocalType, parameterLocals[i]); } } }
internal static InvokeDelegate GenerateInvokeDelegate(MethodInfo method, out int inputParameterCount, out int outputParameterCount) { ParameterInfo[] parameters = method.GetParameters(); bool returnsValue = method.ReturnType != typeof(void); int paramCount = parameters.Length; var inputParamPositions = new List <int>(); var outputParamPositions = new List <int>(); for (int i = 0; i < parameters.Length; i++) { if (ServiceReflector.FlowsIn(parameters[i])) { inputParamPositions.Add(i); } if (ServiceReflector.FlowsOut(parameters[i])) { outputParamPositions.Add(i); } } int[] inputPos = inputParamPositions.ToArray(); int[] outputPos = outputParamPositions.ToArray(); inputParameterCount = inputPos.Length; outputParameterCount = outputPos.Length; // TODO: Replace with expression to remove performance cost of calling delegate.Invoke. InvokeDelegate lambda = delegate(object target, object[] inputs, object[] outputs) { object[] paramsLocal = null; if (paramCount > 0) { paramsLocal = new object[paramCount]; for (int i = 0; i < inputPos.Length; i++) { paramsLocal[inputPos[i]] = inputs[i]; } } object result = null; try { if (returnsValue) { result = method.Invoke(target, paramsLocal); } else { method.Invoke(target, paramsLocal); } } catch (TargetInvocationException tie) { ExceptionDispatchInfo.Capture(tie.InnerException).Throw(); } for (int i = 0; i < outputPos.Length; i++) { Debug.Assert(paramsLocal != null); outputs[i] = paramsLocal[outputPos[i]]; } return(result); }; return(lambda); }