示例#1
0
        public static MSA.DynamicExpression /*!*/ MakeCallAction(string /*!*/ name, ActionBinder /*!*/ binder, RubyCallSignature signature,
                                                                 params MSA.Expression[] /*!*/ args)
        {
            RubyCallAction call = RubyCallAction.Make(name, signature);

            switch (args.Length)
            {
            case 0: return(Ast.Dynamic(call, typeof(object), AstFactory.EmptyExpressions));

            case 1: return(Ast.Dynamic(call, typeof(object), args[0]));

            case 2: return(Ast.Dynamic(call, typeof(object), args[0], args[1]));

            case 3: return(Ast.Dynamic(call, typeof(object), args[0], args[1], args[2]));

            case 4: return(Ast.Dynamic(call, typeof(object), args[0], args[1], args[2], args[3]));

            default:
                return(Ast.Dynamic(
                           call,
                           typeof(object),
                           new ReadOnlyCollection <MSA.Expression>(args)
                           ));
            }
        }
示例#2
0
            protected override MSA.Expression /*!*/ VisitDynamic(MSA.DynamicExpression /*!*/ node)
            {
                var callAction = node.Binder as RubyCallAction;

                if (callAction != null)
                {
                    var args = new MSA.Expression[node.Arguments.Count];

                    for (int i = 0; i < args.Length; i++)
                    {
                        args[i] = node.Arguments[i];
                    }

                    Debug.Assert(args.Length > 0);
                    int last = args.Length - 1;

                    args[last] = typeof(TracingRubyCallAction).GetMethod("EnterCallSite").MakeGenericMethod(args[last].Type).OpCall(
                        args[last],
                        AstUtils.Constant(_sourceId),
                        AstUtils.Constant(_sites[node].Start.Index)
                        );

                    return(Ast.Dynamic(
                               new TracingRubyCallAction(callAction.MethodName, callAction.Signature),
                               node.Type,
                               args
                               ));
                }
                else
                {
                    return(base.VisitDynamic(node));
                }
            }
        private static Expression /*!*/ AddExtensibleSelfCheck(DynamicMetaObjectBinder /*!*/ convertToAction, Type toType, DynamicMetaObject /*!*/ self, Expression /*!*/ callExpr)
        {
            ParameterExpression  tmp     = Ast.Variable(callExpr.Type, "tmp");
            ConversionResultKind resKind = GetResultKind(convertToAction);
            Type retType = (resKind == ConversionResultKind.ExplicitTry || resKind == ConversionResultKind.ImplicitTry) ? typeof(object) : toType;

            callExpr = Ast.Block(
                new ParameterExpression[] { tmp },
                Ast.Block(
                    Ast.Assign(tmp, callExpr),
                    Ast.Condition(
                        Ast.Equal(tmp, self.Expression),
                        AstUtils.Convert(
                            Ast.Property(
                                AstUtils.Convert(self.Expression, self.GetLimitType()),
                                self.GetLimitType().GetProperty("Value")
                                ),
                            retType
                            ),
                        Ast.Dynamic(
                            new PythonConversionBinder(
                                PythonContext.GetPythonContext(convertToAction),
                                toType,
                                GetResultKind(convertToAction)
                                ),
                            retType,
                            tmp
                            )
                        )
                    )
                );
            return(callExpr);
        }
示例#4
0
 public MSA.Expression /*!*/ MakeSuperCallAction(int lexicalScopeId)
 {
     return(Ast.Dynamic(
                SuperCallAction.Make(MakeCallSignature(true), lexicalScopeId),
                typeof(object),
                GetExpressions()
                ));
 }
示例#5
0
        public virtual MSAst.Expression /*!*/ Dynamic(DynamicMetaObjectBinder /*!*/ binder, Type /*!*/ retType, params MSAst.Expression /*!*/[] /*!*/ args)
        {
            Assert.NotNull(binder, retType, args);
            Assert.NotNullItems(args);


            return(Ast.Dynamic(binder, retType, args));
        }
示例#6
0
 /// <summary>
 /// Backwards compatible Convert for the old sites that need to flow CodeContext
 /// </summary>
 public static Expression /*!*/ Convert(Expression /*!*/ codeContext, PythonContext /*!*/ binder, Type /*!*/ type, ConversionResultKind resultKind, Expression /*!*/ target)
 {
     return(Ast.Dynamic(
                binder.Convert(type, resultKind),
                type,
                target
                ));
 }
