internal override bool IsSetDescriptor(CodeContext context, PythonType owner)
        {
            PythonType pt = DynamicHelpers.GetPythonType(Value);

            if (pt.IsSystemType)
            {
                return(false);
            }
            return(pt.TryResolveSlot(context, "__set__", out _));
        }
Esempio n. 2
0
            public virtual Delegate MakeBindingResult()
            {
                int version = _type.Version;

                PythonTypeSlot init, newInst;

                _type.TryResolveSlot(_context, "__new__", out newInst);
                _type.TryResolveSlot(_context, "__init__", out init);

                Delegate newDlg;

                if (newInst == InstanceOps.New)
                {
                    if (_genTypeArgs.Length > 0 && init == InstanceOps.Init)
                    {
                        // new needs to report an error, we don't optimize for the error case.
                        return(null);
                    }
                    newDlg = GetOrCreateFastNew();
                }
                else if (newInst.GetType() == typeof(staticmethod) && ((staticmethod)newInst)._func is PythonFunction)
                {
                    // need an extra argument to pass the class to __new__
                    newDlg = GetNewSiteDelegate(_binder.Context.Invoke(_binder.Signature.InsertArgument(Argument.Simple)), ((staticmethod)newInst)._func);
                }
                else
                {
                    // odd slot in __new__, we don't handle this.
                    newDlg = null;
                }

                if (newDlg == null)
                {
                    // can't optimize this method because we have no fast-new
                    return(null);
                }

                return(MakeDelegate(version, newDlg, _type.GetLateBoundInitBinder(_binder.Signature)));
            }
        private void CalculateDescriptorInfo()
        {
            PythonType pt = DynamicHelpers.GetPythonType(_value);

            if (!pt.IsSystemType)
            {
                _descVersion = pt.Version;
                if (!pt.TryResolveSlot(pt.Context.SharedClsContext, "__get__", out _desc))
                {
                    _descVersion = UserDescriptorFalse;
                }
            }
            else
            {
                _descVersion = UserDescriptorFalse;
            }
        }
        /// <summary>
        /// Checks to see if this type has __getattribute__ that overrides all other attribute lookup.
        /// 
        /// This is more complex then it needs to be.  The problem is that when we have a 
        /// mixed new-style/old-style class we have a weird __getattribute__ defined.  When
        /// we always dispatch through rules instead of PythonTypes it should be easy to remove
        /// this.
        /// </summary>
        private static bool TryGetGetAttribute(CodeContext/*!*/ context, PythonType/*!*/ type, out PythonTypeSlot dts) {
            if (type.TryResolveSlot(context, Symbols.GetAttribute, out dts)) {
                BuiltinMethodDescriptor bmd = dts as BuiltinMethodDescriptor;

                if (bmd == null || bmd.DeclaringType != typeof(object) ||
                    bmd.Template.Targets.Count != 1 ||
                    bmd.Template.Targets[0].DeclaringType != typeof(ObjectOps) ||
                    bmd.Template.Targets[0].Name != "__getattribute__") {
                    return dts != null;
                }
            }
            return false;
        }
Esempio n. 5
0
        private static object GetTypeNew(CodeContext/*!*/ context, PythonType dt) {
            PythonTypeSlot dts;

            if (!dt.TryResolveSlot(context, "__new__", out dts)) {
                throw PythonOps.TypeError("cannot create instances of {0}", dt.Name);
            }

            object newInst;
            bool res = dts.TryGetValue(context, dt, dt, out newInst);
            Debug.Assert(res);

            return newInst;
        }
Esempio n. 6
0
        private static void AddFinalizer(CodeContext/*!*/ context, PythonType dt, object newObject) {
            // check if object has finalizer...
            PythonTypeSlot dummy;
            if (dt.TryResolveSlot(context, "__del__", out dummy)) {
                IWeakReferenceable iwr = newObject as IWeakReferenceable;
                Debug.Assert(iwr != null);

                InstanceFinalizer nif = new InstanceFinalizer(context, newObject);
                iwr.SetFinalizer(new WeakRefTracker(nif, nif));
            }
        }
