예제 #1
0
 private static MetaObject MakeIMembersListRule(Expression codeContext, MetaObject target)
 {
     return(new MetaObject(
                Ast.Call(
                    typeof(BinderOps).GetMethod("GetStringMembers"),
                    Ast.Call(
                        AstUtils.Convert(target.Expression, typeof(IMembersList)),
                        typeof(IMembersList).GetMethod("GetMemberNames"),
                        codeContext
                        )
                    ),
                Restrictions.GetTypeRestriction(target.Expression, target.LimitType).Merge(target.Restrictions)
                ));
 }
예제 #2
0
        /// <summary>
        /// Builds the restrictions for calling with a splatted argument array.  Ensures that the
        /// argument is still an ICollection of object and that it has the same number of arguments.
        /// </summary>
        private static BindingRestrictions MakeParamsTest(DynamicMetaObject splattee, bool testTypes)
        {
            IList <object> list = splattee.Value as IList <object>;

            if (list == null)
            {
                if (splattee.Value == null)
                {
                    return(BindingRestrictions.GetExpressionRestriction(Ast.Equal(splattee.Expression, AstUtils.Constant(null))));
                }

                return(BindingRestrictions.GetTypeRestriction(splattee.Expression, splattee.Value.GetType()));
            }

            BindingRestrictions res = BindingRestrictions.GetExpressionRestriction(
                Ast.AndAlso(
                    Ast.TypeIs(splattee.Expression, typeof(IList <object>)),
                    Ast.Equal(
                        Ast.Property(
                            Ast.Convert(splattee.Expression, typeof(IList <object>)),
                            typeof(ICollection <object>).GetDeclaredProperty("Count")
                            ),
                        AstUtils.Constant(list.Count)
                        )
                    )
                );

            if (testTypes)
            {
                for (int i = 0; i < list.Count; i++)
                {
                    res = res.Merge(
                        BindingRestrictionsHelpers.GetRuntimeTypeRestriction(
                            Ast.Call(
                                AstUtils.Convert(
                                    splattee.Expression,
                                    typeof(IList <object>)
                                    ),
                                typeof(IList <object>).GetMethod("get_Item"),
                                AstUtils.Constant(i)
                                ),
                            CompilerHelpers.GetType(list[i])
                            )
                        );
                }
            }

            return(res);
        }
예제 #3
0
        protected override Expression VisitConstant(ConstantExpression node)
        {
            if (node.Value is CallSite site)
            {
                return(RewriteCallSite(site));
            }

            if (node.Value is IExpressionSerializable exprSerializable)
            {
                EnsureConstantPool();

                if (!_constantCache.TryGetValue(node.Value, out Expression res))
                {
                    Expression serialized = exprSerializable.CreateExpression();
                    _constants.Add(serialized);

                    _constantCache[node.Value] = res = AstUtils.Convert(
                        Expression.ArrayAccess(_constantPool, AstUtils.Constant(_constants.Count - 1)),
                        serialized.Type
                        );
                }

                return(res);
            }

            if (node.Value is string[] strings)
            {
                if (strings.Length == 0)
                {
                    return(Expression.Field(null, typeof(ArrayUtils).GetDeclaredField("EmptyStrings")));
                }

                _constants.Add(
                    Expression.NewArrayInit(
                        typeof(string),
                        new ReadOnlyCollection <Expression>(
                            strings.Map(s => Expression.Constant(s, typeof(string)))
                            )
                        )
                    );

                return(AstUtils.Convert(
                           Expression.ArrayAccess(_constantPool, AstUtils.Constant(_constants.Count - 1)),
                           typeof(string[])
                           ));
            }

            return(base.VisitConstant(node));
        }
예제 #4
0
 public override MSAst.Expression Reduce()
 {
     // (yield z) becomes:
     // .comma (1) {
     //    .void ( .yield_statement (_expression) ),
     //    $gen.CheckThrowable() // <-- has return result from send
     //  }
     return(Ast.Block(
                AstUtils.YieldReturn(
                    GeneratorLabel,
                    Expression == null ? AstUtils.Constant(null) : AstUtils.Convert(Expression, typeof(object))
                    ),
                CreateCheckThrowExpression(Span) // emits ($gen.CheckThrowable())
                ));
 }
 private void MakeIMembersListRule()
 {
     _rule.Target =
         _rule.MakeReturn(
             Binder,
             Ast.Call(
                 typeof(ScriptingRuntimeHelpers).GetMethod("GetStringMembers"),
                 Ast.Call(
                     AstUtils.Convert(_rule.Parameters[0], typeof(IMembersList)),
                     typeof(IMembersList).GetMethod("GetMemberNames"),
                     _rule.Context
                     )
                 )
             );
 }
