threads compile again; attempt to fix serious code gen issue (except + return)
This commit is contained in:
parent
c8d270268a
commit
728328eec2
4 changed files with 25 additions and 17 deletions
|
|
@ -117,7 +117,7 @@ proc genIfStmt(p: BProc, n: PNode) =
|
||||||
else: internalError(n.info, "genIfStmt()")
|
else: internalError(n.info, "genIfStmt()")
|
||||||
if sonsLen(n) > 1: fixLabel(p, Lend)
|
if sonsLen(n) > 1: fixLabel(p, Lend)
|
||||||
|
|
||||||
proc popSafePoints(p: BProc, howMany: int) =
|
proc blockLeaveActions(p: BProc, howMany: int) =
|
||||||
var L = p.nestedTryStmts.len
|
var L = p.nestedTryStmts.len
|
||||||
# danger of endless recursion! we workaround this here by a temp stack
|
# danger of endless recursion! we workaround this here by a temp stack
|
||||||
var stack: seq[PNode]
|
var stack: seq[PNode]
|
||||||
|
|
@ -134,10 +134,12 @@ proc popSafePoints(p: BProc, howMany: int) =
|
||||||
# push old elements again:
|
# push old elements again:
|
||||||
for i in countdown(howMany-1, 0):
|
for i in countdown(howMany-1, 0):
|
||||||
p.nestedTryStmts.add(stack[i])
|
p.nestedTryStmts.add(stack[i])
|
||||||
|
for i in countdown(p.popCurrExc-1, 0):
|
||||||
|
appcg(p, cpsStmts, "#popCurrentException();$n", [])
|
||||||
|
|
||||||
proc genReturnStmt(p: BProc, t: PNode) =
|
proc genReturnStmt(p: BProc, t: PNode) =
|
||||||
p.beforeRetNeeded = true
|
p.beforeRetNeeded = true
|
||||||
popSafePoints(p, min(1, p.nestedTryStmts.len))
|
blockLeaveActions(p, min(1, p.nestedTryStmts.len))
|
||||||
genLineDir(p, t)
|
genLineDir(p, t)
|
||||||
if (t.sons[0].kind != nkEmpty): genStmts(p, t.sons[0])
|
if (t.sons[0].kind != nkEmpty): genStmts(p, t.sons[0])
|
||||||
appff(p.s[cpsStmts], "goto BeforeRet;$n", "br label %BeforeRet$n", [])
|
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)
|
assert(sym.loc.k == locOther)
|
||||||
idx = sym.loc.a
|
idx = sym.loc.a
|
||||||
p.blocks[idx].id = abs(p.blocks[idx].id) # label is used
|
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)
|
genLineDir(p, t)
|
||||||
appf(p.s[cpsStmts], "goto LA$1;$n", [toRope(p.blocks[idx].id)])
|
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)
|
add(p.nestedTryStmts, t)
|
||||||
genStmts(p, t.sons[0])
|
genStmts(p, t.sons[0])
|
||||||
appcg(p, cpsStmts, "#popSafePoint();$n} else {$n#popSafePoint();$n")
|
appcg(p, cpsStmts, "#popSafePoint();$n} else {$n#popSafePoint();$n")
|
||||||
|
discard pop(p.nestedTryStmts)
|
||||||
var i = 1
|
var i = 1
|
||||||
while (i < length) and (t.sons[i].kind == nkExceptBranch):
|
while (i < length) and (t.sons[i].kind == nkExceptBranch):
|
||||||
var blen = sonsLen(t.sons[i])
|
var blen = sonsLen(t.sons[i])
|
||||||
if blen == 1:
|
if blen == 1:
|
||||||
# general except section:
|
# general except section:
|
||||||
if i > 1: appf(p.s[cpsStmts], "else {$n")
|
if i > 1: appf(p.s[cpsStmts], "else {$n")
|
||||||
|
inc p.popCurrExc
|
||||||
genStmts(p, t.sons[i].sons[0])
|
genStmts(p, t.sons[i].sons[0])
|
||||||
|
dec p.popCurrExc
|
||||||
appcg(p, cpsStmts, "$1.status = 0;#popCurrentException();$n", [safePoint])
|
appcg(p, cpsStmts, "$1.status = 0;#popCurrentException();$n", [safePoint])
|
||||||
if i > 1: appf(p.s[cpsStmts], "}$n")
|
if i > 1: appf(p.s[cpsStmts], "}$n")
|
||||||
else:
|
else:
|
||||||
|
inc p.popCurrExc
|
||||||
var orExpr: PRope = nil
|
var orExpr: PRope = nil
|
||||||
for j in countup(0, blen - 2):
|
for j in countup(0, blen - 2):
|
||||||
assert(t.sons[i].sons[j].kind == nkType)
|
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)])
|
[genTypeInfo(p.module, t.sons[i].sons[j].typ)])
|
||||||
if i > 1: app(p.s[cpsStmts], "else ")
|
if i > 1: app(p.s[cpsStmts], "else ")
|
||||||
appf(p.s[cpsStmts], "if ($1) {$n", [orExpr])
|
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:
|
# code to clear the exception:
|
||||||
appcg(p, cpsStmts, "$1.status = 0;#popCurrentException();}$n",
|
appcg(p, cpsStmts, "$1.status = 0;#popCurrentException();}$n",
|
||||||
[safePoint])
|
[safePoint])
|
||||||
inc(i)
|
inc(i)
|
||||||
appf(p.s[cpsStmts], "}$n") # end of if statement
|
appf(p.s[cpsStmts], "}$n") # end of if statement
|
||||||
discard pop(p.nestedTryStmts)
|
|
||||||
if i < length and t.sons[i].kind == nkFinally:
|
if i < length and t.sons[i].kind == nkFinally:
|
||||||
genStmts(p, t.sons[i].sons[0])
|
genStmts(p, t.sons[i].sons[0])
|
||||||
appcg(p, cpsStmts, "if ($1.status != 0) #reraiseException();$n", [safePoint])
|
appcg(p, cpsStmts, "if ($1.status != 0) #reraiseException();$n", [safePoint])
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,8 @@ type
|
||||||
ThreadVarAccessed*: bool # true if the proc already accessed some threadvar
|
ThreadVarAccessed*: bool # true if the proc already accessed some threadvar
|
||||||
nestedTryStmts*: seq[PNode] # in how many nested try statements we are
|
nestedTryStmts*: seq[PNode] # in how many nested try statements we are
|
||||||
# (the vars must be volatile then)
|
# (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
|
labels*: Natural # for generating unique labels in the C proc
|
||||||
blocks*: seq[TBlock] # nested blocks
|
blocks*: seq[TBlock] # nested blocks
|
||||||
options*: TOptions # options that should be used for code
|
options*: TOptions # options that should be used for code
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ type
|
||||||
ready: bool
|
ready: bool
|
||||||
region: TMemRegion
|
region: TMemRegion
|
||||||
PRawChannel = ptr TRawChannel
|
PRawChannel = ptr TRawChannel
|
||||||
TLoadStoreMode = enum mStore, mLoad
|
TLoadStoreMode = enum mStore, mLoad
|
||||||
TChannel*[TMsg] = TRawChannel ## a channel for thread communication
|
TChannel*[TMsg] = TRawChannel ## a channel for thread communication
|
||||||
|
|
||||||
const ChannelDeadMask = -2
|
const ChannelDeadMask = -2
|
||||||
|
|
@ -45,7 +45,7 @@ proc deinitRawChannel(p: pointer) =
|
||||||
deinitSys(c.lock)
|
deinitSys(c.lock)
|
||||||
deinitSysCond(c.cond)
|
deinitSysCond(c.cond)
|
||||||
|
|
||||||
proc storeAux(dest, src: Pointer, mt: PNimType, t: PRawChannel,
|
proc storeAux(dest, src: Pointer, mt: PNimType, t: PRawChannel,
|
||||||
mode: TLoadStoreMode)
|
mode: TLoadStoreMode)
|
||||||
proc storeAux(dest, src: Pointer, n: ptr TNimNode, t: PRawChannel,
|
proc storeAux(dest, src: Pointer, n: ptr TNimNode, t: PRawChannel,
|
||||||
mode: TLoadStoreMode) =
|
mode: TLoadStoreMode) =
|
||||||
|
|
@ -62,14 +62,14 @@ proc storeAux(dest, src: Pointer, n: ptr TNimNode, t: PRawChannel,
|
||||||
n.typ.size)
|
n.typ.size)
|
||||||
var m = selectBranch(src, n)
|
var m = selectBranch(src, n)
|
||||||
if m != nil: storeAux(dest, src, m, t, mode)
|
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,
|
proc storeAux(dest, src: Pointer, mt: PNimType, t: PRawChannel,
|
||||||
mode: TLoadStoreMode) =
|
mode: TLoadStoreMode) =
|
||||||
var
|
var
|
||||||
d = cast[TAddress](dest)
|
d = cast[TAddress](dest)
|
||||||
s = cast[TAddress](src)
|
s = cast[TAddress](src)
|
||||||
sysAssert(mt != nil)
|
sysAssert(mt != nil, "mt == nil")
|
||||||
case mt.Kind
|
case mt.Kind
|
||||||
of tyString:
|
of tyString:
|
||||||
if mode == mStore:
|
if mode == mStore:
|
||||||
|
|
@ -100,7 +100,7 @@ proc storeAux(dest, src: Pointer, mt: PNimType, t: PRawChannel,
|
||||||
else:
|
else:
|
||||||
unsureAsgnRef(x, nil)
|
unsureAsgnRef(x, nil)
|
||||||
else:
|
else:
|
||||||
sysAssert(dest != nil)
|
sysAssert(dest != nil, "dest == nil")
|
||||||
if mode == mStore:
|
if mode == mStore:
|
||||||
x[] = Alloc(t.region, seq.len *% mt.base.size +% GenericSeqSize)
|
x[] = Alloc(t.region, seq.len *% mt.base.size +% GenericSeqSize)
|
||||||
else:
|
else:
|
||||||
|
|
@ -140,8 +140,8 @@ proc storeAux(dest, src: Pointer, mt: PNimType, t: PRawChannel,
|
||||||
if mode == mStore:
|
if mode == mStore:
|
||||||
x[] = Alloc(t.region, mt.base.size)
|
x[] = Alloc(t.region, mt.base.size)
|
||||||
else:
|
else:
|
||||||
# XXX we should use the dynamic type here too, but that is not stored
|
# 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
|
# in the inbox at all --> use source[]'s object type? but how? we need
|
||||||
# a tyRef to the object!
|
# a tyRef to the object!
|
||||||
var obj = newObj(mt.base, mt.base.size)
|
var obj = newObj(mt.base, mt.base.size)
|
||||||
unsureAsgnRef(x, obj)
|
unsureAsgnRef(x, obj)
|
||||||
|
|
@ -237,8 +237,8 @@ proc close*[TMsg](c: var TChannel[TMsg]) =
|
||||||
deinitRawChannel(addr(c))
|
deinitRawChannel(addr(c))
|
||||||
|
|
||||||
proc ready*[TMsg](c: var TChannel[TMsg]): bool =
|
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.
|
## new messages.
|
||||||
var q = cast[PRawChannel](addr(c))
|
var q = cast[PRawChannel](addr(c))
|
||||||
result = q.ready
|
result = q.ready
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -221,7 +221,7 @@ when not defined(useNimRtl):
|
||||||
t.prev = nil
|
t.prev = nil
|
||||||
t.next = threadList
|
t.next = threadList
|
||||||
if threadList != nil:
|
if threadList != nil:
|
||||||
sysAssert(threadList.prev == nil)
|
sysAssert(threadList.prev == nil, "threadList.prev == nil")
|
||||||
threadList.prev = t
|
threadList.prev = t
|
||||||
threadList = t
|
threadList = t
|
||||||
ReleaseSys(HeapLock)
|
ReleaseSys(HeapLock)
|
||||||
|
|
@ -315,7 +315,7 @@ proc joinThreads*[TArg](t: openArray[TThread[TArg]]) =
|
||||||
## waits for every thread in `t` to finish.
|
## waits for every thread in `t` to finish.
|
||||||
when hostOS == "windows":
|
when hostOS == "windows":
|
||||||
var a: array[0..255, TSysThread]
|
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
|
for i in 0..t.high: a[i] = t[i].sys
|
||||||
discard WaitForMultipleObjects(t.len, cast[ptr TSysThread](addr(a)), 1, -1)
|
discard WaitForMultipleObjects(t.len, cast[ptr TSysThread](addr(a)), 1, -1)
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue