/// <summary>
 /// Helper to produce the rule for converting T to Nullable of T
 /// </summary>
 private static DynamicMetaObject MakeTToNullableOfTTarget(Type toType, Type knownType, BindingRestrictions restrictions, DynamicMetaObject arg)
 {
     // T -> Nullable<T>
     return(new DynamicMetaObject(
                Ast.New(
                    toType.GetConstructor(new Type[] { knownType }),
                    AstUtils.Convert(arg.Expression, knownType)
                    ),
                restrictions
                ));
 }
예제 #2
0
        private static Expression /*!*/ GetCallError(DynamicMetaObjectBinder binder, DynamicMetaObject /*!*/ self)
        {
            Assert.NotNull(self);

            return(binder.Throw(
                       Ast.Call(
                           typeof(PythonOps).GetMethod(nameof(PythonOps.UncallableError)),
                           AstUtils.Convert(self.Expression, typeof(object))
                           )
                       ));
        }
예제 #3
0
 internal static MSAst.Expression /*!*/ ConvertIfNeeded(MSAst.Expression /*!*/ expression, Type /*!*/ type)
 {
     Debug.Assert(expression != null);
     // Do we need conversion?
     if (!CanAssign(type, expression.Type))
     {
         // Add conversion step to the AST
         expression = AstUtils.Convert(expression, type);
     }
     return(expression);
 }
        protected internal override bool TryImplicitConversion(MetaObjectBuilder /*!*/ metaBuilder, CallArguments /*!*/ args)
        {
            var convertedTarget = args.Target as IList;

            if (convertedTarget != null)
            {
                metaBuilder.Result = AstUtils.Convert(args.TargetExpression, typeof(IList));
                return(true);
            }
            return(false);
        }
예제 #5
0
        public override MSAst.Expression Reduce()
        {
            MSAst.Expression ifTrue  = AstUtils.Convert(TrueExpression, typeof(object));
            MSAst.Expression ifFalse = AstUtils.Convert(FalseExpression, typeof(object));

            return(Ast.Condition(
                       GlobalParent.Convert(typeof(bool), ConversionResultKind.ExplicitCast, Test),
                       ifTrue,
                       ifFalse
                       ));
        }
예제 #6
0
 public DynamicMetaObject GetMetaObject(Expression parameter, int index)
 {
     return(DynamicMetaObject.Create(
                GetArgument(index),
                Expression.Call(
                    _GetArgMethod,
                    AstUtils.Convert(parameter, typeof(ArgumentArray)),
                    AstUtils.Constant(index)
                    )
                ));
 }
예제 #7
0
        private Expression /*!*/ MarshalArgument(MetaObjectBuilder /*!*/ metaBuilder, DynamicMetaObject /*!*/ arg, ArgType parameterType)
        {
            object value = arg.Value;

            if (value == null)
            {
                metaBuilder.AddRestriction(Ast.Equal(arg.Expression, AstUtils.Constant(null)));
            }
            else
            {
                metaBuilder.AddTypeRestriction(value.GetType(), arg.Expression);
            }

            switch (parameterType)
            {
            case ArgType.Buffer:
                if (value == null)
                {
                    return(AstUtils.Constant(null, typeof(byte[])));
                }

                if (value is int && (int)value == 0)
                {
                    metaBuilder.AddRestriction(Ast.Equal(AstUtils.Convert(arg.Expression, typeof(int)), AstUtils.Constant(0)));
                    return(AstUtils.Constant(null, typeof(byte[])));
                }

                if (value.GetType() == typeof(MutableString))
                {
                    return(Methods.GetMutableStringBytes.OpCall(
                               AstUtils.Convert(arg.Expression, typeof(MutableString))
                               ));
                }

                return(Methods.GetMutableStringBytes.OpCall(
                           AstUtils.LightDynamic(ConvertToStrAction.Make(_context), typeof(MutableString), arg.Expression)
                           ));

            case ArgType.Int32:
                if (value is int)
                {
                    return(AstUtils.Convert(arg.Expression, typeof(int)));
                }

                return(Ast.Convert(
                           Ast.Call(
                               AstUtils.LightDynamic(ConvertToIntAction.Make(_context), typeof(IntegerValue), arg.Expression),
                               Methods.IntegerValue_ToUInt32Unchecked
                               ),
                           typeof(int)
                           ));
            }
            throw Assert.Unreachable;
        }
