workaround bug #374441

This commit is contained in:
Andreas Rumpf
2009-05-11 17:34:48 +02:00
parent a74f4ff6af
commit e90ec5a461
5 changed files with 59 additions and 78 deletions

View File

@@ -103,9 +103,7 @@ proc extGetCellType(c: pointer): PNimType {.compilerproc.} =
result = usrToCell(c).typ
proc internRefcount(p: pointer): int {.exportc: "getRefcount".} =
result = int(usrToCell(p).refcount)
if result > 0: result = result shr rcShift
else: result = 0
result = int(usrToCell(p).refcount) shr rcShift
proc GC_disable() = inc(recGcLock)
proc GC_enable() =
@@ -488,11 +486,12 @@ proc stackSize(): int {.noinline.} =
result = abs(cast[int](addr(stackTop[0])) - cast[int](stackBottom))
when defined(sparc): # For SPARC architecture.
proc isOnStack(p: pointer): bool =
var
stackTop: array[0..1, pointer]
result = p >= addr(stackTop[0]) and p <= stackBottom
var stackTop: array [0..1, pointer]
var b = cast[TAddress](stackBottom)
var a = cast[TAddress](addr(stackTop[0]))
var x = cast[TAddress](p)
result = x >=% a and x <=% b
proc markStackAndRegisters(gch: var TGcHeap) {.noinline, cdecl.} =
when defined(sparcv9):
@@ -518,11 +517,12 @@ elif defined(hppa) or defined(hp9000) or defined(hp9000s300) or
# ---------------------------------------------------------------------------
# Generic code for architectures where addresses increase as the stack grows.
# ---------------------------------------------------------------------------
proc isOnStack(p: pointer): bool =
var
stackTop: array[0..1, pointer]
result = p <= addr(stackTop[0]) and p >= stackBottom
var stackTop: array [0..1, pointer]
var a = cast[TAddress](stackBottom)
var b = cast[TAddress](addr(stackTop[0]))
var x = cast[TAddress](p)
result = x >=% a and x <=% b
var
jmpbufSize {.importc: "sizeof(jmp_buf)", nodecl.}: int
@@ -530,45 +530,38 @@ elif defined(hppa) or defined(hp9000) or defined(hp9000s300) or
# in a platform independant way
proc markStackAndRegisters(gch: var TGcHeap) {.noinline, cdecl.} =
var
max = stackBottom
registers: C_JmpBuf # The jmp_buf buffer is in the C stack.
sp: PPointer # Used to traverse the stack and registers assuming
# that `setjmp' will save registers in the C stack.
if c_setjmp(registers) == 0: # To fill the C stack with registers.
sp = cast[ppointer](cast[TAddress](addr(registers)) +%
jmpbufSize -% sizeof(pointer))
var registers: C_JmpBuf
if c_setjmp(registers) == 0'i32: # To fill the C stack with registers.
var max = cast[TAddress](stackBottom)
var sp = cast[TAddress](addr(registers)) +% jmpbufSize -% sizeof(pointer)
# sp will traverse the JMP_BUF as well (jmp_buf size is added,
# otherwise sp would be below the registers structure).
while sp >= max:
gcMark(sp^)
sp = cast[ppointer](cast[TAddress](sp) -% sizeof(pointer))
while sp >=% max:
gcMark(cast[ppointer](sp)^)
sp = sp -% sizeof(pointer)
else:
# ---------------------------------------------------------------------------
# Generic code for architectures where addresses decrease as the stack grows.
# ---------------------------------------------------------------------------
proc isOnStack(p: pointer): bool =
var
stackTop: array [0..1, pointer]
result = p >= addr(stackTop[0]) and p <= stackBottom
var
jmpbufSize {.importc: "sizeof(jmp_buf)", nodecl.}: int
# a little hack to get the size of a TJmpBuf in the generated C code
# in a platform independant way
var stackTop: array [0..1, pointer]
var b = cast[TAddress](stackBottom)
var a = cast[TAddress](addr(stackTop[0]))
var x = cast[TAddress](p)
result = x >=% a and x <=% b
proc markStackAndRegisters(gch: var TGcHeap) {.noinline, cdecl.} =
var
max = stackBottom
registers: C_JmpBuf # The jmp_buf buffer is in the C stack.
sp: PPointer # Used to traverse the stack and registers assuming
# that 'setjmp' will save registers in the C stack.
# We use a jmp_buf buffer that is in the C stack.
# Used to traverse the stack and registers assuming
# that 'setjmp' will save registers in the C stack.
var registers: C_JmpBuf
if c_setjmp(registers) == 0'i32: # To fill the C stack with registers.
sp = cast[ppointer](addr(registers))
while sp <= max:
gcMark(sp^)
sp = cast[ppointer](cast[TAddress](sp) +% sizeof(pointer))
var max = cast[TAddress](stackBottom)
var sp = cast[TAddress](addr(registers))
while sp <=% max:
gcMark(cast[ppointer](sp)^)
sp = sp +% sizeof(pointer)
# ----------------------------------------------------------------------------
# end of non-portable code

