Пример #1
0
        /// <summary>
        /// Works like throwException(), except we search for the right try clause.
        /// </summary>
        public static void ThrowException( State state, object thrown )
        {
            Step tryStep = state.findAction( step => IsTryMarker( step ) );
            if( tryStep == null )
            {
            // Make sure we have a CoralException.
            if( !(thrown is CoralException) )
                thrown = new CoralException( thrown );

            CoralException cex = (CoralException)thrown;
            if( cex.trace == null )
                cex.setStackTrace( state );

            // Unwind everything else off the stack. There is an implicit "except" at the top anyway.
            state.clearActions();

            // Push on a thrower. We do this in a separate step so that the same try/catch can deal
            // with it at the Runner level.
            state.pushAction( new Step( null, a => { throw new UnhandledException( (CoralException)thrown ); }, "re-thrower" ) );
            return;
            }

            AstTry node = (AstTry)tryStep.node;
            node.throwException( state, thrown );
        }
Пример #2
0
        /// <summary>
        /// Throws an exception.
        /// </summary>
        /// <param name="thrown">
        /// The object to throw. It's recommended that this be a dictionary with a
        /// "name" parameter at the least.
        /// </param>
        public void throwException( State state, object thrown )
        {
            // We want to have stack traces, so this is necessary... but we also want to
            // throw data objects and not C# objects. So we have to convert back and forth.
            if( !(thrown is CoralException) )
            thrown = new CoralException( thrown );
            var cex = (CoralException)thrown;
            if( cex.trace == null )
            cex.setStackTrace( state );
            thrown = cex.data;

            state.pushAction( new Step( this, st =>
            {
                // We'll want to hold on to the finally runner if there is one. This will
                // let us properly handle nested exceptions.
                Step finallyStep = null;
                st.unwindActions( step => IsTryMarker( step ), this.finallyBlock != null );
                if( this.finallyBlock != null )
                    finallyStep = st.popAction();

                // The except block may have a parameter.
                if( this.exceptIdentifer != null )
                {
                    IScope exceptScope = new ParameterScope( st.scope, new string[] { this.exceptIdentifer } );
                    exceptScope.set( this.exceptIdentifer, thrown );
                    state.pushActionAndScope( new Step( this, a => {}, "except: scope" ), exceptScope );
                }
                this.exceptBlock.run( st );

                if( finallyStep != null )
                {
                    finallyStep.description = "finally block";
                    st.pushAction( finallyStep );
                }
            },
            "throw" )
            );
        }