예제 #6
0
 private Expression /*!*/ MakeDelegateConstructorCall(Type /*!*/ type, CallArguments /*!*/ args)
 {
     if (args.Signature.HasBlock)
     {
         return(Methods.CreateDelegateFromProc.OpCall(
                    Ast.Constant(type),
                    AstUtils.Convert(args.GetBlockExpression(), typeof(Proc))
                    ));
     }
     else
     {
         // TODO:
         throw new NotImplementedError("no block given");
     }
 }
예제 #7
0
        public override MSAst.Expression Reduce()
        {
            if (HasStarredExpression)
            {
                return(UnpackSequenceHelper <SetCollection>(_items, AstMethods.MakeEmptySet, AstMethods.SetAdd, AstMethods.SetUpdate));
            }

            return(Expression.Call(
                       AstMethods.MakeSet,
                       NewArrayInit(
                           typeof(object),
                           ArrayUtils.ConvertAll(_items, x => AstUtils.Convert(x, typeof(object)))
                           )
                       ));
        }
예제 #8
0
 internal override void MakeGetExpression(PythonBinder /*!*/ binder, Expression /*!*/ codeContext, DynamicMetaObject instance, DynamicMetaObject /*!*/ owner, 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)
                 )
             );
     }
 }
예제 #9
0
        DynamicMetaObject MakeGetMemberTarget(GetMemberInfo info, DynamicMetaObject target)
        {
            var type         = target.GetLimitType();
            var restrictions = target.Restrictions;
            var self         = target;

            target = target.Restrict(target.GetLimitType());
            var members = MemberGroup.EmptyGroup;

            // メンバ取得対象が TypeTracker である場合
            if (typeof(TypeTracker).IsAssignableFrom(type))
            {
                restrictions = restrictions.Merge(BindingRestrictions.GetInstanceRestriction(target.Expression, target.Value));
                var tg = target.Value as TypeGroup;
                if (tg == null || tg.TypesByArity.ContainsKey(0))
                {
                    var targetedType = ((TypeTracker)target.Value).Type;
                    members = GetMember(MemberRequestKind.Get, targetedType, info.Name);
                    if (members.Count > 0)
                    {
                        type = targetedType;
                        self = null;
                    }
                }
            }
            // 通常のメンバ一覧を検索
            if (members.Count == 0)
            {
                members = GetMember(MemberRequestKind.Get, type, info.Name);
            }
            // インターフェイスの場合、object メンバを検索
            if (members.Count == 0 && type.IsInterface)
            {
                members = GetMember(MemberRequestKind.Get, type = typeof(object), info.Name);
            }
            // プロパティ・フィールド用に StrongBox を展開し、そこから検索
            var expandedSelf = self;

            if (members.Count == 0 && typeof(IStrongBox).IsAssignableFrom(type) && expandedSelf != null)
            {
                expandedSelf = new DynamicMetaObject(Expression.Field(AstUtils.Convert(expandedSelf.Expression, type), type.GetField("Value")), expandedSelf.Restrictions, ((IStrongBox)expandedSelf.Value).Value);
                type         = type.GetGenericArguments()[0];
                members      = GetMember(MemberRequestKind.Get, type, info.Name);
            }
            MakeBodyHelper(info, self, expandedSelf, type, members);
            return(info.Body.GetMetaObject(restrictions));
        }