View File

@@ -1108,8 +1108,7 @@ procedure genStrConcat(p: BProc; e: PNode; var d: TLoc);
// asgn(s, tmp0);
// }
var
tmp: TLoc;
a: array of TLoc;
a, tmp: TLoc;
appends, lens: PRope;
L, i: int;
begin
@@ -1118,25 +1117,21 @@ begin
L := 0;
appends := nil;
lens := nil;
{@ignore}
setLength(a, sonsLen(e)-1);
{@emit
newSeq(a, sonsLen(e)-1); }
for i := 0 to sonsLen(e)-2 do begin
// compute the length expression:
initLocExpr(p, e.sons[i+1], a[i]);
initLocExpr(p, e.sons[i+1], a);
if skipVarGenericRange(e.sons[i+1].Typ).kind = tyChar then begin
Inc(L);
useMagic(p.module, 'appendChar');
appf(appends, 'appendChar($1, $2);$n', [tmp.r, rdLoc(a[i])])
appf(appends, 'appendChar($1, $2);$n', [tmp.r, rdLoc(a)])
end
else begin
if e.sons[i+1].kind in [nkStrLit..nkTripleStrLit] then // string literal?
Inc(L, length(e.sons[i+1].strVal))
else
appf(lens, '$1->Sup.len + ', [rdLoc(a[i])]);
appf(lens, '$1->Sup.len + ', [rdLoc(a)]);
useMagic(p.module, 'appendString');
appf(appends, 'appendString($1, $2);$n', [tmp.r, rdLoc(a[i])])
appf(appends, 'appendString($1, $2);$n', [tmp.r, rdLoc(a)])
end
end;
appf(p.s[cpsStmts], '$1 = rawNewString($2$3);$n',
@@ -1161,7 +1156,7 @@ procedure genStrAppend(p: BProc; e: PNode; var d: TLoc);
// appendChar(s, 'z');
// }
var
a: array of TLoc;
a, dest: TLoc;
L, i: int;
appends, lens: PRope;
begin
@@ -1170,32 +1165,28 @@ begin
L := 0;
appends := nil;
lens := nil;
{@ignore}
setLength(a, sonsLen(e)-1);
{@emit
newSeq(a, sonsLen(e)-1); }
expr(p, e.sons[1], a[0]);
initLocExpr(p, e.sons[1], dest);
for i := 0 to sonsLen(e)-3 do begin
// compute the length expression:
initLocExpr(p, e.sons[i+2], a[i+1]);
initLocExpr(p, e.sons[i+2], a);
if skipVarGenericRange(e.sons[i+2].Typ).kind = tyChar then begin
Inc(L);
useMagic(p.module, 'appendChar');
appf(appends, 'appendChar($1, $2);$n',
[rdLoc(a[0]), rdLoc(a[i+1])])
[rdLoc(dest), rdLoc(a)])
end
else begin
if e.sons[i+2].kind in [nkStrLit..nkTripleStrLit] then // string literal?
Inc(L, length(e.sons[i+2].strVal))
else
appf(lens, '$1->Sup.len + ', [rdLoc(a[i+1])]);
appf(lens, '$1->Sup.len + ', [rdLoc(a)]);
useMagic(p.module, 'appendString');
appf(appends, 'appendString($1, $2);$n',
[rdLoc(a[0]), rdLoc(a[i+1])])
[rdLoc(dest), rdLoc(a)])
end
end;
appf(p.s[cpsStmts], '$1 = resizeString($1, $2$3);$n',
[rdLoc(a[0]), lens, toRope(L)]);
[rdLoc(dest), lens, toRope(L)]);
app(p.s[cpsStmts], appends);
end;
@@ -1548,8 +1539,7 @@ end;
procedure genInOp(p: BProc; e: PNode; var d: TLoc);
var
a, b: TLoc;
c: array of TLoc; // Generate code for the 'in' operator
a, b, x, y: TLoc;
len, i: int;
begin
if (e.sons[1].Kind = nkCurly) and fewCmps(e.sons[1]) then begin
@@ -1559,22 +1549,18 @@ begin
initLoc(b, locExpr, e.typ, OnUnknown);
b.r := toRope('('+'');
len := sonsLen(e.sons[1]);
{@emit c := @[];}
for i := 0 to len-1 do begin
if e.sons[1].sons[i].Kind = nkRange then begin
setLength(c, length(c)+2);
InitLocExpr(p, e.sons[1].sons[i].sons[0], c[high(c)-1]);
InitLocExpr(p, e.sons[1].sons[i].sons[1], c[high(c)]);
InitLocExpr(p, e.sons[1].sons[i].sons[0], x);
InitLocExpr(p, e.sons[1].sons[i].sons[1], y);
appf(b.r, '$1 >= $2 && $1 <= $3',
[rdCharLoc(a), rdCharLoc(c[high(c)-1]), rdCharLoc(c[high(c)])])
[rdCharLoc(a), rdCharLoc(x), rdCharLoc(y)])
end
else begin
setLength(c, length(c)+1);
InitLocExpr(p, e.sons[1].sons[i], c[high(c)]);
appf(b.r, '$1 == $2', [rdCharLoc(a), rdCharLoc(c[high(c)])])
InitLocExpr(p, e.sons[1].sons[i], x);
appf(b.r, '$1 == $2', [rdCharLoc(a), rdCharLoc(x)])
end;
if i < len - 1 then
app(b.r, ' || ')
if i < len - 1 then app(b.r, ' || ')
end;
app(b.r, ')'+'');
putIntoDest(p, d, e.typ, b.r);

