예제 #1
0
        public static Expression Rewrite(Expression expression, out LabelTarget exitLabel, out ParameterExpression pendingBranch, out IDictionary<LabelTarget, LeaveLabelData> leaveLabels)
        {
            pendingBranch = Expression.Parameter(typeof(int), "__pendingBranch");
            exitLabel = Expression.Label("__leave");

            var labelScanner = new LabelScanner();
            labelScanner.Visit(expression);

            var gotoScanner = new GotoScanner(labelScanner.Labels, exitLabel, pendingBranch);

            var res = gotoScanner.Visit(expression);

            leaveLabels = gotoScanner.LeaveLabels;
            return res;
        }
        public static Expression Rewrite(Expression expression, out LabelTarget exitLabel, out ParameterExpression pendingBranch, out IDictionary <LabelTarget, LeaveLabelData> leaveLabels)
        {
            pendingBranch = Expression.Parameter(typeof(int), "__pendingBranch");
            exitLabel     = Expression.Label("__leave");

            var labelScanner = new LabelScanner();

            labelScanner.Visit(expression);

            var gotoScanner = new GotoScanner(labelScanner.Labels, exitLabel, pendingBranch);

            var res = gotoScanner.Visit(expression);

            leaveLabels = gotoScanner.LeaveLabels;
            return(res);
        }
            private Expression RewriteHandler(Expression body)
            {
                //
                // 1. Get accessors to the resulting Value and Index.
                //
                var leaveResultValue = Expression.PropertyOrField(_leaveResult, "Value");

                //
                // 2. Compute gotos that leave the body.
                //
                var gotoScanner = new GotoScanner(_labelScanner.Labels);

                gotoScanner.Visit(body);

                //
                // 3. Rewrite body.
                //
                var leaveLabel = Expression.Label(typeof(LeaveHandlerData));
                var rewriter   = new Rewriter(leaveLabel, gotoScanner.LeaveLabels);
                var newBody    = rewriter.Rewrite(body);

                //
                // 4. Create dispatch table.
                //
                if (gotoScanner.LeaveLabels.Count > 0)
                {
                    _jumpTable.AddRange(gotoScanner.LeaveLabels.Select(kv =>
                    {
                        var index = Expression.Constant(kv.Value);
                        var label = kv.Key;
                        var value = label.Type == typeof(void) ? null : Expression.Convert(leaveResultValue, label.Type);
                        var jump  = Expression.Goto(label, value);
                        return(Expression.SwitchCase(jump, index));
                    }));
                }

                return(newBody);
            }
            private Expression RewriteHandler(Expression body)
            {
                //
                // 1. Get accessors to the resulting Value and Index.
                //
                var leaveResultValue = Expression.PropertyOrField(_leaveResult, "Value");

                //
                // 2. Compute gotos that leave the body.
                //
                var gotoScanner = new GotoScanner(_labelScanner.Labels);
                gotoScanner.Visit(body);

                //
                // 3. Rewrite body.
                //
                var leaveLabel = Expression.Label(typeof(LeaveHandlerData));
                var rewriter = new Rewriter(leaveLabel, gotoScanner.LeaveLabels);
                var newBody = rewriter.Rewrite(body);

                //
                // 4. Create dispatch table.
                //
                if (gotoScanner.LeaveLabels.Count > 0)
                {
                    _jumpTable.AddRange(gotoScanner.LeaveLabels.Select(kv =>
                    {
                        var index = Expression.Constant(kv.Value);
                        var label = kv.Key;
                        var value = label.Type == typeof(void) ? null : Expression.Convert(leaveResultValue, label.Type);
                        var jump = Expression.Goto(label, value);
                        return Expression.SwitchCase(jump, index);
                    }));
                }

                return newBody;
            }