Skip to content

Commit

Permalink
refactor eh tables
Browse files Browse the repository at this point in the history
  • Loading branch information
WalterBright committed Mar 9, 2011
1 parent a148ed2 commit db921f2
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 162 deletions.
3 changes: 2 additions & 1 deletion 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
Expand Down Expand Up @@ -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
Expand Down
145 changes: 16 additions & 129 deletions 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
Expand Down Expand Up @@ -27,8 +27,8 @@
#include "scope.h"
#include "parser.h"
#include "cpp.h"
#include "exh.h"
#endif
#include "exh.h"

#if !SPP && NTEXCEPTIONS

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -251,8 +138,8 @@ void nteh_gentables()
sz += 4 + fsize * 2;
}
}
#endif
assert(sz != 0);
#endif

outdata(s); // output the scope table
#if MARS
Expand Down Expand Up @@ -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)
Expand Down
80 changes: 48 additions & 32 deletions 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
Expand All @@ -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"
Expand All @@ -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
Expand All @@ -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);
Expand All @@ -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;

Expand All @@ -98,23 +110,25 @@ 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;
// printf("b->BC = %2d, Bscope_index = %2d, last_index = %2d, offset = x%x\n",
// 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)
Expand All @@ -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

Expand All @@ -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

Expand All @@ -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;
Expand All @@ -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;
}

0 comments on commit db921f2

Please sign in to comment.