Ignore:
Timestamp:
Sep 19, 2010, 8:58:38 PM (15 years ago)
Author:
dmik
Message:

excpt.h: Added support for try/finally/leave SEH statements.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/excpt.h

    r21427 r21448  
    55 *
    66 * Copyright 2010 Dmitry A. Kuminov
     7 */
     8
     9/*
     10 * NOTE: This __try/__except and __try/__finally/__leave implementation is not
     11 * backed up by the low level compiler support and therefore the following
     12 * limitations exist comparing to the MSVC implementation (breaking them will
     13 * crash the application):
     14 *
     15 * 1. You cannot use return, goto and longjmp statements within __try or
     16 *    __except or __finally blocks.
     17 *
     18 * 2. If you use __try and friends inside a do/while/for/switch block, you will
     19 *    lose the meaning of break and continue statements and must not use them.
     20 *
     21 * 3. The scopes of C and C++ exception blocks may not overlap (i.e. you cannot
     22 *    use try/catch inside __try/__except and vice versa).
     23 *
     24 * 4. There may be some other (yet unknown) limitations.
     25 *
     26 * Fortunately, in most cases, these limitations may be worked around by
     27 * slightly changing the original source code.
    728 */
    829
     
    86107#define __except(filter_expr) \
    87108            }                                                                  \
     109            /* cause the next state to be 3 */                                 \
    88110            __seh_frame.state = 2;                                             \
    89111        }                                                                      \
    90112        else if (__seh_frame.state == 1) {                                     \
     113            /* execption caught, call filter expression */                     \
    91114            __seh_frame.filterResult = (filter_expr);                          \
    92115            __asm__("leal %0, %%ebx; jmp *%1"                                  \
     
    101124                     : :                                                       \
    102125                     : "%eax");                                                \
    103         else /* __seh_frame.state == 2 */
     126        else /* __seh_frame.state == 2 -> execute except block */
     127
     128#define __finally \
     129            }                                                                  \
     130            /* cause the next state to be 2 */                                 \
     131            __seh_frame.state = 1;                                             \
     132        }                                                                      \
     133        else if (__seh_frame.state == 1) {                                     \
     134            /* execption caught, handle and proceed to the filally block */    \
     135            __seh_frame.filterResult = EXCEPTION_EXECUTE_HANDLER;              \
     136            __asm__("leal %0, %%ebx; jmp *%1"                                  \
     137                    : : "m"(__seh_frame), "m"(__seh_frame.pHandlerCallback)    \
     138                    : "%ebx");                                                 \
     139        }                                                                      \
     140        else if (__seh_frame.state == 3)                                       \
     141            /* remove exception handler */                                     \
     142            __asm__ ("movl %%fs:0, %%eax; "                                    \
     143                     "movl 0(%%eax), %%eax; "                                  \
     144                     "movl %%eax, %%fs:0; "                                    \
     145                     : :                                                       \
     146                     : "%eax");                                                \
     147        else /* __seh_frame.state == 2 -> execute finally block */
     148
     149#define __leave \
     150            /* cause the next state to be 2 */                                 \
     151            __seh_frame.state = 1;                                             \
     152            continue;
    104153
    105154#else /* defined(__GNUC__) */
Note: See TracChangeset for help on using the changeset viewer.