示例#7
0
 internal override MSA.Expression /*!*/ TransformRead(AstGenerator /*!*/ gen)
 {
     return(Methods.MatchString.OpCall(
                Ast.Dynamic(ConvertToStrAction.Instance, typeof(MutableString), gen.CurrentScopeVariable, _expression.Transform(gen)),
                _regex.Transform(gen),
                gen.CurrentScopeVariable
                ));
 }
        private DynamicMetaObject /*!*/ MakeCallRule(DynamicMetaObjectBinder /*!*/ call, Expression /*!*/ codeContext, DynamicMetaObject[] args)
        {
            PerfTrack.NoteEvent(PerfTrack.Categories.Binding, "OldClass Invoke w/ " + args.Length + " args");
            PerfTrack.NoteEvent(PerfTrack.Categories.BindingTarget, "OldClass Invoke");

            CallSignature signature = BindingHelpers.GetCallSignature(call);

            // TODO: If we know __init__ wasn't present we could construct the OldInstance directly.

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

            ParameterExpression init    = Ast.Variable(typeof(object), "init");
            ParameterExpression instTmp = Ast.Variable(typeof(object), "inst");
            DynamicMetaObject   self    = Restrict(typeof(OldClass));

            return(new DynamicMetaObject(
                       Ast.Block(
                           new ParameterExpression[] { init, instTmp },
                           Ast.Assign(
                               instTmp,
                               Ast.New(
                                   typeof(OldInstance).GetConstructor(new Type[] { typeof(CodeContext), typeof(OldClass) }),
                                   codeContext,
                                   self.Expression
                                   )
                               ),
                           Ast.Condition(
                               Expression.Not(
                                   Expression.TypeIs(
                                       Expression.Assign(
                                           init,
                                           Ast.Call(
                                               typeof(PythonOps).GetMethod("OldClassTryLookupInit"),
                                               self.Expression,
                                               instTmp
                                               )
                                           ),
                                       typeof(OperationFailed)
                                       )
                                   ),
                               Ast.Dynamic(
                                   PythonContext.GetPythonContext(call).Invoke(
                                       signature
                                       ),
                                   typeof(object),
                                   ArrayUtils.Insert <Expression>(codeContext, init, exprArgs)
                                   ),
                               NoInitCheckNoArgs(signature, self, args)
                               ),
                           instTmp
                           ),
                       self.Restrictions.Merge(BindingRestrictions.Combine(args))
                       ));
        }
示例#9
0
 private MSA.Expression /*!*/ TransformSplatType(AstGenerator /*!*/ gen)
 {
     return(Ast.Dynamic(
                TryConvertToArrayAction.Instance,
                typeof(object),
                gen.CurrentScopeVariable,
                _splatType.TransformRead(gen)
                ));
 }
示例#10
0
 public static Expression /*!*/ Get(Expression /*!*/ codeContext, PythonContext /*!*/ binder, Type /*!*/ resultType, string /*!*/ name, Expression /*!*/ target)
 {
     return(Ast.Dynamic(
                binder.GetMember(name),
                resultType,
                target,
                codeContext
                ));
 }
示例#11
0
 internal override MSA.Expression /*!*/ Transform(AstGenerator /*!*/ gen)
 {
     Assert.NotNull(gen);
     return(Ast.Dynamic(
                ConvertToProcAction.Instance,
                typeof(Proc),
                gen.CurrentScopeVariable, _expression.TransformRead(gen)
                ));
 }
示例#12
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(
                               Ast.Call(
                                   typeof(PythonOps).GetMethod("OldInstanceTryGetBoundCustomMember"),
                                   codeContext,
                                   self.Expression,
                                   AstUtils.Constant("__call__"),
                                   tmp
                                   ),
                               Ast.Block(
                                   Utils.Try(
                                       Ast.Call(typeof(PythonOps).GetMethod("FunctionPushFrameCodeContext"), codeContext),
                                       Ast.Assign(
                                           tmp,
                                           Ast.Dynamic(
                                               PythonContext.GetPythonContext(invoke).Invoke(
                                                   BindingHelpers.GetCallSignature(invoke)
                                                   ),
                                               typeof(object),
                                               ArrayUtils.Insert(codeContext, exprArgs)
                                               )
                                           )
                                       ).Finally(
                                       Ast.Call(typeof(PythonOps).GetMethod("FunctionPopFrame"))
                                       ),
                                   tmp
                                   ),
                               Utils.Convert(
                                   BindingHelpers.InvokeFallback(invoke, codeContext, this, args).Expression,
                                   typeof(object)
                                   )
                               )
                           ),
                       self.Restrictions.Merge(BindingRestrictions.Combine(args))
                       ));
        }
示例#13
0
 public static Expression /*!*/ Invoke(Expression codeContext, PythonContext /*!*/ binder, Type /*!*/ resultType, CallSignature signature, params Expression /*!*/[] /*!*/ args)
 {
     return(Ast.Dynamic(
                binder.Invoke(
                    signature
                    ),
                resultType,
                ArrayUtils.Insert(codeContext, args)
                ));
 }
        public static SlotOrFunction /*!*/ GetSlotOrFunction(PythonContext /*!*/ state, string op, params DynamicMetaObject[] types)
        {
            PythonTypeSlot slot;
            SlotOrFunction res;

            if (TryGetBinder(state, types, op, null, out res))
            {
                if (res != SlotOrFunction.Empty)
                {
                    return(res);
                }
            }
            else if (MetaUserObject.GetPythonType(types[0]).TryResolveSlot(state.SharedContext, op, out slot))
            {
                ParameterExpression tmp = Ast.Variable(typeof(object), "slotVal");

                Expression[] args = new Expression[types.Length - 1];
                for (int i = 1; i < types.Length; i++)
                {
                    args[i - 1] = types[i].Expression;
                }
                return(new SlotOrFunction(
                           new DynamicMetaObject(
                               Ast.Block(
                                   new ParameterExpression[] { tmp },
                                   MetaPythonObject.MakeTryGetTypeMember(
                                       state,
                                       slot,
                                       tmp,
                                       types[0].Expression,
                                       Ast.Call(
                                           typeof(DynamicHelpers).GetMethod("GetPythonType"),
                                           types[0].Expression
                                           )
                                       ),
                                   Ast.Dynamic(
                                       state.Invoke(
                                           new CallSignature(args.Length)
                                           ),
                                       typeof(object),
                                       ArrayUtils.Insert <Expression>(
                                           AstUtils.Constant(state.SharedContext),
                                           tmp,
                                           args
                                           )
                                       )
                                   ),
                               BindingRestrictions.Combine(types).Merge(BindingRestrictionsHelpers.GetRuntimeTypeRestriction(types[0].Expression, types[0].GetLimitType()))
                               ),
                           slot
                           ));
            }

            return(SlotOrFunction.Empty);
        }
示例#15
0
 // when <expr>
 //   generates into:
 //   RubyOps.IsTrue(<expr>) if the case has no value, otherise:
 //   RubyOps.IsTrue(InvokeMember("===", <expr>, <value>))
 private static MSA.Expression /*!*/ MakeTest(AstGenerator /*!*/ gen, MSA.Expression /*!*/ expr, MSA.Expression /*!*/ value)
 {
     if (value != null)
     {
         // InvokeMember("===", <expr>, <value>)
         expr = Ast.Dynamic(RubyCallAction.Make("===", RubyCallSignature.WithScope(1)), typeof(object),
                            gen.CurrentScopeVariable,
                            expr,
                            value
                            );
     }
     return(AstFactory.IsTrue(expr));
 }
示例#16
0
        public Ast ResolveForDelete(string name)
        {
            var param = Parameters.Select(x => x.ParameterVariable).FirstOrDefault(x => x != null && x.Name == name);

            if (param != null || _variables.TryGetValue(name, out param))
            {
                return(Ast.Constant(0L));
            }
            else
            {
                return(Ast.Dynamic(new ThisProxyMemberAccessBinder(
                                       LanguageContext, name, false, MemberAccessKind.Delete
                                       ), typeof(object), _context, _global));
            }
        }
示例#17
0
        public Ast ResolveForWrite(string name, Ast value, bool direct)
        {
            var param = Parameters.Select(x => x.ParameterVariable).FirstOrDefault(x => x != null && x.Name == name);

            if (param != null || _variables.TryGetValue(name, out param))
            {
                return(Ast.Assign(param, value));
            }
            else
            {
                return(Ast.Dynamic(new ThisProxyMemberAccessBinder(
                                       LanguageContext, name, false,
                                       direct ? MemberAccessKind.Set | MemberAccessKind.Direct : MemberAccessKind.Set
                                       ), typeof(object), _context, _global, value));
            }
        }
示例#18
0
        internal static DynamicMetaObject ConvertToIEnumerator(DynamicMetaObjectBinder /*!*/ conversion, DynamicMetaObject /*!*/ metaUserObject)
        {
            PythonType     pt      = MetaPythonObject.GetPythonType(metaUserObject);
            PythonContext  state   = PythonContext.GetPythonContext(conversion);
            CodeContext    context = state.SharedContext;
            PythonTypeSlot pts;


            if (pt.TryResolveSlot(context, "__iter__", out pts))
            {
                ParameterExpression tmp = Ast.Parameter(typeof(object), "iterVal");

                return(new DynamicMetaObject(
                           Expression.Block(
                               new[] { tmp },
                               Expression.Call(
                                   typeof(PythonOps).GetMethod("CreatePythonEnumerator"),
                                   Ast.Block(
                                       MetaPythonObject.MakeTryGetTypeMember(
                                           state,
                                           pts,
                                           metaUserObject.Expression,
                                           tmp
                                           ),
                                       Ast.Dynamic(
                                           new PythonInvokeBinder(
                                               state,
                                               new CallSignature(0)
                                               ),
                                           typeof(object),
                                           AstUtils.Constant(context),
                                           tmp
                                           )
                                       )
                                   )
                               ),
                           metaUserObject.Restrictions
                           ));
            }
            else if (pt.TryResolveSlot(context, "__getitem__", out pts))
            {
                return(MakeGetItemIterable(metaUserObject, state, pts, "CreateItemEnumerator"));
            }

            return(null);
        }
        /// <summary>
        /// Used for conversions to bool
        /// </summary>
        private static Expression /*!*/ GetConvertByLengthBody(PythonContext /*!*/ state, Expression /*!*/ call)
        {
            Assert.NotNull(state, call);

            Expression callAsInt = call;

            if (call.Type != typeof(int))
            {
                callAsInt = Ast.Dynamic(
                    state.Convert(typeof(int), ConversionResultKind.ExplicitCast),
                    typeof(int),
                    call
                    );
            }

            return(Ast.NotEqual(callAsInt, AstUtils.Constant(0)));
        }
示例#20
0
        internal override MSA.Expression /*!*/ TransformRead(AstGenerator /*!*/ gen)
        {
            Assert.NotNull(gen);

            MSA.Expression transformedBlock = _block.Transform(gen);

            MSA.Expression blockArgVariable = gen.CurrentScope.DefineHiddenVariable("#forloop-block", typeof(Proc));

            MSA.Expression result = Ast.Dynamic(RubyCallAction.Make("each", RubyCallSignature.WithScopeAndBlock(0)), typeof(object),
                                                gen.CurrentScopeVariable,
                                                _list.TransformRead(gen),
                                                blockArgVariable
                                                );

            return(gen.DebugMark(MethodCall.MakeCallWithBlockRetryable(gen, result, blockArgVariable, transformedBlock, true),
                                 "#RB: method call with a block ('for-loop')"));
        }
示例#21
0
        //
        // Traverses expressions in "parts" and concats all contiguous literal strings.
        // Notes:
        //  - Instead of usign StringBuilder we place the string values that can be concatenated so far in to "literals" list and keep track
        //    of their total length in "concatLength" and encoding in "concatEncoding".
        //    If we reach a non-literal expression and we have some literals ready in "literals" array we do the concat and clear the list
        //    and "concatLength" and "concatEncoding".
        //  - "result" list contains argument expressions to the CreateMutableString* overloads.
        //  - "opName" contains the name of the operation. This method appends suffix based on the argument types (see RubyOps.Suffix*).
        //
        private static void ConcatLiteralsAndTransformRecursive(AstGenerator /*!*/ gen, List <Expression> /*!*/ parts,
                                                                List <string> /*!*/ literals, ref int concatLength, ref StringLiteralEncoding concatEncoding, List <MSA.Expression> /*!*/ result,
                                                                StringBuilder /*!*/ opName)
        {
            for (int i = 0; i < parts.Count; i++)
            {
                Expression        part = parts[i];
                StringLiteral     literal;
                StringConstructor ctor;

                if ((literal = part as StringLiteral) != null)
                {
                    literals.Add(literal.Value);
                    concatEncoding = CombineEncoding(concatEncoding, literal);
                    concatLength  += literal.Value.Length;
                }
                else if ((ctor = part as StringConstructor) != null)
                {
                    ConcatLiteralsAndTransformRecursive(gen, ctor.Parts, literals, ref concatLength, ref concatEncoding, result, opName);
                }
                else
                {
                    if (literals.Count > 0)
                    {
                        result.Add(Ast.Constant(Concat(literals, concatLength)));
                        opName.Append(OpSuffix(gen, concatEncoding));
                        concatLength   = 0;
                        concatEncoding = StringLiteralEncoding.Ascii;
                        literals.Clear();
                    }

                    result.Add(
                        Ast.Dynamic(
                            ConvertToSAction.Instance,
                            typeof(MutableString),
                            gen.CurrentScopeVariable, part.TransformRead(gen)
                            )
                        );
                    opName.Append(RubyOps.SuffixMutable);
                }
            }
        }
示例#22
0
        internal override MSA.Expression /*!*/ TransformRead(AstGenerator /*!*/ gen)
        {
            switch (_kind)
            {
            case StringKind.Mutable:
                return(TransformConcatentation(gen, _parts, Methods.CreateMutableString, null));

            case StringKind.Immutable:
                return(TransformConcatentation(gen, _parts, Methods.CreateSymbol, null));

            case StringKind.Command:
                return(Ast.Dynamic(RubyCallAction.Make("`", new RubyCallSignature(1, RubyCallFlags.HasScope | RubyCallFlags.HasImplicitSelf)), typeof(object),
                                   gen.CurrentScopeVariable,
                                   gen.CurrentSelfVariable,
                                   TransformConcatentation(gen, _parts, Methods.CreateMutableString, null)
                                   ));
            }

            throw Assert.Unreachable;
        }
示例#23
0
            protected DynamicMetaObject /*!*/ MakeDefaultNew(DefaultBinder /*!*/ binder, Expression /*!*/ function)
            {
                // calling theType.__new__(theType, args)
                List <Expression> args = new List <Expression>();

                args.Add(CodeContext);
                args.Add(function);

                AppendNewArgs(args);

                return(new DynamicMetaObject(
                           Ast.Dynamic(
                               PythonContext.Invoke(
                                   GetDynamicNewSignature()
                                   ),
                               typeof(object),
                               args.ToArray()
                               ),
                           Arguments.Self.Restrictions
                           ));
            }
            protected override void AddMetaGetAttribute(PythonType metaType, PythonTypeSlot pts)
            {
                EnsureTmp();

                _cb.AddCondition(
                    Ast.Call(
                        typeof(PythonOps).GetMethod("SlotTryGetBoundValue"),
                        _codeContext,
                        AstUtils.Constant(pts, typeof(PythonTypeSlot)),
                        Expression,
                        AstUtils.Constant(metaType),
                        _tmp
                        ),
                    Ast.Dynamic(
                        _state.InvokeOne,
                        typeof(object),
                        _codeContext,
                        _tmp,
                        AstUtils.Constant(GetGetMemberName(_member))
                        )
                    );
            }
        private DynamicMetaObject /*!*/ MakeSetMember(SetMemberBinder /*!*/ member, DynamicMetaObject /*!*/ value)
        {
            PythonContext     state = PythonContext.GetPythonContext(member);
            DynamicMetaObject self  = Restrict(Value.GetType());

            if (Value.GetType() != typeof(PythonType) && DynamicHelpers.GetPythonType(Value).IsSystemType)
            {
                // built-in subclass of .NET type.  Usually __setattr__ is handled by MetaUserObject
                // but we can have a built-in subtype that's not a user type.
                PythonTypeSlot pts;
                if (Value.TryGetCustomSetAttr(state.SharedContext, out pts))
                {
                    Debug.Assert(pts.GetAlwaysSucceeds);

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

                    return(BindingHelpers.AddDynamicTestAndDefer(
                               member,
                               new DynamicMetaObject(
                                   Ast.Block(
                                       new[] { tmp },
                                       Ast.Dynamic(
                                           state.Invoke(new CallSignature(2)),
                                           typeof(object),
                                           AstUtils.Constant(state.SharedContext),
                                           Ast.Block(
                                               Ast.Call(
                                                   typeof(PythonOps).GetMethod("SlotTryGetValue"),
                                                   AstUtils.Constant(state.SharedContext),
                                                   AstUtils.Convert(AstUtils.WeakConstant(pts), typeof(PythonTypeSlot)),
                                                   AstUtils.Convert(Expression, typeof(object)),
                                                   AstUtils.Convert(AstUtils.WeakConstant(DynamicHelpers.GetPythonType(Value)), typeof(PythonType)),
                                                   tmp
                                                   ),
                                               tmp
                                               ),
                                           Ast.Constant(member.Name),
                                           value.Expression
                                           )
                                       ),
                                   self.Restrictions
                                   ),
                               new DynamicMetaObject[] { this, value },
                               TestUserType()
                               ));
                }
            }

            return(BindingHelpers.AddDynamicTestAndDefer(
                       member,
                       new DynamicMetaObject(
                           Ast.Call(
                               typeof(PythonOps).GetMethod("PythonTypeSetCustomMember"),
                               AstUtils.Constant(PythonContext.GetPythonContext(member).SharedContext),
                               self.Expression,
                               AstUtils.Constant(member.Name),
                               AstUtils.Convert(
                                   value.Expression,
                                   typeof(object)
                                   )
                               ),
                           self.Restrictions.Merge(value.Restrictions)
                           ),
                       new DynamicMetaObject[] { this, value },
                       TestUserType()
                       ));
        }
        private DynamicMetaObject /*!*/ MakeConvertRuleForCall(DynamicMetaObjectBinder /*!*/ convertToAction, Type toType, DynamicMetaObject /*!*/ self, string name, string returner, Func <DynamicMetaObject> fallback, Func <Expression, Expression> resultConverter)
        {
            PythonType     pt = ((IPythonObject)self.Value).PythonType;
            PythonTypeSlot pts;
            CodeContext    context = PythonContext.GetPythonContext(convertToAction).SharedContext;
            ValidationInfo valInfo = BindingHelpers.GetValidationInfo(this, pt);

            if (pt.TryResolveSlot(context, name, out pts) && !IsBuiltinConversion(context, pts, name, pt))
            {
                ParameterExpression tmp = Ast.Variable(typeof(object), "func");

                Expression callExpr = resultConverter(
                    Ast.Call(
                        PythonOps.GetConversionHelper(returner, GetResultKind(convertToAction)),
                        Ast.Dynamic(
                            PythonContext.GetPythonContext(convertToAction).InvokeNone,
                            typeof(object),
                            PythonContext.GetCodeContext(convertToAction),
                            tmp
                            )
                        )
                    );

                if (typeof(Extensible <>).MakeGenericType(toType).IsAssignableFrom(self.GetLimitType()))
                {
                    // if we're doing a conversion to the underlying type and we're an
                    // Extensible<T> of that type:

                    // if an extensible type returns it's self in a conversion, then we need
                    // to actually return the underlying value.  If an extensible just keeps
                    // returning more instances  of it's self a stack overflow occurs - both
                    // behaviors match CPython.
                    callExpr = AstUtils.Convert(AddExtensibleSelfCheck(convertToAction, toType, self, callExpr), typeof(object));
                }

                return(BindingHelpers.AddDynamicTestAndDefer(
                           convertToAction,
                           new DynamicMetaObject(
                               Ast.Condition(
                                   MakeTryGetTypeMember(
                                       PythonContext.GetPythonContext(convertToAction),
                                       pts,
                                       self.Expression,
                                       tmp
                                       ),
                                   callExpr,
                                   AstUtils.Convert(
                                       ConversionFallback(convertToAction),
                                       typeof(object)
                                       )
                                   ),
                               self.Restrict(self.GetRuntimeType()).Restrictions
                               ),
                           new DynamicMetaObject[] { this },
                           valInfo,
                           tmp
                           ));
            }

            return(fallback());
        }
