Scope Form of SEH Clause Declaration

Scope Form of SEH Clause Declaration

The label form of the EH clause declaration is universal, ubiquitous, and close to the actual representation of the EH clauses in the EH table. The only quality the label form lacks is convenience. In view of that, ILAsm offers an alternative form of EH clause description: a scope form. You’ve already encountered the scope form in Chapter 2, which discussed protecting the code against possible surprises in the unmanaged code being invoked. Just to remind you, here’s what the protected part of the method (from the sample file Simple2.il on the companion CD) looks like:

             .try {              // Guarded block begins            call string [mscorlib]System.Console::ReadLine()            // pop              // ldnull             ldstr "%d"             ldsflda int32 Odd.or.Even::val            call vararg int32 sscanf(string,string,...,int32*)            stloc.0             leave.s DidntBlowUp              // Guarded block ends       }        catch [mscorlib]System.Exception          { // Exception handler begins            pop            ldstr "KABOOM!"            call void [mscorlib]System.Console::WriteLine(string)            leave.s Return       } // Exception handler ends    DidntBlowUp:       

The scope form can be used only for a limited subset of all possible EH clause configurations: the handler blocks must immediately follow the previous handler block or the guarded block. If the EH clause configuration is different, we must resort to the label form or a mixed form:

       br AfterHandler HandlerBegins:    // The exception handler code        leave KeepGoing AfterHandler:        .try {       // Guarded code                    leave KeepGoing    }    catch [mscorlib]System.Exception        handler HandlerBegins to AfterHandler     KeepGoing:    

The IL Disassembler by default outputs the EH clauses in the scope form—at least those clauses that can be represented in this form. However, we have the option to suppress the scope form and output all EH clauses in their generic label form. But let’s suppose for the sake of convenience that we can shape the code in such a way that the contiguity condition is satisfied, allowing us to use the scope form.

A single guarded block with multiple handlers in scope form will look like this:

.try {    // Guarded code        leave KeepGoing } catch [mscorlib]System.StackOverflowException {    // The exception handler #1 code        leave KeepGoing } catch [mscorlib]System.Exception {    // The exception handler #2 code           leave KeepGoing }     KeepGoing:    

Much more readable, isn’t it? The nested EH configuration shown earlier in Figure 11-1 is easily understandable when written in scope form:

.try {    .try {       .try {          // Guarded code                    leave L1       }       catch A {          // This code works when exception A is thrown                    leave L2       }    } // No need for leave here!    finally {       // This code works in any case              endfinally    } } // No need for leave here either! catch B {    // This code works when exception B is thrown in guarded code        leave L3 }

The filter EH clauses in scope form are subject to the same limitation: the handler block must immediately follow the guarded block. But because in a filter clause the handler block includes first the filter block and then, immediately following it, the actual handler, the scope form of a filter clause looks like this:

.try {    // Guarded code        leave KeepGoing } filter {    // Here we decide whether we should invoke the actual handler        ldc.i4.1 // OK, let's invoke the handler    endfilter} {    // Actual handler code        leave KeepGoing }

And, of course, we can easily switch between scope form and label form within a single EH clause declaration. The general ILAsm syntax for an EH clause declaration is as follows:

<EH_clause> ::= .try <guarded_block>                       <EH_type_specific> <handler_block>Where <guarded_block> ::= <label> to <label>   <scope> <EH_type_specific> ::= catch <class_ref>           filter <label>   filter <scope>           finally  Fault <handler_block> ::= handler <label> to <label>   <scope>

The nonterminals <label> and <class_ref> must be familiar by now, and the meaning of <scope> is obvious: “code enclosed in curly braces.”



Inside Microsoft. NET IL Assembler
Inside Microsoft .NET IL Assembler
ISBN: 0735615470
EAN: 2147483647
Year: 2005
Pages: 147
Authors: SERGE LIDIN

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net