예제 #10
0
        public override MSAst.Expression Reduce()
        {
            var codeObj  = GetOrMakeFunctionCode();
            var funcCode = GlobalParent.Constant(codeObj);

            FuncCodeExpr = funcCode;

            MSAst.Expression lambda;
            if (EmitDebugSymbols)
            {
                lambda = GetLambda();
            }
            else
            {
                lambda = NullLambda;
                ThreadPool.QueueUserWorkItem((x) => {
                    // class defs are almost always run, so start
                    // compiling the code now so it might be ready
                    // when we actually go and execute it
                    codeObj.UpdateDelegate(PyContext, true);
                });
            }

            MSAst.Expression classDef = Ast.Call(
                AstMethods.MakeClass,
                funcCode,
                lambda,
                Parent.LocalContext,
                AstUtils.Constant(_name),
                Ast.NewArrayInit(
                    typeof(object),
                    ToObjectArray(_bases)
                    ),
                Metaclass is null ? AstUtils.Constant(null, typeof(object)) : AstUtils.Convert(Metaclass, typeof(object)),
                AstUtils.Constant(FindSelfNames())
                );

            classDef = AddDecorators(classDef, Decorators);

            return(GlobalParent.AddDebugInfoAndVoid(
                       AssignValue(Parent.GetVariableExpression(PythonVariable), classDef),
                       new SourceSpan(
                           GlobalParent.IndexToLocation(StartIndex),
                           GlobalParent.IndexToLocation(HeaderIndex)
                           )
                       ));
        }
예제 #11
0
            // TODO: support for IgnoreCase in underlying ScriptScope APIs
            public override MetaObject BindDeleteMember(DeleteMemberBinder action)
            {
                var fallback = action.FallbackDeleteMember(this);

                return(new MetaObject(
                           Expression.Condition(
                               Expression.Call(
                                   AstUtils.Convert(Expression, typeof(ScriptScope)),
                                   typeof(ScriptScope).GetMethod("RemoveVariable"),
                                   Expression.Constant(action.Name)
                                   ),
                               Expression.Empty(),
                               Expression.Convert(fallback.Expression, typeof(void))
                               ),
                           Restrictions.Merge(Restrictions.GetTypeRestriction(Expression, typeof(ScriptScope))).Merge(fallback.Restrictions)
                           ));
            }
예제 #12
0
        public static DynamicMetaObject MakeError(ErrorInfo error, BindingRestrictions restrictions, Type type)
        {
            switch (error.Kind)
            {
            case ErrorInfoKind.Error:
                return(new ErrorMetaObject(AstUtils.Convert(error.Expression, type), restrictions));

            case ErrorInfoKind.Exception:
                return(new ErrorMetaObject(AstUtils.Convert(Expression.Throw(error.Expression), type), restrictions));

            case ErrorInfoKind.Success:
                return(new ErrorMetaObject(AstUtils.Convert(error.Expression, type), restrictions));

            default:
                throw new InvalidOperationException();
            }
        }
예제 #13
0
        protected override bool TryImplicitConversion(MetaObjectBuilder /*!*/ metaBuilder, CallArguments /*!*/ args)
        {
            if (args.Target == null)
            {
                metaBuilder.Result = Ast.Constant(null);
                return(true);
            }

            var convertedTarget = args.Target as TTargetType;

            if (convertedTarget != null)
            {
                metaBuilder.Result = AstUtils.Convert(args.TargetExpression, typeof(TTargetType));
                return(true);
            }
            return(false);
        }
예제 #14
0
        /// <summary>
        /// Binds to the BoundMemberTracker and uses the instance in the tracker and restricts
        /// based upon the object instance type.
        /// </summary>
        private TargetInfo TryGetBoundMemberTargets(DynamicMetaObject self, DynamicMetaObject[] args, BoundMemberTracker bmt) {
            if (bmt != null) {
                Debug.Assert(bmt.Instance == null); // should be null for trackers that leak to user code

                MethodBase[] targets;

                // instance is pulled from the BoundMemberTracker and restricted to the correct
                // type.
                DynamicMetaObject instance = new DynamicMetaObject(
                    AstUtils.Convert(
                        Expression.Property(
                            Expression.Convert(self.Expression, typeof(BoundMemberTracker)),
                            typeof(BoundMemberTracker).GetDeclaredProperty("ObjectInstance")
                        ),
                        bmt.BoundTo.DeclaringType
                    ),
                    self.Restrictions
                ).Restrict(CompilerHelpers.GetType(bmt.ObjectInstance));

                // we also add a restriction to make sure we're going to the same BoundMemberTracker
                BindingRestrictions restrictions = BindingRestrictions.GetExpressionRestriction(
                    Expression.Equal(
                        Expression.Property(
                            Expression.Convert(self.Expression, typeof(BoundMemberTracker)),
                            typeof(BoundMemberTracker).GetDeclaredProperty("BoundTo")
                        ),
                        AstUtils.Constant(bmt.BoundTo)
                    )
                );

                switch (bmt.BoundTo.MemberType) {
                    case TrackerTypes.MethodGroup:
                        targets = ((MethodGroup)bmt.BoundTo).GetMethodBases();
                        break;
                    case TrackerTypes.Method:
                        targets = new MethodBase[] { ((MethodTracker)bmt.BoundTo).Method };
                        break;
                    default:
                        throw new InvalidOperationException(); // nothing else binds yet
                }

                return new TargetInfo(instance, args, restrictions, targets);
            }
            return null;
        }