예제 #8
0
 internal static MSAst.Expression TransformOrConstantNull(Expression expression, Type /*!*/ type)
 {
     if (expression == null)
     {
         return(AstUtils.Constant(null, type));
     }
     else
     {
         return(AstUtils.Convert(expression, type));
     }
 }
        /// <summary>
        /// Helper to produce a rule when no conversion is required from an extensible type's
        /// underlying storage to the type we're converting to.  The type of extensible type
        /// matches the type we're converting to or has an implicit conversion at the IL level.
        /// </summary>
        private static DynamicMetaObject MakeSimpleExtensibleConversionTarget(Type toType, BindingRestrictions restrictions, DynamicMetaObject arg)
        {
            Type extType = typeof(Extensible <>).MakeGenericType(toType);

            return(new DynamicMetaObject(
                       AstUtils.Convert(
                           GetExtensibleValue(extType, arg),
                           toType
                           ),
                       restrictions
                       ));
        }
예제 #10
0
 internal static ValidationInfo /*!*/ GetValidationInfo(DynamicMetaObject /*!*/ tested, PythonType type)
 {
     return(new ValidationInfo(
                Ast.AndAlso(
                    Ast.TypeEqual(tested.Expression, type.UnderlyingSystemType),
                    CheckTypeVersion(
                        AstUtils.Convert(tested.Expression, type.UnderlyingSystemType),
                        type.Version
                        )
                    )
                ));
 }
예제 #11
0
        private ValidationInfo GetTypeTest()
        {
            int version = Value.Version;

            return(new ValidationInfo(
                       Ast.Call(
                           typeof(PythonOps).GetMethod(nameof(PythonOps.CheckSpecificTypeVersion)),
                           AstUtils.Convert(Expression, typeof(PythonType)),
                           AstUtils.Constant(version)
                           )
                       ));
        }
예제 #12
0
            public override DynamicMetaObject /*!*/ MakeInitCall(PythonBinder /*!*/ binder, DynamicMetaObject /*!*/ createExpr)
            {
                Expression init = Ast.Call(
                    typeof(PythonOps).GetMethod("GetMixedMember"),
                    CodeContext,
                    Ast.Convert(Arguments.Self.Expression, typeof(PythonType)),
                    AstUtils.Convert(createExpr.Expression, typeof(object)),
                    AstUtils.Constant("__init__")
                    );

                return(MakeDefaultInit(binder, createExpr, init));
            }
예제 #13
0
 /// <summary>
 /// Helper to produce the rule for converting T to Nullable of T
 /// </summary>
 private void MakeTToNullableOfTTarget(Type toType, Type knownType)
 {
     // T -> Nullable<T>
     _rule.Target =
         _rule.MakeReturn(
             Binder,
             Ast.New(
                 toType.GetConstructor(new Type[] { knownType }),
                 AstUtils.Convert(_rule.Parameters[0], knownType)
                 )
             );
 }