示例#27
0
        /// <summary>
        /// WithStatement is translated to the DLR AST equivalent to
        /// the following Python code snippet (from with statement spec):
        ///
        /// mgr = (EXPR)
        /// exit = mgr.__exit__  # Not calling it yet
        /// value = mgr.__enter__()
        /// exc = True
        /// try:
        ///     VAR = value  # Only if "as VAR" is present
        ///     BLOCK
        /// except:
        ///     # The exceptional case is handled here
        ///     exc = False
        ///     if not exit(*sys.exc_info()):
        ///         raise
        ///     # The exception is swallowed if exit() returns true
        /// finally:
        ///     # The normal and non-local-goto cases are handled here
        ///     if exc:
        ///         exit(None, None, None)
        ///
        /// </summary>
        public override MSAst.Expression Reduce()
        {
            // Five statements in the result...
            ReadOnlyCollectionBuilder <MSAst.Expression>          statements = new ReadOnlyCollectionBuilder <MSAst.Expression>(6);
            ReadOnlyCollectionBuilder <MSAst.ParameterExpression> variables  = new ReadOnlyCollectionBuilder <MSAst.ParameterExpression>(6);

            MSAst.ParameterExpression lineUpdated = Ast.Variable(typeof(bool), "$lineUpdated_with");
            variables.Add(lineUpdated);

            //******************************************************************
            // 1. mgr = (EXPR)
            //******************************************************************
            MSAst.ParameterExpression manager = Ast.Variable(typeof(object), "with_manager");
            variables.Add(manager);
            statements.Add(
                GlobalParent.AddDebugInfo(
                    Ast.Assign(
                        manager,
                        _contextManager
                        ),
                    new SourceSpan(Start, _header)
                    )
                );

            //******************************************************************
            // 2. exit = mgr.__exit__  # Not calling it yet
            //******************************************************************
            MSAst.ParameterExpression exit = Ast.Variable(typeof(object), "with_exit");
            variables.Add(exit);
            statements.Add(
                MakeAssignment(
                    exit,
                    GlobalParent.Get(
                        "__exit__",
                        manager
                        )
                    )
                );

            //******************************************************************
            // 3. value = mgr.__enter__()
            //******************************************************************
            MSAst.ParameterExpression value = Ast.Variable(typeof(object), "with_value");
            variables.Add(value);
            statements.Add(
                GlobalParent.AddDebugInfoAndVoid(
                    MakeAssignment(
                        value,
                        Parent.Invoke(
                            new CallSignature(0),
                            Parent.LocalContext,
                            GlobalParent.Get(
                                "__enter__",
                                manager
                                )
                            )
                        ),
                    new SourceSpan(Start, _header)
                    )
                );

            //******************************************************************
            // 4. exc = True
            //******************************************************************
            MSAst.ParameterExpression exc = Ast.Variable(typeof(bool), "with_exc");
            variables.Add(exc);
            statements.Add(
                MakeAssignment(
                    exc,
                    AstUtils.Constant(true)
                    )
                );

            //******************************************************************
            //  5. The final try statement:
            //
            //  try:
            //      VAR = value  # Only if "as VAR" is present
            //      BLOCK
            //  except:
            //      # The exceptional case is handled here
            //      exc = False
            //      if not exit(*sys.exc_info()):
            //          raise
            //      # The exception is swallowed if exit() returns true
            //  finally:
            //      # The normal and non-local-goto cases are handled here
            //      if exc:
            //          exit(None, None, None)
            //******************************************************************

            MSAst.ParameterExpression exception;
            MSAst.ParameterExpression nestedFrames = Ast.Variable(typeof(List <DynamicStackFrame>), "$nestedFrames");
            variables.Add(nestedFrames);
            statements.Add(
                // try:
                AstUtils.Try(
                    AstUtils.Try(// try statement body
                        PushLineUpdated(false, lineUpdated),
                        _var != null ?
                        (MSAst.Expression)Ast.Block(
                            // VAR = value
                            _var.TransformSet(SourceSpan.None, value, PythonOperationKind.None),
                            // BLOCK
                            _body,
                            AstUtils.Empty()
                            ) :
                        // BLOCK
                        (MSAst.Expression)_body // except:, // try statement location
                        ).Catch(exception = Ast.Variable(typeof(Exception), "exception"),
                                                // Python specific exception handling code
                                TryStatement.GetTracebackHeader(
                                    this,
                                    exception,
                                    GlobalParent.AddDebugInfoAndVoid(
                                        Ast.Block(
                                            // exc = False
                                            MakeAssignment(
                                                exc,
                                                AstUtils.Constant(false)
                                                ),
                                            Ast.Assign(
                                                nestedFrames,
                                                Ast.Call(AstMethods.GetAndClearDynamicStackFrames)
                                                ),
                                            //  if not exit(*sys.exc_info()):
                                            //      raise
                                            AstUtils.IfThen(
                                                GlobalParent.Convert(
                                                    typeof(bool),
                                                    ConversionResultKind.ExplicitCast,
                                                    GlobalParent.Operation(
                                                        typeof(bool),
                                                        PythonOperationKind.IsFalse,
                                                        MakeExitCall(exit, exception)
                                                        )
                                                    ),
                                                UpdateLineUpdated(true),
                                                Ast.Call(
                                                    AstMethods.SetDynamicStackFrames,
                                                    nestedFrames
                                                    ),
                                                Ast.Throw(
                                                    Ast.Call(
                                                        AstMethods.MakeRethrowExceptionWorker,
                                                        exception
                                                        )
                                                    )
                                                )
                                            ),
                                        _body.Span
                                        )
                                    ),
                                Ast.Call(
                                    AstMethods.SetDynamicStackFrames,
                                    nestedFrames
                                    ),
                                PopLineUpdated(lineUpdated),
                                Ast.Empty()
                                )
                    // finally:
                    ).Finally(
                    //  if exc:
                    //      exit(None, None, None)
                    AstUtils.IfThen(
                        exc,
                        GlobalParent.AddDebugInfoAndVoid(
                            Ast.Block(
                                Ast.Dynamic(
                                    GlobalParent.PyContext.Invoke(
                                        new CallSignature(3)        // signature doesn't include function
                                        ),
                                    typeof(object),
                                    new MSAst.Expression[] {
                Parent.LocalContext,
                exit,
                AstUtils.Constant(null),
                AstUtils.Constant(null),
                AstUtils.Constant(null)
            }
                                    ),
                                Ast.Empty()
                                ),
                            _contextManager.Span
                            )
                        )
                    )
                );

            statements.Add(AstUtils.Empty());
            return(Ast.Block(variables.ToReadOnlyCollection(), statements.ToReadOnlyCollection()));
        }
