# HG changeset patch # User dkoroskin <> # Date 1260297557 -10800 # Node ID 63623152e82af792b43c2df09933dbbd5489256a # Parent d706d958e4e82f321817cd974486500cd1aa5e9b Fixed memory corruption bug which was introduced when attempting to restore GC functionality diff -r d706d958e4e8 -r 63623152e82a dmd/FileName.d --- a/dmd/FileName.d Mon Oct 26 16:28:19 2009 +0300 +++ b/dmd/FileName.d Tue Dec 08 21:39:17 2009 +0300 @@ -7,7 +7,7 @@ import core.memory; -import core.stdc.stdlib : alloca; +import core.stdc.stdlib : malloc, alloca; import core.stdc.string : memcpy, strlen; import core.stdc.ctype : isspace; @@ -412,7 +412,7 @@ size_t len = e.ptr - name.ptr; size_t extlen = ext.length; - char* s = cast(char*)GC.malloc(len + extlen + 1); + char* s = cast(char*)malloc(len + extlen + 1); /// ! memcpy(s, name.ptr, len); memcpy(s + len, ext.ptr, extlen + 1); return new FileName(assumeUnique(s[0..len+extlen])); diff -r d706d958e4e8 -r 63623152e82a dmd/Module.d --- a/dmd/Module.d Mon Oct 26 16:28:19 2009 +0300 +++ b/dmd/Module.d Tue Dec 08 21:39:17 2009 +0300 @@ -931,13 +931,13 @@ covb = cast(uint*)GC.calloc(((numlines + 32) / 32) * (*covb).sizeof); } - + for (int i = 0; i < members.dim; i++) { Dsymbol member = cast(Dsymbol)members.data[i]; member.toObjFile(multiobj); } - + if (global.params.cov) { /* Generate @@ -1124,12 +1124,13 @@ writefunc(ma); } } + static if (true) { // Always generate module info, because of templates and -cov if (1 || needModuleInfo()) genmoduleinfo(); - } +} obj_termfile(); } diff -r d706d958e4e8 -r 63623152e82a dmd/OutBuffer.d --- a/dmd/OutBuffer.d Mon Oct 26 16:28:19 2009 +0300 +++ b/dmd/OutBuffer.d Tue Dec 08 21:39:17 2009 +0300 @@ -7,6 +7,7 @@ import core.stdc.string; import core.memory; +import core.stdc.stdlib; class OutBuffer { @@ -41,7 +42,7 @@ if (size - offset < nbytes) { size = (offset + nbytes) * 2; - data = cast(ubyte*)GC.realloc(data, size); + data = cast(ubyte*)realloc(data, size); } } @@ -266,7 +267,12 @@ string toChars() { - return getString().idup; + char[] s = getString(); + char* copy = cast(char*)malloc(s.length); + memcpy(copy, s.ptr, s.length); + return assumeUnique(copy[0..s.length]); + + //return getString().idup; } final string extractString() diff -r d706d958e4e8 -r 63623152e82a dmd/StringExp.d --- a/dmd/StringExp.d Mon Oct 26 16:28:19 2009 +0300 +++ b/dmd/StringExp.d Tue Dec 08 21:39:17 2009 +0300 @@ -1,57 +1,58 @@ -module dmd.StringExp; - -import dmd.Expression; -import dmd.backend.elem; -import dmd.InterState; -import dmd.TypeSArray; -import dmd.CastExp; -import dmd.MATCH; -import dmd.TY; -import dmd.TypeDArray; -import dmd.Type; -import dmd.TOK; -import dmd.OutBuffer; -import dmd.Loc; -import dmd.Scope; -import dmd.IRState; -import dmd.StringExp; -import dmd.HdrGenState; -import dmd.Utf; -import dmd.backend.dt_t; -import dmd.backend.Symbol; -import dmd.backend.StringTab; -import dmd.backend.Util; -import dmd.backend.SC; -import dmd.backend.TYM; -import dmd.backend.FL; -import dmd.backend.TYPE; -import dmd.backend.OPER; - -import core.memory; - -import core.stdc.string; - +module dmd.StringExp; + +import dmd.Expression; +import dmd.backend.elem; +import dmd.InterState; +import dmd.TypeSArray; +import dmd.CastExp; +import dmd.MATCH; +import dmd.TY; +import dmd.TypeDArray; +import dmd.Type; +import dmd.TOK; +import dmd.OutBuffer; +import dmd.Loc; +import dmd.Scope; +import dmd.IRState; +import dmd.StringExp; +import dmd.HdrGenState; +import dmd.Utf; +import dmd.backend.dt_t; +import dmd.backend.Symbol; +import dmd.backend.StringTab; +import dmd.backend.Util; +import dmd.backend.SC; +import dmd.backend.TYM; +import dmd.backend.FL; +import dmd.backend.TYPE; +import dmd.backend.OPER; + +import core.memory; + +import core.stdc.string; +import core.stdc.stdlib; + class StringExp : Expression { - void* string_; // char, wchar, or dchar data - size_t len; // number of chars, wchars, or dchars - ubyte sz; // 1: char, 2: wchar, 4: dchar - ubyte committed; // !=0 if type is committed + void* string_; // char, wchar, or dchar data + size_t len; // number of chars, wchars, or dchars + ubyte sz; // 1: char, 2: wchar, 4: dchar + ubyte committed; // !=0 if type is committed ubyte postfix; // 'c', 'w', 'd' this(Loc loc, string s) - { + { this(loc, s, 0); } this(Loc loc, string s, ubyte postfix) { - super(loc, TOK.TOKstring, StringExp.sizeof); - - this.string_ = cast(void*)s.ptr; - this.len = s.length; - this.sz = 1; - this.committed = 0; + super(loc, TOK.TOKstring, StringExp.sizeof); + + this.string_ = cast(void*)s.ptr; + this.len = s.length; + this.sz = 1; + this.committed = 0; this.postfix = postfix; } @@ -67,80 +68,80 @@ Expression semantic(Scope sc) { -version (LOGSEMANTIC) { - printf("StringExp.semantic() %s\n", toChars()); -} - if (!type) - { - scope OutBuffer buffer = new OutBuffer(); - size_t newlen = 0; - string p; - size_t u; - dchar c; - - switch (postfix) - { - case 'd': - for (u = 0; u < len;) - { - p = utf_decodeChar(cast(string)string_[0..len], &u, &c); - if (p !is null) - { - error("%s", p); - break; - } - else - { - buffer.write4(c); - newlen++; - } - } - buffer.write4(0); - string_ = buffer.extractData(); - len = newlen; - sz = 4; - //type = new TypeSArray(Type.tdchar, new IntegerExp(loc, len, Type.tindex)); - type = new TypeDArray(Type.tdchar.invariantOf()); - committed = 1; - break; - - case 'w': - for (u = 0; u < len;) - { - p = utf_decodeChar(cast(string)string_[0..len], &u, &c); - if (p !is null) - { - error("%s", p); - break; - } - else - { - buffer.writeUTF16(c); - newlen++; - if (c >= 0x10000) - newlen++; - } - } - buffer.writeUTF16(0); - string_ = buffer.extractData(); - len = newlen; - sz = 2; - //type = new TypeSArray(Type.twchar, new IntegerExp(loc, len, Type.tindex)); - type = new TypeDArray(Type.twchar.invariantOf()); - committed = 1; - break; - - case 'c': - committed = 1; - default: - //type = new TypeSArray(Type.tchar, new IntegerExp(loc, len, Type.tindex)); - type = new TypeDArray(Type.tchar.invariantOf()); - break; - } - type = type.semantic(loc, sc); - //type = type.invariantOf(); - //printf("type = %s\n", type.toChars()); - } +version (LOGSEMANTIC) { + printf("StringExp.semantic() %s\n", toChars()); +} + if (!type) + { + scope OutBuffer buffer = new OutBuffer(); + size_t newlen = 0; + string p; + size_t u; + dchar c; + + switch (postfix) + { + case 'd': + for (u = 0; u < len;) + { + p = utf_decodeChar(cast(string)string_[0..len], &u, &c); + if (p !is null) + { + error("%s", p); + break; + } + else + { + buffer.write4(c); + newlen++; + } + } + buffer.write4(0); + string_ = buffer.extractData(); + len = newlen; + sz = 4; + //type = new TypeSArray(Type.tdchar, new IntegerExp(loc, len, Type.tindex)); + type = new TypeDArray(Type.tdchar.invariantOf()); + committed = 1; + break; + + case 'w': + for (u = 0; u < len;) + { + p = utf_decodeChar(cast(string)string_[0..len], &u, &c); + if (p !is null) + { + error("%s", p); + break; + } + else + { + buffer.writeUTF16(c); + newlen++; + if (c >= 0x10000) + newlen++; + } + } + buffer.writeUTF16(0); + string_ = buffer.extractData(); + len = newlen; + sz = 2; + //type = new TypeSArray(Type.twchar, new IntegerExp(loc, len, Type.tindex)); + type = new TypeDArray(Type.twchar.invariantOf()); + committed = 1; + break; + + case 'c': + committed = 1; + default: + //type = new TypeSArray(Type.tchar, new IntegerExp(loc, len, Type.tindex)); + type = new TypeDArray(Type.tchar.invariantOf()); + break; + } + type = type.semantic(loc, sc); + //type = type.invariantOf(); + //printf("type = %s\n", type.toChars()); + } return this; } @@ -161,335 +162,335 @@ Expression implicitCastTo(Scope sc, Type t) { - //printf("StringExp.implicitCastTo(%s of type %s) => %s\n", toChars(), type.toChars(), t.toChars()); - ubyte committed = this.committed; - Expression e = Expression.implicitCastTo(sc, t); - if (e.op == TOK.TOKstring) - { - // Retain polysemous nature if it started out that way - (cast(StringExp)e).committed = committed; - } + //printf("StringExp.implicitCastTo(%s of type %s) => %s\n", toChars(), type.toChars(), t.toChars()); + ubyte committed = this.committed; + Expression e = Expression.implicitCastTo(sc, t); + if (e.op == TOK.TOKstring) + { + // Retain polysemous nature if it started out that way + (cast(StringExp)e).committed = committed; + } return e; } MATCH implicitConvTo(Type t) { - MATCH m; - -static if (false) { - printf("StringExp.implicitConvTo(this=%s, committed=%d, type=%s, t=%s)\n", - toChars(), committed, type.toChars(), t.toChars()); -} - if (!committed) - { - if (!committed && t.ty == TY.Tpointer && t.nextOf().ty == TY.Tvoid) - { - return MATCH.MATCHnomatch; - } - if (type.ty == TY.Tsarray || type.ty == TY.Tarray || type.ty == TY.Tpointer) - { - TY tyn = type.nextOf().ty; - if (tyn == TY.Tchar || tyn == TY.Twchar || tyn == TY.Tdchar) - { - Type tn; - MATCH mm; - - switch (t.ty) - { - case TY.Tsarray: - if (type.ty == TY.Tsarray) - { - if ((cast(TypeSArray)type).dim.toInteger() != - (cast(TypeSArray)t).dim.toInteger()) - return MATCH.MATCHnomatch; - TY tynto = t.nextOf().ty; - if (tynto == TY.Tchar || tynto == TY.Twchar || tynto == TY.Tdchar) - return MATCH.MATCHexact; - } - else if (type.ty == TY.Tarray) - { - if (length() > (cast(TypeSArray)t).dim.toInteger()) - return MATCH.MATCHnomatch; - TY tynto = t.nextOf().ty; - if (tynto == TY.Tchar || tynto == TY.Twchar || tynto == TY.Tdchar) - return MATCH.MATCHexact; - } - case TY.Tarray: - case TY.Tpointer: - tn = t.nextOf(); - mm = MATCH.MATCHexact; - if (type.nextOf().mod != tn.mod) - { - if (!tn.isConst()) - return MATCH.MATCHnomatch; - mm = MATCH.MATCHconst; - } - switch (tn.ty) - { - case TY.Tchar: - case TY.Twchar: - case TY.Tdchar: - return mm; - } - break; - default: - break; /// - } - } - } - } - return Expression.implicitConvTo(t); -static if (false) { - m = cast(MATCH)type.implicitConvTo(t); - if (m) - { - return m; - } - - return MATCH.MATCHnomatch; + MATCH m; + +static if (false) { + printf("StringExp.implicitConvTo(this=%s, committed=%d, type=%s, t=%s)\n", + toChars(), committed, type.toChars(), t.toChars()); } - } - - static uint X(TY tf, TY tt) { - return ((tf) * 256 + (tt)); + if (!committed) + { + if (!committed && t.ty == TY.Tpointer && t.nextOf().ty == TY.Tvoid) + { + return MATCH.MATCHnomatch; + } + if (type.ty == TY.Tsarray || type.ty == TY.Tarray || type.ty == TY.Tpointer) + { + TY tyn = type.nextOf().ty; + if (tyn == TY.Tchar || tyn == TY.Twchar || tyn == TY.Tdchar) + { + Type tn; + MATCH mm; + + switch (t.ty) + { + case TY.Tsarray: + if (type.ty == TY.Tsarray) + { + if ((cast(TypeSArray)type).dim.toInteger() != + (cast(TypeSArray)t).dim.toInteger()) + return MATCH.MATCHnomatch; + TY tynto = t.nextOf().ty; + if (tynto == TY.Tchar || tynto == TY.Twchar || tynto == TY.Tdchar) + return MATCH.MATCHexact; + } + else if (type.ty == TY.Tarray) + { + if (length() > (cast(TypeSArray)t).dim.toInteger()) + return MATCH.MATCHnomatch; + TY tynto = t.nextOf().ty; + if (tynto == TY.Tchar || tynto == TY.Twchar || tynto == TY.Tdchar) + return MATCH.MATCHexact; + } + case TY.Tarray: + case TY.Tpointer: + tn = t.nextOf(); + mm = MATCH.MATCHexact; + if (type.nextOf().mod != tn.mod) + { + if (!tn.isConst()) + return MATCH.MATCHnomatch; + mm = MATCH.MATCHconst; + } + switch (tn.ty) + { + case TY.Tchar: + case TY.Twchar: + case TY.Tdchar: + return mm; + } + break; + default: + break; /// + } + } + } + } + return Expression.implicitConvTo(t); +static if (false) { + m = cast(MATCH)type.implicitConvTo(t); + if (m) + { + return m; + } + + return MATCH.MATCHnomatch; +} + } + + static uint X(TY tf, TY tt) { + return ((tf) * 256 + (tt)); } Expression castTo(Scope sc, Type t) - { - /* This follows copy-on-write; any changes to 'this' - * will result in a copy. - * The this.string member is considered immutable. - */ - StringExp se; - Type tb; - int copied = 0; - - //printf("StringExp.castTo(t = %s), '%s' committed = %d\n", t.toChars(), toChars(), committed); - - if (!committed && t.ty == TY.Tpointer && t.nextOf().ty == TY.Tvoid) - { - error("cannot convert string literal to void*"); - } - - se = this; - if (!committed) - { - se = cast(StringExp)copy(); - se.committed = 1; - copied = 1; - } - - if (type == t) - { - return se; - } - - tb = t.toBasetype(); - //printf("\ttype = %s\n", type.toChars()); - if (tb.ty == TY.Tdelegate && type.toBasetype().ty != TY.Tdelegate) - return Expression.castTo(sc, t); - - Type typeb = type.toBasetype(); - if (typeb == tb) - { - if (!copied) - { - se = cast(StringExp)copy(); - copied = 1; - } - se.type = t; - return se; - } - - if (committed && tb.ty == TY.Tsarray && typeb.ty == TY.Tarray) - { - se = cast(StringExp)copy(); - se.sz = cast(ubyte)tb.nextOf().size(); - se.len = (len * sz) / se.sz; - se.committed = 1; - se.type = t; - return se; - } - - if (tb.ty != TY.Tsarray && tb.ty != TY.Tarray && tb.ty != TY.Tpointer) - { - if (!copied) - { - se = cast(StringExp)copy(); - copied = 1; - } - goto Lcast; - } - if (typeb.ty != TY.Tsarray && typeb.ty != TY.Tarray && typeb.ty != TY.Tpointer) - { - if (!copied) - { - se = cast(StringExp)copy(); - copied = 1; - } - goto Lcast; - } - - if (typeb.nextOf().size() == tb.nextOf().size()) - { - if (!copied) - { - se = cast(StringExp)copy(); - copied = 1; - } - - if (tb.ty == TY.Tsarray) - goto L2; // handle possible change in static array dimension - se.type = t; - return se; - } - - if (committed) - goto Lcast; - - { - scope OutBuffer buffer = new OutBuffer(); - size_t newlen = 0; - TY tfty = typeb.nextOf().toBasetype().ty; - TY ttty = tb.nextOf().toBasetype().ty; - switch (X(tfty, ttty)) - { - case X(TY.Tchar, TY.Tchar): - case X(TY.Twchar,TY.Twchar): - case X(TY.Tdchar,TY.Tdchar): - break; - - case X(TY.Tchar, TY.Twchar): - for (size_t u = 0; u < len;) - { - dchar c; - string p = utf_decodeChar(cast(string)se.string_[0..len], &u, &c); - if (p !is null) - error("%s", p); - else - buffer.writeUTF16(c); - } - newlen = buffer.offset / 2; - buffer.writeUTF16(0); - goto L1; - - case X(TY.Tchar, TY.Tdchar): - for (size_t u = 0; u < len;) - { - dchar c; - string p = utf_decodeChar(cast(string)se.string_[0..len], &u, &c); - if (p !is null) - error("%s", p); - buffer.write4(c); - newlen++; - } - buffer.write4(0); - goto L1; - - case X(TY.Twchar,TY.Tchar): - for (size_t u = 0; u < len;) - { - dchar c; - string p = utf_decodeWchar(cast(wstring)se.string_[0..len], &u, &c); - if (p) - error("%s", p); - else - buffer.writeUTF8(c); - } - newlen = buffer.offset; - buffer.writeUTF8(0); - goto L1; - - case X(TY.Twchar,TY.Tdchar): - for (size_t u = 0; u < len;) - { - dchar c; - string p = utf_decodeWchar(cast(wstring)se.string_[0..len], &u, &c); - if (p) - error("%s", p); - buffer.write4(c); - newlen++; - } - buffer.write4(0); - goto L1; - - case X(TY.Tdchar,TY.Tchar): - for (size_t u = 0; u < len; u++) - { - dchar c = (cast(dchar*)se.string_)[u]; - if (!utf_isValidDchar(c)) - error("invalid UCS-32 char \\U%08x", c); - else - buffer.writeUTF8(c); - newlen++; - } - newlen = buffer.offset; - buffer.writeUTF8(0); - goto L1; - - case X(TY.Tdchar,TY.Twchar): - for (size_t u = 0; u < len; u++) - { - dchar c = (cast(dchar*)se.string_)[u]; - if (!utf_isValidDchar(c)) - error("invalid UCS-32 char \\U%08x", c); - else - buffer.writeUTF16(c); - newlen++; - } - newlen = buffer.offset / 2; - buffer.writeUTF16(0); - goto L1; - - L1: - if (!copied) - { - se = cast(StringExp)copy(); - copied = 1; - } - se.string_ = buffer.extractData(); - se.len = newlen; - se.sz = cast(ubyte)tb.nextOf().size(); - break; - - default: - assert(typeb.nextOf().size() != tb.nextOf().size()); - goto Lcast; - } - } - L2: - assert(copied); - - // See if need to truncate or extend the literal - if (tb.ty == TY.Tsarray) - { - int dim2 = cast(int)(cast(TypeSArray)tb).dim.toInteger(); - - //printf("dim from = %d, to = %d\n", se.len, dim2); - - // Changing dimensions - if (dim2 != se.len) - { - // Copy when changing the string literal - uint newsz = se.sz; - void *s; - int d; - - d = (dim2 < se.len) ? dim2 : se.len; - s = cast(ubyte*)GC.malloc((dim2 + 1) * newsz); - memcpy(s, se.string_, d * newsz); - // Extend with 0, add terminating 0 - memset(cast(char*)s + d * newsz, 0, (dim2 + 1 - d) * newsz); - se.string_ = s; - se.len = dim2; - } - } - se.type = t; - return se; - - Lcast: - Expression e = new CastExp(loc, se, t); - e.type = t; // so semantic() won't be run on e + { + /* This follows copy-on-write; any changes to 'this' + * will result in a copy. + * The this.string member is considered immutable. + */ + StringExp se; + Type tb; + int copied = 0; + + //printf("StringExp.castTo(t = %s), '%s' committed = %d\n", t.toChars(), toChars(), committed); + + if (!committed && t.ty == TY.Tpointer && t.nextOf().ty == TY.Tvoid) + { + error("cannot convert string literal to void*"); + } + + se = this; + if (!committed) + { + se = cast(StringExp)copy(); + se.committed = 1; + copied = 1; + } + + if (type == t) + { + return se; + } + + tb = t.toBasetype(); + //printf("\ttype = %s\n", type.toChars()); + if (tb.ty == TY.Tdelegate && type.toBasetype().ty != TY.Tdelegate) + return Expression.castTo(sc, t); + + Type typeb = type.toBasetype(); + if (typeb == tb) + { + if (!copied) + { + se = cast(StringExp)copy(); + copied = 1; + } + se.type = t; + return se; + } + + if (committed && tb.ty == TY.Tsarray && typeb.ty == TY.Tarray) + { + se = cast(StringExp)copy(); + se.sz = cast(ubyte)tb.nextOf().size(); + se.len = (len * sz) / se.sz; + se.committed = 1; + se.type = t; + return se; + } + + if (tb.ty != TY.Tsarray && tb.ty != TY.Tarray && tb.ty != TY.Tpointer) + { + if (!copied) + { + se = cast(StringExp)copy(); + copied = 1; + } + goto Lcast; + } + if (typeb.ty != TY.Tsarray && typeb.ty != TY.Tarray && typeb.ty != TY.Tpointer) + { + if (!copied) + { + se = cast(StringExp)copy(); + copied = 1; + } + goto Lcast; + } + + if (typeb.nextOf().size() == tb.nextOf().size()) + { + if (!copied) + { + se = cast(StringExp)copy(); + copied = 1; + } + + if (tb.ty == TY.Tsarray) + goto L2; // handle possible change in static array dimension + se.type = t; + return se; + } + + if (committed) + goto Lcast; + + { + scope OutBuffer buffer = new OutBuffer(); + size_t newlen = 0; + TY tfty = typeb.nextOf().toBasetype().ty; + TY ttty = tb.nextOf().toBasetype().ty; + switch (X(tfty, ttty)) + { + case X(TY.Tchar, TY.Tchar): + case X(TY.Twchar,TY.Twchar): + case X(TY.Tdchar,TY.Tdchar): + break; + + case X(TY.Tchar, TY.Twchar): + for (size_t u = 0; u < len;) + { + dchar c; + string p = utf_decodeChar(cast(string)se.string_[0..len], &u, &c); + if (p !is null) + error("%s", p); + else + buffer.writeUTF16(c); + } + newlen = buffer.offset / 2; + buffer.writeUTF16(0); + goto L1; + + case X(TY.Tchar, TY.Tdchar): + for (size_t u = 0; u < len;) + { + dchar c; + string p = utf_decodeChar(cast(string)se.string_[0..len], &u, &c); + if (p !is null) + error("%s", p); + buffer.write4(c); + newlen++; + } + buffer.write4(0); + goto L1; + + case X(TY.Twchar,TY.Tchar): + for (size_t u = 0; u < len;) + { + dchar c; + string p = utf_decodeWchar(cast(wstring)se.string_[0..len], &u, &c); + if (p) + error("%s", p); + else + buffer.writeUTF8(c); + } + newlen = buffer.offset; + buffer.writeUTF8(0); + goto L1; + + case X(TY.Twchar,TY.Tdchar): + for (size_t u = 0; u < len;) + { + dchar c; + string p = utf_decodeWchar(cast(wstring)se.string_[0..len], &u, &c); + if (p) + error("%s", p); + buffer.write4(c); + newlen++; + } + buffer.write4(0); + goto L1; + + case X(TY.Tdchar,TY.Tchar): + for (size_t u = 0; u < len; u++) + { + dchar c = (cast(dchar*)se.string_)[u]; + if (!utf_isValidDchar(c)) + error("invalid UCS-32 char \\U%08x", c); + else + buffer.writeUTF8(c); + newlen++; + } + newlen = buffer.offset; + buffer.writeUTF8(0); + goto L1; + + case X(TY.Tdchar,TY.Twchar): + for (size_t u = 0; u < len; u++) + { + dchar c = (cast(dchar*)se.string_)[u]; + if (!utf_isValidDchar(c)) + error("invalid UCS-32 char \\U%08x", c); + else + buffer.writeUTF16(c); + newlen++; + } + newlen = buffer.offset / 2; + buffer.writeUTF16(0); + goto L1; + + L1: + if (!copied) + { + se = cast(StringExp)copy(); + copied = 1; + } + se.string_ = buffer.extractData(); + se.len = newlen; + se.sz = cast(ubyte)tb.nextOf().size(); + break; + + default: + assert(typeb.nextOf().size() != tb.nextOf().size()); + goto Lcast; + } + } + L2: + assert(copied); + + // See if need to truncate or extend the literal + if (tb.ty == TY.Tsarray) + { + int dim2 = cast(int)(cast(TypeSArray)tb).dim.toInteger(); + + //printf("dim from = %d, to = %d\n", se.len, dim2); + + // Changing dimensions + if (dim2 != se.len) + { + // Copy when changing the string literal + uint newsz = se.sz; + void *s; + int d; + + d = (dim2 < se.len) ? dim2 : se.len; + s = cast(ubyte*)GC.malloc((dim2 + 1) * newsz); + memcpy(s, se.string_, d * newsz); + // Extend with 0, add terminating 0 + memset(cast(char*)s + d * newsz, 0, (dim2 + 1 - d) * newsz); + se.string_ = s; + se.len = dim2; + } + } + se.type = t; + return se; + + Lcast: + Expression e = new CastExp(loc, se, t); + e.type = t; // so semantic() won't be run on e return e; } @@ -520,151 +521,151 @@ elem* toElem(IRState* irs) { - elem* e; - Type tb = type.toBasetype(); - -static if (false) { - printf("StringExp.toElem() %s, type = %s\n", toChars(), type.toChars()); -} - - if (tb.ty == TY.Tarray) - { - Symbol* si; - dt_t* dt; - StringTab* st; - -static if (false) { - printf("irs.m = %p\n", irs.m); - printf(" m = %s\n", irs.m.toChars()); - printf(" len = %d\n", len); - printf(" sz = %d\n", sz); -} - for (size_t i = 0; i < STSIZE; i++) - { - st = &stringTab[(stidx + i) % STSIZE]; - //if (!st.m) continue; - //printf(" st.m = %s\n", st.m.toChars()); - //printf(" st.len = %d\n", st.len); - //printf(" st.sz = %d\n", st.sz); - if (st.m is irs.m && - st.si && - st.len == len && - st.sz == sz && - memcmp(st.string_, string_, sz * len) == 0) - { - //printf("use cached value\n"); - si = st.si; // use cached value - goto L1; - } - } - - stidx = (stidx + 1) % STSIZE; - st = &stringTab[stidx]; - - dt = null; - toDt(&dt); - - si = symbol_generate(SC.SCstatic, type_fake(TYM.TYdarray)); - si.Sdt = dt; - si.Sfl = FL.FLdata; -version (ELFOBJ) {// Burton - si.Sseg = Segment.CDATA; -} -version (MACHOBJ) { - si.Sseg = Segment.DATA; -} - outdata(si); - - st.m = irs.m; - st.si = si; - st.string_ = string_; - st.len = len; - st.sz = sz; - L1: - e = el_var(si); - } - else if (tb.ty == TY.Tsarray) - { - Symbol *si; - dt_t *dt = null; - - toDt(&dt); - dtnzeros(&dt, sz); // leave terminating 0 - - si = symbol_generate(SC.SCstatic,type_allocn(TYM.TYarray, tschar)); - si.Sdt = dt; - si.Sfl = FL.FLdata; - -version (ELFOBJ_OR_MACHOBJ) { // Burton - si.Sseg = Segment.CDATA; - } - outdata(si); - - e = el_var(si); - } - else if (tb.ty == TY.Tpointer) - { - e = el_calloc(); - e.Eoper = OPER.OPstring; -static if (true) { - // Match MEM_PH_FREE for OPstring in ztc\el.c - e.EV.ss.Vstring = cast(char*)GC.malloc((len + 1) * sz); - memcpy(e.EV.ss.Vstring, string_, (len + 1) * sz); -} else { - e.EV.ss.Vstring = cast(char*)string_; -} - e.EV.ss.Vstrlen = (len + 1) * sz; - e.Ety = TYM.TYnptr; - } - else - { - writef("type is %s\n", type.toChars()); - assert(0); - } - el_setLoc(e,loc); + elem* e; + Type tb = type.toBasetype(); + +static if (false) { + printf("StringExp.toElem() %s, type = %s\n", toChars(), type.toChars()); +} + + if (tb.ty == TY.Tarray) + { + Symbol* si; + dt_t* dt; + StringTab* st; + +static if (false) { + printf("irs.m = %p\n", irs.m); + printf(" m = %s\n", irs.m.toChars()); + printf(" len = %d\n", len); + printf(" sz = %d\n", sz); +} + for (size_t i = 0; i < STSIZE; i++) + { + st = &stringTab[(stidx + i) % STSIZE]; + //if (!st.m) continue; + //printf(" st.m = %s\n", st.m.toChars()); + //printf(" st.len = %d\n", st.len); + //printf(" st.sz = %d\n", st.sz); + if (st.m is irs.m && + st.si && + st.len == len && + st.sz == sz && + memcmp(st.string_, string_, sz * len) == 0) + { + //printf("use cached value\n"); + si = st.si; // use cached value + goto L1; + } + } + + stidx = (stidx + 1) % STSIZE; + st = &stringTab[stidx]; + + dt = null; + toDt(&dt); + + si = symbol_generate(SC.SCstatic, type_fake(TYM.TYdarray)); + si.Sdt = dt; + si.Sfl = FL.FLdata; +version (ELFOBJ) {// Burton + si.Sseg = Segment.CDATA; +} +version (MACHOBJ) { + si.Sseg = Segment.DATA; +} + outdata(si); + + st.m = irs.m; + st.si = si; + st.string_ = string_; + st.len = len; + st.sz = sz; + L1: + e = el_var(si); + } + else if (tb.ty == TY.Tsarray) + { + Symbol *si; + dt_t *dt = null; + + toDt(&dt); + dtnzeros(&dt, sz); // leave terminating 0 + + si = symbol_generate(SC.SCstatic,type_allocn(TYM.TYarray, tschar)); + si.Sdt = dt; + si.Sfl = FL.FLdata; + +version (ELFOBJ_OR_MACHOBJ) { // Burton + si.Sseg = Segment.CDATA; + } + outdata(si); + + e = el_var(si); + } + else if (tb.ty == TY.Tpointer) + { + e = el_calloc(); + e.Eoper = OPER.OPstring; +static if (true) { + // Match MEM_PH_FREE for OPstring in ztc\el.c + e.EV.ss.Vstring = cast(char*)malloc((len + 1) * sz); /// ! + memcpy(e.EV.ss.Vstring, string_, (len + 1) * sz); +} else { + e.EV.ss.Vstring = cast(char*)string_; +} + e.EV.ss.Vstrlen = (len + 1) * sz; + e.Ety = TYM.TYnptr; + } + else + { + writef("type is %s\n", type.toChars()); + assert(0); + } + el_setLoc(e,loc); return e; } dt_t** toDt(dt_t** pdt) { - //printf("StringExp.toDt() '%s', type = %s\n", toChars(), type.toChars()); - Type t = type.toBasetype(); - - // BUG: should implement some form of static string pooling - switch (t.ty) - { - case TY.Tarray: - dtdword(pdt, len); - pdt = dtabytes(pdt, TYM.TYnptr, 0, (len + 1) * sz, cast(char*)string_); - break; - - case TY.Tsarray: - { - TypeSArray tsa = cast(TypeSArray)type; - long dim; - - pdt = dtnbytes(pdt, len * sz, cast(const(char)*)string_); - if (tsa.dim) - { - dim = tsa.dim.toInteger(); - if (len < dim) - { - // Pad remainder with 0 - pdt = dtnzeros(pdt, cast(uint)((dim - len) * tsa.next.size())); - } - } - break; - } - - case TY.Tpointer: - pdt = dtabytes(pdt, TYM.TYnptr, 0, (len + 1) * sz, cast(char*)string_); - break; - - default: - writef("StringExp.toDt(type = %s)\n", type.toChars()); - assert(0); - } - + //printf("StringExp.toDt() '%s', type = %s\n", toChars(), type.toChars()); + Type t = type.toBasetype(); + + // BUG: should implement some form of static string pooling + switch (t.ty) + { + case TY.Tarray: + dtdword(pdt, len); + pdt = dtabytes(pdt, TYM.TYnptr, 0, (len + 1) * sz, cast(char*)string_); + break; + + case TY.Tsarray: + { + TypeSArray tsa = cast(TypeSArray)type; + long dim; + + pdt = dtnbytes(pdt, len * sz, cast(const(char)*)string_); + if (tsa.dim) + { + dim = tsa.dim.toInteger(); + if (len < dim) + { + // Pad remainder with 0 + pdt = dtnzeros(pdt, cast(uint)((dim - len) * tsa.next.size())); + } + } + break; + } + + case TY.Tpointer: + pdt = dtabytes(pdt, TYM.TYnptr, 0, (len + 1) * sz, cast(char*)string_); + break; + + default: + writef("StringExp.toDt(type = %s)\n", type.toChars()); + assert(0); + } + return pdt; } } diff -r d706d958e4e8 -r 63623152e82a dmd/SwitchErrorStatement.d --- a/dmd/SwitchErrorStatement.d Mon Oct 26 16:28:19 2009 +0300 +++ b/dmd/SwitchErrorStatement.d Tue Dec 08 21:39:17 2009 +0300 @@ -5,29 +5,46 @@ import dmd.Loc; import dmd.IRState; import dmd.HdrGenState; -import dmd.BE; +import dmd.BE; + +import dmd.backend.elem; +import dmd.backend.Blockx; +import dmd.backend.Util; +import dmd.backend.TYM; +import dmd.backend.OPER; +import dmd.backend.RTLSYM; class SwitchErrorStatement : Statement { this(Loc loc) { - assert(false); super(loc); } BE blockExit() { - assert(false); + return BE.BEthrow; } void toCBuffer(OutBuffer buf, HdrGenState* hgs) { - assert(false); + buf.writestring("SwitchErrorStatement.toCBuffer()"); + buf.writenl(); } void toIR(IRState* irs) { - assert(false); + elem* e; + elem* elinnum; + elem* efilename; + Blockx* blx = irs.blx; + + //printf("SwitchErrorStatement.toIR()\n"); + + efilename = blx.module_.toEmodulename(); + elinnum = el_long(TYM.TYint, loc.linnum); + e = el_bin(OPER.OPcall, TYM.TYvoid, el_var(rtlsym[RTLSYM_DSWITCHERR]), el_param(elinnum, efilename)); + block_appendexp(blx.curblock, e); } } diff -r d706d958e4e8 -r 63623152e82a dmd/SwitchStatement.d --- a/dmd/SwitchStatement.d Mon Oct 26 16:28:19 2009 +0300 +++ b/dmd/SwitchStatement.d Tue Dec 08 21:39:17 2009 +0300 @@ -49,6 +49,8 @@ import core.memory; +import core.stdc.stdlib; + class SwitchStatement : Statement { Expression condition; @@ -408,7 +410,8 @@ block_appendexp(mystate.switchBlock, econd); block_next(blx,BCswitch,null); - targ_llong* pu = cast(targ_llong*) GC.malloc(targ_llong.sizeof * (numcases + 1)); + /// + targ_llong* pu = cast(targ_llong*) malloc(targ_llong.sizeof * (numcases + 1)); mystate.switchBlock.Bswitch = pu; /* First pair is the number of cases, and the default block */ diff -r d706d958e4e8 -r 63623152e82a dmd/backend/Util.d --- a/dmd/backend/Util.d Mon Oct 26 16:28:19 2009 +0300 +++ b/dmd/backend/Util.d Tue Dec 08 21:39:17 2009 +0300 @@ -19,6 +19,8 @@ import dmd.backend.code; import std.string; +import core.stdc.stdlib; +import core.stdc.string; alias ubyte mangle_t; @@ -51,7 +53,10 @@ alias elem* elem_p; // data type big enough for type masks void el_setLoc(elem* e, Loc loc) { - e.Esrcpos.Sfilename = cast(char*)toStringz(loc.filename); + size_t len = loc.filename.length; + e.Esrcpos.Sfilename = cast(char*)malloc(len + 1); + memcpy(e.Esrcpos.Sfilename, loc.filename.ptr, len); + e.Esrcpos.Sfilename[len] = 0; e.Esrcpos.Slinnum = loc.linnum; } diff -r d706d958e4e8 -r 63623152e82a dmd/backend/block.d --- a/dmd/backend/block.d Mon Oct 26 16:28:19 2009 +0300 +++ b/dmd/backend/block.d Tue Dec 08 21:39:17 2009 +0300 @@ -150,4 +150,13 @@ /// BFLlooprt = 0x40, // set if looprotate() changes it's Bnext ///} BFLvolatile = 0x4000, // block is volatile +} + +void dump_block(block* foo) +{ + foreach (a, b; foo.tupleof) + { + std.stdio.writeln(foo.tupleof[a].stringof, " ", cast(char*)&foo.tupleof[a] - cast(char*)foo, " = ", foo.tupleof[a]); + //std.stdio.writeln("printf(\"", foo.tupleof[a].stringof, " %d = %d\\n\",(char*)(&", foo.tupleof[a].stringof, ")-(char*)foo, ", foo.tupleof[a].stringof, ");"); + } } \ No newline at end of file diff -r d706d958e4e8 -r 63623152e82a dmd/backend/iasm.d --- a/dmd/backend/iasm.d Mon Oct 26 16:28:19 2009 +0300 +++ b/dmd/backend/iasm.d Tue Dec 08 21:39:17 2009 +0300 @@ -45,6 +45,7 @@ import core.stdc.stdio : printf; import core.stdc.string : strlen; +import core.stdc.stdlib : realloc; import core.stdc.limits; import std.bitmanip; @@ -1872,7 +1873,7 @@ if (usBytes+usSize > usMaxbytes) { usMaxbytes = usBytes + usSize + 10; - c.IEV1.as.bytes = cast(char*)GC.realloc(c.IEV1.as.bytes,usMaxbytes); + c.IEV1.as.bytes = cast(char*)realloc(c.IEV1.as.bytes,usMaxbytes); } switch (tok_value) { @@ -1932,7 +1933,7 @@ if (len) { usMaxbytes += len * usSize; - c.IEV1.as.bytes = cast(char*)GC.realloc(c.IEV1.as.bytes,usMaxbytes); + c.IEV1.as.bytes = cast(char*)realloc(c.IEV1.as.bytes,usMaxbytes); memcpy(c.IEV1.as.bytes + usBytes,asmtok.ustring,len); char* p = c.IEV1.as.bytes + usBytes; diff -r d706d958e4e8 -r 63623152e82a dmd/codegen/Util.d --- a/dmd/codegen/Util.d Mon Oct 26 16:28:19 2009 +0300 +++ b/dmd/codegen/Util.d Tue Dec 08 21:39:17 2009 +0300 @@ -54,6 +54,7 @@ import std.string; import core.stdc.string; +import core.stdc.stdlib; import core.memory; @@ -999,7 +1000,7 @@ es.Eoper = OPER.OPstring; // Match MEM_PH_FREE for OPstring in ztc\el.c - es.EV.ss.Vstring = cast(char*)GC.malloc(len); /// + es.EV.ss.Vstring = cast(char*)malloc(len); /// ! memcpy(es.EV.ss.Vstring, &e.EV, len); es.EV.ss.Vstrlen = len;