Пример #1
0
        public override DynamicMetaObject FallbackInvoke(DynamicMetaObject target, DynamicMetaObject[] args, DynamicMetaObject errorSuggestion)
        {
            var combinedArgs = new Expr[args.Length + 1];

            combinedArgs[0] = target.Expression;
            Array.Copy(args.Select(a => a.Expression).ToArray(), 0, combinedArgs, 1, args.Length);

            var restrictions = target.Restrictions.Merge(BindingRestrictions.Combine(args));
            var expression   =
                Expr.Dynamic(
                    Context.DynamicCache.GetInvokeBinder(new CallInfo(args.Length)),
                    typeof(object),
                    combinedArgs);

            return(new DynamicMetaObject(expression, restrictions));
        }
Пример #2
0
        /// <summary>
        /// Defers the binding of the operation until later time when the runtime values of all dynamic operation arguments have been computed.
        /// </summary>
        /// <param name="target">The target of the dynamic operation.</param>
        /// <param name="args">An array of arguments of the dynamic operation.</param>
        /// <returns>The <see cref="DynamicMetaObject"/> representing the result of the binding.</returns>
        public DynamicMetaObject Defer(DynamicMetaObject target, params DynamicMetaObject[] args)
        {
            ContractUtils.RequiresNotNull(target, "target");

            if (args == null)
            {
                return(MakeDeferred(target.Restrictions, target));
            }
            else
            {
                return(MakeDeferred(
                           target.Restrictions.Merge(BindingRestrictions.Combine(args)),
                           args.AddFirst(target)
                           ));
            }
        }
        public override DynamicMetaObject FallbackInvoke(DynamicMetaObject target, DynamicMetaObject[] args, DynamicMetaObject errorSuggestion)
        {
            if (ComBinder.TryBindInvoke(this, target, args, out DynamicMetaObject res))
            {
                return(res);
            }

            return(errorSuggestion ?? new DynamicMetaObject(
                       Expression.Throw(
                           Expression.New(
                               typeof(NotSupportedException).GetConstructor(new[] { typeof(string) }),
                               Expression.Constant(Strings.CannotCall)
                               )
                           ),
                       target.Restrictions.Merge(BindingRestrictions.Combine(args))
                       ));
        }
Пример #4
0
        // TODO: revisit
        private DynamicMetaObject MakeInvalidParametersRule(DefaultOverloadResolver binder, BindingRestrictions restrictions, BindingTarget bt)
        {
            var args = binder.Arguments;

            BindingRestrictions restriction = MakeSplatTests(binder.CallType, binder.Signature, true, args);

            // restrict to the exact type of all parameters for errors
            for (int i = 0; i < args.Count; i++)
            {
                args[i] = args[i].Restrict(args[i].GetLimitType());
            }

            return(MakeError(
                       binder.MakeInvalidParametersError(bt),
                       restrictions.Merge(BindingRestrictions.Combine(args).Merge(restriction)),
                       typeof(object)
                       ));
        }
Пример #5
0
        private DynamicMetaObject MakeMetaMethodCall(CallSignature signature, OverloadResolverFactory resolverFactory, TargetInfo targetInfo) {
            BindingRestrictions restrictions = BindingRestrictions.Combine(targetInfo.Arguments).Merge(targetInfo.Restrictions);
            if (targetInfo.Instance != null) {
                restrictions = targetInfo.Instance.Restrictions.Merge(restrictions);
            }

            DynamicMetaObject[] args;
            CallTypes callType;
            if (targetInfo.Instance != null) {
                args = ArrayUtils.Insert(targetInfo.Instance, targetInfo.Arguments);
                callType = CallTypes.ImplicitInstance;
            } else {
                args = targetInfo.Arguments;
                callType = CallTypes.None;
            }

            return CallMethod(resolverFactory.CreateOverloadResolver(args, signature, callType), targetInfo.Targets, restrictions);
        }
Пример #6
0
        } // func GetRuntime

        internal static BindingRestrictions GetMethodSignatureRestriction(DynamicMetaObject target, DynamicMetaObject[] args)
        {
            BindingRestrictions restrictions = BindingRestrictions.Combine(args);

            if (target != null)
            {
                restrictions = restrictions
                               .Merge(target.Restrictions)
                               .Merge(GetSimpleRestriction(target));
            }

            for (int i = 0; i < args.Length; i++)
            {
                restrictions = restrictions.Merge(GetSimpleRestriction(args[i]));
            }

            return(restrictions);
        } // func GetMethodSignatureRestriction
Пример #7
0
        public static BindingRestrictions MergeTypeRestrictions(params DynamicMetaObject[] dmos)
        {
            var restrictions = BindingRestrictions.Combine(dmos);

            foreach (var dmo in dmos)
            {
                if (dmo.HasValue && dmo.Value == null)
                {
                    restrictions = restrictions.Merge(BindingRestrictions.GetInstanceRestriction(dmo.Expression, dmo.Value));
                }
                else
                {
                    restrictions = restrictions.Merge(BindingRestrictions.GetTypeRestriction(dmo.Expression, dmo.LimitType));
                }
            }

            return(restrictions);
        }