View File

@@ -801,18 +801,18 @@ begin
if optCompileOnly in gGlobalOptions then
result := ropeff(
'/* Generated by the Nimrod Compiler v$1 */$n' +
'/* (c) 2008 Andreas Rumpf */$n',
'/* (c) 2009 Andreas Rumpf */$n',
'; Generated by the Nimrod Compiler v$1$n' +
'; (c) 2008 Andreas Rumpf$n',
'; (c) 2009 Andreas Rumpf$n',
[toRope(versionAsString)])
else
result := ropeff(
'/* Generated by the Nimrod Compiler v$1 */$n' +
'/* (c) 2008 Andreas Rumpf */$n' +
'/* (c) 2009 Andreas Rumpf */$n' +
'/* Compiled for: $2, $3, $4 */$n' +
'/* Command for C compiler:$n $5 */$n',
'; Generated by the Nimrod Compiler v$1$n' +
'; (c) 2008 Andreas Rumpf$n' +
'; (c) 2009 Andreas Rumpf$n' +
'; Compiled for: $2, $3, $4$n' +
'; Command for C compiler:$n $5$n',
[toRope(versionAsString), toRope(platform.OS[targetOS].name),

View File

@@ -5,7 +5,7 @@
@if llvm_gcc or gcc:
# GCC, LLVM and Visual C++ have a problem to optimize some modules.
# This is really strange.
cgen.speed = "-O0"
# cgen.speed = "-O0"
@elif vcc:
cgen.speed = ""
# cgen.speed = ""
@end

View File

@@ -11,6 +11,8 @@ Plan
Bugs
----
- BUG: seq[TLoc] in C code generator always failed --> probably some reference
counting is wrong; try to reproduce this in the GC test
- BUG: returning an array does not work --> see md5.nim module
- BUG: if not nodeOfDegree(g, 1) >= 0: inc(counter)
- BUG: the parser allows empty object case branches