Builds up a series of conditionals when the False clause isn't yet known. We can keep appending conditions and if true's. Each subsequent true branch becomes the false branch of the previous condition and body. Finally a non-conditional terminating branch must be added.
Ejemplo n.º 1
0
 internal override void MakeGetExpression(PythonBinder/*!*/ binder, Expression/*!*/ codeContext, Expression instance, Expression/*!*/ owner, ConditionalBuilder/*!*/ builder) {
     if (instance != null) {
         builder.FinishCondition(
             Ast.Call(
                 typeof(PythonOps).GetMethod("MakeBoundBuiltinFunction"),
                 AstUtils.Constant(_template),
                 instance
             )
         );
     } else {
         builder.FinishCondition(AstUtils.Constant(this));
     }
 }
Ejemplo n.º 2
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;
 }
Ejemplo n.º 3
0
        /// <summary>
        /// Gets an expression which is used for accessing this slot.  If the slot lookup fails the error expression
        /// is used again.
        /// 
        /// The default implementation just calls the TryGetValue method.  Subtypes of PythonTypeSlot can override
        /// this and provide a more optimal implementation.
        /// </summary>
        internal virtual void MakeGetExpression(PythonBinder/*!*/ binder, Expression/*!*/ codeContext, DynamicMetaObject instance, DynamicMetaObject/*!*/ owner, ConditionalBuilder/*!*/ builder) {
            ParameterExpression tmp = Ast.Variable(typeof(object), "slotTmp");
            Expression call = Ast.Call(
                 typeof(PythonOps).GetMethod("SlotTryGetValue"),
                 codeContext,
                 AstUtils.Convert(AstUtils.WeakConstant(this), typeof(PythonTypeSlot)),
                 instance != null ? instance.Expression : AstUtils.Constant(null),
                 owner.Expression,
                 tmp
            );

            builder.AddVariable(tmp);
            if (!GetAlwaysSucceeds) {
                builder.AddCondition(
                    call,
                    tmp
                );
            } else {
                builder.FinishCondition(Ast.Block(call, tmp));
            }
        }
Ejemplo n.º 4
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);
        }
Ejemplo n.º 5
0
 internal override void MakeGetExpression(PythonBinder /*!*/ binder, Expression /*!*/ codeContext, DynamicMetaObject instance, DynamicMetaObject /*!*/ owner, IronPython.Runtime.Binding.ConditionalBuilder /*!*/ builder)
 {
     if (Getter.Length != 0 && !Getter[0].IsPublic)
     {
         // fallback to runtime call
         base.MakeGetExpression(binder, codeContext, instance, owner, builder);
     }
     else if (NeedToReturnProperty(instance, Getter))
     {
         builder.FinishCondition(AstUtils.Constant(this));
     }
     else if (Getter[0].ContainsGenericParameters)
     {
         builder.FinishCondition(
             DefaultBinder.MakeError(
                 binder.MakeContainsGenericParametersError(
                     MemberTracker.FromMemberInfo(_info)
                     ),
                 typeof(object)
                 ).Expression
             );
     }
     else if (instance != null)
     {
         builder.FinishCondition(
             AstUtils.Convert(
                 binder.MakeCallExpression(
                     new PythonOverloadResolverFactory(binder, codeContext),
                     Getter[0],
                     instance
                     ).Expression,
                 typeof(object)
                 )
             );
     }
     else
     {
         builder.FinishCondition(
             AstUtils.Convert(
                 binder.MakeCallExpression(
                     new PythonOverloadResolverFactory(binder, codeContext),
                     Getter[0]
                     ).Expression,
                 typeof(object)
                 )
             );
     }
 }
Ejemplo n.º 6
0
 internal override void MakeGetExpression(PythonBinder /*!*/ binder, Expression /*!*/ codeContext, DynamicMetaObject instance, DynamicMetaObject /*!*/ owner, IronPython.Runtime.Binding.ConditionalBuilder /*!*/ builder)
 {
     if (!_info.IsPublic || _info.DeclaringType.ContainsGenericParameters)
     {
         // fallback to reflection
         base.MakeGetExpression(binder, codeContext, instance, owner, builder);
     }
     else if (instance == null)
     {
         if (_info.IsStatic)
         {
             builder.FinishCondition(AstUtils.Convert(Ast.Field(null, _info), typeof(object)));
         }
         else
         {
             builder.FinishCondition(Ast.Constant(this));
         }
     }
     else
     {
         builder.FinishCondition(
             AstUtils.Convert(
                 Ast.Field(
                     binder.ConvertExpression(
                         instance.Expression,
                         _info.DeclaringType,
                         ConversionResultKind.ExplicitCast,
                         new PythonOverloadResolverFactory(binder, codeContext)
                         ),
                     _info
                     ),
                 typeof(object)
                 )
             );
     }
 }
Ejemplo n.º 7
0
 internal override void MakeGetExpression(PythonBinder /*!*/ binder, Expression /*!*/ codeContext, DynamicMetaObject instance, DynamicMetaObject /*!*/ owner, IronPython.Runtime.Binding.ConditionalBuilder /*!*/ builder)
 {
     builder.FinishCondition(Ast.Constant(this));
 }