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); } }
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); }
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 )); }
public FastSlotGet(Type type, PythonTypeSlot slot, PythonType owner) { _type = type; _slot = slot; _owner = owner; }
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 )); }
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 ) )); }
protected override void AddMetaGetAttribute(PythonType metaType, PythonTypeSlot pts) { _gets.Add(new MetaGetAttributeDelegate(_context, pts, metaType, _binder.Name).Target); }
protected abstract bool AddSlotAccess(PythonType pt, PythonTypeSlot pts);
protected abstract void AddMetaGetAttribute(PythonType metaType, PythonTypeSlot pts);