Ejemplo n.º 1
0
        private Func <CallSite, TSelfType, CodeContext, object> MakeGetMemberTarget <TSelfType>(string name, object target)
        {
            Type type = CompilerHelpers.GetType(target);

            // needed for GetMember call until DynamicAction goes away
            if (typeof(TypeTracker).IsAssignableFrom(type))
            {
                // no fast path for TypeTrackers
                PerfTrack.NoteEvent(PerfTrack.Categories.BindingSlow, "GetNoFast TypeTracker");
                return(null);
            }

            MemberGroup members = Context.Binder.GetMember(MemberRequestKind.Get, type, name);

            if (members.Count == 0 && type.IsInterface)
            {
                // all interfaces have object members
                type    = typeof(object);
                members = Context.Binder.GetMember(MemberRequestKind.Get, type, name);
            }

            if (members.Count == 0 && typeof(IStrongBox).IsAssignableFrom(type))
            {
                // no fast path for strong box access
                PerfTrack.NoteEvent(PerfTrack.Categories.BindingSlow, "GetNoFast StrongBox");
                return(null);
            }

            MethodInfo getMem = Context.Binder.GetMethod(type, "GetCustomMember");

            if (getMem != null && getMem.IsSpecialName)
            {
                // no fast path for custom member access
                PerfTrack.NoteEvent(PerfTrack.Categories.BindingSlow, "GetNoFast GetCustomMember " + type);
                return(null);
            }

            Expression   error;
            TrackerTypes memberType = Context.Binder.GetMemberType(members, out error);

            if (error == null)
            {
                PythonType argType  = DynamicHelpers.GetPythonTypeFromType(type);
                bool       isHidden = argType.IsHiddenMember(name);
                if (isHidden)
                {
                    PerfTrack.NoteEvent(PerfTrack.Categories.BindingSlow, "GetNoFast FilteredMember " + memberType);
                    return(null);
                }

                switch (memberType)
                {
                case TrackerTypes.TypeGroup:
                case TrackerTypes.Type:
                    object typeObj;
                    if (members.Count == 1)
                    {
                        typeObj = DynamicHelpers.GetPythonTypeFromType(((TypeTracker)members[0]).Type);
                    }
                    else
                    {
                        TypeTracker typeTracker = (TypeTracker)members[0];
                        for (int i = 1; i < members.Count; i++)
                        {
                            typeTracker = TypeGroup.UpdateTypeEntity(typeTracker, (TypeTracker)members[i]);
                        }
                        typeObj = typeTracker;
                    }

                    return(new FastTypeGet <TSelfType>(type, typeObj).GetTypeObject);

                case TrackerTypes.Method:
                    PythonTypeSlot slot = PythonTypeOps.GetSlot(members, name, _context.DomainManager.Configuration.PrivateBinding);
                    if (slot is BuiltinMethodDescriptor)
                    {
                        return(new FastMethodGet <TSelfType>(type, (BuiltinMethodDescriptor)slot).GetMethod);
                    }
                    else if (slot is BuiltinFunction)
                    {
                        return(new FastSlotGet <TSelfType>(type, slot, DynamicHelpers.GetPythonTypeFromType(type)).GetRetSlot);
                    }
                    return(new FastSlotGet <TSelfType>(type, slot, DynamicHelpers.GetPythonTypeFromType(type)).GetBindSlot);

                case TrackerTypes.Event:
                    if (members.Count == 1 && !((EventTracker)members[0]).IsStatic)
                    {
                        slot = PythonTypeOps.GetSlot(members, name, _context.DomainManager.Configuration.PrivateBinding);
                        return(new FastSlotGet <TSelfType>(type, slot, DynamicHelpers.GetPythonTypeFromType(((EventTracker)members[0]).DeclaringType)).GetBindSlot);
                    }
                    PerfTrack.NoteEvent(PerfTrack.Categories.BindingSlow, "GetNoFast Event " + members.Count + " " + ((EventTracker)members[0]).IsStatic);
                    return(null);

                case TrackerTypes.Property:
                    if (members.Count == 1)
                    {
                        PropertyTracker pt = (PropertyTracker)members[0];
                        if (!pt.IsStatic && pt.GetIndexParameters().Length == 0)
                        {
                            MethodInfo      prop = pt.GetGetMethod();
                            ParameterInfo[] parameters;

                            if (prop != null && (parameters = prop.GetParameters()).Length == 0)
                            {
                                if (prop.ReturnType == typeof(bool))
                                {
                                    return(new FastPropertyGet <TSelfType>(type, CallInstruction.Create(prop, parameters).Invoke).GetPropertyBool);
                                }
                                else if (prop.ReturnType == typeof(int))
                                {
                                    return(new FastPropertyGet <TSelfType>(type, CallInstruction.Create(prop, parameters).Invoke).GetPropertyInt);
                                }
                                else
                                {
                                    return(new FastPropertyGet <TSelfType>(type, CallInstruction.Create(prop, parameters).Invoke).GetProperty);
                                }
                            }
                        }
                    }
                    PerfTrack.NoteEvent(PerfTrack.Categories.BindingSlow, "GetNoFast Property " + members.Count + " " + ((PropertyTracker)members[0]).IsStatic);
                    return(null);

                case TrackerTypes.All:
                    getMem = Context.Binder.GetMethod(type, "GetBoundMember");
                    if (getMem != null && getMem.IsSpecialName)
                    {
                        PerfTrack.NoteEvent(PerfTrack.Categories.BindingSlow, "GetNoFast GetBoundMember " + type);
                        return(null);
                    }

                    if (IsNoThrow)
                    {
                        return(new FastErrorGet <TSelfType>(type, name).GetErrorNoThrow);
                    }
                    else if (SupportsLightThrow)
                    {
                        return(new FastErrorGet <TSelfType>(type, name).GetErrorLightThrow);
                    }
                    else
                    {
                        return(new FastErrorGet <TSelfType>(type, name).GetError);
                    }

                default:
                    PerfTrack.NoteEvent(PerfTrack.Categories.BindingSlow, "GetNoFast " + memberType);
                    return(null);
                }
            }
            else
            {
                StringBuilder sb = new StringBuilder();
                foreach (MemberTracker mi in members)
                {
                    if (sb.Length != 0)
                    {
                        sb.Append(", ");
                    }
                    sb.Append(mi.MemberType);
                    sb.Append(" : ");
                    sb.Append(mi.ToString());
                }

                return(new FastErrorGet <TSelfType>(type, sb.ToString()).GetAmbiguous);
            }
        }
