Label Form of SEH Clause Declaration

Label Form of SEH Clause Declaration

The most generic form of IL assembly language (ILAsm) notation of an EH clause is as follows:

.try <label> to <label> <EH_type_specific> handler <label> to <label>

where <EH_type_specific> ::=

   catch <class_ref>     filter <label>     finally     fault

Take a look at this example:

BeginTry:        leave KeepGoing BeginHandler:        leave KeepGoing KeepGoing:        ret    .try BeginTry to BeginHandler catch [mscorlib]System.Exception        handler BeginHandler to KeepGoing

Figure 11-1 Engagement of the finally exception handler.

In the final lines of the example, the code .try <label> to <label> defines the guarded block, and handler <label> to <label> defines the handler block. In both cases, the second <label> is exclusive, pointing at the first instruction after the respective block. ILAsm imposes a limitation on the positioning of the EH clause declaration directives: all labels used in the directives must have already been defined. Thus, the best place for EH clause declarations in the label form is at the end of the method scope.

In the case just presented, the handler block immediately follows the guarded block, but we could put the handler block anywhere within the method, provided it does not overlap with the guarded block or other handlers:

       br AfterHandler // Can't enter the handler block on our own BeginHandler:        leave KeepGoing AfterHandler:     BeginTry:        leave KeepGoing KeepGoing:        ret    .try BeginTry to KeepGoing catch [mscorlib]System.Exception        handler BeginHandler to AfterHandler

A single guarded block can have several handlers:

       br AfterHandler2 // Can't enter the handler block(s) on our own BeginHandler1:        leave KeepGoing AfterHandler1:     BeginHandler2:        leave KeepGoing AfterHandler2:       BeginTry:        leave KeepGoing KeepGoing:        ret    .try BeginTry to KeepGoing        catch [mscorlib]System.StackOverflowException           handler BeginHandler1 to AfterHandler1    .try BeginTry to KeepGoing catch [mscorlib]System.Exception        handler BeginHandler2 to AfterHandler2

In the case of multiple handlers—catch or filter, but not finally or fault—the guarded block declaration need not be repeated:

   .try BeginTry to KeepGoing        catch [mscorlib]System.StackOverflowException           handler BeginHandler1 to AfterHandler1       catch [mscorlib]System.Exception           handler BeginHandler2 to AfterHandler2

The lexical order of handlers belonging to the same guarded block is the order in which the ILAsm compiler emits the EH clauses, and hence is the same order in which the execution engine of the runtime processes these clauses. We must be careful about ordering the handlers. For instance, if we swap the handlers in the preceding example, the handler for [mscorlib]System.Exception will always work and the handler for [mscorlib]System.StackOverflowException will never work. This is because all exceptions are derived, eventually, from [mscorlib]System.Exception, and hence all exceptions are caught by the first handler, leaving the other handlers unemployed.

The finally and fault handlers cannot peacefully coexist with other handlers, so if a guarded block has a finally or fault handler, it cannot have anything else. To combine a finally or fault handler with other handlers, we need to nest the guarded and handler blocks within other guarded blocks, as shown in Figure 11-1, so that each finally or fault handler has its own personal guarded block.



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