private static void ProxyInvoke(ICode c, Type returnType, IParameterList args, Func <FactoryPair, IOperand[], IOperand> callTarget) { bool hasRef = false; IOperand[] vars = new IOperand[args.Count]; IOperand[] parameters = new IOperand[args.Count]; FactoryPair[] pairs = new FactoryPair[args.Count]; for (int i = 0; i < args.Count; i++) { var arg = args[i]; var pair = GetFactoryPair(arg.Type); if (pair == null) { parameters[i] = arg; continue; } pairs[i] = pair; if (arg.Direction == ParameterDirection.In) { parameters[i] = c.Invoke(pair.GetTarget, arg); continue; } hasRef = true; vars[i] = c.Variable(arg.Type.GetElementType(), arg.Name + "Target"); if (arg.Direction == ParameterDirection.Ref) { c.Assign(vars[i], c.Invoke(pair.GetTarget, arg)); } parameters[i] = vars[i]; } var returnPair = GetFactoryPair(returnType); var result = callTarget(returnPair, parameters); bool isVoid = returnType == typeof(void) || result == null; if (hasRef) { if (!isVoid) { result = c.Variable(returnType, "result", result); } for (int i = 0; i < args.Count; i++) { if (vars[i] == null) { continue; } c.Assign(args[i], c.Invoke(pairs[i].GetProxy, vars[i])); } } if (result == null) { c.Return(); } else if (returnPair == null) { c.Return(result); } else { c.Return(c.Invoke(returnPair.GetProxy, result)); } }