Example #1
0
        /// <summary>
        /// Returns the successor BlockPCs from the given BlockPC, properly taking into account finally blocks
        /// </summary>
        public IEnumerable <BlockPC> Successors(BlockPC pc)
        {
            var current = this.BlockFor[pc.Current];
            var succs   = this.SuccessorsFor(current);

            if (succs.Count > 0)
            {
                foreach (var succ in succs)
                {
                    var finallyBlocks = this.FinallyBlocksOnEdge(current, succ);
                    if (finallyBlocks != null)
                    {
                        var to = pc.Stack.Tail;    // pop current
                        to = to.Cons(succ.Offset); // push ultimate successor
                        while (finallyBlocks != null)
                        {
                            to            = to.Cons(finallyBlocks.Head.Offset); // push each finally block to execute
                            finallyBlocks = finallyBlocks.Tail;
                        }
                        yield return(new BlockPC(to));
                    }
                    else
                    {
                        yield return(pc.Replace(succ.Offset));
                    }
                }
            }
            else
            {
                // no direct successors

                // find the next pending block
                var to = pc.Stack.Tail;
                if (to != null)
                {
                    yield return(new BlockPC(to));
                }
            }
        }