279 changes: 279 additions & 0 deletions src/irstate.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,279 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2015 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// Distributed under the Boost Software License, Version 1.0.
// http://www.boost.org/LICENSE_1_0.txt

module ddmd.irstate;

import ddmd.arraytypes;
import ddmd.backend;
import ddmd.dmodule;
import ddmd.dsymbol;
import ddmd.func;
import ddmd.identifier;
import ddmd.statement;
import ddmd.root.aav;
import ddmd.globals;
import ddmd.mtype;
import ddmd.errors;

struct IRState
{
IRState* prev;
Statement statement;
Module m; // module
Dsymbol symbol;
Identifier ident;
Symbol* shidden; // hidden parameter to function
Symbol* sthis; // 'this' parameter to function (member and nested)
Symbol* sclosure; // pointer to closure instance
Blockx* blx;
Dsymbols* deferToObj; // array of Dsymbol's to run toObjFile(bool multiobj) on later
elem* ehidden; // transmit hidden pointer to CallExp::toElem()
Symbol* startaddress;
VarDeclarations* varsInScope; // variables that are in scope that will need destruction later
AA** labels; // table of labels used/declared in function
block* breakBlock;
block* contBlock;
block* switchBlock;
block* defaultBlock;
block* finallyBlock;

extern (D) this(IRState* irs, Statement s)
{
prev = irs;
statement = s;
symbol = null;
breakBlock = null;
contBlock = null;
switchBlock = null;
defaultBlock = null;
finallyBlock = null;
ident = null;
ehidden = null;
startaddress = null;
if (irs)
{
m = irs.m;
shidden = irs.shidden;
sclosure = irs.sclosure;
sthis = irs.sthis;
blx = irs.blx;
deferToObj = irs.deferToObj;
varsInScope = irs.varsInScope;
labels = irs.labels;
}
else
{
m = null;
shidden = null;
sclosure = null;
sthis = null;
blx = null;
deferToObj = null;
varsInScope = null;
labels = null;
}
}

extern (D) this(IRState* irs, Dsymbol s)
{
prev = irs;
statement = null;
symbol = s;
breakBlock = null;
contBlock = null;
switchBlock = null;
defaultBlock = null;
finallyBlock = null;
ident = null;
ehidden = null;
startaddress = null;
if (irs)
{
m = irs.m;
shidden = irs.shidden;
sclosure = irs.sclosure;
sthis = irs.sthis;
blx = irs.blx;
deferToObj = irs.deferToObj;
varsInScope = irs.varsInScope;
labels = irs.labels;
}
else
{
m = null;
shidden = null;
sclosure = null;
sthis = null;
blx = null;
deferToObj = null;
varsInScope = null;
labels = null;
}
}

extern (D) this(Module m, Dsymbol s)
{
prev = null;
statement = null;
this.m = m;
symbol = s;
breakBlock = null;
contBlock = null;
switchBlock = null;
defaultBlock = null;
finallyBlock = null;
ident = null;
ehidden = null;
shidden = null;
sclosure = null;
sthis = null;
blx = null;
deferToObj = null;
startaddress = null;
varsInScope = null;
labels = null;
}

extern (C++) block* getBreakBlock(Identifier ident)
{
IRState* bc;
if (ident)
{
Statement related = null;
block* ret = null;
for (bc = &this; bc; bc = bc.prev)
{
// The label for a breakBlock may actually be some levels up (e.g.
// on a try/finally wrapping a loop). We'll see if this breakBlock
// is the one to return once we reach that outer statement (which
// in many cases will be this same statement).
if (bc.breakBlock)
{
related = bc.statement.getRelatedLabeled();
ret = bc.breakBlock;
}
if (bc.statement == related && bc.prev.ident == ident)
return ret;
}
}
else
{
for (bc = &this; bc; bc = bc.prev)
{
if (bc.breakBlock)
return bc.breakBlock;
}
}
return null;
}

extern (C++) block* getContBlock(Identifier ident)
{
IRState* bc;
if (ident)
{
block* ret = null;
for (bc = &this; bc; bc = bc.prev)
{
// The label for a contBlock may actually be some levels up (e.g.
// on a try/finally wrapping a loop). We'll see if this contBlock
// is the one to return once we reach that outer statement (which
// in many cases will be this same statement).
if (bc.contBlock)
{
ret = bc.contBlock;
}
if (bc.prev && bc.prev.ident == ident)
return ret;
}
}
else
{
for (bc = &this; bc; bc = bc.prev)
{
if (bc.contBlock)
return bc.contBlock;
}
}
return null;
}

extern (C++) block* getSwitchBlock()
{
IRState* bc;
for (bc = &this; bc; bc = bc.prev)
{
if (bc.switchBlock)
return bc.switchBlock;
}
return null;
}

extern (C++) block* getDefaultBlock()
{
IRState* bc;
for (bc = &this; bc; bc = bc.prev)
{
if (bc.defaultBlock)
return bc.defaultBlock;
}
return null;
}

extern (C++) block* getFinallyBlock()
{
IRState* bc;
for (bc = &this; bc; bc = bc.prev)
{
if (bc.finallyBlock)
return bc.finallyBlock;
}
return null;
}

extern (C++) FuncDeclaration getFunc()
{
IRState* bc;
for (bc = &this; bc.prev; bc = bc.prev)
{
}
return cast(FuncDeclaration)bc.symbol;
}

/**********************
* Returns true if do array bounds checking for the current function
*/
extern (C++) bool arrayBoundsCheck()
{
bool result;
switch (global.params.useArrayBounds)
{
case BOUNDSCHECKoff:
result = false;
break;
case BOUNDSCHECKon:
result = true;
break;
case BOUNDSCHECKsafeonly:
{
result = false;
FuncDeclaration fd = getFunc();
if (fd)
{
Type t = fd.type;
if (t.ty == Tfunction && (cast(TypeFunction)t).trust == TRUSTsafe)
result = true;
}
break;
}
default:
assert(0);
}
return result;
}
}
99 changes: 96 additions & 3 deletions src/irstate.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,102 @@ struct IRState
block *defaultBlock;
block *finallyBlock;