Пример #8
0
 public override DynamicMetaObject FallbackDeleteIndex(DynamicMetaObject target, DynamicMetaObject[] indexes, DynamicMetaObject errorSuggestion)
 {
     if (indexes[0].LimitType == typeof(string))
     {
         return(new DynamicMetaObject(
                    Expression.Dynamic(new TjsDeleteMemberBinder(_context, (string)indexes[0].Value, false), ReturnType, target.Expression),
                    BindingRestrictions.Combine(ArrayUtils.Insert(target, indexes)).Merge(
                        BindingRestrictions.GetInstanceRestriction(indexes[0].Expression, indexes[0].Value)
                        ).Merge(
                        BindingRestrictions.GetTypeRestriction(indexes[0].Expression, indexes[0].LimitType)
                        )
                    ));
     }
     return(errorSuggestion ?? new DynamicMetaObject(
                Expression.Throw(Expression.Constant(new MissingMemberException(indexes[0].Value.ToString())), typeof(object)),
                BindingRestrictions.Combine(ArrayUtils.Insert(target, indexes)).Merge(BindingRestrictions.GetTypeRestriction(indexes[0].Expression, indexes[0].LimitType))
                ));
 }
Пример #9
0
        // GetTargetArgsRestrictions generates the restrictions needed for the
        // MO resulting from binding an operation.  This combines all existing
        // restrictions and adds some for arg conversions.  targetInst indicates
        // whether to restrict the target to an instance (for operations on type
        // objects) or to a type (for operations on an instance of that type).
        //
        // NOTE, this function should only be used when the caller is converting
        // arguments to the same types as these restrictions.
        //
        public static BindingRestrictions GetTargetArgsRestrictions(
            DynamicMetaObject target, DynamicMetaObject[] args,
            bool instanceRestrictionOnTarget)
        {
            // Important to add existing restriction first because the
            // DynamicMetaObjects (and possibly values) we're looking at depend
            // on the pre-existing restrictions holding true.
            var restrictions = target.Restrictions.Merge(BindingRestrictions
                                                         .Combine(args));

            //LC Use instance restriction is value is null
            if (instanceRestrictionOnTarget || target.Value == null)
            {
                restrictions = restrictions.Merge(
                    BindingRestrictions.GetInstanceRestriction(
                        target.Expression,
                        target.Value
                        ));
            }
            else
            {
                restrictions = restrictions.Merge(
                    BindingRestrictions.GetTypeRestriction(
                        target.Expression,
                        target.LimitType
                        ));
            }
            for (int i = 0; i < args.Length; i++)
            {
                BindingRestrictions r;
                if (args[i].HasValue && args[i].Value == null)
                {
                    r = BindingRestrictions.GetInstanceRestriction(
                        args[i].Expression, null);
                }
                else
                {
                    r = BindingRestrictions.GetTypeRestriction(
                        args[i].Expression, args[i].LimitType);
                }
                restrictions = restrictions.Merge(r);
            }
            return(restrictions);
        }
        /// <summary>
        /// Gets the resulting meta object for the full body.  FinishCondition
        /// must have been called.
        /// </summary>
        public DynamicMetaObject GetMetaObject(params DynamicMetaObject[] types)
        {
            if (_body == null)
            {
                throw new InvalidOperationException("FinishCondition should have been called");
            }

            if (_isError)
            {
                return(new ErrorMetaObject(
                           _body,
                           BindingRestrictions.Combine(types).Merge(Restrictions)
                           ));
            }

            return(new DynamicMetaObject(
                       _body,
                       BindingRestrictions.Combine(types).Merge(Restrictions)
                       ));
        }
Пример #11
0
        public override DynamicMetaObject FallbackInvoke(
            DynamicMetaObject target, DynamicMetaObject[] args,
            DynamicMetaObject errorSuggestion)
        {
            var argexprs = new Expression[args.Length + 1];

            for (var i = 0; i < args.Length; i++)
            {
                argexprs[i + 1] = args[i].Expression;
            }
            argexprs[0] = target.Expression;

            return(new DynamicMetaObject(
                       Runtime.CompileDynamicExpression(
                           Runtime.GetInvokeBinder(args.Length),
                           typeof(object),
                           argexprs),
                       target.Restrictions.Merge(
                           BindingRestrictions.Combine(args))));
        }
Пример #12
0
        public override DynamicMetaObject FallbackInvoke(DynamicMetaObject target, DynamicMetaObject[] args, DynamicMetaObject?errorSuggestion)
        {
            var argExpressions = new Expression[args.Length + 1];

            for (var i = 0; i < args.Length; i++)
            {
                argExpressions[i + 1] = args[i].Expression;
            }

            argExpressions[0] = target.Expression;
            // Just "defer" since we have code in SymplInvokeBinder that knows what to do, and
            // typically this fallback is from a language like Python that passes a DynamicMetaObject
            // with HasValue == false.
            return(new DynamicMetaObject(Expression.Dynamic(
                                             // This call site doesn't share any L2 caching since we don't call
                                             // GetInvokeBinder from Sympl. We aren't plumbed to get the runtime instance here.
                                             new SymplInvokeBinder(new CallInfo(args.Length)), typeof(Object), // ret type
                                             argExpressions),
                                                                                                               // No new restrictions since SymplInvokeBinder will handle it.
                                         target.Restrictions.Merge(BindingRestrictions.Combine(args))));
        }
