Пример #1
0
        protected override ICode VisitCil(StmtCil s)
        {
            var bsi       = this.blockStartInfos[s];
            var stack     = new Stack <Expr>(bsi.Stack.Reverse());
            var locals    = bsi.Locals.Cast <Expr>().ToArray();
            var args      = bsi.Args.Cast <Expr>().ToArray();
            var orgStack  = stack.ToArray();
            var orgLocals = locals.ToArray();
            var orgArgs   = args.ToArray();
            var cil       = new CilProcessor(this.ctx, stack, locals, args, this.instResults);
            var stmts     = new List <Stmt>();

            switch (s.BlockType)
            {
            case StmtCil.SpecialBlock.Normal:
                foreach (var inst in s.Insts)
                {
                    var stmt = cil.Process(inst);
                    if (stmt != null)
                    {
                        stmts.Add(stmt);
                    }
                }
                break;

            case StmtCil.SpecialBlock.Start:
                // Do nothing
                break;

            case StmtCil.SpecialBlock.End:
                stmts.Add(cil.ProcessReturn());
                break;

            default:
                throw new InvalidOperationException("Invalid block type: " + s.BlockType);
            }
            this.stmtVarsChanged.Add(s, new StmtVarChanged {
                Stack  = stack.Zip(orgStack, (a, b) => a == b).ToArray(),
                Locals = locals.Zip(orgLocals, (a, b) => a == b).ToArray(),
                Args   = args.Zip(orgArgs, (a, b) => a == b).ToArray(),
            });
            // Merge phi's
            var continuations = VisitorFindContinuations.Get(s);

            foreach (var continuation in continuations)
            {
                this.CreateOrMergeBsi(continuation.To, stack.ToArray(), locals, args);
            }
            // End
            var next = (Stmt)this.Visit(s.EndCil);

            stmts.Add(next);
            return(new StmtBlock(this.ctx, stmts));
        }
 protected override ICode VisitCil(StmtCil s) {
     var bsi = this.blockStartInfos[s];
     var stack = new Stack<Expr>(bsi.Stack.Reverse());
     var locals = bsi.Locals.Cast<Expr>().ToArray();
     var args = bsi.Args.Cast<Expr>().ToArray();
     var orgStack = stack.ToArray();
     var orgLocals = locals.ToArray();
     var orgArgs = args.ToArray();
     var cil = new CilProcessor(this.ctx, stack, locals, args, this.instResults);
     var stmts = new List<Stmt>();
     switch (s.BlockType) {
     case StmtCil.SpecialBlock.Normal:
         foreach (var inst in s.Insts) {
             var stmt = cil.Process(inst);
             if (stmt != null) {
                 stmts.Add(stmt);
             }
         }
         break;
     case StmtCil.SpecialBlock.Start:
         // Do nothing
         break;
     case StmtCil.SpecialBlock.End:
         stmts.Add(cil.ProcessReturn());
         break;
     default:
         throw new InvalidOperationException("Invalid block type: " + s.BlockType);
     }
     this.stmtVarsChanged.Add(s, new StmtVarChanged {
         Stack = stack.Zip(orgStack, (a, b) => a == b).ToArray(),
         Locals = locals.Zip(orgLocals, (a, b) => a == b).ToArray(),
         Args = args.Zip(orgArgs, (a, b) => a == b).ToArray(),
     });
     // Merge phi's
     var continuations = VisitorFindContinuations.Get(s);
     foreach (var continuation in continuations) {
         this.CreateOrMergeBsi(continuation.To, stack.ToArray(), locals, args);
     }
     // End
     var next = (Stmt)this.Visit(s.EndCil);
     stmts.Add(next);
     return new StmtBlock(this.ctx, stmts);
 }