Beispiel #1
0
        public ConversionBinder(BinderState/*!*/ state, Type/*!*/ type, ConversionResultKind resultKind)
            : base(type, resultKind == ConversionResultKind.ExplicitCast || resultKind == ConversionResultKind.ExplicitTry) {
            Assert.NotNull(state, type);

            _state = state;
            _kind = resultKind;
        }
Beispiel #2
0
 internal AstGenerator(AstGenerator/*!*/ parent, string name, bool generator, bool print)
     : this(name, generator, false) {
     Assert.NotNull(parent);
     _context = parent.Context;
     _binderState = parent.BinderState;
     _document = _context.SourceUnit.Document;
 }
Beispiel #3
0
 internal AstGenerator(CompilerContext/*!*/ context, SourceSpan span, string name, bool generator, bool print)
     : this(name, generator, print) {
     Assert.NotNull(context);
     _context = context;
     _binderState = new BinderState(Binder);
     _document = _context.SourceUnit.Document;
 }
Beispiel #4
0
 /// <summary>
 /// Backwards compatible Convert for the old sites that need to flow CodeContext
 /// </summary>
 public static Expression/*!*/ Convert(Expression/*!*/ codeContext, BinderState/*!*/ binder, Type/*!*/ type, ConversionResultKind resultKind, Expression/*!*/ target) {
     return Ast.Dynamic(
         binder.Convert(type, resultKind),
         type,
         target
     );
 }
Beispiel #5
0
 public static Expression/*!*/ Get(Expression/*!*/ codeContext, BinderState/*!*/ binder, Type/*!*/ resultType, string/*!*/ name, Expression/*!*/ target) {
     return Ast.Dynamic(
         binder.GetMember(name),
         resultType,
         target,
         codeContext
     );
 }
Beispiel #6
0
 public static Expression/*!*/ Operation(BinderState/*!*/ binder, Type/*!*/ resultType, string/*!*/ operation, Expression arg0) {
     return Ast.Dynamic(
         new PythonOperationBinder(
             binder,
             operation
         ),
         resultType,
         arg0
     );
 }
Beispiel #7
0
 public static Expression/*!*/ Convert(BinderState/*!*/ binder, Type/*!*/ type, ConversionResultKind resultKind, Expression/*!*/ target) {
     return Ast.Dynamic(
         new ConversionBinder(
             binder,
             type,
             resultKind
         ),
         type,
         target
     );
 }
Beispiel #8
0
        public static DynamicMetaObjectBinder UnaryOperationBinder(BinderState state, PythonOperationKind operatorName) {
            ExpressionType? et = GetExpressionTypeFromUnaryOperator(operatorName);
            
            if (et == null) {
                return state.Operation(
                    operatorName
                );
            }

            return state.UnaryOperation(et.Value);
        }
Beispiel #9
0
 internal static MethodCallExpression MakeTryGetTypeMember(BinderState/*!*/ binderState, PythonTypeSlot dts, ParameterExpression tmp, Expression instance, Expression pythonType) {
     return Ast.Call(
         TypeInfo._PythonOps.SlotTryGetBoundValue,
         Ast.Constant(binderState.Context),
         AstUtils.Convert(Utils.WeakConstant(dts), typeof(PythonTypeSlot)),
         AstUtils.Convert(instance, typeof(object)),
         AstUtils.Convert(
             pythonType,
             typeof(PythonType)
         ),
         tmp
     );
 }
Beispiel #10
0
 public static DynamicMetaObjectBinder/*!*/ BinaryOperationRetType(BinderState/*!*/ state, PythonOperationKind operatorName, Type retType) {
     return new ComboBinder(
         new BinderMappingInfo(
             BinaryOperationBinder(state, operatorName),
             ParameterMappingInfo.Parameter(0),
             ParameterMappingInfo.Parameter(1)
         ),
         new BinderMappingInfo(
             state.Convert(retType, ConversionResultKind.ExplicitCast),
             ParameterMappingInfo.Action(0)
         )
     );
 }