Пример #13
0
        internal DynamicMetaObject Invoke()
        {
            _keywordArgNames   = _callInfo.ArgumentNames.ToArray();
            _totalExplicitArgs = _args.Length;

            Type[] marshalArgTypes = new Type[_args.Length];

            // We already tested the instance, so no need to test it again
            for (int i = 0; i < _args.Length; i++)
            {
                DynamicMetaObject curMo = _args[i];
                marshalArgTypes[i] = MarshalType(curMo, _isByRef[i]);
            }

            _varEnumSelector = new VarEnumSelector(marshalArgTypes);

            return(new DynamicMetaObject(
                       CreateScope(MakeIDispatchInvokeTarget()),
                       BindingRestrictions.Combine(_args).Merge(_restrictions)
                       ));
        }
Пример #14
0
        internal static DynamicMetaObject CreateThrow(
            DynamicMetaObject target,
            DynamicMetaObject[] args,
            BindingRestrictions restrictions,
            Type exception,
            object[] exceptionArgs)
        {
            if (exception is null)
            {
                throw new ArgumentNullException($"Argument {nameof(exception)} is null!");
            }

            Expression[] argExpressions = null;
            var          argTypes       = Type.EmptyTypes;

            if (exceptionArgs != null)
            {
                var argsLength = exceptionArgs.Length;
                argExpressions = new Expression[argsLength];
                argTypes       = new Type[argsLength];

                for (int i = 0; i < exceptionArgs.Length; i++)
                {
                    var expression = Expression.Constant(exceptionArgs[i]);
                    argExpressions[i] = expression;
                    argTypes[i]       = expression.Type;
                }
            }

            var constructor = exception.GetConstructor(argTypes);

            if (constructor is null)
            {
                throw new ArgumentException($"Type {exception.ToString()} coming from argument {nameof(exception)} doesn't contain a constructor with the given signature.");
            }

            return(new DynamicMetaObject(Expression.Throw(
                                             Expression.New(constructor, argExpressions), typeof(object)),
                                         target.Restrictions.Merge(BindingRestrictions.Combine(args).Merge(restrictions))));
        }
Пример #15
0
        // CreateThrow is a convenience function for when binders cannot bind.
        // They need to return a DynamicMetaObject with appropriate restrictions
        // that throws.  Binders never just throw due to the protocol since
        // a binder or MO down the line may provide an implementation.
        //
        // It returns a DynamicMetaObject whose expr throws the exception, and
        // ensures the expr's type is object to satisfy the CallSite return type
        // constraint.
        //
        // A couple of calls to CreateThrow already have the args and target
        // restrictions merged in, but BindingRestrictions.Merge doesn't add
        // duplicates.
        //
        public static DynamicMetaObject CreateThrow
            (DynamicMetaObject target, DynamicMetaObject[] args,
            BindingRestrictions moreTests,
            Type exception, params object[] exceptionArgs)
        {
            Expression[] argExprs = null;
            Type[]       argTypes = Type.EmptyTypes;
            int          i;

            if (exceptionArgs != null)
            {
                i        = exceptionArgs.Length;
                argExprs = new Expression[i];
                argTypes = new Type[i];
                i        = 0;
                foreach (object o in exceptionArgs)
                {
                    Expression e = Expression.Constant(o);
                    argExprs[i] = e;
                    argTypes[i] = e.Type;
                    i          += 1;
                }
            }
            ConstructorInfo constructor = exception.GetConstructor(argTypes);

            if (constructor == null)
            {
                throw new ArgumentException(
                          "Type doesn't have constructor with a given signature");
            }
            return(new DynamicMetaObject(
                       Expression.Throw(
                           Expression.New(constructor, argExprs),
                           // Force expression to be type object so that DLR CallSite
                           // code things only type object flows out of the CallSite.
                           typeof(object)),
                       target.Restrictions.Merge(BindingRestrictions.Combine(args))
                       .Merge(moreTests)));
        }
Пример #16
0
            // TODO: support for IgnoreCase in underlying ScriptScope APIs
            public override DynamicMetaObject BindInvokeMember(InvokeMemberBinder action, DynamicMetaObject[] args)
            {
                var fallback = action.FallbackInvokeMember(this, args);
                var result   = Expression.Variable(typeof(object), "result");

                var fallbackInvoke = action.FallbackInvoke(new DynamicMetaObject(result, BindingRestrictions.Empty), args, null);

                return(new DynamicMetaObject(
                           Expression.Block(
                               new ParameterExpression[] { result },
                               Expression.Condition(
                                   Expression.Call(
                                       Expression.Convert(Expression, typeof(ScriptScope)),
                                       typeof(ScriptScope).GetMethod("TryGetVariable", new[] { typeof(string), typeof(object).MakeByRefType() }),
                                       Expression.Constant(action.Name),
                                       result
                                       ),
                                   Expression.Convert(fallbackInvoke.Expression, typeof(object)),
                                   Expression.Convert(fallback.Expression, typeof(object))
                                   )
                               ),
                           BindingRestrictions.Combine(args).Merge(BindingRestrictions.GetTypeRestriction(Expression, typeof(ScriptScope))).Merge(fallback.Restrictions)
                           ));
            }