IRState(IRState *irs, Statement *s);
IRState(IRState *irs, Dsymbol *s);
IRState(Module *m, Dsymbol *s);
IRState(IRState *irs, Statement *s)
{
prev = irs;
statement = s;
symbol = NULL;
breakBlock = NULL;
contBlock = NULL;
switchBlock = NULL;
defaultBlock = NULL;
finallyBlock = NULL;
ident = NULL;
ehidden = NULL;
startaddress = NULL;
if (irs)
{
m = irs->m;
shidden = irs->shidden;
sclosure = irs->sclosure;
sthis = irs->sthis;
blx = irs->blx;
deferToObj = irs->deferToObj;
varsInScope = irs->varsInScope;
labels = irs->labels;
}
else
{
m = NULL;
shidden = NULL;
sclosure = NULL;
sthis = NULL;
blx = NULL;
deferToObj = NULL;
varsInScope = NULL;
labels = NULL;
}
}

IRState(IRState *irs, Dsymbol *s)
{
prev = irs;
statement = NULL;
symbol = s;
breakBlock = NULL;
contBlock = NULL;
switchBlock = NULL;
defaultBlock = NULL;
finallyBlock = NULL;
ident = NULL;
ehidden = NULL;
startaddress = NULL;
if (irs)
{
m = irs->m;
shidden = irs->shidden;
sclosure = irs->sclosure;
sthis = irs->sthis;
blx = irs->blx;
deferToObj = irs->deferToObj;
varsInScope = irs->varsInScope;
labels = irs->labels;
}
else
{
m = NULL;
shidden = NULL;
sclosure = NULL;
sthis = NULL;
blx = NULL;
deferToObj = NULL;
varsInScope = NULL;
labels = NULL;
}
}

