threads compile again; attempt to fix serious code gen issue (except + return)

This commit is contained in:
Araq
2011-12-03 19:22:01 +01:00
parent c8d270268a
commit 728328eec2
4 changed files with 25 additions and 17 deletions

View File

@@ -117,7 +117,7 @@ proc genIfStmt(p: BProc, n: PNode) =
else: internalError(n.info, "genIfStmt()")
if sonsLen(n) > 1: fixLabel(p, Lend)
proc popSafePoints(p: BProc, howMany: int) =
proc blockLeaveActions(p: BProc, howMany: int) =
var L = p.nestedTryStmts.len
# danger of endless recursion! we workaround this here by a temp stack
var stack: seq[PNode]
@@ -134,10 +134,12 @@ proc popSafePoints(p: BProc, howMany: int) =
# push old elements again:
for i in countdown(howMany-1, 0):
p.nestedTryStmts.add(stack[i])
for i in countdown(p.popCurrExc-1, 0):
appcg(p, cpsStmts, "#popCurrentException();$n", [])
proc genReturnStmt(p: BProc, t: PNode) =
p.beforeRetNeeded = true
popSafePoints(p, min(1, p.nestedTryStmts.len))
blockLeaveActions(p, min(1, p.nestedTryStmts.len))
genLineDir(p, t)
if (t.sons[0].kind != nkEmpty): genStmts(p, t.sons[0])
appff(p.s[cpsStmts], "goto BeforeRet;$n", "br label %BeforeRet$n", [])
@@ -196,7 +198,7 @@ proc genBreakStmt(p: BProc, t: PNode) =
assert(sym.loc.k == locOther)
idx = sym.loc.a
p.blocks[idx].id = abs(p.blocks[idx].id) # label is used
popSafePoints(p, p.nestedTryStmts.len - p.blocks[idx].nestedTryStmts)
blockLeaveActions(p, p.nestedTryStmts.len - p.blocks[idx].nestedTryStmts)
genLineDir(p, t)
appf(p.s[cpsStmts], "goto LA$1;$n", [toRope(p.blocks[idx].id)])
@@ -510,16 +512,20 @@ proc genTryStmt(p: BProc, t: PNode) =
add(p.nestedTryStmts, t)
genStmts(p, t.sons[0])
appcg(p, cpsStmts, "#popSafePoint();$n} else {$n#popSafePoint();$n")
discard pop(p.nestedTryStmts)
var i = 1
while (i < length) and (t.sons[i].kind == nkExceptBranch):
var blen = sonsLen(t.sons[i])
if blen == 1:
# general except section:
if i > 1: appf(p.s[cpsStmts], "else {$n")
inc p.popCurrExc
genStmts(p, t.sons[i].sons[0])
dec p.popCurrExc
appcg(p, cpsStmts, "$1.status = 0;#popCurrentException();$n", [safePoint])
if i > 1: appf(p.s[cpsStmts], "}$n")
else:
else:
inc p.popCurrExc
var orExpr: PRope = nil
for j in countup(0, blen - 2):
assert(t.sons[i].sons[j].kind == nkType)
@@ -529,13 +535,13 @@ proc genTryStmt(p: BProc, t: PNode) =
[genTypeInfo(p.module, t.sons[i].sons[j].typ)])
if i > 1: app(p.s[cpsStmts], "else ")
appf(p.s[cpsStmts], "if ($1) {$n", [orExpr])
genStmts(p, t.sons[i].sons[blen-1])
genStmts(p, t.sons[i].sons[blen-1])
dec p.popCurrExc
# code to clear the exception:
appcg(p, cpsStmts, "$1.status = 0;#popCurrentException();}$n",
[safePoint])
inc(i)
appf(p.s[cpsStmts], "}$n") # end of if statement
discard pop(p.nestedTryStmts)
if i < length and t.sons[i].kind == nkFinally:
genStmts(p, t.sons[i].sons[0])
appcg(p, cpsStmts, "if ($1.status != 0) #reraiseException();$n", [safePoint])

View File