Beispiel #11
0
 /// <summary>
 /// Trys to get the BuiltinFunction for the given name on the type of the provided MetaObject.  
 /// 
 /// Succeeds if the MetaObject is a BuiltinFunction or BuiltinMethodDescriptor.
 /// </summary>
 internal static bool TryGetStaticFunction(BinderState/*!*/ state, SymbolId op, DynamicMetaObject/*!*/ mo, out BuiltinFunction function) {
     PythonType type = MetaPythonObject.GetPythonType(mo);
     function = null;
     if (op != SymbolId.Empty) {
         PythonTypeSlot xSlot;
         object val;
         if (type.TryResolveSlot(state.Context, op, out xSlot) &&
             xSlot.TryGetValue(state.Context, null, type, out val)) {
             function = TryConvertToBuiltinFunction(val);
             if (function == null) return false;
         }
     }
     return true;
 }
Beispiel #12
0
 internal static MethodCallExpression MakeTryGetTypeMember(BinderState/*!*/ binderState, PythonTypeSlot dts, Expression self, ParameterExpression tmp) {
     return MakeTryGetTypeMember(
         binderState,
         dts, 
         tmp,
         self,
         Ast.Property(
             Ast.Convert(
                 self,
                 typeof(IPythonObject)),
             TypeInfo._IPythonObject.PythonType
         )
     );
 }
Beispiel #13
0
        public static Expression/*!*/ Invoke(BinderState/*!*/ binder, Type/*!*/ resultType, CallSignature signature, params Expression/*!*/[]/*!*/ args) {
            PythonInvokeBinder invoke = new PythonInvokeBinder(binder, signature);
            switch(args.Length) {
                case 0: return Ast.Dynamic(invoke, resultType, AstUtils.CodeContext());
                case 1: return Ast.Dynamic(invoke, resultType, AstUtils.CodeContext(), args[0]);
                case 2: return Ast.Dynamic(invoke, resultType, AstUtils.CodeContext(), args[0], args[1]);
                case 3: return Ast.Dynamic(invoke, resultType, AstUtils.CodeContext(), args[0], args[1], args[2]);
                default:
                    return Ast.Dynamic(
                        invoke,
                        resultType,
                        new ReadOnlyCollection<Expression>(ArrayUtils.Insert(AstUtils.CodeContext(), args))
                    );
            }

        }
        private DynamicMetaObject/*!*/ FallbackGetMember(DynamicMetaObjectBinder member, BinderState state) {
            MemberTracker tt = MemberTracker.FromMemberInfo(Value.UnderlyingSystemType);

            if (member is IPythonSite) {
                // bind the .NET members
                string memberName = GetGetMemberName(member);
                return state.Binder.GetMember(
                    memberName,
                    new DynamicMetaObject(
                        Ast.Constant(tt),
                        BindingRestrictions.Empty,
                        tt
                    ),
                    Ast.Constant(state.Context),
                    BindingHelpers.IsNoThrow(member)

                );
            }

            // let the calling language bind the .NET members
            return GetMemberFallback(this, member, BinderState.GetCodeContext(member));
        }
        private DynamicMetaObject/*!*/ GetFallbackGet(DynamicMetaObjectBinder/*!*/ member, BinderState/*!*/ state, Expression codeContext) {
            string memberName = GetGetMemberName(member);
            DynamicMetaObject res = new DynamicMetaObject(
                FallbackGetMember(member, state).Expression,
                BindingRestrictions.GetInstanceRestriction(Expression, Value).Merge(Restrictions)
            );

            if (codeContext != null && Value.IsHiddenMember(memberName)) {
                res = BindingHelpers.FilterShowCls(
                    codeContext,
                    member,
                    res,
                    Ast.Throw(
                        Ast.Call(
                            typeof(PythonOps).GetMethod("AttributeErrorForMissingAttribute", new Type[] { typeof(string), typeof(SymbolId) }),
                            AstUtils.Constant(Value.Name),
                            AstUtils.Constant(SymbolTable.StringToId(memberName))
                        )
                    )
                );
            }

            return res;
        }
 public PythonGetMemberBinder(BinderState/*!*/ binder, string/*!*/ name) {
     _state = binder;
     _name = name;
 }
 public CompatibilityGetMember(BinderState/*!*/ binder, string/*!*/ name)
     : this(binder, name, false) {
 }
Beispiel #18
0
        internal AstGenerator(AstGenerator/*!*/ parent, string name, bool generator, string profilerName)
            : this(name, generator, profilerName, false) {
            Assert.NotNull(parent);
            _context = parent.Context;
            _binderState = parent.BinderState;
            _parent = parent;
            _document = _context.SourceUnit.Document ?? Ast.SymbolDocument(name, PythonContext.LanguageGuid, PythonContext.VendorGuid);
            _profiler = parent._profiler;

            _globals = parent._globals;
        }
Beispiel #19
0
 public static Expression/*!*/ Invoke(Expression codeContext, BinderState/*!*/ binder, Type/*!*/ resultType, CallSignature signature, params Expression/*!*/[]/*!*/ args) {
     return Ast.Dynamic(
         binder.Invoke(
             signature
         ),
         resultType,
         ArrayUtils.Insert(codeContext, args)
     );
 }
Beispiel #20
0
        /// <summary>
        /// Used for conversions to bool
        /// </summary>
        private static Expression/*!*/ GetConvertByLengthBody(BinderState/*!*/ state, Expression/*!*/ call) {
            Assert.NotNull(state, call);

            Expression callAsInt = call;
            if (call.Type != typeof(int)) {
                callAsInt = Ast.Dynamic(
                    state.Convert(typeof(int), ConversionResultKind.ExplicitCast),
                    typeof(int),
                    call
                );
            }

            return Ast.NotEqual(callAsInt, AstUtils.Constant(0));
        }
Beispiel #21
0
 private static DynamicMetaObject MakeGetItemIterable(DynamicMetaObject metaUserObject, BinderState state, PythonTypeSlot pts, string method) {
     ParameterExpression tmp = Ast.Parameter(typeof(object), "getitemVal");
     return new DynamicMetaObject(
         Expression.Block(
             new[] { tmp },
             Expression.Call(
                 typeof(PythonOps).GetMethod(method),
                 Ast.Block(
                     MetaPythonObject.MakeTryGetTypeMember(
                         state,
                         pts,
                         tmp,
                         metaUserObject.Expression,
                         Ast.Call(
                             typeof(DynamicHelpers).GetMethod("GetPythonType"),
                             AstUtils.Convert(
                                 metaUserObject.Expression,
                                 typeof(object)
                             )
                         )
                     ),
                     tmp
                 ),
                 AstUtils.Constant(
                     CallSite<Func<CallSite, CodeContext, object, int, object>>.Create(
                         new PythonInvokeBinder(state, new CallSignature(1))
                     )
                 )
             )
         ),
         metaUserObject.Restrictions
     );
 }
Beispiel #22
0
        internal AstGenerator(CompilationMode mode, CompilerContext/*!*/ context, SourceSpan span, string name, bool generator, bool print)
            : this(name, generator, null, print) {
            Assert.NotNull(context);
            _context = context;
            _binderState = new BinderState(Binder);
            _document = _context.SourceUnit.Document;

            LanguageContext pc = context.SourceUnit.LanguageContext;
            switch (mode) {
                case CompilationMode.Collectable: _globals = new ArrayGlobalAllocator(pc); break;
                case CompilationMode.Lookup: _globals = new DictionaryGlobalAllocator(); break;
                case CompilationMode.ToDisk: _globals = new SavableGlobalAllocator(pc); break;
                case CompilationMode.Uncollectable: _globals = new StaticGlobalAllocator(pc, name); break;
            }

            PythonOptions po = (pc.Options as PythonOptions);
            Assert.NotNull(po);
            if (po.EnableProfiler && mode != CompilationMode.ToDisk) {
                _profiler = Profiler.GetProfiler(PythonContext);
                if (mode == CompilationMode.Lookup) {
                    _profilerName = NameForExec;
                }
            }
        }
 public PythonSetSliceBinder(BinderState/*!*/ state) {
     _state = state;
 }
        private static void GetOpreatorMethods(DynamicMetaObject/*!*/[]/*!*/ types, PythonOperationKind oper, BinderState state, out SlotOrFunction fbinder, out SlotOrFunction rbinder, out PythonTypeSlot fSlot, out PythonTypeSlot rSlot) {
            oper = NormalizeOperator(oper);
            oper &= ~PythonOperationKind.InPlace;

            SymbolId op, rop;
            if (!IsReverseOperator(oper)) {
                op = Symbols.OperatorToSymbol(oper);
                rop = Symbols.OperatorToReversedSymbol(oper);
            } else {
                // coming back after coercion, just try reverse operator.
                rop = Symbols.OperatorToSymbol(oper);
                op = Symbols.OperatorToReversedSymbol(oper);
            }

            fSlot = null;
            rSlot = null;
            PythonType fParent, rParent;

            if (oper == PythonOperationKind.Multiply && 
                IsSequence(types[0]) && 
                !PythonOps.IsNonExtensibleNumericType(types[1].GetLimitType())) {
                // class M:
                //      def __rmul__(self, other):
                //          print "CALLED"
                //          return 1
                //
                // print [1,2] * M()
                //
                // in CPython this results in a successful call to __rmul__ on the type ignoring the forward
                // multiplication.  But calling the __mul__ method directly does NOT return NotImplemented like
                // one might expect.  Therefore we explicitly convert the MetaObject argument into an Index
                // for binding purposes.  That allows this to work at multiplication time but not with
                // a direct call to __mul__.

                DynamicMetaObject[] newTypes = new DynamicMetaObject[2];
                newTypes[0] = types[0];
                newTypes[1] = new DynamicMetaObject(
                    Ast.New(
                        typeof(Index).GetConstructor(new Type[] { typeof(object) }),
                        AstUtils.Convert(types[1].Expression, typeof(object))
                    ),
                    BindingRestrictions.Empty
                );
                types = newTypes;
            }

            if (!SlotOrFunction.TryGetBinder(state, types, op, SymbolId.Empty, out fbinder, out fParent)) {
                foreach (PythonType pt in MetaPythonObject.GetPythonType(types[0]).ResolutionOrder) {
                    if (pt.TryLookupSlot(state.Context, op, out fSlot)) {
                        fParent = pt;
                        break;
                    }
                }
            }

            if (!SlotOrFunction.TryGetBinder(state, types, SymbolId.Empty, rop, out rbinder, out rParent)) {
                foreach (PythonType pt in MetaPythonObject.GetPythonType(types[1]).ResolutionOrder) {
                    if (pt.TryLookupSlot(state.Context, rop, out rSlot)) {
                        rParent = pt;
                        break;
                    }
                }
            }

            if (fParent != null && (rbinder.Success || rSlot != null) && rParent != fParent && rParent.IsSubclassOf(fParent)) {
                // Python says if x + subx and subx defines __r*__ we should call r*.
                fbinder = SlotOrFunction.Empty;
                fSlot = null;
            }

            if (!fbinder.Success && !rbinder.Success && fSlot == null && rSlot == null) {
                if (op == Symbols.OperatorTrueDivide || op == Symbols.OperatorReverseTrueDivide) {
                    // true div on a type which doesn't support it, go ahead and try normal divide
                    PythonOperationKind newOp = op == Symbols.OperatorTrueDivide ? PythonOperationKind.Divide : PythonOperationKind.ReverseDivide;

                    GetOpreatorMethods(types, newOp, state, out fbinder, out rbinder, out fSlot, out rSlot);
                }
            }
        }
