# HG changeset patch # User korDen # Date 1282653874 -14400 # Node ID ee3a9f34dc482db5c0b06279a9cbad58095fd8f5 # Parent f708f0452e81063f668c5cc9b4afd447f39892c8 final bits of codegen implementation to compile Phobos diff -r f708f0452e81 -r ee3a9f34dc48 commands.txt --- a/commands.txt Mon Aug 23 21:21:05 2010 +0400 +++ b/commands.txt Tue Aug 24 16:44:34 2010 +0400 @@ -86,6 +86,7 @@ dmd\TypeInfoTypedefDeclaration.d dmd\TypeInfoPointerDeclaration.d dmd\TypeInfoStaticArrayDeclaration.d +dmd\TypeInfoAssociativeArrayDeclaration.d dmd\DsymbolExp.d dmd\GlobalExpressions.d dmd\NewExp.d diff -r f708f0452e81 -r ee3a9f34dc48 dmd/ArrayLiteralExp.d --- a/dmd/ArrayLiteralExp.d Mon Aug 23 21:21:05 2010 +0400 +++ b/dmd/ArrayLiteralExp.d Tue Aug 24 16:44:34 2010 +0400 @@ -25,9 +25,11 @@ import dmd.expression.Util; import dmd.backend.Util; import dmd.backend.RTLSYM; -import dmd.backend.OPER; +import dmd.backend.OPER; +import dmd.backend.Symbol; import dmd.backend.TYM; import dmd.backend.mTY; +import dmd.codegen.Util; class ArrayLiteralExp : Expression { @@ -329,7 +331,50 @@ dt_t** toDt(dt_t** pdt) { - assert(false); + //printf("ArrayLiteralExp.toDt() '%s', type = %s\n", toChars(), type.toChars()); + + dt_t *d; + dt_t **pdtend; + + d = null; + pdtend = &d; + for (int i = 0; i < elements.dim; i++) + { + Expression e = cast(Expression)elements.data[i]; + + pdtend = e.toDt(pdtend); + } + Type t = type.toBasetype(); + + switch (t.ty) + { + case Tsarray: + pdt = dtcat(pdt, d); + break; + + case Tpointer: + case Tarray: + if (t.ty == Tarray) + dtdword(pdt, elements.dim); + if (d) + { + // Create symbol, and then refer to it + Symbol* s; + s = static_sym(); + s.Sdt = d; + outdata(s); + + dtxoff(pdt, s, 0, TYnptr); + } + else + dtdword(pdt, 0); + + break; + + default: + assert(0); + } + return pdt; } version (DMDV2) { diff -r f708f0452e81 -r ee3a9f34dc48 dmd/AssignExp.d --- a/dmd/AssignExp.d Mon Aug 23 21:21:05 2010 +0400 +++ b/dmd/AssignExp.d Tue Aug 24 16:44:34 2010 +0400 @@ -26,6 +26,7 @@ import dmd.TypeClass; import dmd.OutBuffer; import dmd.Loc; +import dmd.TypeNext; import dmd.TupleExp; import dmd.VarDeclaration; import dmd.Scope; @@ -777,15 +778,18 @@ { CallExp ce = cast(CallExp)e2; - TypeFunction tf = cast(TypeFunction)ce.e1.type.toBasetype(); - if (tf.ty == TY.Tfunction && tf.retStyle() == RET.RETstack) - { - elem* ehidden = e1.toElem(irs); - ehidden = el_una(OPER.OPaddr, TYM.TYnptr, ehidden); - assert(!irs.ehidden); - irs.ehidden = ehidden; - e = e2.toElem(irs); - goto Lret; + Type t = ce.e1.type.toBasetype(); + if (t.ty == TY.Tfunction) { + TypeFunction tf = cast(TypeFunction)t; + if (tf.retStyle() == RET.RETstack) + { + elem* ehidden = e1.toElem(irs); + ehidden = el_una(OPER.OPaddr, TYM.TYnptr, ehidden); + assert(!irs.ehidden); + irs.ehidden = ehidden; + e = e2.toElem(irs); + goto Lret; + } } } } diff -r f708f0452e81 -r ee3a9f34dc48 dmd/AssocArrayLiteralExp.d --- a/dmd/AssocArrayLiteralExp.d Mon Aug 23 21:21:05 2010 +0400 +++ b/dmd/AssocArrayLiteralExp.d Tue Aug 24 16:44:34 2010 +0400 @@ -22,6 +22,11 @@ import dmd.TOK; import dmd.PREC; import dmd.expression.Util; +import dmd.backend.Util; +import dmd.backend.TYM; +import dmd.backend.mTY; +import dmd.backend.OPER; +import dmd.backend.RTLSYM; class AssocArrayLiteralExp : Expression { @@ -112,7 +117,57 @@ elem* toElem(IRState* irs) { - assert(false); + elem* e; + size_t dim; + + //printf("AssocArrayLiteralExp.toElem() %s\n", toChars()); + dim = keys.dim; + e = el_long(TYint, dim); + for (size_t i = 0; i < dim; i++) + { + Expression el = cast(Expression)keys.data[i]; + + for (int j = 0; j < 2; j++) + { + elem* ep = el.toElem(irs); + + if (tybasic(ep.Ety) == TYstruct || tybasic(ep.Ety) == TYarray) + { + ep = el_una(OPstrpar, TYstruct, ep); + ep.Enumbytes = cast(uint)el.type.size(); + } + //printf("[%d] %s\n", i, el.toChars()); + //elem_print(ep); + e = el_param(ep, e); + el = cast(Expression)values.data[i]; + } + } + + Type t = type.toBasetype().mutableOf(); + assert(t.ty == Taarray); + TypeAArray ta = cast(TypeAArray)t; + + /* Unfortunately, the hash function for Aa (array of chars) is custom and + * different from Axa and Aya, which get the generic hash function. + * So, rewrite the type of the AArray so that if it's key type + * is an array of const or invariant, make it an array of mutable. + */ + Type tkey = ta.index.toBasetype(); + if (tkey.ty == Tarray) + { + tkey = tkey.nextOf().mutableOf().arrayOf(); + tkey = tkey.semantic(Loc(0), null); + ta = new TypeAArray(ta.nextOf(), tkey); + ta = cast(TypeAArray)ta.merge(); + } + + e = el_param(e, ta.getTypeInfo(null).toElem(irs)); + + // call _d_assocarrayliteralT(ti, dim, ...) + e = el_bin(OPcall,TYnptr,el_var(rtlsym[RTLSYM_ASSOCARRAYLITERALT]),e); + + el_setLoc(e,loc); + return e; } bool checkSideEffect(int flag) diff -r f708f0452e81 -r ee3a9f34dc48 dmd/CaseStatement.d --- a/dmd/CaseStatement.d Mon Aug 23 21:21:05 2010 +0400 +++ b/dmd/CaseStatement.d Tue Aug 24 16:44:34 2010 +0400 @@ -119,9 +119,12 @@ return this; } - int compare(Object obj) + int opCmp(Object obj) { - assert(false); + // Sort cases so we can do an efficient lookup + CaseStatement cs2 = cast(CaseStatement)obj; + + return exp.opCmp(cs2.exp); } bool usesEH() diff -r f708f0452e81 -r ee3a9f34dc48 dmd/Declaration.d --- a/dmd/Declaration.d Mon Aug 23 21:21:05 2010 +0400 +++ b/dmd/Declaration.d Tue Aug 24 16:44:34 2010 +0400 @@ -266,7 +266,7 @@ bool isThreadlocal() { - assert(false); + return false; } bool isCodeseg() diff -r f708f0452e81 -r ee3a9f34dc48 dmd/FuncDeclaration.d --- a/dmd/FuncDeclaration.d Mon Aug 23 21:21:05 2010 +0400 +++ b/dmd/FuncDeclaration.d Tue Aug 24 16:44:34 2010 +0400 @@ -2066,7 +2066,7 @@ bool isCodeseg() { - assert(false); + return true; // functions are always in the code segment } bool isOverloadable() diff -r f708f0452e81 -r ee3a9f34dc48 dmd/GotoDefaultStatement.d --- a/dmd/GotoDefaultStatement.d Mon Aug 23 21:21:05 2010 +0400 +++ b/dmd/GotoDefaultStatement.d Tue Aug 24 16:44:34 2010 +0400 @@ -11,6 +11,11 @@ import dmd.IRState; import dmd.BE; +import dmd.backend.block; +import dmd.backend.Blockx; +import dmd.backend.Util; +import dmd.backend.BC; + class GotoDefaultStatement : Statement { SwitchStatement sw; @@ -52,6 +57,33 @@ void toIR(IRState *irs) { - assert(false); + block *b; + Blockx *blx = irs.blx; + block *bdest = irs.getDefaultBlock(); + + b = blx.curblock; + + // The rest is equivalent to GotoStatement + + // Adjust exception handler scope index if in different try blocks + if (b.Btry != bdest.Btry) + { + // Check that bdest is in an enclosing try block + for (block* bt = b.Btry; bt != bdest.Btry; bt = bt.Btry) + { + if (!bt) + { + //printf("b.Btry = %p, bdest.Btry = %p\n", b.Btry, bdest.Btry); + error("cannot goto into try block"); + break; + } + } + + //setScopeIndex(blx, b, bdest.Btry ? bdest.Btry.Bscope_index : -1); + } + + list_append(&b.Bsucc,bdest); + incUsage(irs, loc); + block_next(blx,BCgoto,null); } } \ No newline at end of file diff -r f708f0452e81 -r ee3a9f34dc48 dmd/Identifier.d --- a/dmd/Identifier.d Mon Aug 23 21:21:05 2010 +0400 +++ b/dmd/Identifier.d Tue Aug 24 16:44:34 2010 +0400 @@ -28,7 +28,7 @@ assert(false); } - int compare(Object o) + int opCmp(Object o) { assert(false); } diff -r f708f0452e81 -r ee3a9f34dc48 dmd/IdentifierExp.d --- a/dmd/IdentifierExp.d Mon Aug 23 21:21:05 2010 +0400 +++ b/dmd/IdentifierExp.d Tue Aug 24 16:44:34 2010 +0400 @@ -155,7 +155,7 @@ int isLvalue() { - assert(false); + return 1; } Expression toLvalue(Scope sc, Expression e) diff -r f708f0452e81 -r ee3a9f34dc48 dmd/IntegerExp.d --- a/dmd/IntegerExp.d Mon Aug 23 21:21:05 2010 +0400 +++ b/dmd/IntegerExp.d Tue Aug 24 16:44:34 2010 +0400 @@ -474,7 +474,8 @@ break; case TY.Tint64: - buf.printf("%jdL", v); + //buf.printf("%jdL", v); + buf.printf("%sL", v); break; case TY.Tuns64: diff -r f708f0452e81 -r ee3a9f34dc48 dmd/OutBuffer.d --- a/dmd/OutBuffer.d Mon Aug 23 21:21:05 2010 +0400 +++ b/dmd/OutBuffer.d Tue Aug 24 16:44:34 2010 +0400 @@ -95,6 +95,19 @@ final void writenl() // write newline { assert(false); +version (_WIN32) { + version (M_UNICODE) { + write4(0x000A000D); // newline is CR,LF on Microsoft OS's + } else { + writeword(0x0A0D); // newline is CR,LF on Microsoft OS's + } +} else { + version (M_UNICODE) { + writeword('\n'); + } else { + writeByte('\n'); + } +} } final void writeByte(uint b) diff -r f708f0452e81 -r ee3a9f34dc48 dmd/ReturnStatement.d --- a/dmd/ReturnStatement.d Mon Aug 23 21:21:05 2010 +0400 +++ b/dmd/ReturnStatement.d Tue Aug 24 16:44:34 2010 +0400 @@ -399,10 +399,11 @@ void toIR(IRState* irs) { Blockx* blx = irs.blx; - + incUsage(irs, loc); if (exp) { + //printf("%.*s %.*s\n", exp.classinfo.name, exp.toChars()); elem *e; FuncDeclaration func = irs.getFunc(); @@ -420,7 +421,7 @@ */ if (exp.op == TOK.TOKstructliteral) { - scope StructLiteralExp se = cast(StructLiteralExp)exp; + StructLiteralExp se = cast(StructLiteralExp)exp; enum objectSize = __traits(classInstanceSize, StructLiteralExp); ubyte save[objectSize]; memcpy(save.ptr, cast(void*)se, objectSize); @@ -461,7 +462,8 @@ //if (tb.ty == TY.Tstruct) exp.dump(0); if ((exp.op == TOK.TOKvar || exp.op == TOK.TOKdotvar || exp.op == TOK.TOKstar) && tb.ty == TY.Tstruct) - { StructDeclaration sd = (cast(TypeStruct)tb).sym; + { + StructDeclaration sd = (cast(TypeStruct)tb).sym; if (sd.postblit) { FuncDeclaration fd = sd.postblit; diff -r f708f0452e81 -r ee3a9f34dc48 dmd/String.d --- a/dmd/String.d Mon Aug 23 21:21:05 2010 +0400 +++ b/dmd/String.d Tue Aug 24 16:44:34 2010 +0400 @@ -73,7 +73,7 @@ return str == (cast(String)obj).str; } - int compare(Object obj) + int opCmp(Object obj) { return cmp(str, (cast(String)obj).str); } diff -r f708f0452e81 -r ee3a9f34dc48 dmd/StringExp.d --- a/dmd/StringExp.d Mon Aug 23 21:21:05 2010 +0400 +++ b/dmd/StringExp.d Tue Aug 24 16:44:34 2010 +0400 @@ -70,7 +70,7 @@ { if (e.op == TOKstring) { - return compare(o) == 0; + return opCmp(o) == 0; } } @@ -577,7 +577,7 @@ return e; } - int compare(Object obj) + int opCmp(Object obj) { // Used to sort case statement expressions so we can do an efficient lookup StringExp se2 = cast(StringExp)(obj); diff -r f708f0452e81 -r ee3a9f34dc48 dmd/TypeAArray.d --- a/dmd/TypeAArray.d Mon Aug 23 21:21:05 2010 +0400 +++ b/dmd/TypeAArray.d Tue Aug 24 16:44:34 2010 +0400 @@ -4,6 +4,7 @@ import dmd.MOD; import dmd.ArrayTypes; import dmd.TypeInfoDeclaration; +import dmd.TypeInfoAssociativeArrayDeclaration; import dmd.Expression; import dmd.Scope; import dmd.Loc; @@ -183,7 +184,15 @@ void toCBuffer2(OutBuffer buf, HdrGenState* hgs, MOD mod) { - assert(false); + if (mod != this.mod) + { + toCBuffer3(buf, hgs, mod); + return; + } + next.toCBuffer2(buf, hgs, this.mod); + buf.writeByte('['); + index.toCBuffer2(buf, hgs, MODundefined); + buf.writeByte(']'); } Expression dotExp(Scope sc, Expression e, Identifier ident) @@ -300,7 +309,7 @@ TypeInfoDeclaration getTypeInfoDeclaration() { - assert(false); + return new TypeInfoAssociativeArrayDeclaration(this); } bool hasPointers() diff -r f708f0452e81 -r ee3a9f34dc48 dmd/TypeEnum.d --- a/dmd/TypeEnum.d Mon Aug 23 21:21:05 2010 +0400 +++ b/dmd/TypeEnum.d Tue Aug 24 16:44:34 2010 +0400 @@ -19,6 +19,7 @@ import dmd.TypeInfoEnumDeclaration; import dmd.ArrayTypes; import dmd.TY; +import dmd.MOD; import dmd.Util; import dmd.backend.TYPE; @@ -84,9 +85,14 @@ buf.printf("%s", name); } - void toCBuffer2(OutBuffer buf, HdrGenState* hgs, int mod) + void toCBuffer2(OutBuffer buf, HdrGenState* hgs, MOD mod) { - assert(false); + if (mod != this.mod) + { + toCBuffer3(buf, hgs, mod); + return; + } + buf.writestring(sym.toChars()); } Expression dotExp(Scope sc, Expression e, Identifier ident) diff -r f708f0452e81 -r ee3a9f34dc48 dmd/TypeInfoAssociativeArrayDeclaration.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dmd/TypeInfoAssociativeArrayDeclaration.d Tue Aug 24 16:44:34 2010 +0400 @@ -0,0 +1,35 @@ +module dmd.TypeInfoAssociativeArrayDeclaration; + +import dmd.Type; +import dmd.TypeAArray; +import dmd.TY; +import dmd.TypeInfoDeclaration; +import dmd.backend.dt_t; +import dmd.backend.TYM; +import dmd.backend.Util; + +class TypeInfoAssociativeArrayDeclaration : TypeInfoDeclaration +{ + this(Type tinfo) + { + super(tinfo, 0); + } + + void toDt(dt_t** pdt) + { + //printf("TypeInfoAssociativeArrayDeclaration.toDt()\n"); + dtxoff(pdt, Type.typeinfoassociativearray.toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_AssociativeArray + dtdword(pdt, 0); // monitor + + assert(tinfo.ty == Taarray); + + TypeAArray tc = cast(TypeAArray)tinfo; + + tc.next.getTypeInfo(null); + dtxoff(pdt, tc.next.vtinfo.toSymbol(), 0, TYnptr); // TypeInfo for array of type + + tc.index.getTypeInfo(null); + dtxoff(pdt, tc.index.vtinfo.toSymbol(), 0, TYnptr); // TypeInfo for array of type + } +} + diff -r f708f0452e81 -r ee3a9f34dc48 dmd/TypeInfoStaticArrayDeclaration.d --- a/dmd/TypeInfoStaticArrayDeclaration.d Mon Aug 23 21:21:05 2010 +0400 +++ b/dmd/TypeInfoStaticArrayDeclaration.d Tue Aug 24 16:44:34 2010 +0400 @@ -2,6 +2,11 @@ import dmd.Type; import dmd.TypeInfoDeclaration; +import dmd.TypeSArray; +import dmd.TY; + +import dmd.backend.Util; +import dmd.backend.TYM; import dmd.backend.dt_t; class TypeInfoStaticArrayDeclaration : TypeInfoDeclaration @@ -11,8 +16,19 @@ super(tinfo, 0); } - void toDt(dt_t **pdt) + void toDt(dt_t** pdt) { - assert(false); + //printf("TypeInfoStaticArrayDeclaration.toDt()\n"); + dtxoff(pdt, Type.typeinfostaticarray.toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_StaticArray + dtdword(pdt, 0); // monitor + + assert(tinfo.ty == Tsarray); + + TypeSArray tc = cast(TypeSArray)tinfo; + + tc.next.getTypeInfo(null); + dtxoff(pdt, tc.next.vtinfo.toSymbol(), 0, TYnptr); // TypeInfo for array of type + + dtdword(pdt, cast(int)tc.dim.toInteger()); // length } } \ No newline at end of file diff -r f708f0452e81 -r ee3a9f34dc48 dmd/TypedefDeclaration.d --- a/dmd/TypedefDeclaration.d Mon Aug 23 21:21:05 2010 +0400 +++ b/dmd/TypedefDeclaration.d Tue Aug 24 16:44:34 2010 +0400 @@ -14,11 +14,16 @@ import dmd.TypeTypedef; import dmd.Global; import dmd.STC; +import dmd.Id; import dmd.backend.SC; import dmd.backend.FL; +import dmd.backend.SFL; import dmd.backend.Symbol; import dmd.backend.Util; +import dmd.backend.LIST; +import dmd.backend.Classsym; +import dmd.codegen.Util; class TypedefDeclaration : Declaration { @@ -175,6 +180,18 @@ Symbol* sinit; Symbol* toInitializer() { - assert(false); + Symbol* s; + Classsym* stag; + + if (!sinit) + { + stag = fake_classsym(Id.ClassInfo); + s = toSymbolX("__init", SCextern, stag.Stype, "Z"); + s.Sfl = FLextern; + s.Sflags |= SFLnodebug; + slist_add(s); + sinit = s; + } + return sinit; } } diff -r f708f0452e81 -r ee3a9f34dc48 dmd/VarDeclaration.d --- a/dmd/VarDeclaration.d Mon Aug 23 21:21:05 2010 +0400 +++ b/dmd/VarDeclaration.d Tue Aug 24 16:44:34 2010 +0400 @@ -13,6 +13,7 @@ import dmd.CastExp; import dmd.WANT; import dmd.StructDeclaration; +import dmd.StorageClassDeclaration; import dmd.DsymbolExp; import dmd.TypeSArray; import dmd.IntegerExp; @@ -673,7 +674,28 @@ void toCBuffer(OutBuffer buf, HdrGenState* hgs) { - assert(false); + StorageClassDeclaration.stcToCBuffer(buf, storage_class); + + /* If changing, be sure and fix CompoundDeclarationStatement.toCBuffer() + * too. + */ + if (type) + type.toCBuffer(buf, ident, hgs); + else + buf.writestring(ident.toChars()); + if (init) + { + buf.writestring(" = "); +///version (DMDV2) { + ExpInitializer ie = init.isExpInitializer(); + if (ie && (ie.exp.op == TOKconstruct || ie.exp.op == TOKblit)) + (cast(AssignExp)ie.exp).e2.toCBuffer(buf, hgs); + else +///} + init.toCBuffer(buf, hgs); + } + buf.writeByte(';'); + buf.writenl(); } version (_DH) { diff -r f708f0452e81 -r ee3a9f34dc48 dmd/VoidInitializer.d --- a/dmd/VoidInitializer.d Mon Aug 23 21:21:05 2010 +0400 +++ b/dmd/VoidInitializer.d Tue Aug 24 16:44:34 2010 +0400 @@ -9,6 +9,7 @@ import dmd.HdrGenState; import dmd.backend.dt_t; +import dmd.backend.Util; class VoidInitializer : Initializer { @@ -43,7 +44,13 @@ dt_t* toDt() { - assert(false); + /* Void initializers are set to 0, just because we need something + * to set them to in the static data segment. + */ + dt_t *dt = null; + + dtnzeros(&dt, cast(uint)type.size()); + return dt; } VoidInitializer isVoidInitializer() { return this; } diff -r f708f0452e81 -r ee3a9f34dc48 dmd/XorAssignExp.d --- a/dmd/XorAssignExp.d Mon Aug 23 21:21:05 2010 +0400 +++ b/dmd/XorAssignExp.d Tue Aug 24 16:44:34 2010 +0400 @@ -12,6 +12,7 @@ import dmd.Id; import dmd.TOK; import dmd.backend.elem; +import dmd.backend.OPER; class XorAssignExp : BinExp { @@ -47,6 +48,6 @@ elem* toElem(IRState* irs) { - assert(false); + return toElemBin(irs,OPxorass); } }