public static DynamicMetaObject Operation(BinaryOperationBinder operation, DynamicMetaObject target, DynamicMetaObject arg, DynamicMetaObject errorSuggestion) { PerfTrack.NoteEvent(PerfTrack.Categories.Binding, "Fallback BinaryOperator " + target.LimitType.FullName + " " + operation.Operation + " " + arg.LimitType.FullName); PerfTrack.NoteEvent(PerfTrack.Categories.BindingTarget, operation.Operation.ToString()); DynamicMetaObject[] args = new[] { target, arg }; if (BindingHelpers.NeedsDeferal(args)) return operation.Defer(args); ValidationInfo valInfo = BindingHelpers.GetValidationInfo(args); TotemOperationKind? toOperator = null; switch (operation.Operation) { case ExpressionType.Add: toOperator = TotemOperationKind.Add; break; case ExpressionType.And: toOperator = TotemOperationKind.BitwiseAnd; break; case ExpressionType.Divide: toOperator = TotemOperationKind.Divide; break; case ExpressionType.ExclusiveOr: toOperator = TotemOperationKind.ExclusiveOr; break; case ExpressionType.Modulo: toOperator = TotemOperationKind.Mod; break; case ExpressionType.Multiply: toOperator = TotemOperationKind.Multiply; break; case ExpressionType.Or: toOperator = TotemOperationKind.BitwiseOr; break; case ExpressionType.Power: toOperator = TotemOperationKind.Power; break; case ExpressionType.RightShift: toOperator = TotemOperationKind.RightShift; break; case ExpressionType.LeftShift: toOperator = TotemOperationKind.LeftShift; break; case ExpressionType.Subtract: toOperator = TotemOperationKind.Subtract; break; case ExpressionType.AddAssign: toOperator = TotemOperationKind.InPlaceAdd; break; case ExpressionType.AndAssign: toOperator = TotemOperationKind.InPlaceBitwiseAnd; break; case ExpressionType.DivideAssign: toOperator = TotemOperationKind.InPlaceDivide; break; case ExpressionType.ExclusiveOrAssign: toOperator = TotemOperationKind.InPlaceExclusiveOr; break; case ExpressionType.ModuloAssign: toOperator = TotemOperationKind.InPlaceMod; break; case ExpressionType.MultiplyAssign: toOperator = TotemOperationKind.InPlaceMultiply; break; case ExpressionType.OrAssign: toOperator = TotemOperationKind.InPlaceBitwiseOr; break; case ExpressionType.PowerAssign: toOperator = TotemOperationKind.InPlacePower; break; case ExpressionType.RightShiftAssign: toOperator = TotemOperationKind.InPlaceRightShift; break; case ExpressionType.LeftShiftAssign: toOperator = TotemOperationKind.InPlaceLeftShift; break; case ExpressionType.SubtractAssign: toOperator = TotemOperationKind.InPlaceSubtract; break; case ExpressionType.Equal: toOperator = TotemOperationKind.Equal; break; case ExpressionType.GreaterThan: toOperator = TotemOperationKind.GreaterThan; break; case ExpressionType.GreaterThanOrEqual: toOperator = TotemOperationKind.GreaterThanOrEqual; break; case ExpressionType.LessThan: toOperator = TotemOperationKind.LessThan; break; case ExpressionType.LessThanOrEqual: toOperator = TotemOperationKind.LessThanOrEqual; break; case ExpressionType.NotEqual: toOperator = TotemOperationKind.NotEqual; break; } DynamicMetaObject res = null; if (toOperator != null) res = MakeBinaryOperation(operation, args, toOperator.Value, errorSuggestion); else res = operation.FallbackBinaryOperation(target, arg); return BindingHelpers.AddDynamicTestAndDefer(operation, BindingHelpers.AddTotemBoxing(res), args, valInfo); }
public static DynamicMetaObject Operation(UnaryOperationBinder operation, DynamicMetaObject arg, DynamicMetaObject errorSuggestion) { PerfTrack.NoteEvent(PerfTrack.Categories.Binding, "Fallback UnaryOperator " + " " + operation.Operation + " " + arg.LimitType.FullName); PerfTrack.NoteEvent(PerfTrack.Categories.BindingTarget, operation.Operation.ToString()); DynamicMetaObject[] args = new[] { arg }; if (arg.NeedsDeferral()) return operation.Defer(arg); ValidationInfo valInfo = BindingHelpers.GetValidationInfo(args); TotemOperationKind? toOperator = null; Type retType = typeof(object); bool box = true; bool inverse = false; switch (operation.Operation) { case ExpressionType.UnaryPlus: toOperator = TotemOperationKind.Positive; break; case ExpressionType.Negate: toOperator = TotemOperationKind.Negate; break; case ExpressionType.OnesComplement: toOperator = TotemOperationKind.OnesComplement; break; case ExpressionType.Not: toOperator = TotemOperationKind.Not; box = false; break; case ExpressionType.IsFalse: toOperator = TotemOperationKind.IsFalse; box = false; retType = typeof(bool); break; case ExpressionType.IsTrue: toOperator = TotemOperationKind.IsFalse; box = false; retType = typeof(bool); inverse = true; break; } DynamicMetaObject res = null; if (toOperator != null) res = MakeUnaryOperation(operation, args[0], toOperator.Value, errorSuggestion, retType); else res = operation.FallbackUnaryOperation(arg); if (inverse) { res = new DynamicMetaObject( Expression.Condition( res.Expression, Utils.Constant(ScriptingRuntimeHelpers.False), Utils.Constant(ScriptingRuntimeHelpers.True) ), res.Restrictions ); } if (box) { res = BindingHelpers.AddTotemBoxing(res); } return BindingHelpers.AddDynamicTestAndDefer(operation, res, args, valInfo, retType); }