public override DynamicMetaObject FallbackUnaryOperation(DynamicMetaObject target, DynamicMetaObject errorSuggestion)
        {
            if (!target.HasValue)
            {
                return(Defer(target));
            }

            DynamicMetaObject firstVarargs;

            if (RuntimeHelpers.TryGetFirstVarargs(target, out firstVarargs))
            {
                return(FallbackUnaryOperation(firstVarargs, errorSuggestion));
            }

            Expr expression;

            switch (Operation)
            {
            case ExprType.Negate:
                expression = NegateOp(target);
                break;

            case ExprType.Not:
                expression = NotOp(target);
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            return(new DynamicMetaObject(Expr.Convert(expression, typeof(object)), RuntimeHelpers.MergeTypeRestrictions(target)));
        }
Beispiel #2
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));
        }
Beispiel #3
0
        public override DynamicMetaObject FallbackConvert(DynamicMetaObject target, DynamicMetaObject errorSuggestion)
        {
            Expr expression = null;

            if (Type == typeof(double))
            {
                expression = ToNumber(target);
            }
            else if (Type == typeof(bool))
            {
                expression = ToBool(target);
            }

            if (expression == null)
            {
                throw new InvalidOperationException();
            }

            return(new DynamicMetaObject(expression, RuntimeHelpers.MergeTypeRestrictions(target)));
        }
        public override DynamicMetaObject FallbackBinaryOperation(DynamicMetaObject target, DynamicMetaObject arg, DynamicMetaObject errorSuggestion)
        {
            if (!target.HasValue || !arg.HasValue)
            {
                return(Defer(target, arg));
            }

            DynamicMetaObject targetFirst, argFirst;

            if (RuntimeHelpers.TryGetFirstVarargs(target, out targetFirst) | RuntimeHelpers.TryGetFirstVarargs(arg, out argFirst))
            {
                return(FallbackBinaryOperation(targetFirst, argFirst, errorSuggestion));
            }

            Expr expression = null;

            switch (BinaryExprTypes[Operation])
            {
            case BinaryOpType.Relational:
                expression = Relational(target, arg);
                break;

            case BinaryOpType.Logical:
                expression = Logical(target, arg);
                break;

            case BinaryOpType.Numeric:
                expression = Numeric(target, arg);
                break;
            }

            if (expression == null)
            {
                expression = MetamethodFallbacks.BinaryOp(context, Operation, target, arg);
            }

            return(new DynamicMetaObject(Expr.Convert(expression, typeof(object)), RuntimeHelpers.MergeTypeRestrictions(target, arg)));
        }