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); }