예제 #14
0
        internal LoopFunc CreateDelegate()
        {
            var loop          = (LoopExpression)Visit(_loop);
            var body          = new ReadOnlyCollectionBuilder <Expression>();
            var finallyClause = new ReadOnlyCollectionBuilder <Expression>();

            foreach (var variable in _loopVariables)
            {
                LocalVariable local   = _locals[variable.Key];
                Expression    elemRef = local.LoadFromArray(_frameDataVar, _frameClosureVar);

                if (local.InClosureOrBoxed)
                {
                    var box = variable.Value.BoxStorage;
                    Debug.Assert(box != null);
                    body.Add(Expression.Assign(box, elemRef));
                    AddTemp(box);
                }
                else
                {
                    // Always initialize the variable even if it is only written to.
                    // If a write-only variable is actually not assigned during execution of the loop we will still write some value back.
                    // This value must be the original value, which we assign at entry.
                    body.Add(Expression.Assign(variable.Key, AstUtils.Convert(elemRef, variable.Key.Type)));

                    if ((variable.Value.Access & ExpressionAccess.Write) != 0)
                    {
                        finallyClause.Add(Expression.Assign(elemRef, AstUtils.Box(variable.Key)));
                    }

                    AddTemp(variable.Key);
                }
            }

            if (finallyClause.Count > 0)
            {
                body.Add(Expression.TryFinally(loop, Expression.Block(finallyClause)));
            }
            else
            {
                body.Add(loop);
            }

            body.Add(Expression.Label(_returnLabel, Expression.Constant(_loopEndInstructionIndex - _loopStartInstructionIndex)));

            var lambda = Expression.Lambda <LoopFunc>(
                _temps != null ? Expression.Block(_temps.ToReadOnlyCollection(), body) : Expression.Block(body),
                new[] { _frameDataVar, _frameClosureVar, _frameVar }
                );

            return(lambda.Compile());
        }
예제 #15
0
        /// <summary>
        /// Helper to produce a rule when no conversion is required from an extensible type's
        /// underlying storage to the type we're converting to.  The type of extensible type
        /// matches the type we're converting to or has an implicit conversion at the IL level.
        /// </summary>
        /// <param name="toType"></param>
        private void MakeSimpleExtensibleConversionTarget(Type toType)
        {
            Type extType = typeof(Extensible <>).MakeGenericType(toType);

            _rule.Target =
                _rule.MakeReturn(
                    Binder,
                    AstUtils.Convert(
                        GetExtensibleValue(extType),
                        toType
                        )
                    );
        }
예제 #16
0
 internal MSA.Expression /*!*/ AddReturnTarget(MSA.Expression /*!*/ expression)
 {
     if (expression.Type != typeof(object))
     {
         expression = AstUtils.Convert(expression, typeof(object));
     }
     if (_returnLabel != null)
     {
         expression   = Ast.Label(_returnLabel, expression);
         _returnLabel = null;
     }
     return(expression);
 }
예제 #17
0
 private DynamicMetaObject ConvertFromMemoryToBufferProtocol(DynamicMetaObject self, Type fromType)
 {
     return(new DynamicMetaObject(
                AstUtils.Convert(
                    Ast.New(
                        typeof(MemoryBufferProtocolWrapper).GetConstructor(new Type[] { fromType }),
                        AstUtils.Convert(self.Expression, fromType)
                        ),
                    typeof(IBufferProtocol)
                    ),
                self.Restrictions
                ));
 }
예제 #18
0
 private DynamicMetaObject ConvertFromBufferProtocolToByteList(DynamicMetaObject self, Type toType)
 {
     return(new DynamicMetaObject(
                AstUtils.Convert(
                    Ast.Call(
                        typeof(PythonConversionBinder).GetMethod(nameof(PythonConversionBinder.ConvertFromBufferProtocolToByteListHelper), BindingFlags.NonPublic | BindingFlags.Static),
                        AstUtils.Convert(self.Expression, typeof(IBufferProtocol))
                        ),
                    toType
                    ),
                self.Restrictions
                ));
 }
예제 #19
0
 private DynamicMetaObject ConvertFromBufferProtocolToMemory(DynamicMetaObject self, Type toType)
 {
     return(new DynamicMetaObject(
                AstUtils.Convert(
                    Ast.Call(
                        AstUtils.Convert(self.Expression, typeof(IBufferProtocol)),
                        typeof(IBufferProtocol).GetMethod(nameof(IBufferProtocol.ToMemory))
                        ),
                    toType
                    ),
                self.Restrictions
                ));
 }
예제 #20
0
 private DynamicMetaObject ConvertIntToBigInteger(DynamicMetaObject self, Type toType)
 {
     return(new DynamicMetaObject(
                AstUtils.Convert(
                    Ast.Call(
                        typeof(PythonOps).GetMethod(nameof(PythonOps.ConvertIntToBigInt)),
                        AstUtils.Convert(self.Expression, typeof(object))
                        ),
                    toType
                    ),
                self.Restrictions
                ));
 }