Beispiel #25
0
        internal AstGenerator(AstGenerator/*!*/ parent, string name, bool generator, string profilerName)
            : this(name, generator, profilerName, false) {
            Assert.NotNull(parent);
            _context = parent.Context;
            _binderState = parent.BinderState;
            _parent = parent;
            _document = _context.SourceUnit.Document;
            _profiler = parent._profiler;

            _globals = parent._globals;
        }
        private static bool MakeOneTarget(BinderState/*!*/ state, SlotOrFunction/*!*/ target, PythonTypeSlot slotTarget, ConditionalBuilder/*!*/ bodyBuilder, bool reverse, DynamicMetaObject/*!*/[]/*!*/ types) {
            if (target == SlotOrFunction.Empty && slotTarget == null) return true;

            if (slotTarget != null) {
                MakeSlotCall(state, types, bodyBuilder, slotTarget, reverse);
                return true;
            } else if (target.MaybeNotImplemented) {
                Debug.Assert(target.ReturnType == typeof(object));

                ParameterExpression tmp = Ast.Variable(typeof(object), "slot");
                bodyBuilder.AddVariable(tmp);

                bodyBuilder.AddCondition(
                    Ast.NotEqual(
                        Ast.Assign(
                            tmp,
                            target.Target.Expression
                        ),
                        Ast.Property(null, typeof(PythonOps).GetProperty("NotImplemented"))
                    ),
                    tmp
                );

                return true;
            } else {
                bodyBuilder.FinishCondition(target.Target.Expression);
                return false;
            }
        }
 public CompatibilityGetMember(BinderState/*!*/ binder, string/*!*/ name, bool ignoreCase)
     : base(name, ignoreCase) {
     _state = binder;
 }
        private static void MakeSlotCall(BinderState/*!*/ state, DynamicMetaObject/*!*/[]/*!*/ types, ConditionalBuilder/*!*/ bodyBuilder, PythonTypeSlot/*!*/ slotTarget, bool reverse) {
            Debug.Assert(slotTarget != null);

            Expression self, other;
            if (reverse) {
                self = types[1].Expression;
                other = types[0].Expression;
            } else {
                self = types[0].Expression;
                other = types[1].Expression;
            }

            MakeSlotCallWorker(state, slotTarget, self, bodyBuilder, other);
        }
 public PythonGetMemberBinder(BinderState/*!*/ binder, string/*!*/ name, bool isNoThrow)
     : this(binder, name) {
     _options = isNoThrow ? GetMemberOptions.IsNoThrow : GetMemberOptions.None;
 }
        private static void MakeSlotCallWorker(BinderState/*!*/ state, PythonTypeSlot/*!*/ slotTarget, Expression/*!*/ self, ConditionalBuilder/*!*/ bodyBuilder, params Expression/*!*/[]/*!*/ args) {
            // Generate:
            // 
            // SlotTryGetValue(context, slot, selfType, out callable) && (tmp=callable(args)) != NotImplemented) ?
            //      tmp :
            //      RestOfOperation
            //
            ParameterExpression callable = Ast.Variable(typeof(object), "slot");
            ParameterExpression tmp = Ast.Variable(typeof(object), "slot");

            bodyBuilder.AddCondition(
                Ast.AndAlso(
                    Ast.Call(
                        typeof(PythonOps).GetMethod("SlotTryGetValue"),
                        AstUtils.Constant(state.Context),
                        AstUtils.Convert(Utils.WeakConstant(slotTarget), typeof(PythonTypeSlot)),
                        AstUtils.Convert(self, typeof(object)),
                        Ast.Call(
                            typeof(DynamicHelpers).GetMethod("GetPythonType"),
                            AstUtils.Convert(self, typeof(object))
                        ),
                        callable
                    ),
                    Ast.NotEqual(
                        Ast.Assign(
                            tmp,
                            Ast.Dynamic(
                                state.Invoke(
                                    new CallSignature(args.Length)
                                ),
                                typeof(object),
                                ArrayUtils.Insert(AstUtils.Constant(state.Context), (Expression)callable, args)
                            )
                        ),
                        Ast.Property(null, typeof(PythonOps).GetProperty("NotImplemented"))
                    )
                ),
                tmp
            );
            bodyBuilder.AddVariable(callable);
            bodyBuilder.AddVariable(tmp);
        }