예제 #15
0
        public Expression /*!*/ MakeAllocatorCall(CallArguments /*!*/ args, Func <Expression> /*!*/ defaultExceptionMessage)
        {
            Type type = GetUnderlyingSystemType();

            if (_structInfo != null)
            {
                return(Methods.AllocateStructInstance.OpCall(AstUtils.Convert(args.TargetExpression, typeof(RubyClass))));
            }

            if (type.IsSubclassOf(typeof(Delegate)))
            {
                return(MakeDelegateConstructorCall(type, args));
            }

            ConstructorInfo ctor;

            if (IsException())
            {
                if ((ctor = type.GetConstructor(new[] { typeof(string) })) != null)
                {
                    return(Ast.New(ctor, defaultExceptionMessage()));
                }
                else if ((ctor = type.GetConstructor(new[] { typeof(string), typeof(Exception) })) != null)
                {
                    return(Ast.New(ctor, defaultExceptionMessage(), Ast.Constant(null)));
                }
            }

            if ((ctor = type.GetConstructor(new[] { typeof(RubyClass) })) != null)
            {
                return(Ast.New(ctor, AstUtils.Convert(args.TargetExpression, typeof(RubyClass))));
            }

            if ((ctor = type.GetConstructor(new[] { typeof(RubyContext) })) != null)
            {
                return(Ast.New(ctor, args.ContextExpression));
            }

            if ((ctor = type.GetConstructor(Type.EmptyTypes)) != null)
            {
                return(Ast.New(ctor));
            }

            throw RubyExceptions.CreateTypeError(String.Format("allocator undefined for {0}", Name));
        }
예제 #16
0
        protected override bool TryImplicitConversion(MetaObjectBuilder /*!*/ metaBuilder, CallArguments /*!*/ args)
        {
            object target = args.Target;

            if (args.Target == null)
            {
                metaBuilder.Result = Ast.Constant(false);
                return(true);
            }

            if (target is bool)
            {
                metaBuilder.Result = AstUtils.Convert(args.TargetExpression, typeof(bool));
                return(true);
            }

            return(true);
        }
예제 #17
0
        /// <summary>
        /// OldCallAction on Proc target.
        /// From control flow perspective it "yields" to the proc.
        /// </summary>
        internal void SetCallActionRule(MetaObjectBuilder /*!*/ metaBuilder, CallArguments /*!*/ args)
        {
            Assert.NotNull(metaBuilder, args);
            Debug.Assert(!args.Signature.HasBlock);

            var convertedTarget = AstUtils.Convert(args.TargetExpression, typeof(BlockParam));

            // test for target type:
            metaBuilder.AddTypeRestriction(args.Target.GetType(), args.TargetExpression);

            metaBuilder.Result = AstFactory.YieldExpression(
                args.GetSimpleArgumentExpressions(),
                args.GetSplattedArgumentExpression(),
                args.GetRhsArgumentExpression(),
                convertedTarget,                              // block param
                Ast.Property(convertedTarget, SelfProperty)   // self
                );
        }
예제 #18
0
        protected internal override DynamicMetaObject GetBoundValue(OverloadResolverFactory resolverFactory, ActionBinder binder, Type type, DynamicMetaObject instance)
        {
            if (IsPublic && DeclaringType.IsVisible)
            {
                return(new DynamicMetaObject(
                           AstUtils.Convert(
                               Expression.Field(
                                   AstUtils.Convert(instance.Expression, Field.DeclaringType),
                                   Field
                                   ),
                               typeof(object)
                               ),
                           BindingRestrictions.Empty
                           ));
            }

            return(DefaultBinder.MakeError(((DefaultBinder)binder).MakeNonPublicMemberGetError(resolverFactory, this, type, instance), BindingRestrictions.Empty, typeof(object)));
        }
