Exemplo n.º 1
0
        public override DynamicMetaObject FallbackInvoke(DynamicMetaObject target, DynamicMetaObject[] args, DynamicMetaObject errorSuggestion)
        {
            if (!target.HasValue || args.Any(a => !a.HasValue))
            {
                return(Defer(target, args));
            }

            var restrictions = RuntimeHelpers.MergeTypeRestrictions(target);

            if (!target.LimitType.IsSubclassOf(typeof(Delegate)))
            {
                return(new DynamicMetaObject(MetamethodFallbacks.Call(context, target, args), restrictions));
            }

            restrictions = restrictions.Merge(
                RuntimeHelpers.MergeTypeRestrictions(args).Merge(
                    RuntimeHelpers.MergeInstanceRestrictions(target)));

            List <Expr> sideEffects;
            Expr        failExpr;
            var         function   = (Delegate)target.Value;
            var         methodInfo = function.Method;
            var         mappedArgs = MapArguments(args, methodInfo, ref restrictions, out sideEffects, out failExpr);

            if (failExpr != null)
            {
                return(new DynamicMetaObject(Expr.Block(failExpr, Expr.Default(typeof(object))), restrictions));
            }

            var invokeExpr = InvokeExpression(target, mappedArgs, methodInfo);

            // Execute overflowing arguments for side effects
            Expr expr;

            if (sideEffects.Count == 0)
            {
                expr = invokeExpr;
            }
            else
            {
                var tempVar = Expr.Variable(typeof(object));
                var assign  = Expr.Assign(tempVar, invokeExpr);
                sideEffects.Insert(0, assign);
                sideEffects.Add(tempVar);
                expr = Expr.Block(new[] { tempVar }, sideEffects);
            }

            return(new DynamicMetaObject(expr, restrictions));
        }
Exemplo n.º 2
0
        void ExpandLastArg(List <Argument> arguments, DynamicMetaObject[] args, ref BindingRestrictions restrictions)
        {
            if (args.Length == 0)
            {
                return;
            }

            var lastArg = args.Last();

            if (lastArg.LimitType != typeof(Varargs))
            {
                return;
            }

            // TODO: Use custom restriction (checks length and types) and add arguments by indexing into Varargs value
            restrictions = restrictions.Merge(RuntimeHelpers.MergeInstanceRestrictions(lastArg));

            var varargs = (Varargs)lastArg.Value;

            arguments.RemoveAt(arguments.Count - 1);
            arguments.AddRange(varargs.Select(value => new Argument(Expr.Constant(value), value.GetType())));
        }