workaround bug #374441

This commit is contained in:
Andreas Rumpf 2009-05-11 17:34:48 +02:00
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 result = usrToCell(c).typ
proc internRefcount(p: pointer): int {.exportc: "getRefcount".} = proc internRefcount(p: pointer): int {.exportc: "getRefcount".} =
result = int(usrToCell(p).refcount) result = int(usrToCell(p).refcount) shr rcShift
if result > 0: result = result shr rcShift
else: result = 0
proc GC_disable() = inc(recGcLock) proc GC_disable() = inc(recGcLock)
proc GC_enable() = proc GC_enable() =
@ -488,11 +486,12 @@ proc stackSize(): int {.noinline.} =
result = abs(cast[int](addr(stackTop[0])) - cast[int](stackBottom)) result = abs(cast[int](addr(stackTop[0])) - cast[int](stackBottom))
when defined(sparc): # For SPARC architecture. when defined(sparc): # For SPARC architecture.
proc isOnStack(p: pointer): bool = proc isOnStack(p: pointer): bool =
var var stackTop: array [0..1, pointer]
stackTop: array[0..1, pointer] var b = cast[TAddress](stackBottom)
result = p >= addr(stackTop[0]) and p <= 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.} = proc markStackAndRegisters(gch: var TGcHeap) {.noinline, cdecl.} =
when defined(sparcv9): 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. # Generic code for architectures where addresses increase as the stack grows.
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
proc isOnStack(p: pointer): bool = proc isOnStack(p: pointer): bool =
var var stackTop: array [0..1, pointer]
stackTop: array[0..1, pointer] var a = cast[TAddress](stackBottom)
result = p <= addr(stackTop[0]) and p >= stackBottom var b = cast[TAddress](addr(stackTop[0]))
var x = cast[TAddress](p)
result = x >=% a and x <=% b
var var
jmpbufSize {.importc: "sizeof(jmp_buf)", nodecl.}: int 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 # in a platform independant way
proc markStackAndRegisters(gch: var TGcHeap) {.noinline, cdecl.} = proc markStackAndRegisters(gch: var TGcHeap) {.noinline, cdecl.} =
var var registers: C_JmpBuf
max = stackBottom if c_setjmp(registers) == 0'i32: # To fill the C stack with registers.
registers: C_JmpBuf # The jmp_buf buffer is in the C stack. var max = cast[TAddress](stackBottom)
sp: PPointer # Used to traverse the stack and registers assuming var sp = cast[TAddress](addr(registers)) +% jmpbufSize -% sizeof(pointer)
# 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))
# sp will traverse the JMP_BUF as well (jmp_buf size is added, # sp will traverse the JMP_BUF as well (jmp_buf size is added,
# otherwise sp would be below the registers structure). # otherwise sp would be below the registers structure).
while sp >= max: while sp >=% max:
gcMark(sp^) gcMark(cast[ppointer](sp)^)
sp = cast[ppointer](cast[TAddress](sp) -% sizeof(pointer)) sp = sp -% sizeof(pointer)
else: else:
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
# Generic code for architectures where addresses decrease as the stack grows. # Generic code for architectures where addresses decrease as the stack grows.
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
proc isOnStack(p: pointer): bool = proc isOnStack(p: pointer): bool =
var var stackTop: array [0..1, pointer]
stackTop: array [0..1, pointer] var b = cast[TAddress](stackBottom)
result = p >= addr(stackTop[0]) and p <= stackBottom var a = cast[TAddress](addr(stackTop[0]))
var x = cast[TAddress](p)
var result = x >=% a and x <=% b
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
proc markStackAndRegisters(gch: var TGcHeap) {.noinline, cdecl.} = proc markStackAndRegisters(gch: var TGcHeap) {.noinline, cdecl.} =
var # We use a jmp_buf buffer that is in the C stack.
max = stackBottom # Used to traverse the stack and registers assuming
registers: C_JmpBuf # The jmp_buf buffer is in the C stack. # that 'setjmp' will save registers in the C stack.
sp: PPointer # Used to traverse the stack and registers assuming var registers: C_JmpBuf
# that 'setjmp' will save registers in the C stack.
if c_setjmp(registers) == 0'i32: # To fill the C stack with registers. if c_setjmp(registers) == 0'i32: # To fill the C stack with registers.
sp = cast[ppointer](addr(registers)) var max = cast[TAddress](stackBottom)
while sp <= max: var sp = cast[TAddress](addr(registers))
gcMark(sp^) while sp <=% max:
sp = cast[ppointer](cast[TAddress](sp) +% sizeof(pointer)) gcMark(cast[ppointer](sp)^)
sp = sp +% sizeof(pointer)
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# end of non-portable code # end of non-portable code

View file

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

View file

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

View file

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

View file

@ -11,6 +11,8 @@ Plan
Bugs 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: returning an array does not work --> see md5.nim module
- BUG: if not nodeOfDegree(g, 1) >= 0: inc(counter) - BUG: if not nodeOfDegree(g, 1) >= 0: inc(counter)
- BUG: the parser allows empty object case branches - BUG: the parser allows empty object case branches