From e8be19533406ae4aa830ec0c7d85e56c8082e1ff Mon Sep 17 00:00:00 2001 From: Daniel Murphy Date: Wed, 26 Aug 2015 11:35:36 +1000 Subject: [PATCH] Convert irstate to D --- src/backend.d | 2 + src/irstate.c | 261 ---------------------------------------------- src/irstate.d | 279 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/irstate.h | 99 +++++++++++++++++- src/posix.mak | 6 +- src/win32.mak | 9 +- 6 files changed, 383 insertions(+), 273 deletions(-) delete mode 100644 src/irstate.c create mode 100644 src/irstate.d diff --git a/src/backend.d b/src/backend.d index 5c238e96cd11..efedc9701396 100644 --- a/src/backend.d +++ b/src/backend.d @@ -21,6 +21,8 @@ struct TYPE; alias type = TYPE; struct code; struct block; +struct Blockx; +struct elem; extern extern (C++) void backend_init(); extern extern (C++) void backend_term(); diff --git a/src/irstate.c b/src/irstate.c deleted file mode 100644 index c1728bfb77b0..000000000000 --- a/src/irstate.c +++ /dev/null @@ -1,261 +0,0 @@ - -/* Compiler implementation of the D programming language - * Copyright (c) 1999-2014 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 - * https://github.com/D-Programming-Language/dmd/blob/master/src/irstate.c - */ - -#include - -#include "mars.h" -#include "mtype.h" -#include "declaration.h" -#include "irstate.h" -#include "statement.h" - -IRState::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(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::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 *IRState::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; -} - -block *IRState::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; -} - -block *IRState::getSwitchBlock() -{ - IRState *bc; - - for (bc = this; bc; bc = bc->prev) - { - if (bc->switchBlock) - return bc->switchBlock; - } - return NULL; -} - -block *IRState::getDefaultBlock() -{ - IRState *bc; - - for (bc = this; bc; bc = bc->prev) - { - if (bc->defaultBlock) - return bc->defaultBlock; - } - return NULL; -} - -block *IRState::getFinallyBlock() -{ - IRState *bc; - - for (bc = this; bc; bc = bc->prev) - { - if (bc->finallyBlock) - return bc->finallyBlock; - } - return NULL; -} - -FuncDeclaration *IRState::getFunc() -{ - IRState *bc; - - for (bc = this; bc->prev; bc = bc->prev) - { - } - return (FuncDeclaration *)(bc->symbol); -} - - -/********************** - * Returns true if do array bounds checking for the current function - */ -bool IRState::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 && ((TypeFunction *)t)->trust == TRUSTsafe) - result = true; - } - break; - } - - default: - assert(0); - } - return result; -} diff --git a/src/irstate.d b/src/irstate.d new file mode 100644 index 000000000000..cf294be319c3 --- /dev/null +++ b/src/irstate.d @@ -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; + } +} diff --git a/src/irstate.h b/src/irstate.h index 7933200733d3..7fc69d5d3dda 100644 --- a/src/irstate.h +++ b/src/irstate.h @@ -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); diff --git a/src/posix.mak b/src/posix.mak index 55f2ebdcd124..5c6aed21d8b0 100644 --- a/src/posix.mak +++ b/src/posix.mak @@ -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 @@ -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) @@ -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 diff --git a/src/win32.mak b/src/win32.mak index b2457e4e4e6f..ccde7a07e7f9 100644 --- a/src/win32.mak +++ b/src/win32.mak @@ -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 \ @@ -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 @@ -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