Пример #17
0
        private DynamicMetaObject /*!*/ MakeDynamicMemberAccess(DynamicMetaObjectBinder /*!*/ member, string /*!*/ name, MemberAccess access, DynamicMetaObject /*!*/[] /*!*/ args)
        {
            DynamicMetaObject self = Restrict(typeof(OldInstance));
            Expression        target;

            ParameterExpression tmp = Ast.Variable(typeof(object), "result");

            switch (access)
            {
            case MemberAccess.Invoke:

                target = Ast.Block(
                    new ParameterExpression[] { tmp },
                    Ast.Condition(
                        Expression.Not(
                            Expression.TypeIs(
                                Expression.Assign(
                                    tmp,
                                    Ast.Call(
                                        typeof(PythonOps).GetMethod(nameof(PythonOps.OldInstanceTryGetBoundCustomMember)),
                                        AstUtils.Constant(PythonContext.GetPythonContext(member).SharedContext),
                                        self.Expression,
                                        AstUtils.Constant(name)
                                        )
                                    ),
                                typeof(OperationFailed)
                                )
                            ),
                        ((InvokeMemberBinder)member).FallbackInvoke(new DynamicMetaObject(tmp, BindingRestrictions.Empty), args, null).Expression,
                        AstUtils.Convert(
                            ((InvokeMemberBinder)member).FallbackInvokeMember(this, args).Expression,
                            typeof(object)
                            )
                        )
                    );
                break;

            case MemberAccess.Get:
                target = Ast.Block(
                    new ParameterExpression[] { tmp },
                    Ast.Condition(
                        Expression.Not(
                            Expression.TypeIs(
                                Expression.Assign(
                                    tmp,
                                    Ast.Call(
                                        typeof(PythonOps).GetMethod(nameof(PythonOps.OldInstanceTryGetBoundCustomMember)),
                                        AstUtils.Constant(PythonContext.GetPythonContext(member).SharedContext),
                                        self.Expression,
                                        AstUtils.Constant(name)
                                        )
                                    ),
                                typeof(OperationFailed)
                                )
                            ),
                        tmp,
                        AstUtils.Convert(
                            FallbackGet(member, args),
                            typeof(object)
                            )
                        )
                    );
                break;

            case MemberAccess.Set:
                target = Ast.Call(
                    typeof(PythonOps).GetMethod(nameof(PythonOps.OldInstanceSetCustomMember)),
                    AstUtils.Constant(PythonContext.GetPythonContext(member).SharedContext),
                    self.Expression,
                    AstUtils.Constant(name),
                    AstUtils.Convert(args[1].Expression, typeof(object))
                    );
                break;

            case MemberAccess.Delete:
                target = Ast.Call(
                    typeof(PythonOps).GetMethod(nameof(PythonOps.OldInstanceDeleteCustomMember)),
                    AstUtils.Constant(PythonContext.GetPythonContext(member).SharedContext),
                    self.Expression,
                    AstUtils.Constant(name)
                    );
                break;

            default:
                throw new InvalidOperationException();
            }

            return(new DynamicMetaObject(
                       target,
                       self.Restrictions.Merge(BindingRestrictions.Combine(args))
                       ));
        }
Пример #18
0
        private DynamicMetaObject /*!*/ MakeMemberAccess(DynamicMetaObjectBinder /*!*/ member, string name, MemberAccess access, params DynamicMetaObject /*!*/[] /*!*/ args)
        {
            DynamicMetaObject self = Restrict(typeof(OldInstance));

            CustomInstanceDictionaryStorage dict;
            int key = GetCustomStorageSlot(name, out dict);

            if (key == -1)
            {
                PerfTrack.NoteEvent(PerfTrack.Categories.Binding, "OldInstance " + access + " NoOptimized");
                return(MakeDynamicMemberAccess(member, name, access, args));
            }

            ParameterExpression tmp = Ast.Variable(typeof(object), "dict");
            Expression          target;

            ValidationInfo test = new ValidationInfo(
                Ast.NotEqual(
                    Ast.Assign(
                        tmp,
                        Ast.Call(
                            typeof(PythonOps).GetMethod(nameof(PythonOps.OldInstanceGetOptimizedDictionary)),
                            self.Expression,
                            AstUtils.Constant(dict.KeyVersion)
                            )
                        ),
                    AstUtils.Constant(null)
                    )
                );

            PerfTrack.NoteEvent(PerfTrack.Categories.Binding, "OldInstance " + access + " Optimized");
            switch (access)
            {
            case MemberAccess.Invoke:
                ParameterExpression value = Ast.Variable(typeof(object), "value");
                target = Ast.Block(
                    new[] { value },
                    Ast.Condition(
                        Ast.Call(
                            typeof(PythonOps).GetMethod(nameof(PythonOps.TryOldInstanceDictionaryGetValueHelper)),
                            tmp,
                            Ast.Constant(key),
                            AstUtils.Convert(Expression, typeof(object)),
                            value
                            ),
                        AstUtils.Convert(
                            ((InvokeMemberBinder)member).FallbackInvoke(new DynamicMetaObject(value, BindingRestrictions.Empty), args, null).Expression,
                            typeof(object)
                            ),
                        AstUtils.Convert(
                            ((InvokeMemberBinder)member).FallbackInvokeMember(self, args).Expression,
                            typeof(object)
                            )
                        )
                    );
                break;

            case MemberAccess.Get:
                // BUG: There's a missing Fallback path here that's always been present even
                // in the version that used rules.
                target = Ast.Call(
                    typeof(PythonOps).GetMethod(nameof(PythonOps.OldInstanceDictionaryGetValueHelper)),
                    tmp,
                    AstUtils.Constant(key),
                    AstUtils.Convert(Expression, typeof(object))
                    );
                break;

            case MemberAccess.Set:
                target = Ast.Call(
                    typeof(PythonOps).GetMethod(nameof(PythonOps.OldInstanceDictionarySetExtraValue)),
                    tmp,
                    AstUtils.Constant(key),
                    AstUtils.Convert(args[1].Expression, typeof(object))
                    );
                break;

            case MemberAccess.Delete:
                target = Ast.Call(
                    typeof(PythonOps).GetMethod(nameof(PythonOps.OldInstanceDeleteCustomMember)),
                    AstUtils.Constant(PythonContext.GetPythonContext(member).SharedContext),
                    AstUtils.Convert(Expression, typeof(OldInstance)),
                    AstUtils.Constant(name)
                    );
                break;

            default:
                throw new InvalidOperationException();
            }

            return(BindingHelpers.AddDynamicTestAndDefer(
                       member,
                       new DynamicMetaObject(
                           target,
                           BindingRestrictions.Combine(args).Merge(self.Restrictions)
                           ),
                       args,
                       test,
                       tmp
                       ));
        }
