From db921f26e1d3003f8a3de2669435646d963e9e9c Mon Sep 17 00:00:00 2001 From: Walter Bright Date: Tue, 8 Mar 2011 17:12:37 -0800 Subject: [PATCH] refactor eh tables --- src/backend/exh.h | 3 +- src/backend/nteh.c | 145 +++++---------------------------------------- src/eh.c | 80 +++++++++++++++---------- 3 files changed, 66 insertions(+), 162 deletions(-) diff --git a/src/backend/exh.h b/src/backend/exh.h index 99fc8e3c0c3b..12a15c7cdd3b 100644 --- a/src/backend/exh.h +++ b/src/backend/exh.h @@ -1,5 +1,5 @@ // Copyright (C) 1993-1998 by Symantec -// Copyright (C) 2000-2009 by Digital Mars +// Copyright (C) 2000-2011 by Digital Mars // All Rights Reserved // http://www.digitalmars.com // Written by Walter Bright @@ -40,6 +40,7 @@ void except_mark(); void except_release(); symbol *except_gensym(); symbol *except_gentables(); +void except_fillInEHTable(symbol *s); void except_reset(); #endif diff --git a/src/backend/nteh.c b/src/backend/nteh.c index 13dfb6f7b44a..b93b82d8c66e 100644 --- a/src/backend/nteh.c +++ b/src/backend/nteh.c @@ -1,5 +1,5 @@ // Copyright (C) 1994-1998 by Symantec -// Copyright (C) 2000-2009 by Digital Mars +// Copyright (C) 2000-2011 by Digital Mars // All Rights Reserved // http://www.digitalmars.com // Written by Walter Bright @@ -27,8 +27,8 @@ #include "scope.h" #include "parser.h" #include "cpp.h" -#include "exh.h" #endif +#include "exh.h" #if !SPP && NTEXCEPTIONS @@ -94,135 +94,22 @@ STATIC symbol *nteh_scopetable() */ void nteh_gentables() -{ symbol *s; - int sz; // size so far - dt_t **pdt; - unsigned fsize; // target size of function pointer - long spoff; - block *b; - int guarddim; - int i; - - s = s_table; +{ + symbol *s = s_table; symbol_debug(s); - fsize = 4; - pdt = &s->Sdt; - sz = 0; - #if MARS - /* - void* pointer to start of function - unsigned offset of ESP from EBP - unsigned offset from start of function to return code - { int last_index; // previous index - unsigned catchoffset; // offset to catch block from symbol - void *finally; // finally code to execute - } guard[]; - catchoffset: - unsigned ncatches; // number of catch blocks - { void *type; // symbol representing type - unsigned bpoffset; // EBP offset of catch variable - void *handler; // catch handler code - } catch[]; + except_fillInEHTable(s); +#else + /* The table consists of triples: + * parent index + * filter address + * handler address */ + unsigned fsize = 4; // target size of function pointer + dt_t **pdt = &s->Sdt; + int sz = 0; // size so far - sz = 0; - - // Address of start of function - symbol_debug(funcsym_p); - pdt = dtxoff(pdt,funcsym_p,0,TYnptr); - sz += fsize; - - // Get offset of ESP from EBP - spoff = cod3_spoff(); - pdt = dtnbytes(pdt,intsize,(char *)&spoff); - sz += intsize; - - // Offset from start of function to return code - pdt = dtnbytes(pdt,intsize,(char *)&retoffset); - sz += intsize; - - // First, calculate starting catch offset - guarddim = 0; // max dimension of guard[] - for (b = startblock; b; b = b->Bnext) - { - if (b->BC == BC_try && b->Bscope_index >= guarddim) - guarddim = b->Bscope_index + 1; - } - unsigned catchoffset = sz + guarddim * (3 * 4); - - // Generate guard[] - i = 0; - for (b = startblock; b; b = b->Bnext) - { - if (b->BC == BC_try) - { dt_t *dt; - block *bhandler; - int nsucc; - - assert(b->Bscope_index >= i); - if (i < b->Bscope_index) - { - pdt = dtnzeros(pdt, (b->Bscope_index - i) * (3 * 4)); - sz += (b->Bscope_index - i) * (3 * 4); - } - i = b->Bscope_index + 1; - - nsucc = list_nitems(b->Bsucc); - pdt = dtdword(pdt,b->Blast_index); // parent index - - if (b->jcatchvar) // if try-catch - { - pdt = dtdword(pdt,catchoffset); - pdt = dtdword(pdt,0); // no finally handler - - catchoffset += 4 + (nsucc - 1) * (3 * 4); - } - else // else try-finally - { - assert(nsucc == 2); - pdt = dtdword(pdt,0); // no catch offset - bhandler = list_block(list_next(b->Bsucc)); - assert(bhandler->BC == BC_finally); - // To successor of BC_finally block - bhandler = list_block(bhandler->Bsucc); - pdt = dtcoff(pdt,bhandler->Boffset); // finally handler address - } - sz += 4 + fsize * 2; - } - } - - // Generate catch[] - for (b = startblock; b; b = b->Bnext) - { - if (b->BC == BC_try) - { block *bhandler; - int nsucc; - - if (b->jcatchvar) // if try-catch - { list_t bl; - - nsucc = list_nitems(b->Bsucc); - pdt = dtdword(pdt,nsucc - 1); // # of catch blocks - sz += 4; - - for (bl = list_next(b->Bsucc); bl; bl = list_next(bl)) - { - block *bcatch = list_block(bl); - - pdt = dtxoff(pdt,bcatch->Bcatchtype,0,TYjhandle); - - pdt = dtdword(pdt,cod3_bpoffset(b->jcatchvar)); // EBP offset - - pdt = dtcoff(pdt,bcatch->Boffset); // finally handler address - - sz += 3 * 4; - } - } - } - } -#else - for (b = startblock; b; b = b->Bnext) + for (block *b = startblock; b; b = b->Bnext) { if (b->BC == BC_try) { dt_t *dt; @@ -251,8 +138,8 @@ void nteh_gentables() sz += 4 + fsize * 2; } } -#endif assert(sz != 0); +#endif outdata(s); // output the scope table #if MARS @@ -604,7 +491,7 @@ code *nteh_filter(block *b) } /******************************* - * Generate C++ or Jupiter frame handler. + * Generate C++ or D frame handler. */ void nteh_framehandler(symbol *scopetable) diff --git a/src/eh.c b/src/eh.c index a79e2f1bbffb..79dfb5c8bce1 100644 --- a/src/eh.c +++ b/src/eh.c @@ -1,6 +1,6 @@ /* * Copyright (c) 1994-1998 by Symantec - * Copyright (c) 2000-2010 by Digital Mars + * Copyright (c) 2000-2011 by Digital Mars * All Rights Reserved * http://www.digitalmars.com * http://www.dsource.org/projects/dmd/browser/branches/dmd-1.x/src/eh.c @@ -25,6 +25,7 @@ #include "global.h" #include "type.h" #include "dt.h" +#include "exh.h" static char __file__[] = __FILE__; /* for tassert.h */ #include "tassert.h" @@ -37,35 +38,41 @@ symbol *except_gentables() { //printf("except_gentables()\n"); #if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS - symbol *s; - int sz; // size so far - dt_t **pdt; - unsigned fsize; // target size of function pointer - long spoff; - block *b; - int guarddim; - int i; // BUG: alloca() changes the stack size, which is not reflected // in the fixed eh tables. assert(!usedalloca); - s = symbol_generate(SCstatic,tsint); + symbol *s = symbol_generate(SCstatic,tsint); s->Sseg = UNKNOWN; symbol_keep(s); symbol_debug(s); - fsize = NPTRSIZE; - pdt = &s->Sdt; - sz = 0; + except_fillInEHTable(s); + + outdata(s); // output the scope table + + obj_ehtables(funcsym_p,funcsym_p->Ssize,s); +#endif + return NULL; +} + +/********************************************** + * Initializes the symbol s with the contents of the exception handler table. + */ + +void except_fillInEHTable(symbol *s) +{ + unsigned fsize = NPTRSIZE; // target size of function pointer + dt_t **pdt = &s->Sdt; /* void* pointer to start of function unsigned offset of ESP from EBP unsigned offset from start of function to return code - unsigned nguards; // dimension of guard[] - { unsigned offset; // offset of start of guarded section - unsigned endoffset; // ending offset of guarded section + unsigned nguards; // dimension of guard[] (Linux) + { unsigned offset; // offset of start of guarded section (Linux) + unsigned endoffset; // ending offset of guarded section (Linux) int last_index; // previous index (enclosing guarded section) unsigned catchoffset; // offset to catch block from symbol void *finally; // finally code to execute @@ -77,9 +84,14 @@ symbol *except_gentables() void *handler; // catch handler code } catch[]; */ + +#if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS #define GUARD_SIZE (I64 ? 3*8 : 5*4) // number of bytes in one guard +#else +#define GUARD_SIZE (3*4) +#endif - sz = 0; + int sz = 0; // Address of start of function symbol_debug(funcsym_p); @@ -89,7 +101,7 @@ symbol *except_gentables() //printf("ehtables: func = %s, offset = x%x, startblock->Boffset = x%x\n", funcsym_p->Sident, funcsym_p->Soffset, startblock->Boffset); // Get offset of ESP from EBP - spoff = cod3_spoff(); + long spoff = cod3_spoff(); pdt = dtdword(pdt,spoff); sz += 4; @@ -98,8 +110,8 @@ symbol *except_gentables() sz += 4; // First, calculate starting catch offset - guarddim = 0; // max dimension of guard[] - for (b = startblock; b; b = b->Bnext) + int guarddim = 0; // max dimension of guard[] + for (block *b = startblock; b; b = b->Bnext) { if (b->BC == BC_try && b->Bscope_index >= guarddim) guarddim = b->Bscope_index + 1; @@ -107,14 +119,16 @@ symbol *except_gentables() // b->BC, b->Bscope_index, b->Blast_index, b->Boffset); } +#if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS pdt = dtsize_t(pdt,guarddim); sz += NPTRSIZE; +#endif unsigned catchoffset = sz + guarddim * GUARD_SIZE; // Generate guard[] - i = 0; - for (b = startblock; b; b = b->Bnext) + int i = 0; + for (block *b = startblock; b; b = b->Bnext) { //printf("b = %p, b->Btry = %p, b->offset = %x\n", b, b->Btry, b->Boffset); if (b->BC == BC_try) @@ -128,6 +142,8 @@ symbol *except_gentables() i = b->Bscope_index + 1; int nsucc = list_nitems(b->Bsucc); + +#if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS //printf("DHandlerInfo: offset = %x", (int)(b->Boffset - startblock->Boffset)); pdt = dtdword(pdt,b->Boffset - startblock->Boffset); // offset to start of block @@ -144,6 +160,7 @@ symbol *except_gentables() } //printf(" endoffset = %x, prev_index = %d\n", endoffset, b->Blast_index); pdt = dtdword(pdt,endoffset); // offset past end of guarded block +#endif pdt = dtdword(pdt,b->Blast_index); // parent index @@ -162,15 +179,18 @@ symbol *except_gentables() assert(bhandler->BC == BC_finally); // To successor of BC_finally block bhandler = list_block(bhandler->Bsucc); +#if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS pdt = dtxoff(pdt,funcsym_p,bhandler->Boffset - startblock->Boffset, TYnptr); // finally handler address - //pdt = dtcoff(pdt,bhandler->Boffset); // finally handler address +#else + pdt = dtcoff(pdt,bhandler->Boffset); // finally handler address +#endif } sz += GUARD_SIZE; } } // Generate catch[] - for (b = startblock; b; b = b->Bnext) + for (block *b = startblock; b; b = b->Bnext) { if (b->BC == BC_try) { block *bhandler; @@ -191,19 +211,15 @@ symbol *except_gentables() pdt = dtsize_t(pdt,cod3_bpoffset(b->jcatchvar)); // EBP offset +#if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS pdt = dtxoff(pdt,funcsym_p,bcatch->Boffset - startblock->Boffset, TYnptr); // catch handler address - //pdt = dtcoff(pdt,bcatch->Boffset); // catch handler address - +#else + pdt = dtcoff(pdt,bcatch->Boffset); // catch handler address +#endif sz += 3 * NPTRSIZE; } } } } assert(sz != 0); - - outdata(s); // output the scope table - - obj_ehtables(funcsym_p,funcsym_p->Ssize,s); -#endif - return NULL; }