internal Expression MakeExpression(RestrictedArguments restrictedArgs) { bool[] usageMarkers; Expression[] spilledArgs; Expression[] callArgs = GetArgumentExpressions(restrictedArgs, out usageMarkers, out spilledArgs); Expression call; MethodBase mb = _overload.ReflectionInfo; // TODO: make MakeExpression virtual on OverloadInfo? if (mb == null) { throw new InvalidOperationException("Cannot generate an expression for an overload w/o MethodBase"); } MethodInfo mi = mb as MethodInfo; if (mi != null) { Expression instance; if (mi.IsStatic) { instance = null; } else { Debug.Assert(mi != null); instance = _instanceBuilder.ToExpression(ref mi, _resolver, restrictedArgs, usageMarkers); Debug.Assert(instance != null, "Can't skip instance expression"); } if (CompilerHelpers.IsVisible(mi)) { call = AstUtils.SimpleCallHelper(instance, mi, callArgs); } else { call = Ast.Call( typeof(BinderOps).GetMethod("InvokeMethod"), AstUtils.Constant(mi), instance != null ? AstUtils.Convert(instance, typeof(object)) : AstUtils.Constant(null), AstUtils.NewArrayHelper(typeof(object), callArgs) ); } } else { ConstructorInfo ci = (ConstructorInfo)mb; if (CompilerHelpers.IsVisible(ci)) { call = AstUtils.SimpleNewHelper(ci, callArgs); } else { call = Ast.Call( typeof(BinderOps).GetMethod("InvokeConstructor"), AstUtils.Constant(ci), AstUtils.NewArrayHelper(typeof(object), callArgs) ); } } if (spilledArgs != null) { call = Expression.Block(spilledArgs.AddLast(call)); } Expression ret = _returnBuilder.ToExpression(_resolver, _argBuilders, restrictedArgs, call); List <Expression> updates = null; for (int i = 0; i < _argBuilders.Count; i++) { Expression next = _argBuilders[i].UpdateFromReturn(_resolver, restrictedArgs); if (next != null) { if (updates == null) { updates = new List <Expression>(); } updates.Add(next); } } if (updates != null) { if (ret.Type != typeof(void)) { ParameterExpression temp = Ast.Variable(ret.Type, "$ret"); updates.Insert(0, Ast.Assign(temp, ret)); updates.Add(temp); ret = Ast.Block(new[] { temp }, updates.ToArray()); } else { updates.Insert(0, ret); ret = Ast.Block(typeof(void), updates.ToArray()); } } if (_resolver.Temps != null) { ret = Ast.Block(_resolver.Temps, ret); } return(ret); }