Пример #19
0
        private DynamicMetaObject /*!*/ InvokeWorker(DynamicMetaObjectBinder /*!*/ invoke, Expression /*!*/ codeContext, DynamicMetaObject /*!*/[] args)
        {
            PerfTrack.NoteEvent(PerfTrack.Categories.Binding, "OldClass Invoke");

            DynamicMetaObject self = Restrict(typeof(OldInstance));

            Expression[] exprArgs = new Expression[args.Length + 1];
            for (int i = 0; i < args.Length; i++)
            {
                exprArgs[i + 1] = args[i].Expression;
            }

            ParameterExpression tmp = Ast.Variable(typeof(object), "callFunc");

            exprArgs[0] = tmp;
            return(new DynamicMetaObject(
                       // we could get better throughput w/ a more specific rule against our current custom old class but
                       // this favors less code generation.

                       Ast.Block(
                           new ParameterExpression[] { tmp },
                           Ast.Condition(
                               Expression.Not(
                                   Expression.TypeIs(
                                       Expression.Assign(
                                           tmp,
                                           Ast.Call(
                                               typeof(PythonOps).GetMethod(nameof(PythonOps.OldInstanceTryGetBoundCustomMember)),
                                               codeContext,
                                               self.Expression,
                                               AstUtils.Constant("__call__")
                                               )
                                           ),
                                       typeof(OperationFailed)
                                       )
                                   ),
                               Ast.Block(
                                   Utils.Try(
                                       Ast.Call(typeof(PythonOps).GetMethod(nameof(PythonOps.FunctionPushFrameCodeContext)), codeContext),
                                       Ast.Assign(
                                           tmp,
                                           DynamicExpression.Dynamic(
                                               PythonContext.GetPythonContext(invoke).Invoke(
                                                   BindingHelpers.GetCallSignature(invoke)
                                                   ),
                                               typeof(object),
                                               ArrayUtils.Insert(codeContext, exprArgs)
                                               )
                                           )
                                       ).Finally(
                                       Ast.Call(typeof(PythonOps).GetMethod(nameof(PythonOps.FunctionPopFrame)))
                                       ),
                                   tmp
                                   ),
                               Utils.Convert(
                                   BindingHelpers.InvokeFallback(invoke, codeContext, this, args).Expression,
                                   typeof(object)
                                   )
                               )
                           ),
                       self.Restrictions.Merge(BindingRestrictions.Combine(args))
                       ));
        }
Пример #20
0
        public override DynamicMetaObject FallbackInvoke(DynamicMetaObject target, DynamicMetaObject[] args, DynamicMetaObject errorSuggestion)
        {
            DynamicMetaObject dynamicMetaObject  = errorSuggestion;
            DynamicMetaObject dynamicMetaObject1 = dynamicMetaObject;

            if (dynamicMetaObject == null)
            {
                PSInvokeBinder pSInvokeBinder = new PSInvokeBinder(base.CallInfo);
                Type           type           = typeof(object);
                IEnumerable <DynamicMetaObject> dynamicMetaObjects = args.Prepend <DynamicMetaObject>(target);
                dynamicMetaObject1 = new DynamicMetaObject(Expression.Dynamic(pSInvokeBinder, type, dynamicMetaObjects.Select <DynamicMetaObject, Expression>((DynamicMetaObject dmo) => dmo.Expression)), target.Restrictions.Merge(BindingRestrictions.Combine(args)));
            }
            return(dynamicMetaObject1);
        }
