39 changes: 25 additions & 14 deletions src/backend/debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ void WRBC(unsigned bc)
"exit ","asm ","switch","ifthen","jmptab",
"try ","catch ","jump ",
"_try ","_filte","_final","_ret ","_excep",
"jcatch"
"jcatch","_lpad ",
};

assert(sizeof(bcs) / sizeof(bcs[0]) == BCMAX);
Expand Down Expand Up @@ -323,24 +323,30 @@ void WRblock(block *b)
{
targ_llong *pu;
int ncases;
list_t bl;

assert(b);
dbg_printf("********* Basic Block %p ************\n",b);
if (b->Belem) elem_print(b->Belem);
dbg_printf("block: ");
printf("%p %d ", b, b->BC);
printf("***** block %p ", b);
WRBC(b->BC);
dbg_printf(" Btry=%p Bindex=%d",b->Btry,b->Bindex);
if (b->Btry)
printf(" Btry=%p",b->Btry);
if (b->Bindex)
printf(" Bindex=%d",b->Bindex);
if (b->BC == BC_finally)
printf(" b_ret=%p", b->BS.BI_FINALLY.b_ret);
#if MARS
if (b->Bsrcpos.Sfilename)
dbg_printf(" %s(%u)", b->Bsrcpos.Sfilename, b->Bsrcpos.Slinnum);
#endif
dbg_printf("\n");
dbg_printf("\tBpred:\n");
for (bl = b->Bpred; bl; bl = list_next(bl))
dbg_printf("\t%p\n",list_block(bl));
bl = b->Bsucc;
if (b->Belem) elem_print(b->Belem);
if (b->Bpred)
{
printf("\tBpred:");
for (list_t bl = b->Bpred; bl; bl = list_next(bl))
printf(" %p",list_block(bl));
printf("\n");
}
list_t bl = b->Bsucc;
switch (b->BC)
{
case BCswitch:
Expand All @@ -365,13 +371,18 @@ printf("%p %d ", b, b->BC);
case BC_try:
case BC_filter:
case BC_finally:
case BC_lpad:
case BC_ret:
case BC_except:

Lsucc:
dbg_printf("\tBsucc:\n");
for ( ; bl; bl = list_next(bl))
dbg_printf("\t%p\n",list_block(bl));
if (bl)
{
dbg_printf("\tBsucc:");
for ( ; bl; bl = list_next(bl))
dbg_printf(" %p",list_block(bl));
printf("\n");
}
break;
case BCret:
case BCretexp:
Expand Down
2 changes: 2 additions & 0 deletions src/backend/dwarf.c
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,7 @@ const char* debug_info = "__debug_info";
const char* debug_pubnames = "__debug_pubnames";
const char* debug_aranges = "__debug_aranges";
const char* eh_frame_name = "__eh_frame";
const char* except_table_name = "__gcc_except_table";
#elif ELFOBJ
const char* debug_frame_name = ".debug_frame";
const char* debug_str = ".debug_str";
Expand All @@ -519,6 +520,7 @@ const char* debug_info = ".debug_info";
const char* debug_pubnames = ".debug_pubnames";
const char* debug_aranges = ".debug_aranges";
const char* eh_frame_name = ".eh_frame";
const char* except_table_name = ".gcc_except_table";
#endif

/*****************************************
Expand Down
106 changes: 102 additions & 4 deletions src/backend/el.c
Original file line number Diff line number Diff line change
Expand Up @@ -2238,11 +2238,13 @@ elem * el_const(tym_t ty,union eve *pconst)

/**************************
* Insert constructor information into tree.
* e code to construct the object
* decl VarDeclaration of variable being constructed
* A corresponding el_ddtor() must be called later.
* Params:
* e = code to construct the object
* decl = VarDeclaration of variable being constructed
*/

#if MARS
#if 0
elem *el_dctor(elem *e,void *decl)
{
elem *ector = el_calloc();
Expand All @@ -2267,7 +2269,7 @@ elem *el_dctor(elem *e,void *decl)
* (must match decl for corresponding OPctor)
*/

#if MARS
#if 0
elem *el_ddtor(elem *e,void *decl)
{
/* A destructor always executes code, or we wouldn't need
Expand All @@ -2283,6 +2285,102 @@ elem *el_ddtor(elem *e,void *decl)
}
#endif

/*********************************************
* Create constructor/destructor pair of elems.
* Params:
* ec = code to construct (may be NULL)
* ed = code to destruct
* pedtor = set to destructor node
* Returns:
* constructor node
*/

elem *el_ctor_dtor(elem *ec, elem *ed, elem **pedtor)
{
elem *er;
if (config.ehmethod == EH_DWARF)
{
/* Construct (note that OPinfo is evaluated RTOL):
* er = (OPdctor OPinfo (__flag = 0, ec))
* edtor = __flag = 1, (OPddtor ((__exception_object = _EAX), ed, (!__flag && _Unsafe_Resume(__exception_object))))
*/

/* Declare __flag, __EAX, __exception_object variables.
* Use volatile to prevent optimizer from messing them up, since optimizer doesn't know about
* landing pads (the landing pad will be on the OPddtor's EV.ed.Eleft)
*/
symbol *sflag = symbol_name("__flag", SCauto, type_fake(mTYvolatile | TYbool));
symbol *sreg = symbol_name("__EAX", SCpseudo, type_fake(mTYvolatile | TYnptr));
sreg->Sreglsw = 0; // EAX, RAX, whatevs
symbol *seo = symbol_name("__exception_object", SCauto, tspvoid);

symbol_add(sflag);
symbol_add(sreg);
symbol_add(seo);

elem *ector = el_calloc();
ector->Eoper = OPdctor;
ector->Ety = TYvoid;
// ector->EV.ed.Edecl = decl;

union eve c;
memset(&c, 0, sizeof(c));
elem *e_flag_0 = el_bin(OPeq, TYvoid, el_var(sflag), el_const(TYbool, &c)); // __flag = 0
er = el_bin(OPinfo, ec ? ec->Ety : TYvoid, ector, el_combine(e_flag_0, ec));

/* A destructor always executes code, or we wouldn't need
* eh for it.
* An OPddtor must match 1:1 with an OPdctor
*/
elem *edtor = el_calloc();
edtor->Eoper = OPddtor;
edtor->Ety = TYvoid;
// edtor->EV.ed.Edecl = decl;
// edtor->EV.ed.Eleft = e;

c.Vint = 1;
elem *e_flag_1 = el_bin(OPeq, TYvoid, el_var(sflag), el_const(TYbool, &c)); // __flag = 1
elem *e_eax = el_bin(OPeq, TYvoid, el_var(seo), el_var(sreg)); // __exception_object = __EAX
elem *eu = el_bin(OPcall, TYvoid, el_var(getRtlsym(RTLSYM_UNWIND_RESUME)), el_var(seo));
eu = el_bin(OPandand, TYvoid, el_una(OPnot, TYbool, el_var(sflag)), eu);

edtor->EV.ed.Eleft = el_combine(el_combine(e_eax, ed), eu);

*pedtor = el_combine(e_flag_1, edtor);
}
else
{
/* Construct (note that OPinfo is evaluated RTOL):
* er = (OPdctor OPinfo ec)
* edtor = (OPddtor ed)
*/
elem *ector = el_calloc();
ector->Eoper = OPdctor;
ector->Ety = TYvoid;
// ector->EV.ed.Edecl = decl;
if (ec)
er = el_bin(OPinfo,ec->Ety,ector,ec);
else
/* Remember that a "constructor" may execute no code, hence
* the need for OPinfo if there is code to execute.
*/
er = ector;

/* A destructor always executes code, or we wouldn't need
* eh for it.
* An OPddtor must match 1:1 with an OPdctor
*/
elem *edtor = el_calloc();
edtor->Eoper = OPddtor;
edtor->Ety = TYvoid;
// edtor->EV.ed.Edecl = decl;
edtor->EV.ed.Eleft = ed;
*pedtor = edtor;
}

return er;
}

/**************************
* Insert constructor information into tree.
* ector pointer to object being constructed
Expand Down
5 changes: 3 additions & 2 deletions src/backend/el.h
Original file line number Diff line number Diff line change
Expand Up @@ -178,8 +178,9 @@ elem_p el_long(tym_t,targ_llong);

int ERTOL(elem_p);
int el_noreturn(elem_p);
elem *el_dctor(elem *e,void *decl);
elem *el_ddtor(elem *e,void *decl);
//elem *el_dctor(elem *e,void *decl);
//elem *el_ddtor(elem *e,void *decl);
elem *el_ctor_dtor(elem *ec, elem *ed, elem **pedtor);
elem *el_ctor(elem *ector,elem *e,symbol *sdtor);
elem *el_dtor(elem *edtor,elem *e);
elem *el_zero(type *t);
Expand Down
2 changes: 2 additions & 0 deletions src/backend/gdag.c
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ void builddags()
list_next(b->Bpred) != NULL))
|| b->BC == BCasm
|| b->BC == BC_finally
|| b->BC == BC_lpad
#if SCPP
|| b->BC == BCcatch
#endif
Expand Down Expand Up @@ -616,6 +617,7 @@ void boolopt()
list_next(b->Bpred) != NULL))
|| b->BC == BCasm
|| b->BC == BC_finally
|| b->BC == BC_lpad
#if SCPP
|| b->BC == BCcatch
#endif
Expand Down
1 change: 1 addition & 0 deletions src/backend/gother.c
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ STATIC void rd_compute()
case BCjcatch:
#endif
case BC_finally:
case BC_lpad:
case BCasm:
case BCcatch:
block_visit(b);
Expand Down
1 change: 1 addition & 0 deletions src/backend/rtlsym.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ SYMBOL_SCPP(CPP_HANDLER, FLfunc,FREGSAVED,"_cpp_framehandler", 0, tsclib) \
SYMBOL_MARS(D_HANDLER, FLfunc,FREGSAVED,"_d_framehandler", 0, tsclib) \
SYMBOL_MARS(D_LOCAL_UNWIND2, FLfunc,FREGSAVED,"_d_local_unwind2", 0, tsclib) \
SYMBOL_SCPP(LOCAL_UNWIND2, FLfunc,FREGSAVED,"_local_unwind2", 0, tsclib) \
SYMBOL_Z(UNWIND_RESUME, FLfunc,FREGSAVED,"_Unwind_Resume", SFLexit, tsclib) \
\
SYMBOL_Z(TLS_INDEX, FLextern,0,"_tls_index",0,tsint) \
SYMBOL_Z(TLS_ARRAY, FLextern,0,"_tls_array",0,tspvoid) \
Expand Down
16 changes: 9 additions & 7 deletions src/e2ir.c
Original file line number Diff line number Diff line change
Expand Up @@ -4969,12 +4969,16 @@ elem *toElem(Expression *e, IRState *irs)
*/
if (vd->edtor && !vd->noscope)
{
e = el_dctor(e, vd);
elem *ed = NULL;
e = el_ctor_dtor(e, toElem(vd->edtor, irs), &ed);

// Put vd on list of things needing destruction
// ed needs to be inserted into the code later
if (!irs->varsInScope)
/* Don't have an Expressions_create(), so press VarDeclarations_create()
* into service. Fix when this file is converted to D.
*/
irs->varsInScope = VarDeclarations_create();
irs->varsInScope->push(vd);
irs->varsInScope->push((VarDeclaration *)ed);
}
}
}
Expand Down Expand Up @@ -5513,13 +5517,11 @@ elem *appendDtors(IRState *irs, elem *er, size_t starti, size_t endi)
elem *edtors = NULL;
for (size_t i = starti; i != endi; ++i)
{
VarDeclaration *vd = (*irs->varsInScope)[i];
if (vd)
elem *ed = (elem *)(*irs->varsInScope)[i];
if (ed)
{
//printf("appending dtor\n");
(*irs->varsInScope)[i] = NULL;
elem *ed = toElem(vd->edtor, irs);
ed = el_ddtor(ed, vd);
edtors = el_combine(ed, edtors); // execute in reverse order
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/glue.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ RET retStyle(TypeFunction *tf);

elem *addressElem(elem *e, Type *t, bool alwaysCopy = false);
void Statement_toIR(Statement *s, IRState *irs);
void insertFinallyBlockCalls(block *startblock);
elem *toEfilename(Module *m);
Symbol *toSymbol(Dsymbol *s);
void buildClosure(FuncDeclaration *fd, IRState *irs);
Expand Down Expand Up @@ -1240,6 +1241,7 @@ void FuncDeclaration_toObjFile(FuncDeclaration *fd, bool multiobj)
}
}
}
insertFinallyBlockCalls(f->Fstartblock);
}

// If static constructor
Expand Down
513 changes: 440 additions & 73 deletions src/s2ir.c

Large diffs are not rendered by default.