IRState(Module *m, Dsymbol *s)
{
prev = NULL;
statement = NULL;
this->m = m;
symbol = s;
breakBlock = NULL;
contBlock = NULL;
switchBlock = NULL;
defaultBlock = NULL;
finallyBlock = NULL;
ident = NULL;
ehidden = NULL;
shidden = NULL;
sclosure = NULL;
sthis = NULL;
blx = NULL;
deferToObj = NULL;
startaddress = NULL;
varsInScope = NULL;
labels = NULL;
}

block *getBreakBlock(Identifier *ident);
block *getContBlock(Identifier *ident);
Expand Down
6 changes: 3 additions & 3 deletions src/posix.mak
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ DMD_SRCS=$(addsuffix .d,access aggregate aliasthis apply argtypes arrayop \
globals hdrgen id identifier impcnvtab imphint init inline intrange \
json lexer lib link mars mtype nogc nspace opover optimize parse sapply \
sideeffect statement staticassert target tokens traits utf visitor \
typinf)
typinf irstate)

ifeq ($(D_OBJC),1)
DMD_SRCS += objc.d
Expand All @@ -196,7 +196,7 @@ ROOT_SRCS = $(addsuffix .d,$(addprefix $(ROOT)/,aav array file filename \
stringtable))

GLUE_OBJS = glue.o msc.o s2ir.o todt.o e2ir.o tocsym.o toobj.o toctype.o \
toelfdebug.o toir.o irstate.o iasm.o
toelfdebug.o toir.o iasm.o


ifeq ($(D_OBJC),1)
Expand Down Expand Up @@ -246,7 +246,7 @@ ROOT_SRC = $(addprefix $(ROOT)/,aav.h array.h file.h filename.h \

GLUE_SRC = glue.c msc.c s2ir.c todt.c e2ir.c tocsym.c \
toobj.c toctype.c tocvdebug.c toir.h toir.c \
irstate.h irstate.c iasm.c \
irstate.h iasm.c \
toelfdebug.c libelf.d scanelf.d libmach.d scanmach.d \
tk.c eh.c gluestub.c objc_glue.c objc_glue_stubs.c

Expand Down
9 changes: 3 additions & 6 deletions src/win32.mak
Original file line number Diff line number Diff line change
Expand Up @@ -148,12 +148,12 @@ DMD_SRCS=access.d aggregate.d aliasthis.d apply.d argtypes.d arrayop.d \
mars.d mtype.d nogc.d nspace.d objc_stubs.d opover.d optimize.d parse.d \
sapply.d sideeffect.d statement.d staticassert.d target.d tokens.d \
traits.d utf.d visitor.d libomf.d scanomf.d typinf.d \
libmscoff.d scanmscoff.d
libmscoff.d scanmscoff.d irstate.d

# Glue layer
GLUEOBJ=glue.obj msc.obj s2ir.obj todt.obj e2ir.obj tocsym.obj \
toobj.obj toctype.obj tocvdebug.obj toir.obj \
irstate.obj iasm.obj objc_glue_stubs.obj
iasm.obj objc_glue_stubs.obj

# D back end
BACKOBJ= go.obj gdag.obj gother.obj gflow.obj gloop.obj var.obj el.obj \
Expand Down Expand Up @@ -186,7 +186,7 @@ SRCS = win32.mak posix.mak osmodel.mak aggregate.h aliasthis.h arraytypes.h \
# Glue layer
GLUESRC= glue.c msc.c s2ir.c todt.c e2ir.c tocsym.c \
toobj.c toctype.c tocvdebug.c toir.h toir.c \
irstate.h irstate.c iasm.c \
irstate.h iasm.c \
toelfdebug.c libelf.d scanelf.d libmach.d scanmach.d \
tk.c eh.c objc_glue_stubs.c objc_glue.c

Expand Down Expand Up @@ -438,9 +438,6 @@ cod5.obj : $C\cod5.c
code.obj : $C\code.c
$(CC) -c $(MFLAGS) $C\code

irstate.obj : irstate.h irstate.c
$(CC) -c $(MFLAGS) -I$(ROOT) irstate

csymbol.obj : $C\symbol.c
$(CC) -c $(MFLAGS) $C\symbol -ocsymbol.obj

Expand Down