Esempio n. 7
0
        // *** END GENERATED CODE ***

        #endregion

        public override T BindDelegate <T>(CallSite <T> site, object[] args)
        {
            if (args.Length <= MaxFastLateBoundInitArgs)
            {
                CodeContext context  = (CodeContext)args[0];
                object      inst     = args[1];
                PythonType  instType = DynamicHelpers.GetPythonType(inst);

                PythonTypeSlot delSlot;
                PythonFunction initFunc   = null;
                string         callTarget = null;
                if (!instType.TryResolveSlot(context, "__del__", out delSlot))          // we don't have fast code for classes w/ finalizers

                {
                    if (IronPython.Modules.Builtin.isinstance(inst, _newType) &&
                        NeedsInitCall((CodeContext)context, instType, args.Length))
                    {
                        PythonTypeSlot init;
                        instType.TryResolveSlot(context, "__init__", out init);

                        if (init is PythonFunction)
                        {
                            // we can do a fast bind
                            callTarget = "CallTarget";
                            initFunc   = (PythonFunction)init;
                        }
                    }
                    else
                    {
                        // we need no initialization, we can do a fast bind
                        callTarget = "EmptyCallTarget";
                    }
                }

                if (callTarget != null)
                {
                    int genArgCount           = args.Length - 2;
                    PythonInvokeBinder binder = context.LanguageContext.Invoke(_signature.InsertArgument(Argument.Simple));
                    if (genArgCount == 0)
                    {
                        FastInitSite fastSite = new FastInitSite(instType.Version, binder, initFunc);
                        if (callTarget == "CallTarget")
                        {
                            return((T)(object)new Func <CallSite, CodeContext, object, object>(fastSite.CallTarget));
                        }
                        else
                        {
                            return((T)(object)new Func <CallSite, CodeContext, object, object>(fastSite.EmptyCallTarget));
                        }
                    }
                    else
                    {
                        Type[] genArgs = ArrayUtils.ConvertAll(typeof(T).GetMethod("Invoke").GetParameters(), x => x.ParameterType);
                        Type   initSiteType;

                        switch (args.Length - 2)
                        {
                            #region Generated Python Fast Init Switch

                        // *** BEGIN GENERATED CODE ***
                        // generated by function: gen_fast_init_switch from: generate_calls.py

                        case 1: initSiteType = typeof(FastInitSite <>); break;

                        case 2: initSiteType = typeof(FastInitSite <,>); break;

                        case 3: initSiteType = typeof(FastInitSite <, ,>); break;

                        case 4: initSiteType = typeof(FastInitSite <, , ,>); break;

                        case 5: initSiteType = typeof(FastInitSite <, , , ,>); break;

                            // *** END GENERATED CODE ***

                            #endregion

                        default: throw new InvalidOperationException();
                        }

                        Type   genType      = initSiteType.MakeGenericType(ArrayUtils.ShiftLeft(genArgs, 3));
                        object initSiteInst = Activator.CreateInstance(genType, instType.Version, binder, initFunc);
                        return((T)(object)genType.GetMethod(callTarget).CreateDelegate(typeof(T), initSiteInst));
                    }
                }
            }

            return(base.BindDelegate(site, args));
        }
Esempio n. 8
0
        /// <summary>
        /// target is the newly initialized value.
        /// args are the arguments to be passed to __init__
        /// </summary>
        public override DynamicMetaObject Bind(DynamicMetaObject target, DynamicMetaObject[] args)
        {
            DynamicMetaObject codeContext = target;
            CodeContext       context     = (CodeContext)codeContext.Value;

            target = args[0];
            args   = ArrayUtils.RemoveFirst(args);

            ValidationInfo valInfo = BindingHelpers.GetValidationInfo(target);

            Expression          res;
            PythonType          instType         = DynamicHelpers.GetPythonType(target.Value);
            BindingRestrictions initRestrictions = BindingRestrictions.Empty;

            if (IronPython.Modules.Builtin.isinstance(target.Value, _newType) &&
                NeedsInitCall((CodeContext)codeContext.Value, instType, args.Length))
            {
                // resolve __init__
                PythonTypeSlot init;
                instType.TryResolveSlot(context, "__init__", out init);

                if (init is PythonFunction)
                {
                    // avoid creating the bound method, just invoke it directly
                    Expression[] allArgs = new Expression[args.Length + 3];
                    allArgs[0] = codeContext.Expression;
                    allArgs[1] = AstUtils.WeakConstant(init);
                    allArgs[2] = target.Expression;
                    for (int i = 0; i < args.Length; i++)
                    {
                        allArgs[3 + i] = args[i].Expression;
                    }

                    res = DynamicExpression.Dynamic(
                        context.LanguageContext.Invoke(_signature.InsertArgument(Argument.Simple)),
                        typeof(object),
                        allArgs
                        );
                }
                else if (init is BuiltinMethodDescriptor || init is BuiltinFunction)
                {
                    IList <MethodBase> targets;
                    if (init is BuiltinMethodDescriptor)
                    {
                        targets = ((BuiltinMethodDescriptor)init).Template.Targets;
                    }
                    else
                    {
                        targets = ((BuiltinFunction)init).Targets;
                    }

                    PythonBinder binder = context.LanguageContext.Binder;

                    DynamicMetaObject initInvoke = binder.CallMethod(
                        new PythonOverloadResolver(
                            binder,
                            target,
                            args,
                            _signature,
                            codeContext.Expression
                            ),
                        targets,
                        BindingRestrictions.Empty
                        );

                    res = initInvoke.Expression;
                    initRestrictions = initInvoke.Restrictions;
                }
                else
                {
                    // some weird descriptor has been put in place for __init__, we need
                    // to call __get__ on it each time.
                    res = MakeDynamicInitInvoke(
                        context,
                        args,
                        Expression.Call(
                            typeof(PythonOps).GetMethod("GetInitSlotMember"),
                            codeContext.Expression,
                            Expression.Convert(AstUtils.WeakConstant(_newType), typeof(PythonType)),
                            Expression.Convert(AstUtils.WeakConstant(init), typeof(PythonTypeSlot)),
                            AstUtils.Convert(target.Expression, typeof(object))
                            ),
                        codeContext.Expression
                        );
                }
            }
            else
            {
                // returned something that isn't a subclass of the creating type
                // __init__ will not be run.
                res = AstUtils.Empty();
            }

            // check for __del__
            PythonTypeSlot delSlot;

            if (instType.TryResolveSlot(context, "__del__", out delSlot))
            {
                res = Expression.Block(
                    res,
                    Expression.Call(
                        typeof(PythonOps).GetMethod("InitializeForFinalization"),
                        codeContext.Expression,
                        AstUtils.Convert(target.Expression, typeof(object))
                        )
                    );
            }

            return(BindingHelpers.AddDynamicTestAndDefer(
                       this,
                       new DynamicMetaObject(
                           Expression.Block(
                               res,
                               target.Expression
                               ),
                           target.Restrict(target.LimitType).Restrictions.Merge(initRestrictions)
                           ),
                       args,
                       valInfo
                       ));
        }