Пример #21
0
 private BindingRestrictions ComTypeLibInfoRestrictions(params DynamicMetaObject[] args)
 {
     return(BindingRestrictions.Combine(args).Merge(BindingRestrictions.GetTypeRestriction(Expression, typeof(ComTypeLibInfo))));
 }
Пример #22
0
        private static DynamicMetaObject TryPrimitiveCompare(OperatorInfo info, DynamicMetaObject[] args)
        {
            if (args[0].GetLimitType().GetNonNullableType() == args[1].GetLimitType().GetNonNullableType() &&
                args[0].GetLimitType().IsNumeric())
            {
                Expression arg0 = args[0].Expression;
                Expression arg1 = args[1].Expression;

                // TODO: Nullable<PrimitveType> Support
                Expression expr;
                switch (info.Operator)
                {
                case ExpressionType.Equal: expr = Expression.Equal(arg0, arg1); break;

                case ExpressionType.NotEqual: expr = Expression.NotEqual(arg0, arg1); break;

                case ExpressionType.GreaterThan: expr = Expression.GreaterThan(arg0, arg1); break;

                case ExpressionType.LessThan: expr = Expression.LessThan(arg0, arg1); break;

                case ExpressionType.GreaterThanOrEqual: expr = Expression.GreaterThanOrEqual(arg0, arg1); break;

                case ExpressionType.LessThanOrEqual: expr = Expression.LessThanOrEqual(arg0, arg1); break;

                default: throw new InvalidOperationException();
                }

                return(new DynamicMetaObject(
                           expr,
                           BindingRestrictionsHelpers.GetRuntimeTypeRestriction(arg0, args[0].GetLimitType()).Merge(BindingRestrictionsHelpers.GetRuntimeTypeRestriction(arg1, args[0].GetLimitType())).Merge(BindingRestrictions.Combine(args))
                           ));
            }

            return(null);
        }
Пример #23
0
 public BindingRestrictions GetAllRestrictions()
 {
     return(BindingRestrictions.Combine(_objects));
 }
Пример #24
0
        private DynamicMetaObject MakeArrayIndexRule(OverloadResolverFactory factory, IndexType oper, DynamicMetaObject[] args)
        {
            if (CanConvertFrom(GetArgType(args, 1), typeof(int), false, NarrowingLevel.All))
            {
                BindingRestrictions restrictions = BindingRestrictionsHelpers.GetRuntimeTypeRestriction(args[0].Expression, args[0].GetLimitType()).Merge(BindingRestrictions.Combine(args));

                if (oper == IndexType.Get)
                {
                    return(new DynamicMetaObject(
                               Expression.ArrayAccess(
                                   args[0].Expression,
                                   ConvertIfNeeded(factory, args[1].Expression, typeof(int))
                                   ),
                               restrictions
                               ));
                }

                return(new DynamicMetaObject(
                           Expression.Assign(
                               Expression.ArrayAccess(
                                   args[0].Expression,
                                   ConvertIfNeeded(factory, args[1].Expression, typeof(int))
                                   ),
                               ConvertIfNeeded(factory, args[2].Expression, args[0].GetLimitType().GetElementType())
                               ),
                           restrictions.Merge(args[1].Restrictions)
                           ));
            }

            return(null);
        }
Пример #25
0
        private static DynamicMetaObject TryMakeDefaultUnaryRule(OperatorInfo info, DynamicMetaObject[] args)
        {
            if (args.Length == 1)
            {
                BindingRestrictions restrictions = BindingRestrictionsHelpers.GetRuntimeTypeRestriction(args[0].Expression, args[0].GetLimitType()).Merge(BindingRestrictions.Combine(args));
                switch (info.Operator)
                {
                case ExpressionType.IsTrue:
                    if (args[0].GetLimitType() == typeof(bool))
                    {
                        return(args[0]);
                    }
                    break;

                case ExpressionType.Negate:
                    if (args[0].GetLimitType().IsArithmetic())
                    {
                        return(new DynamicMetaObject(
                                   Expression.Negate(args[0].Expression),
                                   restrictions
                                   ));
                    }
                    break;

                case ExpressionType.Not:
                    if (args[0].GetLimitType().IsIntegerOrBool())
                    {
                        return(new DynamicMetaObject(
                                   Expression.Not(args[0].Expression),
                                   restrictions
                                   ));
                    }
                    break;
                }
            }
            return(null);
        }
 public void CombineRestrictionsFromNull()
 {
     Assert.Same(BindingRestrictions.Empty, BindingRestrictions.Combine(null));
 }
