Esempio n. 1
0
        DynamicMetaObject IPythonOperable.BindOperation(PythonOperationBinder action, DynamicMetaObject[] args)
        {
            switch (action.Operation)
            {
            case PythonOperationKind.CallSignatures:
                return(PythonProtocol.MakeCallSignatureOperation(this, Value.Template.Targets));
            }

            return(null);
        }
Esempio n. 2
0
        DynamicMetaObject IPythonOperable.BindOperation(PythonOperationBinder action, DynamicMetaObject[] args) {
            PerfTrack.NoteEvent(PerfTrack.Categories.Binding, "BuiltinFunc Operation " + action.Operation);
            PerfTrack.NoteEvent(PerfTrack.Categories.BindingTarget, "BuiltinFunc Operation");
            switch (action.Operation) {
                case PythonOperationKind.CallSignatures:
                    return PythonProtocol.MakeCallSignatureOperation(this, Value.Targets);
            }

            return null;
        }
Esempio n. 3
0
        DynamicMetaObject IPythonOperable.BindOperation(PythonOperationBinder action, DynamicMetaObject[] args) {
            PerfTrack.NoteEvent(PerfTrack.Categories.Binding, "BuiltinFunc Operation " + action.Operation);
            PerfTrack.NoteEvent(PerfTrack.Categories.BindingTarget, "BuiltinFunc Operation");
            switch (action.Operation) {
                case PythonOperationKind.CallSignatures:
                    return PythonProtocol.MakeCallSignatureOperation(this, Value.Targets);
            }

            return null;
        }
Esempio n. 4
0
        DynamicMetaObject IPythonOperable.BindOperation(PythonOperationBinder action, DynamicMetaObject[] args)
        {
            PerfTrack.NoteEvent(PerfTrack.Categories.Binding, "OldClass PythonOperation " + action.Operation);

            if (action.Operation == PythonOperationKind.IsCallable)
            {
                return(MakeIsCallable(action));
            }

            return(null);
        }
        public override bool Equals(object obj)
        {
            PythonOperationBinder ob = obj as PythonOperationBinder;

            if (ob == null)
            {
                return(false);
            }

            return(ob._context.Binder == _context.Binder && base.Equals(obj));
        }
        DynamicMetaObject IPythonOperable.BindOperation(PythonOperationBinder action, DynamicMetaObject[] args)
        {
            if (action.Operation == PythonOperationKind.IsCallable)
            {
                return(new DynamicMetaObject(
                           AstUtils.Constant(true),
                           Restrictions.Merge(BindingRestrictions.GetTypeRestriction(Expression, typeof(OldClass)))
                           ));
            }

            return(null);
        }
