Showing with 50 additions and 0 deletions.
  1. +3 −0 src/backend/blockopt.c
  2. +7 −0 src/backend/cc.h
  3. +1 −0 src/backend/symbol.c
  4. +39 −0 src/s2ir.c
3 changes: 3 additions & 0 deletions src/backend/blockopt.c
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,9 @@ void block_free(block *b)
type_free(b->Bcatchtype);
break;
#endif
case BCjcatch:
free(b->BS.BIJCATCH.actionTable);
break;
case BCasm:
code_free(b->Bcode);
break;
Expand Down
7 changes: 7 additions & 0 deletions src/backend/cc.h
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,8 @@ typedef struct block
struct
{ Symbol *catchtype; // one type for each catch block
#define Bcatchtype BS.BIJCATCH.catchtype

unsigned *actionTable; // EH_DWARF: indices into typeTable, first is # of entries
} BIJCATCH; // BCjcatch
#endif
#if NTEXCEPTIONS || MARS
Expand Down Expand Up @@ -722,6 +724,11 @@ typedef struct FUNC_S
Funcsym *Fsurrogatesym; // Fsurrogate: surrogate cast function

char *Fredirect; // redirect function name to this name in object

// Array of catch types for EH_DWARF Types Table generation
Symbol **typesTable;
size_t typesTableDim; // number used in typesTable[]
size_t typesTableCapacity; // allocated capacity of typesTable[]
} func_t;

#define func_calloc() ((func_t *) mem_fcalloc(sizeof(func_t)))
Expand Down
1 change: 1 addition & 0 deletions src/backend/symbol.c
Original file line number Diff line number Diff line change
Expand Up @@ -835,6 +835,7 @@ void symbol_free(symbol *s)
list_free(&f->Fthunks,(list_free_fp)symbol_free);
}
list_free(&f->Fsymtree,(list_free_fp)symbol_free);
free(f->typesTable);
func_free(f);
}
switch (s->Sclass)
Expand Down
39 changes: 39 additions & 0 deletions src/s2ir.c
Original file line number Diff line number Diff line change
Expand Up @@ -1077,6 +1077,7 @@ class S2irVisitor : public Visitor

size_t numcases = s->catches->dim;
bswitch->BS.Bswitch = (targ_llong *) ::malloc(sizeof(targ_llong) * (numcases + 1));
assert(bswitch->BS.Bswitch);
bswitch->BS.Bswitch[0] = numcases;
bswitch->appendSucc(defaultblock);
block_next(blx, BCswitch, NULL);
Expand All @@ -1089,6 +1090,36 @@ class S2irVisitor : public Visitor
if (cs->var)
cs->var->csym = tryblock->jcatchvar;

assert(cs->type);

Symbol *catchtype = toSymbol(cs->type->toBasetype());

/* Look for catchtype in typesTable[] using linear search,
* insert if not already there,
* log index in Action Table (i.e. switch case table)
*/
func_t *f = blx->funcsym->Sfunc;
for (size_t j = 0; 1; ++j)
{
if (j < f->typesTableDim)
{
if (catchtype != f->typesTable[j])
continue;
}
else
{
if (j == f->typesTableCapacity)
{ // enlarge typesTable[]
f->typesTableCapacity = f->typesTableCapacity * 2 + 4;
f->typesTable = (Symbol **)::realloc(f->typesTable, f->typesTableCapacity * sizeof(Symbol *));
assert(f->typesTable);
}
f->typesTable[j] = catchtype;
}
bswitch->BS.Bswitch[1 + i] = 1 + j; // index starts at 1
break;
}

block *bcase = blx->curblock;
bswitch->appendSucc(bcase);

Expand Down Expand Up @@ -1123,6 +1154,14 @@ class S2irVisitor : public Visitor
block_next(blx, BCgoto, NULL);
}

/* Make a copy of the switch case table, which will later become the Action Table.
* Need a copy since the bswitch may get rewritten by the optimizer.
*/
bcatch->BS.BIJCATCH.actionTable = (unsigned *)::malloc(sizeof(unsigned) * (numcases + 1));
assert(bcatch->BS.BIJCATCH.actionTable);
for (size_t i = 0; i < numcases + 1; ++i)
bcatch->BS.BIJCATCH.actionTable[i] = (unsigned)bswitch->BS.Bswitch[i];

}
else
{
Expand Down