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));
        }
Exemplo n.º 3
0
        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));
        }
Exemplo n.º 4
0
        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);
            }
                       ));
        }
Exemplo n.º 5
0
 private static void NoteRuleCreation(DynamicAction action, object[] args)
 {
     PerfTrack.NoteEvent(PerfTrack.Categories.Rules, "MakeRule " + action.ToString() + " " + CompilerHelpers.GetType(args[0]).Name);
 }
Exemplo n.º 6
0
        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);
            }
        }
Exemplo n.º 7
0
 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));
 }
Exemplo n.º 9
0
 [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}"));
 }
Exemplo n.º 11
0
        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();
            }
        }
Exemplo n.º 12
0
 public static object IncorrectBoxType(Type expected, object received)
 {
     throw new ArgumentTypeException(String.Format("Expected type {0}, got {1}", expected, CompilerHelpers.GetType(received)));
 }
Exemplo n.º 13
0
 public static AbstractValue Constant(object value, Expression expression)
 {
     return(new AbstractValue(value, CompilerHelpers.GetType(value), AbstractKind.Constant, expression));
 }
Exemplo n.º 14
0
 public void MakeRule()
 {
     Rule.MakeTest(StrongBoxType ?? CompilerHelpers.GetType(Target));
     Rule.Target = MakeDeleteMemberTarget();
 }
Exemplo n.º 15
0
        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)));
        }
Exemplo n.º 16
0
 public static T IncorrectBoxType <T>(object received)
 {
     throw Error.UnexpectedType("StrongBox<" + typeof(T).Name + ">", CompilerHelpers.GetType(received).Name);
 }
Exemplo n.º 17
0
        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));
        }
Exemplo n.º 18
0
 public static Exception MakeIncorrectBoxTypeError(Type type, object received)
 {
     return(Error.UnexpectedType("StrongBox<" + type.Name + ">", CompilerHelpers.GetType(received).Name));
 }
Exemplo n.º 19
0
        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));
        }
Exemplo n.º 20
0
 private MethodInfo[] GetApplicableMembers(OperatorInfo info)
 {
     return(GetApplicableMembers(CompilerHelpers.GetType(_args[0]), info));
 }
Exemplo n.º 21
0
        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
                       ));
        }
Exemplo n.º 22
0
        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);
        }
Exemplo n.º 23
0
        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
                       ));
        }
Exemplo n.º 24
0
        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);
        }