Ejemplo n.º 1
0
        /// <summary>
        /// Visits the TryBlock.
        ///
        /// Returns a new State object representing the exceptional control flow transfer out of the try block.
        /// </summary>
        protected State HandleTryBlock(TryInstruction inst)
        {
            State oldStateOnException = currentStateOnException;
            State newStateOnException;

            if (stateOnException.TryGetValue(inst, out newStateOnException))
            {
                newStateOnException.JoinWith(state);
            }
            else
            {
                newStateOnException = state.Clone();
                stateOnException.Add(inst, newStateOnException);
            }

            currentStateOnException = newStateOnException;
            inst.TryBlock.AcceptVisitor(this);
            // swap back to the old object instance
            currentStateOnException = oldStateOnException;

            // No matter what kind of try-instruction this is, it's possible
            // that an async exception is thrown immediately in the handler block,
            // so propagate the state:
            oldStateOnException.JoinWith(newStateOnException);

            return(newStateOnException);
        }
Ejemplo n.º 2
0
 public virtual void Visit(TryInstruction instruction)
 {
 }
Ejemplo n.º 3
0
        private string TryReduceTry(BasicBlock root, TryBasicBlock trybb)
        {
            var group = new Set<BasicBlock> { trybb };
            var leavetrybb = trybb.Body as LeaveTryBasicBlock;
            if (leavetrybb == null || leavetrybb.HandlerPopCount != 1)
                return null;
            group.Add(leavetrybb);

            var handlers = new Seq<TryInstructionHandler>();
            foreach (var tbbHandler in trybb.Handlers)
            {
                var catchh = tbbHandler as TBBCatchHandler;
                if (catchh != null)
                {
                    if (!(catchh.Body is NonReturningBasicBlock))
                    {
                        // If body is not already free of control flow, check if it can be made to fall
                        // through to after try
                        var leavecatchbb = catchh.Body as LeaveCatchBasicBlock;
                        if (leavecatchbb == null || leavecatchbb.HandlerPopCount != 1 ||
                            !leavecatchbb.Target.Equals(leavetrybb.Target))
                            return null;
                        if (!group.Add(leavecatchbb))
                            // Should never happen
                            return null;
                    }
                    // else: catch ends with a return, throw, rethrow, break or continue
                    // Catch body WILL NOT end with leave
                    handlers.Add(new CatchTryInstructionHandler(catchh.Type, catchh.Body.Block));
                }
                else
                {
                    var faulth = tbbHandler as TBBFaultHandler;
                    if (faulth != null)
                    {
                        // Body must be an end fault
                        var endfaultbb = faulth.Body as EndFaultBasicBlock;
                        if (endfaultbb == null)
                            return null;
                        if (!group.Add(endfaultbb))
                            // Should never happen
                            return null;
                        // Fault handler body WILL NOT end with endfinally/endfault
                        handlers.Add(new FaultTryInstructionHandler(endfaultbb.Block));
                    }
                    else
                    {
                        var finallyh = tbbHandler as TBBFinallyHandler;
                        if (finallyh != null)
                        {
                            // Body must be an end finally
                            var endfinallybb = finallyh.Body as EndFinallyBasicBlock;
                            if (endfinallybb == null)
                                return null;
                            if (!group.Add(endfinallybb))
                                // Should never happen
                                return null;
                            // Finally handler body WILL NOT end with endfinally/endfault
                            handlers.Add(new FinallyTryInstructionHandler(endfinallybb.Block));
                        }
                        else
                            throw new InvalidOperationException("unrecognized handler");
                    }
                }
            }

            // Try body WILL NOT end with leave
            var tryi = new TryInstruction(NextInstructionId--, leavetrybb.Block, handlers)
                       { BeforeState = trybb.Block.BeforeState, AfterState = leavetrybb.Block.AfterState };
            var newbb = new JumpBasicBlock(nextBlockId++, new Instructions(tryi), leavetrybb.Target);
            root.Coalesce(trybb, group, newbb);
            return String.Format("structural try/catch/finally/fault from B{0}", trybb.Id);
        }
Ejemplo n.º 4
0
 public virtual void Visit(TryInstruction instruction)
 {
     Default(instruction);
 }