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)); }