internal override bool IsSetDescriptor(CodeContext context, PythonType owner) { PythonType pt = DynamicHelpers.GetPythonType(Value); if (pt.IsSystemType) { return(false); } return(pt.TryResolveSlot(context, "__set__", out _)); }
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; }
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; }
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)); } }
// *** 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)); }
/// <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 )); }