示例#1
0
 internal static CallSignature GetReversedSignature(CallSignature signature) {
     return new CallSignature(ArrayUtils.Append(signature.GetArgumentInfos(), new Argument(ArgumentType.Simple)));
 }
示例#2
0
 internal static CallSignature GetReversedSignature(CallSignature signature)
 {
     return(new CallSignature(ArrayUtils.Append(signature.GetArgumentInfos(), new Argument(ArgumentType.Simple))));
 }
示例#3
0
        private DynamicMetaObject InvokeWorker(DynamicMetaObjectBinder /*!*/ callAction, DynamicMetaObject /*!*/[] args)
        {
            PerfTrack.NoteEvent(PerfTrack.Categories.Binding, "Method Invoke " + args.Length);
            PerfTrack.NoteEvent(PerfTrack.Categories.BindingTarget, "Method");

            CallSignature       signature    = BindingHelpers.GetCallSignature(callAction);
            DynamicMetaObject   self         = Restrict(typeof(Method));
            BindingRestrictions restrictions = self.Restrictions;

            // restrict to non-null self (Method is immutable so this is an invariant test)
            restrictions = restrictions.Merge(
                BindingRestrictions.GetExpressionRestriction(
                    Ast.NotEqual(
                        GetSelfExpression(self),
                        AstUtils.Constant(null)
                        )
                    )
                );

            DynamicMetaObject[] newArgs = ArrayUtils.Insert(GetMetaFunction(self), GetMetaSelf(self), args);
            var newSig = new CallSignature(ArrayUtils.Insert(new Argument(ArgumentType.Simple), signature.GetArgumentInfos()));

            var call = new DynamicMetaObject(
                DynamicExpression.Dynamic(
                    PythonContext.GetPythonContext(callAction).Invoke(
                        newSig
                        ).GetLightExceptionBinder(callAction.SupportsLightThrow()),
                    typeof(object),
                    ArrayUtils.Insert(PythonContext.GetCodeContext(callAction), DynamicUtils.GetExpressions(newArgs))
                    ),
                BindingRestrictions.Empty
                );

            /*
             * call = func.Invoke(
             *  new CallBinder(
             *      PythonContext.GetBinderState(callAction),
             *      newSig
             *  ),
             *  newArgs
             * );*/

            if (call.HasValue)
            {
                return(new DynamicMetaObject(
                           call.Expression,
                           restrictions.Merge(call.Restrictions),
                           call.Value
                           ));
            }
            else
            {
                return(new DynamicMetaObject(
                           call.Expression,
                           restrictions.Merge(call.Restrictions)
                           ));
            }
        }
示例#4
0
        private DynamicMetaObject InvokeWorker(DynamicMetaObjectBinder /*!*/ callAction, DynamicMetaObject /*!*/[] args)
        {
            PerfTrack.NoteEvent(PerfTrack.Categories.Binding, "Method Invoke " + args.Length);
            PerfTrack.NoteEvent(PerfTrack.Categories.BindingTarget, "Method");

            CallSignature       signature    = BindingHelpers.GetCallSignature(callAction);
            DynamicMetaObject   self         = Restrict(typeof(Method));
            BindingRestrictions restrictions = self.Restrictions;

            DynamicMetaObject func = GetMetaFunction(self);
            DynamicMetaObject call;

            if (Value.im_self == null)
            {
                // restrict to null self (Method is immutable so this is an invariant test)
                restrictions = restrictions.Merge(
                    BindingRestrictions.GetExpressionRestriction(
                        Ast.Equal(
                            GetSelfExpression(self),
                            AstUtils.Constant(null)
                            )
                        )
                    );

                if (args.Length == 0)
                {
                    // this is an error, we pass null which will throw the normal error
                    call = new DynamicMetaObject(
                        Ast.Call(
                            typeof(PythonOps).GetMethod(nameof(PythonOps.MethodCheckSelf)),
                            PythonContext.GetCodeContext(callAction),
                            self.Expression,
                            AstUtils.Constant(null)
                            ),
                        restrictions
                        );
                }
                else
                {
                    // this may or may not be an error
                    call = new DynamicMetaObject(
                        Ast.Block(
                            MakeCheckSelf(callAction, signature, args),
                            DynamicExpression.Dynamic(
                                PythonContext.GetPythonContext(callAction).Invoke(
                                    BindingHelpers.GetCallSignature(callAction)
                                    ).GetLightExceptionBinder(callAction.SupportsLightThrow()),
                                typeof(object),
                                ArrayUtils.Insert(PythonContext.GetCodeContext(callAction), DynamicUtils.GetExpressions(ArrayUtils.Insert(func, args)))
                                )
                            ),
                        BindingRestrictions.Empty
                        );

                    /*call = func.Invoke(callAction, ArrayUtils.Insert(func, args));
                     * call =  new MetaObject(
                     *  Ast.Comma(
                     *      Ast.Call(
                     *          typeof(PythonOps).GetMethod(nameof(PythonOps.MethodCheckSelf)),
                     *          self.Expression,
                     *          args[0].Expression
                     *      ),
                     *      call.Expression
                     *  ),
                     *  call.Restrictions
                     * );*/
                }
            }
            else
            {
                // restrict to non-null self (Method is immutable so this is an invariant test)
                restrictions = restrictions.Merge(
                    BindingRestrictions.GetExpressionRestriction(
                        Ast.NotEqual(
                            GetSelfExpression(self),
                            AstUtils.Constant(null)
                            )
                        )
                    );

                DynamicMetaObject   im_self = GetMetaSelf(self);
                DynamicMetaObject[] newArgs = ArrayUtils.Insert(func, im_self, args);
                CallSignature       newSig  = new CallSignature(ArrayUtils.Insert(new Argument(ArgumentType.Simple), signature.GetArgumentInfos()));


                call = new DynamicMetaObject(
                    DynamicExpression.Dynamic(
                        PythonContext.GetPythonContext(callAction).Invoke(
                            newSig
                            ).GetLightExceptionBinder(callAction.SupportsLightThrow()),
                        typeof(object),
                        ArrayUtils.Insert(PythonContext.GetCodeContext(callAction), DynamicUtils.GetExpressions(newArgs))
                        ),
                    BindingRestrictions.Empty
                    );

                /*
                 * call = func.Invoke(
                 *  new CallBinder(
                 *      PythonContext.GetBinderState(callAction),
                 *      newSig
                 *  ),
                 *  newArgs
                 * );*/
            }

            if (call.HasValue)
            {
                return(new DynamicMetaObject(
                           call.Expression,
                           restrictions.Merge(call.Restrictions),
                           call.Value
                           ));
            }
            else
            {
                return(new DynamicMetaObject(
                           call.Expression,
                           restrictions.Merge(call.Restrictions)
                           ));
            }
        }