Ejemplo n.º 2
0
        public static object GetAttributeNoThrow(CodeContext /*!*/ context, object self, string name, PythonTypeSlot getAttributeSlot, PythonTypeSlot getAttrSlot, SiteLocalStorage <CallSite <Func <CallSite, CodeContext, object, string, object> > > /*!*/ callSite)
        {
            object value;

            if (callSite.Data == null)
            {
                callSite.Data = MakeGetAttrSite(context);
            }

            try {
                if (getAttributeSlot.TryGetValue(context, self, ((IPythonObject)self).PythonType, out value))
                {
                    return(callSite.Data.Target(callSite.Data, context, value, name));
                }
            } catch (MissingMemberException) {
                try {
                    if (getAttrSlot != null && getAttrSlot.TryGetValue(context, self, ((IPythonObject)self).PythonType, out value))
                    {
                        return(callSite.Data.Target(callSite.Data, context, value, name));
                    }

                    return(OperationFailed.Value);
                } catch (MissingMemberException) {
                    return(OperationFailed.Value);
                }
            }

            try {
                if (getAttrSlot != null && getAttrSlot.TryGetValue(context, self, ((IPythonObject)self).PythonType, out value))
                {
                    return(callSite.Data.Target(callSite.Data, context, value, name));
                }
            } catch (MissingMemberException) {
            }

            return(OperationFailed.Value);
        }
Ejemplo n.º 3
0
        private static DynamicMetaObject MakeGetItemIterable(DynamicMetaObject metaUserObject, PythonContext 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(nameof(DynamicHelpers.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
                       ));
        }
Ejemplo n.º 4
0
 public FastSlotGet(Type type, PythonTypeSlot slot, PythonType owner)
 {
     _type  = type;
     _slot  = slot;
     _owner = owner;
 }
Ejemplo n.º 5
0
 internal static MethodCallExpression MakeTryGetTypeMember(PythonContext /*!*/ PythonContext, PythonTypeSlot dts, ParameterExpression tmp, Expression instance, Expression pythonType)
 {
     return(Ast.Call(
                PythonTypeInfo._PythonOps.SlotTryGetBoundValue,
                AstUtils.Constant(PythonContext.SharedContext),
                AstUtils.Convert(Utils.WeakConstant(dts), typeof(PythonTypeSlot)),
                AstUtils.Convert(instance, typeof(object)),
                AstUtils.Convert(
                    pythonType,
                    typeof(PythonType)
                    ),
                tmp
                ));
 }
Ejemplo n.º 6
0
 internal static MethodCallExpression MakeTryGetTypeMember(PythonContext /*!*/ PythonContext, PythonTypeSlot dts, Expression self, ParameterExpression tmp)
 {
     return(MakeTryGetTypeMember(
                PythonContext,
                dts,
                tmp,
                self,
                Ast.Property(
                    Ast.Convert(
                        self,
                        typeof(IPythonObject)),
                    PythonTypeInfo._IPythonObject.PythonType
                    )
                ));
 }
Ejemplo n.º 7
0
 protected override void AddMetaGetAttribute(PythonType metaType, PythonTypeSlot pts)
 {
     _gets.Add(new MetaGetAttributeDelegate(_context, pts, metaType, _binder.Name).Target);
 }
Ejemplo n.º 8
0
 protected abstract bool AddSlotAccess(PythonType pt, PythonTypeSlot pts);
Ejemplo n.º 9
0
 protected abstract void AddMetaGetAttribute(PythonType metaType, PythonTypeSlot pts);