Пример #27
0
        internal static DynamicMetaObject TranslateArguments(DynamicMetaObjectBinder call, Expression codeContext, DynamicMetaObject function, DynamicMetaObject /*!*/[] args, bool hasSelf, string name)
        {
            if (hasSelf)
            {
                args = ArrayUtils.RemoveFirst(args);
            }

            CallSignature sig = BindingHelpers.GetCallSignature(call);

            if (sig.HasDictionaryArgument())
            {
                int index = sig.IndexOf(ArgumentType.Dictionary);

                DynamicMetaObject dict = args[index];

                if (!(dict.Value is IDictionary) && dict.Value != null)
                {
                    // The DefaultBinder only handles types that implement IDictionary.  Here we have an
                    // arbitrary user-defined mapping type.  We'll convert it into a PythonDictionary
                    // and then have an embedded dynamic site pass that dictionary through to the default
                    // binder.
                    DynamicMetaObject[] dynamicArgs = ArrayUtils.Insert(function, args);

                    dynamicArgs[index + 1] = new DynamicMetaObject(
                        Expression.Call(
                            typeof(PythonOps).GetMethod(nameof(PythonOps.UserMappingToPythonDictionary)),
                            codeContext,
                            args[index].Expression,
                            AstUtils.Constant(name)
                            ),
                        BindingRestrictionsHelpers.GetRuntimeTypeRestriction(dict.Expression, dict.GetLimitType()),
                        PythonOps.UserMappingToPythonDictionary(PythonContext.GetPythonContext(call).SharedContext, dict.Value, name)
                        );

                    if (call is IPythonSite)
                    {
                        dynamicArgs = ArrayUtils.Insert(
                            new DynamicMetaObject(codeContext, BindingRestrictions.Empty),
                            dynamicArgs
                            );
                    }

                    return(new DynamicMetaObject(
                               DynamicExpression.Dynamic(
                                   call,
                                   typeof(object),
                                   DynamicUtils.GetExpressions(dynamicArgs)
                                   ),
                               BindingRestrictions.Combine(dynamicArgs).Merge(BindingRestrictionsHelpers.GetRuntimeTypeRestriction(dict.Expression, dict.GetLimitType()))
                               ));
                }
            }

            if (sig.HasListArgument())
            {
                int index             = sig.IndexOf(ArgumentType.List);
                DynamicMetaObject str = args[index];

                // TODO: ANything w/ __iter__ that's not an IList<object>
                if (!(str.Value is IList <object>) && str.Value is IEnumerable)
                {
                    // The DefaultBinder only handles types that implement IList<object>.  Here we have a
                    // string.  We'll convert it into a tuple
                    // and then have an embedded dynamic site pass that tuple through to the default
                    // binder.
                    DynamicMetaObject[] dynamicArgs = ArrayUtils.Insert(function, args);

                    dynamicArgs[index + 1] = new DynamicMetaObject(
                        Expression.Call(
                            typeof(PythonOps).GetMethod(nameof(PythonOps.MakeTupleFromSequence)),
                            Expression.Convert(args[index].Expression, typeof(object))
                            ),
                        BindingRestrictions.Empty
                        );

                    if (call is IPythonSite)
                    {
                        dynamicArgs = ArrayUtils.Insert(
                            new DynamicMetaObject(codeContext, BindingRestrictions.Empty),
                            dynamicArgs
                            );
                    }

                    return(new DynamicMetaObject(
                               DynamicExpression.Dynamic(
                                   call,
                                   typeof(object),
                                   DynamicUtils.GetExpressions(dynamicArgs)
                                   ),
                               function.Restrictions.Merge(
                                   BindingRestrictions.Combine(args).Merge(BindingRestrictionsHelpers.GetRuntimeTypeRestriction(str.Expression, str.GetLimitType()))
                                   )
                               ));
                }
            }
            return(null);
        }
