public override T BindDelegate <T>(CallSite <T> site, object[] args) { switch (_operation) { case PythonOperationKind.Hash: if (CompilerHelpers.GetType(args[0]) == typeof(PythonType)) { if (typeof(T) == typeof(Func <CallSite, object, int>)) { return((T)(object)new Func <CallSite, object, int>(HashPythonType)); } } break; case PythonOperationKind.Compare: if (CompilerHelpers.GetType(args[0]) == typeof(string) && CompilerHelpers.GetType(args[1]) == typeof(string)) { if (typeof(T) == typeof(Func <CallSite, object, object, int>)) { return((T)(object)new Func <CallSite, object, object, int>(CompareStrings)); } } break; case PythonOperationKind.GetEnumeratorForIteration: if (CompilerHelpers.GetType(args[0]) == typeof(PythonList)) { if (typeof(T) == typeof(Func <CallSite, PythonList, KeyValuePair <IEnumerator, IDisposable> >)) { return((T)(object)new Func <CallSite, PythonList, KeyValuePair <IEnumerator, IDisposable> >(GetListEnumerator)); } return((T)(object)new Func <CallSite, object, KeyValuePair <IEnumerator, IDisposable> >(GetListEnumerator)); } else if (CompilerHelpers.GetType(args[0]) == typeof(PythonTuple)) { if (typeof(T) == typeof(Func <CallSite, PythonTuple, KeyValuePair <IEnumerator, IDisposable> >)) { return((T)(object)new Func <CallSite, PythonTuple, KeyValuePair <IEnumerator, IDisposable> >(GetTupleEnumerator)); } return((T)(object)new Func <CallSite, object, KeyValuePair <IEnumerator, IDisposable> >(GetTupleEnumerator)); } break; case PythonOperationKind.Contains: if (CompilerHelpers.GetType(args[1]) == typeof(PythonList)) { Type tType = typeof(T); if (tType == typeof(Func <CallSite, object, object, bool>)) { return((T)(object)new Func <CallSite, object, object, bool>(ListContains <object>)); } else if (tType == typeof(Func <CallSite, object, PythonList, bool>)) { return((T)(object)new Func <CallSite, object, PythonList, bool>(ListContains)); } else if (tType == typeof(Func <CallSite, int, object, bool>)) { return((T)(object)new Func <CallSite, int, object, bool>(ListContains <int>)); } else if (tType == typeof(Func <CallSite, string, object, bool>)) { return((T)(object)new Func <CallSite, string, object, bool>(ListContains <string>)); } else if (tType == typeof(Func <CallSite, double, object, bool>)) { return((T)(object)new Func <CallSite, double, object, bool>(ListContains <double>)); } else if (tType == typeof(Func <CallSite, PythonTuple, object, bool>)) { return((T)(object)new Func <CallSite, PythonTuple, object, bool>(ListContains <PythonTuple>)); } } else if (CompilerHelpers.GetType(args[1]) == typeof(PythonTuple)) { Type tType = typeof(T); if (tType == typeof(Func <CallSite, object, object, bool>)) { return((T)(object)new Func <CallSite, object, object, bool>(TupleContains <object>)); } else if (tType == typeof(Func <CallSite, object, PythonTuple, bool>)) { return((T)(object)new Func <CallSite, object, PythonTuple, bool>(TupleContains)); } else if (tType == typeof(Func <CallSite, int, object, bool>)) { return((T)(object)new Func <CallSite, int, object, bool>(TupleContains <int>)); } else if (tType == typeof(Func <CallSite, string, object, bool>)) { return((T)(object)new Func <CallSite, string, object, bool>(TupleContains <string>)); } else if (tType == typeof(Func <CallSite, double, object, bool>)) { return((T)(object)new Func <CallSite, double, object, bool>(TupleContains <double>)); } else if (tType == typeof(Func <CallSite, PythonTuple, object, bool>)) { return((T)(object)new Func <CallSite, PythonTuple, object, bool>(TupleContains <PythonTuple>)); } } else if (CompilerHelpers.GetType(args[0]) == typeof(string) && CompilerHelpers.GetType(args[1]) == typeof(string)) { Type tType = typeof(T); if (tType == typeof(Func <CallSite, object, object, bool>)) { return((T)(object)new Func <CallSite, object, object, bool>(StringContains)); } else if (tType == typeof(Func <CallSite, string, object, bool>)) { return((T)(object)new Func <CallSite, string, object, bool>(StringContains)); } else if (tType == typeof(Func <CallSite, object, string, bool>)) { return((T)(object)new Func <CallSite, object, string, bool>(StringContains)); } else if (tType == typeof(Func <CallSite, string, string, bool>)) { return((T)(object)new Func <CallSite, string, string, bool>(StringContains)); } } else if (CompilerHelpers.GetType(args[1]) == typeof(SetCollection)) { if (typeof(T) == typeof(Func <CallSite, object, object, bool>)) { return((T)(object)new Func <CallSite, object, object, bool>(SetContains)); } } break; } return(base.BindDelegate <T>(site, args)); }
//private static Func<CallSite, object, object, object> DoubleAddSite = new Func<CallSite, object, object, object>(DoubleAdd); public override T BindDelegate <T>(CallSite <T> site, object[] args) { if (args[0] != null && CompilerHelpers.GetType(args[0]) == CompilerHelpers.GetType(args[1])) { switch (Operation) { case ExpressionType.Add: case ExpressionType.AddAssign: return(BindAdd <T>(site, args)); case ExpressionType.And: case ExpressionType.AndAssign: return(BindAnd <T>(site, args)); case ExpressionType.Or: case ExpressionType.OrAssign: return(BindOr <T>(site, args)); case ExpressionType.Subtract: case ExpressionType.SubtractAssign: return(BindSubtract <T>(site, args)); case ExpressionType.Equal: return(BindEqual <T>(site, args)); case ExpressionType.NotEqual: return(BindNotEqual <T>(site, args)); case ExpressionType.GreaterThan: return(BindGreaterThan <T>(site, args)); case ExpressionType.LessThan: return(BindLessThan <T>(site, args)); case ExpressionType.LessThanOrEqual: return(BindLessThanOrEqual <T>(site, args)); case ExpressionType.GreaterThanOrEqual: return(BindGreaterThanOrEqual <T>(site, args)); case ExpressionType.Multiply: case ExpressionType.MultiplyAssign: return(BindMultiply <T>(site, args)); case ExpressionType.Divide: case ExpressionType.DivideAssign: return(BindDivide <T>(site, args)); case ExpressionType.Modulo: return(BindModulo <T>(site, args)); } } else { switch (Operation) { case ExpressionType.Modulo: return(BindModulo <T>(site, args)); case ExpressionType.Multiply: return(BindMultiplyDifferentTypes <T>(site, args)); } } return(base.BindDelegate <T>(site, args)); }
public override T BindDelegate <T>(CallSite <T> site, object[] args) { switch (Operation) { case ExpressionType.Negate: if (CompilerHelpers.GetType(args[0]) == typeof(int)) { if (typeof(T) == typeof(Func <CallSite, object, object>)) { return((T)(object)new Func <CallSite, object, object>(IntNegate)); } } break; case ExpressionType.IsFalse: if (args[0] == null) { if (typeof(T) == typeof(Func <CallSite, object, bool>)) { return((T)(object)new Func <CallSite, object, bool>(NoneIsFalse)); } } else if (args[0].GetType() == typeof(string)) { if (typeof(T) == typeof(Func <CallSite, object, bool>)) { return((T)(object)new Func <CallSite, object, bool>(StringIsFalse)); } } else if (args[0].GetType() == typeof(bool)) { if (typeof(T) == typeof(Func <CallSite, object, bool>)) { return((T)(object)new Func <CallSite, object, bool>(BoolIsFalse)); } } else if (args[0].GetType() == typeof(List)) { if (typeof(T) == typeof(Func <CallSite, object, bool>)) { return((T)(object)new Func <CallSite, object, bool>(ListIsFalse)); } } else if (args[0].GetType() == typeof(PythonTuple)) { if (typeof(T) == typeof(Func <CallSite, object, bool>)) { return((T)(object)new Func <CallSite, object, bool>(TupleIsFalse)); } } else if (args[0].GetType() == typeof(int)) { if (typeof(T) == typeof(Func <CallSite, object, bool>)) { return((T)(object)new Func <CallSite, object, bool>(IntIsFalse)); } } break; case ExpressionType.Not: if (args[0] == null) { if (typeof(T) == typeof(Func <CallSite, object, object>)) { return((T)(object)new Func <CallSite, object, object>(NoneNot)); } } else if (args[0].GetType() == typeof(string)) { if (typeof(T) == typeof(Func <CallSite, object, object>)) { return((T)(object)new Func <CallSite, object, object>(StringNot)); } } else if (args[0].GetType() == typeof(bool)) { if (typeof(T) == typeof(Func <CallSite, object, object>)) { return((T)(object)new Func <CallSite, object, object>(BoolNot)); } } else if (args[0].GetType() == typeof(List)) { if (typeof(T) == typeof(Func <CallSite, object, object>)) { return((T)(object)new Func <CallSite, object, object>(ListNot)); } } else if (args[0].GetType() == typeof(PythonTuple)) { if (typeof(T) == typeof(Func <CallSite, object, object>)) { return((T)(object)new Func <CallSite, object, object>(TupleNot)); } } else if (args[0].GetType() == typeof(int)) { if (typeof(T) == typeof(Func <CallSite, object, object>)) { return((T)(object)new Func <CallSite, object, object>(IntNot)); } } break; } return(base.BindDelegate(site, args)); }
private DynamicMetaObject /*!*/ MakeSelfCall(DynamicMetaObjectBinder /*!*/ call, Expression /*!*/ codeContext, DynamicMetaObject /*!*/[] /*!*/ args) { BindingRestrictions selfRestrict = Restrictions.Merge( BindingRestrictionsHelpers.GetRuntimeTypeRestriction( Expression, LimitType ) ).Merge( BindingRestrictions.GetExpressionRestriction( Value.MakeBoundFunctionTest( AstUtils.Convert(Expression, typeof(BuiltinFunction)) ) ) ); Expression instance = Ast.Call( typeof(PythonOps).GetMethod(nameof(PythonOps.GetBuiltinFunctionSelf)), AstUtils.Convert( Expression, typeof(BuiltinFunction) ) ); DynamicMetaObject self = GetInstance(instance, CompilerHelpers.GetType(Value.BindingSelf)); return(Value.MakeBuiltinFunctionCall( call, codeContext, this, ArrayUtils.Insert(self, args), true, // has self selfRestrict, (newArgs) => { CallSignature signature = BindingHelpers.GetCallSignature(call); PythonContext state = PythonContext.GetPythonContext(call); BindingTarget target; PythonOverloadResolver resolver; if (Value.IsReversedOperator) { resolver = new PythonOverloadResolver( state.Binder, newArgs, GetReversedSignature(signature), codeContext ); } else { resolver = new PythonOverloadResolver( state.Binder, self, args, signature, codeContext ); } DynamicMetaObject res = state.Binder.CallMethod( resolver, Value.Targets, self.Restrictions, Value.Name, NarrowingLevel.None, Value.IsBinaryOperator ? PythonNarrowing.BinaryOperator : NarrowingLevel.All, out target ); return BindingHelpers.CheckLightThrow(call, res, target); } )); }
private static void NoteRuleCreation(DynamicAction action, object[] args) { PerfTrack.NoteEvent(PerfTrack.Categories.Rules, "MakeRule " + action.ToString() + " " + CompilerHelpers.GetType(args[0]).Name); }
private Func <CallSite, TSelfType, CodeContext, object> MakeGetMemberTarget <TSelfType>(string name, object target, CodeContext context) { 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 (members.Count == 0) { // we don't yet support fast bindings to extension methods members = context.ModuleContext.ExtensionMethods.GetBinder(_context).GetMember(MemberRequestKind.Get, type, name); if (members.Count == 0) { if (IsNoThrow) { return(new FastErrorGet <TSelfType>(type, name, context.ModuleContext.ExtensionMethods).GetErrorNoThrow); } else if (SupportsLightThrow) { return(new FastErrorGet <TSelfType>(type, name, context.ModuleContext.ExtensionMethods).GetErrorLightThrow); } else { return(new FastErrorGet <TSelfType>(type, name, context.ModuleContext.ExtensionMethods).GetError); } } } return(null); 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(), context.ModuleContext.ExtensionMethods).GetAmbiguous); } }
public virtual string GetObjectTypeName(object arg) { return(GetTypeName(CompilerHelpers.GetType(arg))); }
internal static Expression ExplicitConvert(Type /*!*/ toType, CallArguments /*!*/ args) { return(Converter.ExplicitConvert(args.TargetExpression, CompilerHelpers.GetType(args.Target), toType)); }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] // TODO: fix public static Exception CannotConvertError(Type toType, object value) { return(SimpleTypeError(String.Format("Cannot convert {0}({1}) to {2}", CompilerHelpers.GetType(value).Name, value, toType.Name))); }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] // TODO: fix public static Exception CannotConvertError(Type toType, object value) { return(SimpleTypeError($"Cannot convert {CompilerHelpers.GetType(value).Name}({value}) to {toType.Name}")); }
protected override object DoEvaluate(CodeContext context) { object x = _operand.Evaluate(context); switch (NodeType) { #if FULL case AstNodeType.Convert: return(Cast.Explicit(x, _type)); #endif case AstNodeType.Not: if (x is bool) { return((bool)x ? RuntimeHelpers.False : RuntimeHelpers.True); } if (x is int) { return((int)~(int)x); } if (x is long) { return((long)~(long)x); } if (x is short) { return((short)~(short)x); } if (x is uint) { return((uint)~(uint)x); } if (x is ulong) { return((ulong)~(ulong)x); } if (x is ushort) { return((ushort)~(ushort)x); } if (x is byte) { return((byte)~(byte)x); } if (x is sbyte) { return((sbyte)~(sbyte)x); } throw new InvalidOperationException("can't perform unary not on type " + CompilerHelpers.GetType(x).Name); case AstNodeType.Negate: if (x is int) { return((int)(-(int)x)); } if (x is long) { return((long)(-(long)x)); } if (x is short) { return((short)(-(short)x)); } if (x is float) { return(-(float)x); } if (x is double) { return(-(double)x); } throw new InvalidOperationException("can't negate type " + CompilerHelpers.GetType(x).Name); default: throw new NotImplementedException(); } }
public static object IncorrectBoxType(Type expected, object received) { throw new ArgumentTypeException(String.Format("Expected type {0}, got {1}", expected, CompilerHelpers.GetType(received))); }
public static AbstractValue Constant(object value, Expression expression) { return(new AbstractValue(value, CompilerHelpers.GetType(value), AbstractKind.Constant, expression)); }
public void MakeRule() { Rule.MakeTest(StrongBoxType ?? CompilerHelpers.GetType(Target)); Rule.Target = MakeDeleteMemberTarget(); }
internal DynamicMetaObject FallbackConvert(Type returnType, DynamicMetaObject self, DynamicMetaObject errorSuggestion) { Type type = Type; DynamicMetaObject res = null; switch (type.GetTypeCode()) { case TypeCode.Boolean: res = MakeToBoolConversion(self); break; case TypeCode.Char: res = TryToCharConversion(self); break; case TypeCode.String: var limitType = self.GetLimitType(); if ((limitType == typeof(Bytes) || limitType == typeof(PythonBuffer) || limitType == typeof(ByteArray)) && !_context.PythonOptions.Python30) { res = new DynamicMetaObject( Ast.Call( typeof(PythonOps).GetMethod(nameof(PythonOps.MakeString)), AstUtils.Convert(self.Expression, typeof(IList <byte>)) ), BindingRestrictionsHelpers.GetRuntimeTypeRestriction(self.Expression, limitType) ); } break; case TypeCode.Object: // !!! Deferral? if (type.IsArray && self.Value is PythonTuple && type.GetArrayRank() == 1) { res = MakeToArrayConversion(self, type); } else if (type.IsGenericType && !type.IsAssignableFrom(CompilerHelpers.GetType(self.Value))) { Type genTo = type.GetGenericTypeDefinition(); // Interface conversion helpers... if (genTo == typeof(IList <>)) { if (self.LimitType == typeof(string)) { res = new DynamicMetaObject( Ast.Call( typeof(PythonOps).GetMethod(nameof(PythonOps.MakeByteArray)), AstUtils.Convert(self.Expression, typeof(string)) ), BindingRestrictions.GetTypeRestriction( self.Expression, typeof(string) ) ); } else { res = TryToGenericInterfaceConversion(self, type, typeof(IList <object>), typeof(ListGenericWrapper <>)); } } else if (genTo == typeof(IDictionary <,>)) { res = TryToGenericInterfaceConversion(self, type, typeof(IDictionary <object, object>), typeof(DictionaryGenericWrapper <,>)); } else if (genTo == typeof(IEnumerable <>)) { res = TryToGenericInterfaceConversion(self, type, typeof(IEnumerable), typeof(IEnumerableOfTWrapper <>)); } } else if (type == typeof(IEnumerable)) { if (!typeof(IEnumerable).IsAssignableFrom(self.GetLimitType()) && IsIndexless(self)) { res = ConvertToIEnumerable(this, self.Restrict(self.GetLimitType())); } } else if (type == typeof(IEnumerator)) { if (!typeof(IEnumerator).IsAssignableFrom(self.GetLimitType()) && !typeof(IEnumerable).IsAssignableFrom(self.GetLimitType()) && IsIndexless(self)) { res = ConvertToIEnumerator(this, self.Restrict(self.GetLimitType())); } } break; } if (type.IsEnum() && Enum.GetUnderlyingType(type) == self.GetLimitType()) { // numeric type to enum, this is ok if the value is zero object value = Activator.CreateInstance(type); return(new DynamicMetaObject( Ast.Condition( Ast.Equal( AstUtils.Convert(self.Expression, Enum.GetUnderlyingType(type)), AstUtils.Constant(Activator.CreateInstance(self.GetLimitType())) ), AstUtils.Constant(value), Ast.Call( typeof(PythonOps).GetMethod(nameof(PythonOps.TypeErrorForBadEnumConversion)).MakeGenericMethod(type), AstUtils.Convert(self.Expression, typeof(object)) ) ), self.Restrictions.Merge(BindingRestrictionsHelpers.GetRuntimeTypeRestriction(self.Expression, self.GetLimitType())), value )); } return(res ?? EnsureReturnType(returnType, Context.Binder.ConvertTo(Type, ResultKind, self, _context.SharedOverloadResolverFactory, errorSuggestion))); }
public static T IncorrectBoxType <T>(object received) { throw Error.UnexpectedType("StrongBox<" + typeof(T).Name + ">", CompilerHelpers.GetType(received).Name); }
public override T BindDelegate <T>(CallSite <T> site, object[] args) { //Debug.Assert(typeof(T).GetMethod("Invoke").ReturnType == Type); object target = args[0]; T res = null; if (typeof(T) == typeof(Func <CallSite, object, string>) && target is string) { res = (T)(object)new Func <CallSite, object, string>(StringConversion); } else if (typeof(T) == typeof(Func <CallSite, object, int>)) { if (target is int) { res = (T)(object)new Func <CallSite, object, int>(IntConversion); } else if (target is bool) { res = (T)(object)new Func <CallSite, object, int>(BoolToIntConversion); } } else if (typeof(T) == typeof(Func <CallSite, bool, int>)) { res = (T)(object)new Func <CallSite, bool, int>(BoolToIntConversion); } else if (typeof(T) == typeof(Func <CallSite, object, bool>)) { if (target is bool) { res = (T)(object)new Func <CallSite, object, bool>(BoolConversion); } else if (target is string) { res = (T)(object)new Func <CallSite, object, bool>(StringToBoolConversion); } else if (target is int) { res = (T)(object)new Func <CallSite, object, bool>(IntToBoolConversion); } else if (target == null) { res = (T)(object)new Func <CallSite, object, bool>(NullToBoolConversion); } else if (target.GetType() == typeof(object)) { res = (T)(object)new Func <CallSite, object, bool>(ObjectToBoolConversion); } else if (target.GetType() == typeof(List)) { res = (T)(object)new Func <CallSite, object, bool>(ListToBoolConversion); } else if (target.GetType() == typeof(PythonTuple)) { res = (T)(object)new Func <CallSite, object, bool>(TupleToBoolConversion); } } else if (target != null) { // Special cases: // - string or bytes to IEnumerable or IEnumerator // - CLR 4 only: BigInteger -> Complex if (target is BigInteger) { if (typeof(T) == typeof(Func <CallSite, BigInteger, Complex>)) { res = (T)(object)new Func <CallSite, BigInteger, Complex>(BigIntegerToComplexConversion); } else if (typeof(T) == typeof(Func <CallSite, object, Complex>)) { res = (T)(object)new Func <CallSite, object, Complex>(BigIntegerObjectToComplexConversion); } else if (typeof(T) == typeof(Func <CallSite, BigInteger, object>)) { res = (T)(object)new Func <CallSite, BigInteger, object>(BigIntegerToComplexObjectConversion); } } else if (target is string) { if (typeof(T) == typeof(Func <CallSite, string, IEnumerable>)) { res = (T)(object)new Func <CallSite, string, IEnumerable>(StringToIEnumerableConversion); } else if (typeof(T) == typeof(Func <CallSite, string, IEnumerator>)) { res = (T)(object)new Func <CallSite, string, IEnumerator>(StringToIEnumeratorConversion); } else if (typeof(T) == typeof(Func <CallSite, object, IEnumerable>)) { res = (T)(object)new Func <CallSite, object, IEnumerable>(ObjectToIEnumerableConversion); } else if (typeof(T) == typeof(Func <CallSite, object, IEnumerator>)) { res = (T)(object)new Func <CallSite, object, IEnumerator>(ObjectToIEnumeratorConversion); } } else if (target.GetType() == typeof(Bytes)) { if (typeof(T) == typeof(Func <CallSite, Bytes, IEnumerable>)) { res = (T)(object)new Func <CallSite, Bytes, IEnumerable>(BytesToIEnumerableConversion); } else if (typeof(T) == typeof(Func <CallSite, Bytes, IEnumerator>)) { res = (T)(object)new Func <CallSite, Bytes, IEnumerator>(BytesToIEnumeratorConversion); } else if (typeof(T) == typeof(Func <CallSite, object, IEnumerable>)) { res = (T)(object)new Func <CallSite, object, IEnumerable>(ObjectToIEnumerableConversion); } else if (typeof(T) == typeof(Func <CallSite, object, IEnumerator>)) { res = (T)(object)new Func <CallSite, object, IEnumerator>(ObjectToIEnumeratorConversion); } } if (res == null && (target.GetType() == Type || Type.IsAssignableFrom(target.GetType()))) { if (typeof(T) == typeof(Func <CallSite, object, object>)) { // called via a helper call site in the runtime (e.g. Converter.Convert) res = (T)(object)new Func <CallSite, object, object>(new IdentityConversion(target.GetType()).Convert); } else { // called via an embedded call site Debug.Assert(typeof(T).GetMethod("Invoke").ReturnType == Type); if (typeof(T).GetMethod("Invoke").GetParameters()[1].ParameterType == typeof(object)) { object identityConversion = Activator.CreateInstance(typeof(IdentityConversion <>).MakeGenericType(Type), target.GetType()); res = (T)(object)identityConversion.GetType().GetMethod("Convert").CreateDelegate(typeof(T), identityConversion); } } } } if (res != null) { CacheTarget(res); return(res); } PerfTrack.NoteEvent(PerfTrack.Categories.Binding, "Convert " + Type.FullName + " " + CompilerHelpers.GetType(args[0]) + " " + typeof(T)); return(base.BindDelegate(site, args)); }
public static Exception MakeIncorrectBoxTypeError(Type type, object received) { return(Error.UnexpectedType("StrongBox<" + type.Name + ">", CompilerHelpers.GetType(received).Name)); }
public override T BindDelegate <T>(CallSite <T> site, object[] args) { Debug.Assert(args[1].GetType() == typeof(CodeContext)); IFastGettable fastGet = args[0] as IFastGettable; if (fastGet != null) { T res = fastGet.MakeGetBinding <T>(site, this, (CodeContext)args[1], Name); if (res != null) { PerfTrack.NoteEvent(PerfTrack.Categories.BindingFast, "IFastGettable"); return(res); } PerfTrack.NoteEvent(PerfTrack.Categories.BindingSlow, "IFastGettable"); return(base.BindDelegate <T>(site, args)); } IPythonObject pyObj = args[0] as IPythonObject; if (pyObj != null && !(args[0] is IProxyObject)) { FastBindResult <T> res = UserTypeOps.MakeGetBinding <T>((CodeContext)args[1], site, pyObj, this); if (res.Target != null) { PerfTrack.NoteEvent(PerfTrack.Categories.BindingFast, "IPythonObject"); if (res.ShouldCache) { CacheTarget(res.Target); } return(res.Target); } PerfTrack.NoteEvent(PerfTrack.Categories.BindingSlow, "IPythonObject Get"); return(base.BindDelegate <T>(site, args)); } if (args[0] != null) { if (args[0].GetType() == typeof(PythonModule)) { if (SupportsLightThrow) { return((T)(object)new Func <CallSite, object, CodeContext, object>(new PythonModuleDelegate(_name).LightThrowTarget)); } else if (!IsNoThrow) { return((T)(object)new Func <CallSite, object, CodeContext, object>(new PythonModuleDelegate(_name).Target)); } else { return((T)(object)new Func <CallSite, object, CodeContext, object>(new PythonModuleDelegate(_name).NoThrowTarget)); } } else if (args[0].GetType() == typeof(NamespaceTracker)) { switch (Name) { case "__str__": case "__repr__": case "__doc__": // need to return the built in method descriptor for these... break; case "__file__": return((T)(object)new Func <CallSite, object, CodeContext, object>(new NamespaceTrackerDelegate(_name).GetFile)); case "__dict__": return((T)(object)new Func <CallSite, object, CodeContext, object>(new NamespaceTrackerDelegate(_name).GetDict)); case "__name__": return((T)(object)new Func <CallSite, object, CodeContext, object>(new NamespaceTrackerDelegate(_name).GetName)); default: if (IsNoThrow) { return((T)(object)new Func <CallSite, object, CodeContext, object>(new NamespaceTrackerDelegate(_name).NoThrowTarget)); } else { return((T)(object)new Func <CallSite, object, CodeContext, object>(new NamespaceTrackerDelegate(_name).Target)); } } } } if (args[0] != null && #if FEATURE_COM !Microsoft.Scripting.ComInterop.ComBinder.IsComObject(args[0]) && #endif !(args[0] is IDynamicMetaObjectProvider)) { Type selfType = typeof(T).GetMethod("Invoke").GetParameters()[1].ParameterType; CodeContext context = (CodeContext)args[1]; T res = null; if (selfType == typeof(object)) { res = (T)(object)MakeGetMemberTarget <object>(Name, args[0], context); } else if (selfType == typeof(List)) { res = (T)(object)MakeGetMemberTarget <List>(Name, args[0], context); } else if (selfType == typeof(string)) { res = (T)(object)MakeGetMemberTarget <string>(Name, args[0], context); } if (res != null) { return((T)(object)res); } return(base.BindDelegate <T>(site, args)); } PerfTrack.NoteEvent(PerfTrack.Categories.BindingSlow, "GetNoFast " + IsNoThrow + " " + CompilerHelpers.GetType(args[0])); return(this.LightBind <T>(args, this.Context.Options.CompilationThreshold)); }
private MethodInfo[] GetApplicableMembers(OperatorInfo info) { return(GetApplicableMembers(CompilerHelpers.GetType(_args[0]), info)); }
private DynamicMetaObject /*!*/ GetInstance(Expression /*!*/ instance, Type /*!*/ testType) { Assert.NotNull(instance, testType); object instanceValue = Value.BindingSelf; BindingRestrictions restrictions = BindingRestrictionsHelpers.GetRuntimeTypeRestriction(instance, testType); // cast the instance to the correct type if (CompilerHelpers.IsStrongBox(instanceValue)) { instance = ReadStrongBoxValue(instance); instanceValue = ((IStrongBox)instanceValue).Value; } else if (!testType.IsEnum) { // We need to deal w/ wierd types like MarshalByRefObject. // We could have an MBRO whos DeclaringType is completely different. // Therefore we special case it here and cast to the declaring type Type selfType = CompilerHelpers.GetType(Value.BindingSelf); selfType = CompilerHelpers.GetVisibleType(selfType); if (selfType == typeof(object) && Value.DeclaringType.IsInterface) { selfType = Value.DeclaringType; } if (Value.DeclaringType.IsInterface && selfType.IsValueType) { // explicit interface implementation dispatch on a value type, don't // unbox the value type before the dispatch. instance = AstUtils.Convert(instance, Value.DeclaringType); } else if (selfType.IsValueType) { // We might be calling a a mutating method (like // Rectangle.Intersect). If so, we want it to mutate // the boxed value directly instance = Ast.Unbox(instance, selfType); } else { #if SILVERLIGHT instance = AstUtils.Convert(instance, selfType); #else Type convType = selfType == typeof(MarshalByRefObject) ? CompilerHelpers.GetVisibleType(Value.DeclaringType) : selfType; instance = AstUtils.Convert(instance, convType); #endif } } else { // we don't want to cast the enum to its real type, it will unbox it // and turn it into its underlying type. We presumably want to call // a method on the Enum class though - so we cast to Enum instead. instance = AstUtils.Convert(instance, typeof(Enum)); } return(new DynamicMetaObject( instance, restrictions, instanceValue )); }
public override T BindDelegate <T>(CallSite <T> site, object[] args) { IFastInvokable ifi = args[1] as IFastInvokable; if (ifi != null) { FastBindResult <T> res = ifi.MakeInvokeBinding(site, this, (CodeContext)args[0], ArrayUtils.ShiftLeft(args, 2)); if (res.Target != null) { if (res.ShouldCache) { base.CacheTarget(res.Target); } return(res.Target); } } if (args[1] is Types.PythonType) { PerfTrack.NoteEvent(PerfTrack.Categories.BindingSlow, "InvokeNoFast " + ((Types.PythonType)args[1]).Name); } else { PerfTrack.NoteEvent(PerfTrack.Categories.BindingSlow, "InvokeNoFast " + CompilerHelpers.GetType(args[1])); } var target = this.LightBind <T>(args, Context.Options.CompilationThreshold); base.CacheTarget(target); return(target); }
private DynamicMetaObject /*!*/ GetInstance(Expression /*!*/ instance, Type /*!*/ testType) { Assert.NotNull(instance, testType); object instanceValue = Value.BindingSelf; BindingRestrictions restrictions = BindingRestrictionsHelpers.GetRuntimeTypeRestriction(instance, testType); // cast the instance to the correct type if (CompilerHelpers.IsStrongBox(instanceValue)) { instance = ReadStrongBoxValue(instance); instanceValue = ((IStrongBox)instanceValue).Value; } else if (!testType.IsEnum()) { // We need to deal w/ wierd types like MarshalByRefObject. // We could have an MBRO whos DeclaringType is completely different. // Therefore we special case it here and cast to the declaring type Type selfType = CompilerHelpers.GetType(Value.BindingSelf); selfType = CompilerHelpers.GetVisibleType(selfType); if (selfType == typeof(object) && Value.DeclaringType.IsInterface()) { selfType = Value.DeclaringType; Type genericTypeDefinition = null; // the behavior is different on Mono, it sets FullName for the DeclaringType if (Value.DeclaringType.IsGenericType() && (ClrModule.IsMono || Value.DeclaringType.FullName == null) && Value.DeclaringType.ContainsGenericParameters() && !Value.DeclaringType.IsGenericTypeDefinition()) { // from MSDN: If the current type contains generic type parameters that have not been replaced by // specific types (that is, the ContainsGenericParameters property returns true), but the type // is not a generic type definition (that is, the IsGenericTypeDefinition property returns false), // this property returns Nothing. For example, consider the classes Base and Derived in the following code. // if this type is completely generic (no type arguments specified) then we'll go ahead and get the // generic type definition for the this parameter - that'll let us successfully type infer on it later. var genericArgs = Value.DeclaringType.GetGenericArguments(); bool hasOnlyGenerics = genericArgs.Length > 0; foreach (var genericParam in genericArgs) { if (!genericParam.IsGenericParameter) { hasOnlyGenerics = false; break; } } if (hasOnlyGenerics) { genericTypeDefinition = Value.DeclaringType.GetGenericTypeDefinition(); } } else if (Value.DeclaringType.IsGenericTypeDefinition()) { genericTypeDefinition = Value.DeclaringType; } if (genericTypeDefinition != null) { // we're a generic interface method on a non-public type. // We need to see if we can match any types implemented on // the concrete selfType. var interfaces = CompilerHelpers.GetType(Value.BindingSelf).GetInterfaces(); foreach (var iface in interfaces) { if (iface.IsGenericType() && iface.GetGenericTypeDefinition() == genericTypeDefinition) { selfType = iface; break; } } } } if (Value.DeclaringType.IsInterface() && selfType.IsValueType()) { // explicit interface implementation dispatch on a value type, don't // unbox the value type before the dispatch. instance = AstUtils.Convert(instance, Value.DeclaringType); } else if (selfType.IsValueType()) { // We might be calling a a mutating method (like // Rectangle.Intersect). If so, we want it to mutate // the boxed value directly instance = Ast.Unbox(instance, selfType); } else { #if FEATURE_REMOTING Type convType = selfType == typeof(MarshalByRefObject) ? CompilerHelpers.GetVisibleType(Value.DeclaringType) : selfType; instance = AstUtils.Convert(instance, convType); #else instance = AstUtils.Convert(instance, selfType); #endif } } else { // we don't want to cast the enum to its real type, it will unbox it // and turn it into its underlying type. We presumably want to call // a method on the Enum class though - so we cast to Enum instead. instance = AstUtils.Convert(instance, typeof(Enum)); } return(new DynamicMetaObject( instance, restrictions, instanceValue )); }
public static Dictionary <TKey, TValue> MakeDictionary <TKey, TValue>(string[] names, object[] values) { Debug.Assert(typeof(TKey) == typeof(string) || typeof(TKey) == typeof(object)); Dictionary <TKey, TValue> res = new Dictionary <TKey, TValue>(names.Length); IDictionary id = (IDictionary)res; for (int i = 0; i < names.Length; i++) { try { id[names[i]] = values[i]; } catch (ArgumentException) { throw new ArgumentTypeException($"Unable to cast keyword argument of type {CompilerHelpers.GetType(values[i])} to {typeof(TValue)}."); } } return(res); }