Exemple #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));
        }
        Expr NegateOp(DynamicMetaObject target)
        {
            var expr = LuaConvertBinder.ToNumber(target);

            if (expr == null)
            {
                return(MetamethodFallbacks.UnaryMinus(context, target));
            }

            if (target.LimitType == typeof(string))
            {
                return(FallbackIfNumberIsNan(expr));
            }

            return(Expr.MakeUnary(Operation, Expr.Convert(expr, typeof(double)), null));
        }
        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)));
        }
        public override DynamicMetaObject FallbackGetIndex(DynamicMetaObject target, DynamicMetaObject[] indexes, DynamicMetaObject errorSuggestion)
        {
            var expression = MetamethodFallbacks.Index(context, target, indexes);

            return(new DynamicMetaObject(expression, BindingRestrictions.Empty));
        }