Пример #28
0
        internal static DynamicMetaObject Call(DynamicMetaObjectBinder /*!*/ call, DynamicMetaObject target, DynamicMetaObject /*!*/[] /*!*/ args)
        {
            Assert.NotNull(call, args);
            Assert.NotNullItems(args);

            if (target.NeedsDeferral())
            {
                return(call.Defer(ArrayUtils.Insert(target, args)));
            }

            foreach (DynamicMetaObject mo in args)
            {
                if (mo.NeedsDeferral())
                {
                    RestrictTypes(args);

                    return(call.Defer(
                               ArrayUtils.Insert(target, args)
                               ));
                }
            }

            DynamicMetaObject self = target.Restrict(target.GetLimitType());

            ValidationInfo valInfo   = BindingHelpers.GetValidationInfo(target);
            PythonType     pt        = DynamicHelpers.GetPythonType(target.Value);
            PythonContext  pyContext = PythonContext.GetPythonContext(call);

            // look for __call__, if it's present dispatch to it.  Otherwise fall back to the
            // default binder
            PythonTypeSlot callSlot;

            if (!typeof(Delegate).IsAssignableFrom(target.GetLimitType()) &&
                pt.TryResolveSlot(pyContext.SharedContext, "__call__", out callSlot))
            {
                ConditionalBuilder cb = new ConditionalBuilder(call);

                callSlot.MakeGetExpression(
                    pyContext.Binder,
                    PythonContext.GetCodeContext(call),
                    self,
                    GetPythonType(self),
                    cb
                    );

                if (!cb.IsFinal)
                {
                    cb.FinishCondition(GetCallError(call, self));
                }

                Expression[] callArgs = ArrayUtils.Insert(
                    PythonContext.GetCodeContext(call),
                    cb.GetMetaObject().Expression,
                    DynamicUtils.GetExpressions(args)
                    );

                Expression body = DynamicExpression.Dynamic(
                    PythonContext.GetPythonContext(call).Invoke(
                        BindingHelpers.GetCallSignature(call)
                        ),
                    typeof(object),
                    callArgs
                    );

                body = Ast.TryFinally(
                    Ast.Block(
                        Ast.Call(typeof(PythonOps).GetMethod(nameof(PythonOps.FunctionPushFrame)), Ast.Constant(pyContext)),
                        body
                        ),
                    Ast.Call(typeof(PythonOps).GetMethod(nameof(PythonOps.FunctionPopFrame)))
                    );

                return(BindingHelpers.AddDynamicTestAndDefer(
                           call,
                           new DynamicMetaObject(body, self.Restrictions.Merge(BindingRestrictions.Combine(args))),
                           args,
                           valInfo
                           ));
            }

            return(null);
        }
        public override DynamicMetaObject FallbackInvokeMember(DynamicMetaObject target, DynamicMetaObject[] args, DynamicMetaObject errorSuggestion)
        {
            if (target.HasValue && target.Value == null)
            {
                return(errorSuggestion ??
                       new DynamicMetaObject(
                           Expression.Throw(
                               Expression.New(typeof(MissingMethodException).GetConstructor(new Type[] { typeof(string) }),
                                              Expression.Constant(String.Format("Cannot call {0} method named {1} on nil", _isStatic ? "static" : "instance", this.Name))),
                               typeof(object)),
                           BindingRestrictions.GetInstanceRestriction(target.Expression, null)));
            }



            Type typeToUse = _isStatic && target.Value is Type ? (Type)target.Value : target.LimitType;


            IList <DynamicMetaObject> argsPlus = new List <DynamicMetaObject>(args.Length + (_isStatic ? 0 : 1));

            if (!_isStatic)
            {
                argsPlus.Add(target);
            }
            foreach (DynamicMetaObject arg in args)
            {
                argsPlus.Add(arg);
            }

            OverloadResolverFactory factory = _context.SharedOverloadResolverFactory;
            DefaultOverloadResolver res     = factory.CreateOverloadResolver(argsPlus, new CallSignature(args.Length), _isStatic ? CallTypes.None : CallTypes.ImplicitInstance);

            BindingFlags       flags   = BindingFlags.InvokeMethod | BindingFlags.Public | (_isStatic ? BindingFlags.Static : BindingFlags.Instance);
            IList <MethodBase> methods = new List <MethodBase>(typeToUse.GetMethods(flags).Where <MethodBase>(x => x.Name == Name && x.GetParameters().Length == args.Length));

            if (methods.Count > 0)
            {
                BindingTarget     bt;
                DynamicMetaObject dmo = _context.Binder.CallMethod(
                    res,
                    methods,
                    target.Restrictions.Merge(BindingRestrictionsHelpers.GetRuntimeTypeRestriction(target).Merge(BindingRestrictions.Combine(args))),
                    Name,
                    NarrowingLevel.None,
                    NarrowingLevel.All,
                    out bt);
                dmo = DynUtils.MaybeBoxReturnValue(dmo);

                //; Console.WriteLine(dmo.Expression.DebugView);
                return(dmo);
            }

            return(errorSuggestion ??
                   new DynamicMetaObject(
                       Expression.Throw(
                           Expression.New(typeof(MissingMethodException).GetConstructor(new Type[] { typeof(string) }),
                                          Expression.Constant(String.Format("No matching member {0} taking {1} args for {2}", this.Name, args.Length, typeToUse.Name))),
                           typeof(object)),
                       target.Restrictions.Merge(BindingRestrictionsHelpers.GetRuntimeTypeRestriction(target).Merge(BindingRestrictions.Combine(args)))));
        }
Пример #30
0
        /// <summary>
        /// Produces a rule for comparing a value to null - supports comparing object references and nullable types.
        /// </summary>
        private static DynamicMetaObject TryNullComparisonRule(DynamicMetaObject[] args)
        {
            Type otherType = args[1].GetLimitType();

            BindingRestrictions restrictions = BindingRestrictionsHelpers.GetRuntimeTypeRestriction(args[0].Expression, args[0].GetLimitType()).Merge(BindingRestrictions.Combine(args));

            if (args[0].GetLimitType() == typeof(DynamicNull))
            {
                if (!otherType.IsValueType)
                {
                    return(new DynamicMetaObject(
                               Expression.Equal(args[0].Expression, AstUtils.Constant(null)),
                               restrictions
                               ));
                }

                if (otherType.GetGenericTypeDefinition() == typeof(Nullable <>))
                {
                    return(new DynamicMetaObject(
                               Expression.Property(args[0].Expression, otherType.GetDeclaredProperty("HasValue")),
                               restrictions
                               ));
                }
            }
            else if (otherType == typeof(DynamicNull))
            {
                if (!args[0].GetLimitType().IsValueType)
                {
                    return(new DynamicMetaObject(
                               Expression.Equal(args[0].Expression, AstUtils.Constant(null)),
                               restrictions
                               ));
                }

                if (args[0].GetLimitType().GetGenericTypeDefinition() == typeof(Nullable <>))
                {
                    return(new DynamicMetaObject(
                               Expression.Property(args[0].Expression, otherType.GetDeclaredProperty("HasValue")),
                               restrictions
                               ));
                }
            }
            return(null);
        }