protected void EmitCallWithInvoke (EmitContext ec, Expression binder, Arguments arguments, bool isStatement) { var module = ec.Module; var site_container = ec.CreateDynamicSite (); BlockContext bc = new BlockContext (ec.MemberContext, null, ec.BuiltinTypes.Void); FieldExpr site_field_expr = null; StatementExpression s = null; // create call site var call_site = binder; if (call_site != null) { // resolve call site call_site = call_site.Resolve(bc); // create field for call site var site_type_decl = call_site.Type; var field = site_container.CreateCallSiteField (new TypeExpression(site_type_decl, loc), loc); if (field == null) { throw new InvalidOperationException("Could not create call site field"); } // ??? bool inflate_using_mvar = context_mvars != null && ec.IsAnonymousStoreyMutateRequired; // ??? TypeSpec gt; if (inflate_using_mvar || context_mvars == null) { gt = site_container.CurrentType; } else { gt = site_container.CurrentType.MakeGenericType (module, context_mvars.Types); } // When site container already exists the inflated version has to be // updated manually to contain newly created field if (gt is InflatedTypeSpec && site_container.AnonymousMethodsCounter > 1) { var tparams = gt.MemberDefinition.TypeParametersCount > 0 ? gt.MemberDefinition.TypeParameters : TypeParameterSpec.EmptyTypes; var inflator = new TypeParameterInflator (module, gt, tparams, gt.TypeArguments); gt.MemberCache.AddMember (field.InflateMember (inflator)); } site_field_expr = new FieldExpr (MemberCache.GetMember (gt, field), loc); s = new StatementExpression (new SimpleAssign (site_field_expr, call_site)); } using (ec.With (BuilderContext.Options.OmitDebugInfo, true)) { if (s!= null && s.Resolve (bc)) { Statement init = new If (new Binary (Binary.Operator.Equality, site_field_expr, new NullLiteral (loc)), s, loc); init.Emit (ec); } // remove dynamics from argument list arguments.CastDynamicArgs(bc); IDynamicCallSite dynamicCallSite = (IDynamicCallSite)this.binder; Expression target = dynamicCallSite.InvokeCallSite(bc, site_field_expr, arguments, type, isStatement); if (target != null) target = target.Resolve(bc); if (target != null) { var statement = target as ExpressionStatement; if (isStatement && statement != null) { statement.EmitStatement(ec); } else { if (!isStatement && (target.Type != type)) { // PlayScript: If doing an invoke, we have to cast the return type to the type expected by the expression.. target = new Cast(new TypeExpression(type, loc), target, loc).Resolve (bc); } target.Emit(ec); } } } }