private Expression GenerateComplexCall(RHC rhc, ObjExpr objx, GenContext context)
{
Expression call;
Expression target = GenTargetExpression(objx,context);
List<Expression> exprs = new List<Expression>(_args.Count);
List<ParameterExpression> sbParams = new List<ParameterExpression>();
List<Expression> sbInits = new List<Expression>();
List<Expression> sbTransfers = new List<Expression>();
MethodExpr.GenerateComplexArgList(objx, context, _args, out exprs, out sbParams, out sbInits, out sbTransfers);
Expression[] argExprs = ClrExtensions.ArrayInsert<Expression>(target, exprs);
Type returnType = this.ClrType;
Type stubType = Compiler.CompileStubOrigClassVar.isBound ? (Type)Compiler.CompileStubOrigClassVar.deref() : null;
if (returnType == stubType)
returnType = objx.BaseType;
// TODO: get rid of Default
CreateInstanceBinder binder = new ClojureCreateInstanceBinder(ClojureContext.Default,_args.Count);
DynamicExpression dyn = Expression.Dynamic(binder, typeof(object), argExprs);
// I'd like to use returnType in place of typeof(object) in the previous,
// But I can't override ReturnType in DefaultCreateInstanceBinder and this causes an error.
// Look for the conversion below.
//if (context.Mode == CompilerMode.File)
if (context.DynInitHelper != null)
call = context.DynInitHelper.ReduceDyn(dyn);
else
call = dyn;
call = Expression.Convert(call, returnType);
if (sbParams.Count > 0)
{
// We have ref/out params. Construct the complicated call;
ParameterExpression callValParam = Expression.Parameter(returnType, "__callVal");
ParameterExpression[] allParams = ClrExtensions.ArrayInsert<ParameterExpression>(callValParam, sbParams);
call = Expression.Block(
returnType,
allParams,
Expression.Block(sbInits),
Expression.Assign(callValParam, call),
Expression.Block(sbTransfers),
callValParam);
}
return call;
}