Esempio n. 7
0
        private DynamicMetaObject /*!*/ MakeIsCallable(PythonOperationBinder /*!*/ operation)
        {
            DynamicMetaObject self = Restrict(typeof(OldInstance));

            return(new DynamicMetaObject(
                       Ast.Call(
                           typeof(PythonOps).GetMethod(nameof(PythonOps.OldInstanceIsCallable)),
                           AstUtils.Constant(PythonContext.GetPythonContext(operation).SharedContext),
                           self.Expression
                           ),
                       self.Restrictions
                       ));
        }
        DynamicMetaObject IPythonOperable.BindOperation(PythonOperationBinder action, DynamicMetaObject[] args)
        {
            if (action.Operation == PythonOperationKind.IsCallable)
            {
                DynamicMetaObject self = Restrict(Value.GetType());

                return(new DynamicMetaObject(
                           Ast.Call(
                               typeof(PythonOps).GetMethod("UserObjectIsCallable"),
                               AstUtils.Constant(PythonContext.GetPythonContext(action).SharedContext),
                               self.Expression
                               ),
                           self.Restrictions
                           ));
            }

            return(null);
        }
        /// <summary>
        /// Creates a rule for the contains operator.  This is exposed via "x in y" in 
        /// IronPython.  It is implemented by calling the __contains__ method on x and
        /// passing in y.  
        /// 
        /// If a type doesn't define __contains__ but does define __getitem__ then __getitem__ is 
        /// called repeatedly in order to see if the object is there.
        /// 
        /// For normal .NET enumerables we'll walk the iterator and see if it's present.
        /// </summary>
        private static DynamicMetaObject/*!*/ MakeContainsOperation(PythonOperationBinder/*!*/ operation, DynamicMetaObject/*!*/[]/*!*/ types) {
            DynamicMetaObject res;
            // the paramteres come in backwards from how we look up __contains__, flip them.
            Debug.Assert(types.Length == 2);
            ArrayUtils.SwapLastTwo(types);

            PythonContext state = PythonContext.GetPythonContext(operation);
            SlotOrFunction sf = SlotOrFunction.GetSlotOrFunction(state, "__contains__", types);

            if (sf.Success) {
                // just a call to __contains__
                res = sf.Target;
            } else {
                RestrictTypes(types);

                sf = SlotOrFunction.GetSlotOrFunction(state, "__iter__", types[0]);
                if (sf.Success) {
                    // iterate using __iter__
                    res = new DynamicMetaObject(
                        Ast.Call(
                            typeof(PythonOps).GetMethod("ContainsFromEnumerable"),
                            AstUtils.Constant(state.SharedContext),
                            sf.Target.Expression,
                            AstUtils.Convert(types[1].Expression, typeof(object))
                        ),
                        BindingRestrictions.Combine(types)
                    );
                } else {
                    ParameterExpression curIndex = Ast.Variable(typeof(int), "count");
                    sf = SlotOrFunction.GetSlotOrFunction(state, "__getitem__", types[0], new DynamicMetaObject(curIndex, BindingRestrictions.Empty));
                    if (sf.Success) {
                        // defines __getitem__, need to loop over the indexes and see if we match

                        ParameterExpression getItemRes = Ast.Variable(sf.ReturnType, "getItemRes");
                        ParameterExpression containsRes = Ast.Variable(typeof(bool), "containsRes");

                        LabelTarget target = Ast.Label();
                        res = new DynamicMetaObject(
                            Ast.Block(
                                new ParameterExpression[] { curIndex, getItemRes, containsRes },
                                Utils.Loop(
                                    null,                                                     // test
                                    Ast.Assign(curIndex, Ast.Add(curIndex, AstUtils.Constant(1))), // increment
                                    Ast.Block(                                            // body
                            // getItemRes = param0.__getitem__(curIndex)
                                        Utils.Try(
                                            Ast.Block(
                                                Ast.Assign(
                                                    getItemRes,
                                                    sf.Target.Expression
                                                ),
                                                Ast.Empty()
                                            )
                                        ).Catch(
                            // end of indexes, return false
                                            typeof(IndexOutOfRangeException),
                                            Ast.Break(target)
                                        ),
                            // if(getItemRes == param1) return true
                                        Utils.If(
                                            DynamicExpression.Dynamic(
                                                state.BinaryOperationRetType(
                                                    state.BinaryOperation(ExpressionType.Equal),
                                                    state.Convert(typeof(bool), ConversionResultKind.ExplicitCast)
                                                ),
                                                typeof(bool),
                                                types[1].Expression,
                                                getItemRes
                                            ),
                                            Ast.Assign(containsRes, AstUtils.Constant(true)),
                                            Ast.Break(target)
                                        ),
                                        AstUtils.Empty()
                                    ),
                                    null,                                               // loop else
                                    target,                                             // break label target
                                    null
                                ),
                                containsRes
                            ),
                            BindingRestrictions.Combine(types)
                        );
                    } else {
                        // non-iterable object
                        res = new DynamicMetaObject(
                            operation.Throw(
                                Ast.Call(
                                    typeof(PythonOps).GetMethod("TypeErrorForNonIterableObject"),
                                    AstUtils.Convert(
                                        types[1].Expression,
                                        typeof(object)
                                    )
                                ),
                                typeof(bool)
                            ),
                            BindingRestrictions.Combine(types)
                        );
                    }
                }
            }

            if (res.GetLimitType() != typeof(bool) && res.GetLimitType() != typeof(void)) {
                res = new DynamicMetaObject(
                    DynamicExpression.Dynamic(
                        state.Convert(
                            typeof(bool),
                            ConversionResultKind.ExplicitCast
                        ),
                        typeof(bool),
                        res.Expression
                    ),
                    res.Restrictions
                );
            }

            return res;
        }
        private static DynamicMetaObject/*!*/ MakeOperationRule(PythonOperationBinder/*!*/ operation, DynamicMetaObject/*!*/[]/*!*/ args) {
            ValidationInfo valInfo = BindingHelpers.GetValidationInfo(args);
            DynamicMetaObject res;

            Type deferType = typeof(object);
            switch (NormalizeOperator(operation.Operation)) {
                case PythonOperationKind.Documentation:
                    res = BindingHelpers.AddPythonBoxing(MakeDocumentationOperation(operation, args));
                    break;
                case PythonOperationKind.CallSignatures:
                    res = BindingHelpers.AddPythonBoxing(MakeCallSignatureOperation(args[0], CompilerHelpers.GetMethodTargets(args[0].Value)));
                    break;
                case PythonOperationKind.IsCallable:
                    res = MakeIscallableOperation(operation, args);
                    break;
                case PythonOperationKind.Hash:
                    res = MakeHashOperation(operation, args[0]);
                    break;
                case PythonOperationKind.Contains:
                    res = MakeContainsOperation(operation, args);
                    break;
                case PythonOperationKind.AbsoluteValue:
                    res = BindingHelpers.AddPythonBoxing(MakeUnaryOperation(operation, args[0], "__abs__", null));
                    break;
                case PythonOperationKind.Compare:
                    res = MakeSortComparisonRule(args, operation, operation.Operation);
                    Debug.Assert(res.LimitType == typeof(int));
                    break;
                case PythonOperationKind.GetEnumeratorForIteration:
                    res = MakeEnumeratorOperation(operation, args[0]);
                    break;
                default:
                    res = BindingHelpers.AddPythonBoxing(MakeBinaryOperation(operation, args, operation.Operation, null));
                    break;
            }


            return BindingHelpers.AddDynamicTestAndDefer(operation, res, args, valInfo, deferType);

        }
        public static DynamicMetaObject/*!*/ Operation(PythonOperationBinder/*!*/ operation, params DynamicMetaObject/*!*/[]/*!*/ args) {
            if (args.Length == 1) {
                PerfTrack.NoteEvent(PerfTrack.Categories.Binding, "Fallback PythonOp " + " " + operation.Operation + " " + args[0].LimitType);
            } else {
                PerfTrack.NoteEvent(PerfTrack.Categories.Binding, "Fallback PythonOp " + " " + operation.Operation + " " + args[0].LimitType + ", " + args[1].LimitType);
            }
            PerfTrack.NoteEvent(PerfTrack.Categories.BindingTarget, operation.Operation.ToString());
            if (BindingHelpers.NeedsDeferral(args)) {
                return operation.Defer(args);
            }

            return MakeOperationRule(operation, args);
        }
        private static DynamicMetaObject/*!*/ MakeHashOperation(PythonOperationBinder/*!*/ operation, DynamicMetaObject/*!*/ self) {
            self = self.Restrict(self.GetLimitType());

            BinderState state = BinderState.GetBinderState(operation);
            SlotOrFunction func = SlotOrFunction.GetSlotOrFunction(state, Symbols.Hash, self);
            DynamicMetaObject res = func.Target;

            if (func.ReturnType != typeof(int)) {
                if (func.ReturnType == typeof(BigInteger)) {
                    // Python 2.5 defines the result of returning a long as hashing the long
                    res = new DynamicMetaObject(
                        HashBigInt(operation, res.Expression),
                        res.Restrictions
                    );
                } else if (func.ReturnType == typeof(object)) {
                    // need to get the integer value here...
                    ParameterExpression tempVar = Ast.Parameter(typeof(object), "hashTemp");

                    res = new DynamicMetaObject(
                            Expression.Block(
                                new [] { tempVar },
                                Expression.Assign(tempVar, res.Expression),
                                Expression.Condition(
                                    Expression.TypeIs(tempVar, typeof(int)),
                                    Expression.Convert(tempVar, typeof(int)),
                                    Expression.Condition(
                                        Expression.TypeIs(tempVar, typeof(BigInteger)),
                                        HashBigInt(operation, tempVar),
                                        HashConvertToInt(state, tempVar)
                                    )
                                )
                            ),
                            res.Restrictions
                        );
                } else {
                    // need to convert unknown value to object
                    res = new DynamicMetaObject(
                        HashConvertToInt(state, res.Expression),
                        res.Restrictions
                    );
                }
            }

            return res;
        }