示例#5
0
        /// <summary>
        /// Translates our CallSignature into a DLR Argument list and gives the simple MetaObject's which are extracted
        /// from the tuple or dictionary parameters being splatted.
        /// </summary>
        private void TranslateArguments(DynamicMetaObject target, DynamicMetaObject /*!*/[] /*!*/ args, out CallInfo /*!*/ callInfo, out List <Expression /*!*/> /*!*/ metaArgs, out Expression test, out BindingRestrictions restrictions)
        {
            Argument[] argInfo = _signature.GetArgumentInfos();

            List <string> namedArgNames = new List <string>();

            metaArgs = new List <Expression>();
            metaArgs.Add(target.Expression);
            Expression splatArgTest   = null;
            Expression splatKwArgTest = null;

            restrictions = BindingRestrictions.Empty;

            for (int i = 0; i < argInfo.Length; i++)
            {
                Argument ai = argInfo[i];

                switch (ai.Kind)
                {
                case ArgumentType.Dictionary:
                    PythonDictionary iac      = (PythonDictionary)args[i].Value;
                    List <string>    argNames = new List <string>();

                    foreach (KeyValuePair <object, object> kvp in iac)
                    {
                        string key = (string)kvp.Key;
                        namedArgNames.Add(key);
                        argNames.Add(key);

                        metaArgs.Add(
                            Expression.Call(
                                AstUtils.Convert(args[i].Expression, typeof(PythonDictionary)),
                                typeof(PythonDictionary).GetMethod("get_Item", new[] { typeof(object) }),
                                AstUtils.Constant(key)
                                )
                            );
                    }

                    restrictions   = restrictions.Merge(BindingRestrictionsHelpers.GetRuntimeTypeRestriction(args[i].Expression, args[i].GetLimitType()));
                    splatKwArgTest = Expression.Call(
                        typeof(PythonOps).GetMethod("CheckDictionaryMembers"),
                        AstUtils.Convert(args[i].Expression, typeof(PythonDictionary)),
                        AstUtils.Constant(argNames.ToArray())
                        );
                    break;

                case ArgumentType.List:
                    IList <object> splattedArgs = (IList <object>)args[i].Value;
                    splatArgTest = Expression.Equal(
                        Expression.Property(AstUtils.Convert(args[i].Expression, args[i].GetLimitType()), typeof(ICollection <object>).GetProperty("Count")),
                        AstUtils.Constant(splattedArgs.Count)
                        );

                    for (int splattedArg = 0; splattedArg < splattedArgs.Count; splattedArg++)
                    {
                        metaArgs.Add(
                            Expression.Call(
                                AstUtils.Convert(args[i].Expression, typeof(IList <object>)),
                                typeof(IList <object>).GetMethod("get_Item"),
                                AstUtils.Constant(splattedArg)
                                )
                            );
                    }

                    restrictions = restrictions.Merge(BindingRestrictionsHelpers.GetRuntimeTypeRestriction(args[i].Expression, args[i].GetLimitType()));
                    break;

                case ArgumentType.Named:
                    namedArgNames.Add(ai.Name);
                    metaArgs.Add(args[i].Expression);
                    break;

                case ArgumentType.Simple:
                    metaArgs.Add(args[i].Expression);
                    break;

                default:
                    throw new InvalidOperationException();
                }
            }

            callInfo = new CallInfo(metaArgs.Count - 1, namedArgNames.ToArray());

            test = splatArgTest;
            if (splatKwArgTest != null)
            {
                if (test != null)
                {
                    test = Expression.AndAlso(test, splatKwArgTest);
                }
                else
                {
                    test = splatKwArgTest;
                }
            }
        }