@@ -60,6 +60,8 @@ type
ThreadVarAccessed*: bool # true if the proc already accessed some threadvar
nestedTryStmts*: seq[PNode] # in how many nested try statements we are
# (the vars must be volatile then)
popCurrExc*: Natural # how often to emit 'popCurrentException()'
# before 'break'|'return'
labels*: Natural # for generating unique labels in the C proc
blocks*: seq[TBlock] # nested blocks
options*: TOptions # options that should be used for code

View File

@@ -25,7 +25,7 @@ type
ready: bool
region: TMemRegion
PRawChannel = ptr TRawChannel
TLoadStoreMode = enum mStore, mLoad
TLoadStoreMode = enum mStore, mLoad
TChannel*[TMsg] = TRawChannel ## a channel for thread communication
const ChannelDeadMask = -2
@@ -45,7 +45,7 @@ proc deinitRawChannel(p: pointer) =
deinitSys(c.lock)
deinitSysCond(c.cond)
proc storeAux(dest, src: Pointer, mt: PNimType, t: PRawChannel,
proc storeAux(dest, src: Pointer, mt: PNimType, t: PRawChannel,
mode: TLoadStoreMode)
proc storeAux(dest, src: Pointer, n: ptr TNimNode, t: PRawChannel,
mode: TLoadStoreMode) =
@@ -62,14 +62,14 @@ proc storeAux(dest, src: Pointer, n: ptr TNimNode, t: PRawChannel,
n.typ.size)
var m = selectBranch(src, n)
if m != nil: storeAux(dest, src, m, t, mode)
of nkNone: sysAssert(false)
of nkNone: sysAssert(false, "storeAux")
proc storeAux(dest, src: Pointer, mt: PNimType, t: PRawChannel,
mode: TLoadStoreMode) =
var
d = cast[TAddress](dest)
s = cast[TAddress](src)
sysAssert(mt != nil)
sysAssert(mt != nil, "mt == nil")
case mt.Kind
of tyString:
if mode == mStore:
@@ -100,7 +100,7 @@ proc storeAux(dest, src: Pointer, mt: PNimType, t: PRawChannel,
else:
unsureAsgnRef(x, nil)
else:
sysAssert(dest != nil)
sysAssert(dest != nil, "dest == nil")
if mode == mStore:
x[] = Alloc(t.region, seq.len *% mt.base.size +% GenericSeqSize)
else:
@@ -140,8 +140,8 @@ proc storeAux(dest, src: Pointer, mt: PNimType, t: PRawChannel,
if mode == mStore:
x[] = Alloc(t.region, mt.base.size)
else:
# XXX we should use the dynamic type here too, but that is not stored
# in the inbox at all --> use source[]'s object type? but how? we need
# XXX we should use the dynamic type here too, but that is not stored
# in the inbox at all --> use source[]'s object type? but how? we need
# a tyRef to the object!
var obj = newObj(mt.base, mt.base.size)
unsureAsgnRef(x, obj)
@@ -237,8 +237,8 @@ proc close*[TMsg](c: var TChannel[TMsg]) =
deinitRawChannel(addr(c))
proc ready*[TMsg](c: var TChannel[TMsg]): bool =
## returns true iff some thread is waiting on the channel `c` for
## returns true iff some thread is waiting on the channel `c` for
## new messages.
var q = cast[PRawChannel](addr(c))
result = q.ready

View File

@@ -221,7 +221,7 @@ when not defined(useNimRtl):
t.prev = nil
t.next = threadList
if threadList != nil:
sysAssert(threadList.prev == nil)
sysAssert(threadList.prev == nil, "threadList.prev == nil")
threadList.prev = t
threadList = t
ReleaseSys(HeapLock)
@@ -315,7 +315,7 @@ proc joinThreads*[TArg](t: openArray[TThread[TArg]]) =
## waits for every thread in `t` to finish.
when hostOS == "windows":
var a: array[0..255, TSysThread]
sysAssert a.len >= t.len
sysAssert a.len >= t.len, "a.len >= t.len"
for i in 0..t.high: a[i] = t[i].sys
discard WaitForMultipleObjects(t.len, cast[ptr TSysThread](addr(a)), 1, -1)
else: