Esempio n. 1
0
        private DynamicMetaObject/*!*/ MakeMemberAccess(DynamicMetaObjectBinder/*!*/ member, string name, MemberAccess access, params DynamicMetaObject/*!*/[]/*!*/ args) {
            DynamicMetaObject self = Restrict(typeof(OldInstance));

            CustomOldClassDictionaryStorage 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("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("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("OldInstanceDictionaryGetValueHelper"),
                        tmp,
                        AstUtils.Constant(key),
                        AstUtils.Convert(Expression, typeof(object))
                    );
                    break;
                case MemberAccess.Set:
                    target = Ast.Call(
                        typeof(PythonOps).GetMethod("OldInstanceDictionarySetExtraValue"),
                        tmp,
                        AstUtils.Constant(key),
                        AstUtils.Convert(args[1].Expression, typeof(object))
                    );
                    break;
                case MemberAccess.Delete:
                    target = Ast.Call(
                        typeof(PythonOps).GetMethod("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
            );                            
        }
 public SetBindingInfo(SetMemberBinder/*!*/ action, DynamicMetaObject/*!*/[]/*!*/ args, ConditionalBuilder/*!*/ body, ValidationInfo/*!*/ validation)
     : base(args, body, validation) {
     Action = action;
 }
 public GetBindingInfo(DynamicMetaObjectBinder/*!*/ action, DynamicMetaObject/*!*/[]/*!*/ args, ParameterExpression/*!*/ self, ParameterExpression/*!*/ result, ConditionalBuilder/*!*/ body, ValidationInfo/*!*/ validationInfo)
     : base(args, body, validationInfo) {
     Action = action;
     Self = self;
     Result = result;
 }
        private DynamicMetaObject/*!*/ MakeAbstractInstantiationError(DynamicMetaObjectBinder/*!*/ call, ArgumentValues/*!*/ ai, ValidationInfo/*!*/ valInfo) {
            CodeContext context = PythonContext.GetPythonContext(call).SharedContext;
            string message = Value.GetAbstractErrorMessage(context);
            Debug.Assert(message != null);

            return BindingHelpers.AddDynamicTestAndDefer(
                call,
                new DynamicMetaObject(
                    Ast.Throw(
                        Ast.New(
                            typeof(ArgumentTypeException).GetConstructor(new Type[] { typeof(string) }),
                            AstUtils.Constant(message)
                        ),
                        typeof(object)
                    ),
                    GetErrorRestrictions(ai)
                ),
                ai.Arguments,
                valInfo
            );
        }
 public MemberBindingInfo(DynamicMetaObject/*!*/[]/*!*/ args, ConditionalBuilder/*!*/ body, ValidationInfo/*!*/ validation) {
     Body = body;
     Validation = validation;
     Args = args;
 }
        private DynamicMetaObject/*!*/ MakeIncorrectArgumentsForCallError(DynamicMetaObjectBinder/*!*/ call, ArgumentValues/*!*/ ai, ValidationInfo/*!*/ valInfo) {
            string message;

            if (Value.IsSystemType) {
                if (Value.UnderlyingSystemType.GetConstructors().Length == 0) {
                    // this is a type we can't create ANY instances of, give the user a half-way decent error message
                    message = "cannot create instances of " + Value.Name;
                } else {
                    message = InstanceOps.ObjectNewNoParameters;
                }
            } else {
                message = InstanceOps.ObjectNewNoParameters;
            }

            return BindingHelpers.AddDynamicTestAndDefer(
                call,
                new DynamicMetaObject(
                    call.Throw(
                        Ast.New(
                            typeof(TypeErrorException).GetConstructor(new Type[] { typeof(string) }),
                            AstUtils.Constant(message)
                        )
                    ),
                    GetErrorRestrictions(ai)
                ), 
                ai.Arguments,                
                valInfo
            );
        }
        private DynamicMetaObject/*!*/ MakeGenericTypeDefinitionError(DynamicMetaObjectBinder/*!*/ call, ArgumentValues/*!*/ ai, ValidationInfo/*!*/ valInfo) {
            Debug.Assert(Value.IsSystemType);
            string message = "cannot create instances of " + Value.Name + " because it is a generic type definition";

            return BindingHelpers.AddDynamicTestAndDefer(
                call,
                new DynamicMetaObject(
                    call.Throw(
                        Ast.New(
                            typeof(TypeErrorException).GetConstructor(new Type[] { typeof(string) }),
                            AstUtils.Constant(message)
                        ),
                        typeof(object)
                    ),
                    GetErrorRestrictions(ai)
                ),
                ai.Arguments,
                valInfo
            );
        }
Esempio n. 8
0
        internal static DynamicMetaObject/*!*/ AddDynamicTestAndDefer(DynamicMetaObjectBinder/*!*/ operation, DynamicMetaObject/*!*/ res, DynamicMetaObject/*!*/[] args, ValidationInfo typeTest, Type deferType, params ParameterExpression[] temps) {
            if (typeTest != null) {
                if (typeTest.Test != null) {
                    // add the test and a validator if persent
                    Expression defer = operation.GetUpdateExpression(deferType ?? typeof(object));

                    Type bestType = BindingHelpers.GetCompatibleType(defer.Type, res.Expression.Type);

                    res = new DynamicMetaObject(
                        Ast.Condition(
                            typeTest.Test,
                            AstUtils.Convert(res.Expression, bestType),
                            AstUtils.Convert(defer, bestType)
                        ),
                        res.Restrictions 
                    );
                }
            } 
            
            if (temps.Length > 0) {
                // finally add the scoped variables
                res = new DynamicMetaObject(
                    Ast.Block(temps, res.Expression),
                    res.Restrictions,
                    null
                );
            }

            return res;
        }
Esempio n. 9
0
 internal static DynamicMetaObject/*!*/ AddDynamicTestAndDefer(DynamicMetaObjectBinder/*!*/ operation, DynamicMetaObject/*!*/ res, DynamicMetaObject/*!*/[] args, ValidationInfo typeTest, params ParameterExpression[] temps) {
     return AddDynamicTestAndDefer(operation, res, args, typeTest, null, temps);
 }
Esempio n. 10
0
        /// <summary>
        /// Transforms an invoke member into a Python GetMember/Invoke.  The caller should
        /// verify that the given attribute is not resolved against a normal .NET class
        /// before calling this.  If it is a normal .NET member then a fallback InvokeMember
        /// is preferred.
        /// </summary>
        internal static DynamicMetaObject/*!*/ GenericInvokeMember(InvokeMemberBinder/*!*/ action, ValidationInfo valInfo, DynamicMetaObject target, DynamicMetaObject/*!*/[]/*!*/ args) {
            if (target.NeedsDeferral()) {
                return action.Defer(args);
            }

            return AddDynamicTestAndDefer(action, 
                action.FallbackInvoke(
                    new DynamicMetaObject(
                        Binders.Get(
                            PythonContext.GetCodeContext(action),
                            PythonContext.GetPythonContext(action),
                            typeof(object),
                            action.Name,
                            target.Expression
                        ),
                        BindingRestrictionsHelpers.GetRuntimeTypeRestriction(target)
                    ),
                    args,
                    null
                ),
                args,
                valInfo
            );
        }
Esempio n. 11
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);
                Expression         body;

                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)
                    );

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

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

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

            return(null);
        }
Esempio n. 12
0
 public MetaGetBinderHelper(MetaPythonType type, DynamicMetaObjectBinder member, Expression codeContext, ValidationInfo validationInfo, ValidationInfo metaValidation)
     : base(type.Value, PythonContext.GetPythonContext(member).SharedContext, GetGetMemberName(member))
 {
     _member         = member;
     _codeContext    = codeContext;
     _type           = type;
     _cb             = new ConditionalBuilder(member);
     _symName        = GetGetMemberName(member);
     _restrictedSelf = new DynamicMetaObject(
         AstUtils.Convert(Expression, Value.GetType()),
         Restrictions.Merge(BindingRestrictions.GetInstanceRestriction(Expression, Value)),
         Value
         );
     _state       = PythonContext.GetPythonContext(member);
     _valInfo     = validationInfo;
     _metaValInfo = metaValidation;
 }