예제 #19
0
        /// <summary>
        /// Builds an expression for a call to the provided method using the given expressions.  If the
        /// method is not static the first parameter is used for the instance.
        ///
        /// Parameters are converted using the binder's conversion rules.
        ///
        /// If an incorrect number of parameters is provided MakeCallExpression returns null.
        /// </summary>
        public Expression MakeCallExpression(Expression context, MethodInfo method, IList <Expression> parameters)
        {
            ParameterInfo[] infos = method.GetParameters();
            Expression      callInst = null;
            int             parameter = 0, startArg = 0;

            Expression[] callArgs = new Expression[infos.Length];

            if (!method.IsStatic)
            {
                callInst  = AstUtils.Convert(parameters[0], method.DeclaringType);
                parameter = 1;
            }
            if (infos.Length > 0 && typeof(CodeContext).IsAssignableFrom(infos[0].ParameterType))
            {
                startArg    = 1;
                callArgs[0] = context;
            }

            for (int arg = startArg; arg < infos.Length; arg++)
            {
                if (parameter < parameters.Count)
                {
                    callArgs[arg] = ConvertExpression(
                        parameters[parameter++],
                        infos[arg].ParameterType,
                        ConversionResultKind.ExplicitCast,
                        context
                        );
                }
                else
                {
                    return(null);
                }
            }

            // check that we used all parameters
            if (parameter != parameters.Count)
            {
                return(null);
            }

            return(AstUtils.SimpleCallHelper(callInst, method, callArgs));
        }
예제 #20
0
        internal void SetRule(MetaObjectBuilder /*!*/ metaBuilder, CallArguments /*!*/ args)
        {
            RubyModule currentDeclaringModule;
            string     currentMethodName;

            var scope = args.Scope;

            object target;

            scope.GetSuperCallTarget(out currentDeclaringModule, out currentMethodName, out target);

            var targetExpression = metaBuilder.GetTemporary(typeof(object), "#super-self");

            metaBuilder.AddCondition(
                Methods.IsSuperCallTarget.OpCall(
                    AstUtils.Convert(args.ScopeExpression, typeof(RubyScope)),
                    Ast.Constant(currentDeclaringModule),
                    AstUtils.Constant(currentMethodName),
                    targetExpression
                    )
                );

            args.SetTarget(targetExpression, target);

            Debug.Assert(currentDeclaringModule != null);

            // target is stored in a local, therefore it cannot be part of the restrictions:
            metaBuilder.TreatRestrictionsAsConditions = true;
            metaBuilder.AddTargetTypeTest(target, targetExpression, scope.RubyContext, args.ContextExpression);
            metaBuilder.TreatRestrictionsAsConditions = false;

            RubyMemberInfo method = scope.RubyContext.ResolveSuperMethod(target, currentMethodName, currentDeclaringModule);

            // super calls don't go to method_missing
            if (method == null)
            {
                metaBuilder.SetError(Methods.MakeMissingSuperException.OpCall(Ast.Constant(currentMethodName)));
            }
            else
            {
                method.InvalidateSitesOnOverride = true;
                method.BuildSuperCall(metaBuilder, args, currentMethodName, currentDeclaringModule);
            }
        }
예제 #21
0
 private static void AddArgument(List <Expression> /*!*/ actualArgs, object arg, Expression /*!*/ expr)
 {
     if (arg == null)
     {
         actualArgs.Add(Ast.Constant(null));
     }
     else
     {
         var type = CompilerHelpers.GetVisibleType(arg);
         if (type.IsValueType)
         {
             actualArgs.Add(expr);
         }
         else
         {
             actualArgs.Add(AstUtils.Convert(expr, type));
         }
     }
 }
        /// <summary>
        /// Helper to produce a rule when no conversion is required (the strong type of the expression
        /// input matches the type we're converting to or has an implicit conversion at the IL level)
        /// </summary>
        private static DynamicMetaObject MakeSimpleConversionTarget(Type toType, BindingRestrictions restrictions, DynamicMetaObject arg)
        {
            return(new DynamicMetaObject(
                       AstUtils.Convert(arg.Expression, CompilerHelpers.GetVisibleType(toType)),
                       restrictions));

            /*
             * if (toType.IsValueType && _rule.ReturnType == typeof(object) && Expression.Type == typeof(object)) {
             *  // boxed value type is being converted back to object.  We've done
             *  // the type check, there's no need to unbox & rebox the value.  infact
             *  // it breaks calls on instance methods so we need to avoid it.
             *  _rule.Target =
             *      _rule.MakeReturn(
             *          Binder,
             *          Expression
             *      );
             * }
             * */
        }
 /// <summary>
 /// Helper to wrap explicit conversion call into try/catch incase it throws an exception.  If
 /// it throws the default value is returned.
 /// </summary>
 private static Expression WrapForThrowingTry(ConversionResultKind kind, bool isImplicit, Expression ret, Type retType)
 {
     if (!isImplicit && kind == ConversionResultKind.ExplicitTry)
     {
         Expression          convFailed = GetTryConvertReturnValue(retType);
         ParameterExpression tmp        = Expression.Variable(convFailed.Type == typeof(object) ? typeof(object) : ret.Type, "tmp");
         ret = Expression.Block(
             new ParameterExpression[] { tmp },
             AstUtils.Try(
                 Expression.Assign(tmp, AstUtils.Convert(ret, tmp.Type))
                 ).Catch(
                 typeof(Exception),
                 Expression.Assign(tmp, convFailed)
                 ),
             tmp
             );
     }
     return(ret);
 }