예제 #21
0
 public virtual DynamicMetaObject /*!*/ GetExpression(PythonBinder /*!*/ binder)
 {
     return(MakeDefaultNew(
                binder,
                Ast.Call(
                    typeof(PythonOps).GetMethod("PythonTypeGetMember"),
                    CodeContext,
                    AstUtils.Convert(Arguments.Self.Expression, typeof(PythonType)),
                    AstUtils.Constant(null),
                    AstUtils.Constant("__new__")
                    )
                ));
 }
        internal static DynamicMetaObject FallbackWorker(PythonContext context, DynamicMetaObject /*!*/ self, DynamicMetaObject /*!*/ codeContext, string name, GetMemberOptions options, DynamicMetaObjectBinder action, DynamicMetaObject errorSuggestion)
        {
            if (self.NeedsDeferral())
            {
                return(action.Defer(self));
            }
            PythonOverloadResolverFactory resolverFactory = new PythonOverloadResolverFactory(context.Binder, codeContext.Expression);

            PerfTrack.NoteEvent(PerfTrack.Categories.BindingTarget, "FallbackGet");

            bool isNoThrow = ((options & GetMemberOptions.IsNoThrow) != 0) ? true : false;
            Type limitType = self.GetLimitType();

            if (limitType == typeof(DynamicNull) || PythonBinder.IsPythonType(limitType))
            {
                // look up in the PythonType so that we can
                // get our custom method names (e.g. string.startswith)
                PythonType argType = DynamicHelpers.GetPythonTypeFromType(limitType);

                // if the name is defined in the CLS context but not the normal context then
                // we will hide it.
                if (argType.IsHiddenMember(name))
                {
                    DynamicMetaObject baseRes = PythonContext.GetPythonContext(action).Binder.GetMember(
                        name,
                        self,
                        resolverFactory,
                        isNoThrow,
                        errorSuggestion
                        );
                    Expression failure = GetFailureExpression(limitType, self, name, isNoThrow, action);

                    return(BindingHelpers.FilterShowCls(codeContext, action, baseRes, failure));
                }
            }

            var res = PythonContext.GetPythonContext(action).Binder.GetMember(name, self, resolverFactory, isNoThrow, errorSuggestion);

            // Default binder can return something typed to boolean or int.
            // If that happens, we need to apply Python's boxing rules.
            if (res.Expression.Type.IsValueType)
            {
                res = new DynamicMetaObject(
                    AstUtils.Convert(res.Expression, typeof(object)),
                    res.Restrictions
                    );
            }

            return(res);
        }
예제 #23
0
 private ValidationInfo /*!*/ TestUserType()
 {
     return(new ValidationInfo(
                Ast.Not(
                    Ast.Call(
                        typeof(PythonOps).GetMethod(nameof(PythonOps.IsPythonType)),
                        AstUtils.Convert(
                            Expression,
                            typeof(PythonType)
                            )
                        )
                    )
                ));
 }
예제 #24
0
 internal static MethodCallExpression MakeTryGetTypeMember(PythonContext /*!*/ PythonContext, PythonTypeSlot dts, ParameterExpression tmp, Expression instance, Expression pythonType)
 {
     return(Ast.Call(
                PythonTypeInfo._PythonOps.SlotTryGetBoundValue,
                AstUtils.Constant(PythonContext.SharedContext),
                AstUtils.Convert(Utils.WeakConstant(dts), typeof(PythonTypeSlot)),
                AstUtils.Convert(instance, typeof(object)),
                AstUtils.Convert(
                    pythonType,
                    typeof(PythonType)
                    ),
                tmp
                ));
 }