Esempio n. 13
0
        private DynamicMetaObject/*!*/ MakeIsCallable(PythonOperationBinder/*!*/ operation) {
            DynamicMetaObject self = Restrict(typeof(OldInstance));

            return new DynamicMetaObject(
                Ast.Call(
                    typeof(PythonOps).GetMethod("OldInstanceIsCallable"),
                    AstUtils.Constant(PythonContext.GetPythonContext(operation).SharedContext),
                    self.Expression
                ),
                self.Restrictions
            );
        }
        private static DynamicMetaObject/*!*/ MakeIscallableOperation(PythonOperationBinder/*!*/ operation, DynamicMetaObject/*!*/[]/*!*/ args) {
            // Certain non-python types (encountered during interop) are callable, but don't have 
            // a __call__ attribute. The default base binder also checks these, but since we're overriding
            // the base binder, we check them here.
            DynamicMetaObject self = args[0];

            // only applies when called from a Python site
            if (typeof(Delegate).IsAssignableFrom(self.GetLimitType()) ||
                typeof(MethodGroup).IsAssignableFrom(self.GetLimitType())) {
                return new DynamicMetaObject(
                    AstUtils.Constant(true),
                    self.Restrict(self.GetLimitType()).Restrictions
                );
            }

            PythonContext state = PythonContext.GetPythonContext(operation);
            Expression isCallable = Ast.NotEqual(
                Binders.TryGet(
                    PythonContext.GetCodeContext(operation),
                    state,
                    typeof(object),
                    "__call__",
                    self.Expression
                ),
                AstUtils.Constant(OperationFailed.Value)
            );

            return new DynamicMetaObject(
                isCallable,
                self.Restrict(self.GetLimitType()).Restrictions
            );
        }
        private static DynamicMetaObject MakeEnumeratorOperation(PythonOperationBinder operation, DynamicMetaObject self) {
            if (self.GetLimitType() == typeof(string)) {
                self = self.Restrict(self.GetLimitType());

                return new DynamicMetaObject(
                    Expression.Call(
                        typeof(PythonOps).GetMethod("StringEnumerator"),
                        self.Expression
                    ),
                    self.Restrictions
                );
            } else if (self.GetLimitType() == typeof(Bytes)) {
                self = self.Restrict(self.GetLimitType());

                if (operation.Context.PythonOptions.Python30) {
                    return new DynamicMetaObject(
                        Expression.Call(
                            typeof(PythonOps).GetMethod("BytesIntEnumerator"),
                            self.Expression
                        ),
                        self.Restrictions
                    );
                } else {
                    return new DynamicMetaObject(
                        Expression.Call(
                            typeof(PythonOps).GetMethod("BytesEnumerator"),
                            self.Expression
                        ),
                        self.Restrictions
                    );
                }
            } else if ((self.Value is IEnumerable ||
                    typeof(IEnumerable).IsAssignableFrom(self.GetLimitType())) && !(self.Value is PythonGenerator)) {
                self = self.Restrict(self.GetLimitType());

                return new DynamicMetaObject(
                    Expression.Call(
                        typeof(PythonOps).GetMethod("GetEnumeratorFromEnumerable"),
                        Expression.Convert(
                            self.Expression,
                            typeof(IEnumerable)
                        )
                    ),
                    self.Restrictions
                );

            } else if (self.Value is IEnumerator ||                              // check for COM object (and fast check when we have values)
                    typeof(IEnumerator).IsAssignableFrom(self.GetLimitType())) { // check if we don't have a value
                DynamicMetaObject ieres = new DynamicMetaObject(
                    MakeEnumeratorResult(
                        Ast.Convert(
                            self.Expression,
                            typeof(IEnumerator)
                        )
                    ),
                    self.Restrict(self.GetLimitType()).Restrictions
                );

#if FEATURE_COM
                if (Microsoft.Scripting.ComInterop.ComBinder.IsComObject(self.Value)) {
                    ieres = new DynamicMetaObject(
                         MakeEnumeratorResult(
                                Expression.Convert(
                                 self.Expression,
                                 typeof(IEnumerator)
                             )
                         ),
                         ieres.Restrictions.Merge(
                            BindingRestrictions.GetExpressionRestriction(
                                Ast.TypeIs(self.Expression, typeof(IEnumerator))
                            )
                        )
                    );
                }
#endif

                return ieres;
            }

            ParameterExpression tmp = Ast.Parameter(typeof(IEnumerator), "enum");
            IPythonConvertible pyConv = self as IPythonConvertible;
            PythonConversionBinder convBinder = PythonContext.GetPythonContext(operation).Convert(typeof(IEnumerator), ConversionResultKind.ExplicitTry);

            DynamicMetaObject res;
            if (pyConv != null) {
                res = pyConv.BindConvert(convBinder);
            } else {
                res = convBinder.Bind(self, new DynamicMetaObject[0]);
            }

            return new DynamicMetaObject(
                Expression.Block(
                    new[] { tmp },
                    Ast.Condition(
                        Ast.NotEqual(
                            Ast.Assign(tmp, res.Expression),
                            AstUtils.Constant(null)
                        ),
                        MakeEnumeratorResult(tmp),
                        Ast.Call(
                            typeof(PythonOps).GetMethod("ThrowTypeErrorForBadIteration"),
                            PythonContext.GetCodeContext(operation),
                            self.Expression
                        )
                    )
                ),
                res.Restrictions
            );
        }
        public static DynamicMetaObject/*!*/ Operation(PythonOperationBinder/*!*/ operation, params DynamicMetaObject/*!*/[]/*!*/ args) {
            if (args.Length == 1) {
                PerfTrack.NoteEvent(PerfTrack.Categories.Binding, "Fallback PythonOp " + " " + operation.Operation + " " + args[0].LimitType);
            } else {
                PerfTrack.NoteEvent(PerfTrack.Categories.Binding, "Fallback PythonOp " + " " + operation.Operation + " " + args[0].LimitType + ", " + args[1].LimitType);
            }
            PerfTrack.NoteEvent(PerfTrack.Categories.BindingTarget, operation.Operation.ToString());
            if (BindingHelpers.NeedsDeferral(args)) {
                return operation.Defer(args);
            }

            ValidationInfo valInfo = BindingHelpers.GetValidationInfo(args);

            DynamicMetaObject res = AddPythonBoxing(MakeOperationRule(operation, args));

            return BindingHelpers.AddDynamicTestAndDefer(operation, res, args, valInfo);
        }