예제 #24
0
        public MSAst.Expression CreateExpression()
        {
            MSAst.Expression[] items = new MSAst.Expression[Count * 2];
            int index = 0;

            foreach (var item in GetItems())
            {
                items[index++] = Utils.Convert(Utils.Constant(item.Value), typeof(object));
                items[index++] = Utils.Convert(Utils.Constant(item.Key), typeof(object));
            }

            return(MSAst.Expression.Call(
                       typeof(PythonOps).GetMethod(nameof(PythonOps.MakeConstantDictStorage)),
                       MSAst.Expression.NewArrayInit(
                           typeof(object),
                           items
                           )
                       ));
        }
예제 #25
0
        private MetaObject TryNumericComparison(OperatorInfo info, MetaObject[] args)
        {
            MethodInfo[] targets = FilterNonMethods(
                args[0].LimitType,
                GetMember(OldDoOperationAction.Make(this, info.Operator),
                          args[0].LimitType,
                          "Compare")
                );

            if (targets.Length > 0)
            {
                MethodBinder  mb     = MethodBinder.MakeBinder(this, targets[0].Name, targets);
                BindingTarget target = mb.MakeBindingTarget(CallTypes.None, args);
                if (target.Success)
                {
                    Expression call = AstUtils.Convert(target.MakeExpression(), typeof(int));
                    switch (info.Operator)
                    {
                    case Operators.GreaterThan: call = Ast.GreaterThan(call, Ast.Constant(0)); break;

                    case Operators.LessThan: call = Ast.LessThan(call, Ast.Constant(0)); break;

                    case Operators.GreaterThanOrEqual: call = Ast.GreaterThanOrEqual(call, Ast.Constant(0)); break;

                    case Operators.LessThanOrEqual: call = Ast.LessThanOrEqual(call, Ast.Constant(0)); break;

                    case Operators.Equals: call = Ast.Equal(call, Ast.Constant(0)); break;

                    case Operators.NotEquals: call = Ast.NotEqual(call, Ast.Constant(0)); break;

                    case Operators.Compare:
                        break;
                    }

                    return(new MetaObject(
                               call,
                               Restrictions.Combine(target.RestrictedArguments)
                               ));
                }
            }

            return(null);
        }
예제 #26
0
        private DynamicMetaObject TryNumericComparison(OperatorInfo info, OverloadResolverFactory resolverFactory, DynamicMetaObject[] args)
        {
            MethodInfo[] targets = FilterNonMethods(
                args[0].GetLimitType(),
                GetMember(
                    MemberRequestKind.Operation,
                    args[0].GetLimitType(),
                    "Compare"
                    )
                );

            if (targets.Length > 0)
            {
                var           resolver = resolverFactory.CreateOverloadResolver(args, new CallSignature(args.Length), CallTypes.None);
                BindingTarget target   = resolver.ResolveOverload(targets[0].Name, targets, NarrowingLevel.None, NarrowingLevel.All);
                if (target.Success)
                {
                    Expression call = AstUtils.Convert(target.MakeExpression(), typeof(int));
                    switch (info.Operator)
                    {
                    case ExpressionType.GreaterThan: call = Expression.GreaterThan(call, AstUtils.Constant(0)); break;

                    case ExpressionType.LessThan: call = Expression.LessThan(call, AstUtils.Constant(0)); break;

                    case ExpressionType.GreaterThanOrEqual: call = Expression.GreaterThanOrEqual(call, AstUtils.Constant(0)); break;

                    case ExpressionType.LessThanOrEqual: call = Expression.LessThanOrEqual(call, AstUtils.Constant(0)); break;

                    case ExpressionType.Equal: call = Expression.Equal(call, AstUtils.Constant(0)); break;

                    case ExpressionType.NotEqual: call = Expression.NotEqual(call, AstUtils.Constant(0)); break;
                    }

                    return(new DynamicMetaObject(
                               call,
                               target.RestrictedArguments.GetAllRestrictions()
                               ));
                }
            }

            return(null);
        }
