mirror of
https://github.com/nim-lang/Nim.git
synced 2026-02-12 22:33:49 +00:00
workaround bug #374441
This commit is contained in:
71
lib/gc.nim
71
lib/gc.nim
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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
|
||||
|
||||
2
todo.txt
2
todo.txt
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user