Esempio n. 17
0
        DynamicMetaObject IPythonOperable.BindOperation(PythonOperationBinder action, DynamicMetaObject[] args) {
            if (action.Operation == PythonOperationKind.IsCallable) {
                return new DynamicMetaObject(
                    AstUtils.Constant(true),
                    Restrictions.Merge(BindingRestrictions.GetTypeRestriction(Expression, typeof(OldClass)))
                );
            }

            return null;
        }
Esempio n. 18
0
        DynamicMetaObject IPythonOperable.BindOperation(PythonOperationBinder action, DynamicMetaObject[] args) {
            if (action.Operation == PythonOperationKind.IsCallable) {
                DynamicMetaObject self = Restrict(Value.GetType());

                return new DynamicMetaObject(
                    Ast.Call(
                        typeof(PythonOps).GetMethod("UserObjectIsCallable"),
                        AstUtils.Constant(PythonContext.GetPythonContext(action).SharedContext),
                        self.Expression
                    ),
                    self.Restrictions
                );
            }

            return null;
        }
        private static DynamicMetaObject/*!*/ MakeMemberNamesOperation(PythonOperationBinder/*!*/ operation, DynamicMetaObject[] args) {
            DynamicMetaObject self = args[0];
            CodeContext context;
            if (args.Length > 1 && args[0].GetLimitType() == typeof(CodeContext)) {
                self = args[1];
                context = (CodeContext)args[0].Value;
            } else {
                context = PythonContext.GetPythonContext(operation).SharedContext;
            }

            if (typeof(IMembersList).IsAssignableFrom(self.GetLimitType())) {
                return MakeIMembersListRule(PythonContext.GetCodeContext(operation), self);
            }

            PythonType pt = DynamicHelpers.GetPythonType(self.Value);
            List<string> strNames = GetMemberNames(context, pt, self.Value);

            if (pt.IsSystemType) {
                return new DynamicMetaObject(
                    AstUtils.Constant(strNames),
                    BindingRestrictions.GetInstanceRestriction(self.Expression, self.Value).Merge(self.Restrictions)
                );
            }

            return new DynamicMetaObject(
                AstUtils.Constant(strNames),
                BindingRestrictions.GetInstanceRestriction(self.Expression, self.Value).Merge(self.Restrictions)
            );
        }
        private static DynamicMetaObject MakeEnumeratorOperation(PythonOperationBinder operation, DynamicMetaObject self) {
            if (self.GetLimitType() == typeof(string)) {
                self = self.Restrict(self.GetLimitType());

                return new DynamicMetaObject(
                    Expression.Call(
                        typeof(PythonOps).GetMethod("StringEnumerator"),
                        self.Expression
                    ),
                    self.Restrictions
                );
            } else if (self.GetLimitType() == typeof(PythonDictionary)) {
                self = self.Restrict(self.GetLimitType());

                return new DynamicMetaObject(
                    Expression.Call(
                        typeof(PythonOps).GetMethod("MakeDictionaryKeyEnumerator"),
                        self.Expression
                    ),
                    self.Restrictions
                );
            } else if (self.Value is IEnumerable ||
                       typeof(IEnumerable).IsAssignableFrom(self.GetLimitType())) {
                self = self.Restrict(self.GetLimitType());

                return new DynamicMetaObject(
                    Expression.Call(
                        Expression.Convert(
                            self.Expression,
                            typeof(IEnumerable)
                        ),
                        typeof(IEnumerable).GetMethod("GetEnumerator")
                    ),
                    self.Restrictions
                );

            } else if (self.Value is IEnumerator ||                                 // check for COM object (and fast check when we have values)
                       typeof(IEnumerator).IsAssignableFrom(self.GetLimitType())) { // check if we don't have a value
                DynamicMetaObject ieres = self.Restrict(self.GetLimitType());

#if !SILVERLIGHT
                if (ComOps.IsComObject(self.Value)) {
                    ieres = new DynamicMetaObject(
                         self.Expression,
                         ieres.Restrictions.Merge(
                            BindingRestrictions.GetExpressionRestriction(
                                Ast.TypeIs(self.Expression, typeof(IEnumerator))
                            )
                        )
                    );
                }
#endif

                return ieres;
            }

            ParameterExpression tmp = Ast.Parameter(typeof(IEnumerator), "enum");
            DynamicMetaObject res = self.BindConvert(new ConversionBinder(BinderState.GetBinderState(operation), typeof(IEnumerator), ConversionResultKind.ExplicitTry));
            return new DynamicMetaObject(                
                Expression.Block(
                    new[] { tmp },
                    Ast.Condition(
                        Ast.NotEqual(
                            Ast.Assign(tmp, res.Expression),
                            AstUtils.Constant(null)
                        ),
                        tmp,
                        Ast.Call(
                            typeof(PythonOps).GetMethod("ThrowTypeErrorForBadIteration"),
                            BinderState.GetCodeContext(operation),
                            self.Expression
                        )
                    )
                ),
                res.Restrictions
            );
        }
        private static DynamicMetaObject/*!*/ MakeHashOperation(PythonOperationBinder/*!*/ operation, DynamicMetaObject/*!*/ self) {
            self = self.Restrict(self.GetLimitType());

            PythonContext state = PythonContext.GetPythonContext(operation);
            SlotOrFunction func = SlotOrFunction.GetSlotOrFunction(state, "__hash__", self);
            DynamicMetaObject res = func.Target;

            if (func.IsNull) {
                // Python 2.6 setting __hash__ = None makes the type unhashable
                res = new DynamicMetaObject(
                    operation.Throw(
                        Expression.Call(
                            typeof(PythonOps).GetMethod("TypeErrorForUnhashableObject"),
                            self.Expression
                        ),
                        typeof(int)
                    ),
                    res.Restrictions
                );
            } else if (func.ReturnType != typeof(int)) {
                if (func.ReturnType == typeof(BigInteger)) {
                    // Python 2.5 defines the result of returning a long as hashing the long
                    res = new DynamicMetaObject(
                        HashBigInt(operation, res.Expression),
                        res.Restrictions
                    );
                } else if (func.ReturnType == typeof(object)) {
                    // need to get the integer value here...
                    ParameterExpression tempVar = Ast.Parameter(typeof(object), "hashTemp");

                    res = new DynamicMetaObject(
                            Expression.Block(
                                new[] { tempVar },
                                Expression.Assign(tempVar, res.Expression),
                                Expression.Condition(
                                    Expression.TypeIs(tempVar, typeof(int)),
                                    Expression.Convert(tempVar, typeof(int)),
                                    Expression.Condition(
                                        Expression.TypeIs(tempVar, typeof(BigInteger)),
                                        HashBigInt(operation, tempVar),
                                        HashConvertToInt(state, tempVar)
                                    )
                                )
                            ),
                            res.Restrictions
                        );
                } else {
                    // need to convert unknown value to object
                    res = new DynamicMetaObject(
                        HashConvertToInt(state, res.Expression),
                        res.Restrictions
                    );
                }
            }

            return res;
        }
 private static DynamicExpression/*!*/ HashBigInt(PythonOperationBinder/*!*/ operation, Expression/*!*/ expression) {
     return DynamicExpression.Dynamic(
         operation,
         typeof(int),
         expression
     );
 }
        DynamicMetaObject IPythonOperable.BindOperation(PythonOperationBinder action, DynamicMetaObject[] args) {
            switch (action.Operation) {
                case PythonOperationKind.CallSignatures:
                    return PythonProtocol.MakeCallSignatureOperation(this, Value.Template.Targets);
            }

            return null;
        }
        private static DynamicMetaObject/*!*/ MakeDocumentationOperation(PythonOperationBinder/*!*/ operation, DynamicMetaObject/*!*/[]/*!*/ args) {
            PythonContext state = PythonContext.GetPythonContext(operation);

            return new DynamicMetaObject(
                Binders.Convert(
                    PythonContext.GetCodeContext(operation),
                    state,
                    typeof(string),
                    ConversionResultKind.ExplicitCast,
                    Binders.Get(
                        PythonContext.GetCodeContext(operation),
                        state,
                        typeof(object),
                        "__doc__",
                        args[0].Expression
                    )
                ),
                args[0].Restrictions
            );
        }