예제 #27
0
            public override MetaObject /*!*/ BindInvoke(InvokeBinder /*!*/ action, MetaObject /*!*/[] /*!*/ args)
            {
                RubyCallSignature callSignature;

                if (RubyCallSignature.TryCreate(action.Arguments, out callSignature))
                {
                    return(action.FallbackInvoke(this, args));
                }

                var metaBuilder = new MetaObjectBuilder();

                var context = new MetaObject(
                    Methods.GetContextFromBlockParam.OpCall(AstUtils.Convert(Expression, typeof(BlockParam))),
                    Restrictions.Empty,
                    RubyOps.GetContextFromBlockParam((BlockParam)Value)
                    );

                BlockParam.SetCallActionRule(metaBuilder, new CallArguments(context, this, args, callSignature));
                return(metaBuilder.CreateMetaObject(action, args));
            }
예제 #28
0
파일: Proc.cs 프로젝트: gaybro8777/ironruby
        internal static void SetCallActionRule(MetaObjectBuilder /*!*/ metaBuilder, CallArguments /*!*/ args, bool testTarget)
        {
            Assert.NotNull(metaBuilder, args);

            var convertedTarget = AstUtils.Convert(args.TargetExpression, typeof(Proc));

            // test for target type:
            if (testTarget)
            {
                metaBuilder.AddTypeRestriction(args.Target.GetType(), args.TargetExpression);
            }

            SetProcCallRule(
                metaBuilder,
                convertedTarget,                              // proc object
                Ast.Property(convertedTarget, SelfProperty),  // self captured by the block closure
                null,
                args
                );
        }
예제 #29
0
 /// <summary>
 ///   Helper to wrap explicit conversion call into try/catch incase it throws an exception.  If
 ///   it throws the default value is returned.
 /// </summary>
 private static MSAst WrapForThrowingTry(ConversionResultKind kind, bool isImplicit, MSAst ret, Type retType)
 {
     if (!isImplicit && kind == ConversionResultKind.ExplicitTry)
     {
         var convFailed = GetTryConvertReturnValue(retType);
         //var tmp = MSAst.Variable(convFailed.Type == typeof(object) ? typeof(object) : ret.Type, "tmp");
         return(AstUtils.Convert(ret, convFailed.Type == typeof(object) ? typeof(object) : ret.Type));
         //ret = MSAst.Block(
         //        new[] { tmp },
         //        AstUtils.Try(
         //            MSAst.Assign(tmp, AstUtils.Convert(ret, tmp.Type))
         //        ).Catch(
         //            typeof(Exception),
         //            MSAst.Assign(tmp, convFailed)
         //        ),
         //        tmp
         //     );
     }
     return(ret);
 }
예제 #30
0
        protected internal static MSAst.BlockExpression UnpackSequenceHelper <T>(IList <Expression> items, MethodInfo makeEmpty, MethodInfo append, MethodInfo extend)
        {
            var expressions = new ReadOnlyCollectionBuilder <MSAst.Expression>(items.Count + 2);
            var varExpr     = Expression.Variable(typeof(T), "$coll");

            expressions.Add(Expression.Assign(varExpr, Expression.Call(makeEmpty)));
            foreach (var item in items)
            {
                if (item is StarredExpression starredExpression)
                {
                    expressions.Add(Expression.Call(extend, varExpr, AstUtils.Convert(starredExpression.Value, typeof(object))));
                }
                else
                {
                    expressions.Add(Expression.Call(append, varExpr, AstUtils.Convert(item, typeof(object))));
                }
            }
            expressions.Add(varExpr);
            return(Expression.Block(typeof(T), new MSAst.ParameterExpression[] { varExpr }, expressions));
        }