예제 #25
0
        private DynamicMetaObject /*!*/ MakeSetMember(string /*!*/ name, DynamicMetaObject /*!*/ value)
        {
            PerfTrack.NoteEvent(PerfTrack.Categories.Binding, "OldClass SetMember");
            PerfTrack.NoteEvent(PerfTrack.Categories.BindingTarget, "OldClass SetMember");
            DynamicMetaObject self = Restrict(typeof(OldClass));

            Expression call, valueExpr = AstUtils.Convert(value.Expression, typeof(object));

            switch (name)
            {
            case "__bases__":
                call = Ast.Call(
                    typeof(PythonOps).GetMethod("OldClassSetBases"),
                    self.Expression,
                    valueExpr
                    );
                break;

            case "__name__":
                call = Ast.Call(
                    typeof(PythonOps).GetMethod("OldClassSetName"),
                    self.Expression,
                    valueExpr
                    );
                break;

            case "__dict__":
                call = Ast.Call(
                    typeof(PythonOps).GetMethod("OldClassSetDictionary"),
                    self.Expression,
                    valueExpr
                    );
                break;

            default:
                call = Ast.Call(
                    typeof(PythonOps).GetMethod("OldClassSetNameHelper"),
                    self.Expression,
                    AstUtils.Constant(name),
                    valueExpr
                    );
                break;
            }

            return(new DynamicMetaObject(
                       call,
                       self.Restrictions.Merge(value.Restrictions)
                       ));
        }
예제 #26
0
 private DynamicMetaObject ConvertFromBufferProtocolToByteList(DynamicMetaObject self, Type toType)
 {
     return(new DynamicMetaObject(
                AstUtils.Convert(
                    Ast.Call(
                        AstUtils.Convert(self.Expression, typeof(IBufferProtocol)),
                        typeof(IBufferProtocol).GetMethod(nameof(IBufferProtocol.ToBytes)),
                        AstUtils.Constant(0, typeof(int)),
                        AstUtils.Constant(null, typeof(Nullable <int>))
                        ),
                    toType
                    ),
                self.Restrictions
                ));
 }
예제 #27
0
        protected internal override bool TryImplicitConversion(MetaObjectBuilder metaBuilder, CallArguments args)
        {
            if (base.TryImplicitConversion(metaBuilder, args))
            {
                return(true);
            }

            if (args.Target is RubySymbol)
            {
                metaBuilder.Result = Methods.ConvertSymbolToMutableString.OpCall(AstUtils.Convert(args.TargetExpression, typeof(RubySymbol)));
                return(true);
            }

            return(false);
        }
예제 #28
0
        private static DynamicMetaObject EnsureReturnType(Type returnType, DynamicMetaObject dynamicMetaObject)
        {
            if (dynamicMetaObject.Expression.Type != returnType)
            {
                dynamicMetaObject = new DynamicMetaObject(
                    AstUtils.Convert(
                        dynamicMetaObject.Expression,
                        returnType
                        ),
                    dynamicMetaObject.Restrictions
                    );
            }

            return(dynamicMetaObject);
        }
예제 #29
0
 protected override DynamicMetaObject GetBoundValue(OverloadResolverFactory factory, ActionBinder binder, Type type, DynamicMetaObject instance) {
     return new DynamicMetaObject(
         Ast.Call(
             typeof(PythonOps).GetMethod("SlotGetValue"),
             ((PythonOverloadResolverFactory)factory)._codeContext,
             AstUtils.Constant(GetSlot(), typeof(PythonTypeSlot)),
             AstUtils.Convert(
                 instance.Expression,
                 typeof(object)
             ),
             AstUtils.Constant(DynamicHelpers.GetPythonTypeFromType(type))
         ),
         BindingRestrictions.Empty
     );
 }
예제 #30
0
        public override DynamicMetaObject /*!*/ BindInvoke(InvokeBinder /*!*/ action, DynamicMetaObject /*!*/[] /*!*/ args)
        {
            Expression context = Ast.Call(
                typeof(PythonOps).GetMethod("GetPythonTypeContext"),
                Ast.Property(
                    AstUtils.Convert(Expression, typeof(IPythonObject)),
                    "PythonType"
                    )
                );

            return(InvokeWorker(
                       action,
                       context,
                       args
                       ));
        }