Esempio n. 25
0
 internal SetIndexAdapter(PythonOperationBinder opBinder) {
     _opBinder = opBinder;
 }
Esempio n. 26
0
        DynamicMetaObject IPythonOperable.BindOperation(PythonOperationBinder action, DynamicMetaObject[] args) {
            PerfTrack.NoteEvent(PerfTrack.Categories.Binding, "OldClass PythonOperation " + action.Operation);

            if (action.Operation == PythonOperationKind.IsCallable) {
                return MakeIsCallable(action);
            }

            return null;
        }
Esempio n. 27
0
        DynamicMetaObject IPythonOperable.BindOperation(PythonOperationBinder action, DynamicMetaObject[] args) {
            switch (action.Operation) {
                case PythonOperationKind.CallSignatures:
                    return MakeCallSignatureRule(this);
                case PythonOperationKind.IsCallable:
                    return MakeIsCallableRule(this);
            }

            return null;
        }
Esempio n. 28
0
        internal PythonOperationBinder/*!*/ Operation(PythonOperationKind operation) {
            if (_operationBinders == null) {
                Interlocked.CompareExchange(
                    ref _operationBinders,
                    new Dictionary<PythonOperationKind, PythonOperationBinder>(),
                    null
                );
            }

            lock (_operationBinders) {
                PythonOperationBinder res;
                if (!_operationBinders.TryGetValue(operation, out res)) {
                    _operationBinders[operation] = res = new PythonOperationBinder(this, operation);
                }

                return res;
            }
        }
 private static DynamicMetaObject/*!*/ MakeOperationRule(PythonOperationBinder/*!*/ operation, DynamicMetaObject/*!*/[]/*!*/ args) {
     switch (NormalizeOperator(operation.Operation)) {
         case PythonOperationKind.Documentation:
             return MakeDocumentationOperation(operation, args);
         case PythonOperationKind.MemberNames:
             return MakeMemberNamesOperation(operation, args);
         case PythonOperationKind.CallSignatures:
             return MakeCallSignatureOperation(args[0], CompilerHelpers.GetMethodTargets(args[0].Value));
         case PythonOperationKind.IsCallable:
             return MakeIscallableOperation(operation, args);
         case PythonOperationKind.Hash:
             return MakeHashOperation(operation, args[0]);
         case PythonOperationKind.Not:
             return MakeUnaryNotOperation(operation, args[0]);
         case PythonOperationKind.Contains:
             return MakeContainsOperation(operation, args);
         case PythonOperationKind.AbsoluteValue:
             return MakeUnaryOperation(operation, args[0], Symbols.AbsoluteValue);
         case PythonOperationKind.Compare:
             return MakeSortComparisonRule(args, operation, operation.Operation);
         case PythonOperationKind.GetEnumeratorForIteration:
             return MakeEnumeratorOperation(operation, args[0]);
         default:
             return MakeBinaryOperation(operation, args, operation.Operation, null);
     }
 }