示例#28
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("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),
                            Ast.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("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(
                    Ast.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)
                           ));
            }
        }
示例#29
0
        internal MSA.Expression <T> /*!*/ Transform <T>(AstGenerator /*!*/ gen)
        {
            Debug.Assert(gen != null);

            ScopeBuilder scope = new ScopeBuilder();

            MSA.ParameterExpression[] parameters;
            MSA.Expression            selfVariable;
            MSA.Expression            rfcVariable;
            MSA.Expression            parentScope;
            MSA.Expression            language;
            MSA.Expression            runtimeScopeVariable;
            MSA.Expression            moduleVariable;
            MSA.Expression            blockParameter;
            MSA.Expression            currentMethodVariable;

            if (gen.CompilerOptions.IsEval)
            {
                parameters = new MSA.ParameterExpression[6];

                parameters[0]         = Ast.Parameter(typeof(RubyScope), "#scope");
                selfVariable          = parameters[1] = Ast.Parameter(typeof(object), "#self");
                parameters[2]         = Ast.Parameter(typeof(RubyModule), "#module");
                blockParameter        = parameters[3] = Ast.Parameter(typeof(Proc), "#block");
                currentMethodVariable = parameters[4] = Ast.Parameter(typeof(RubyMethodInfo), "#method");
                rfcVariable           = parameters[5] = Ast.Parameter(typeof(RuntimeFlowControl), "#rfc");

                if (gen.CompilerOptions.IsModuleEval)
                {
                    runtimeScopeVariable = scope.DefineHiddenVariable("#scope", typeof(RubyScope));
                    parentScope          = parameters[0];
                    moduleVariable       = parameters[2];
                }
                else
                {
                    runtimeScopeVariable = parameters[0];
                    moduleVariable       = null;
                    parentScope          = null;
                }

                language = null;
            }
            else
            {
                parameters  = new MSA.ParameterExpression[2];
                parentScope = parameters[0] = Ast.Parameter(typeof(Scope), "#globalScope");
                language    = parameters[1] = Ast.Parameter(typeof(LanguageContext), "#language");

                selfVariable          = scope.DefineHiddenVariable("#self", typeof(object));
                rfcVariable           = scope.DefineHiddenVariable("#rfc", typeof(RuntimeFlowControl));
                runtimeScopeVariable  = scope.DefineHiddenVariable("#scope", typeof(RubyScope));
                blockParameter        = null;
                currentMethodVariable = null;
                moduleVariable        = null;
            }

            gen.EnterSourceUnit(
                scope,
                selfVariable,
                runtimeScopeVariable,
                blockParameter,
                rfcVariable,
                currentMethodVariable,
                gen.CompilerOptions.TopLevelMethodName, // method name
                null                                    // parameters
                );

            _definedScope.TransformLocals(scope);

            MSA.Expression scopeFactoryCall;

            if (gen.CompilerOptions.IsEval)
            {
                if (gen.CompilerOptions.IsModuleEval)
                {
                    scopeFactoryCall = Methods.CreateModuleEvalScope.OpCall(
                        scope.VisibleVariables(), parentScope, selfVariable, moduleVariable
                        );
                }
                else
                {
                    scopeFactoryCall = null;
                }
            }
            else if (!gen.CompilerOptions.IsIncluded)
            {
                scopeFactoryCall = Methods.CreateMainTopLevelScope.OpCall(scope.VisibleVariables(), parentScope, language, selfVariable, rfcVariable,
                                                                          Ast.Constant(gen.SourceUnit.Path, typeof(string)), Ast.Constant(_dataOffset));
            }
            else if (gen.CompilerOptions.IsWrapped)
            {
                scopeFactoryCall = Methods.CreateWrappedTopLevelScope.OpCall(scope.VisibleVariables(), parentScope, language, selfVariable, rfcVariable);
            }
            else
            {
                scopeFactoryCall = Methods.CreateTopLevelScope.OpCall(scope.VisibleVariables(), parentScope, language, selfVariable, rfcVariable);
            }

            MSA.Expression prologue, body;

            if (scopeFactoryCall != null)
            {
                prologue = Ast.Assign(runtimeScopeVariable, scopeFactoryCall);
            }
            else
            {
                prologue = null;
            }

            if (gen.SourceUnit.Kind == SourceCodeKind.InteractiveCode)
            {
                var resultVariable = scope.DefineHiddenVariable("#result", typeof(object));

                var epilogue = Methods.PrintInteractiveResult.OpCall(runtimeScopeVariable,
                                                                     Ast.Dynamic(ConvertToSAction.Instance, typeof(MutableString), gen.CurrentScopeVariable,
                                                                                 Ast.Dynamic(RubyCallAction.Make("inspect", RubyCallSignature.WithScope(0)), typeof(object),
                                                                                             gen.CurrentScopeVariable, resultVariable
                                                                                             )
                                                                                 )
                                                                     );

                body = gen.TransformStatements(prologue, _statements, epilogue, ResultOperation.Store(resultVariable));
            }
            else
            {
                body = gen.TransformStatements(prologue, _statements, ResultOperation.Return);
            }

            body = gen.AddReturnTarget(scope.CreateScope(body));
            gen.LeaveSourceUnit();

            return(Ast.Lambda <T>(
                       body,
                       RubyExceptionData.TopLevelMethodName,
                       parameters
                       ));
        }
示例#30
0
 public virtual MSAst.Expression /*!*/ Dynamic(DynamicMetaObjectBinder /*!*/ binder, Type /*!*/ retType, MSAst.Expression /*!*/ arg0, MSAst.Expression /*!*/ arg1, MSAst.Expression /*!*/ arg2, MSAst.Expression /*!*/ arg3)
 {
     return(Ast.Dynamic(binder, retType, arg0, arg1, arg2, arg3));
 }