Fixes 9716 [backport] (#9790)
* reuse temporary variable * fixes #9716 [backport] * Declare local vars in safer place
This commit is contained in:
parent
47d0582ebf
commit
410fd1deae
4 changed files with 30 additions and 14 deletions
|
|
@ -307,11 +307,13 @@ proc genSingleVar(p: BProc, a: PNode) =
|
||||||
|
|
||||||
proc genClosureVar(p: BProc, a: PNode) =
|
proc genClosureVar(p: BProc, a: PNode) =
|
||||||
var immediateAsgn = a.sons[2].kind != nkEmpty
|
var immediateAsgn = a.sons[2].kind != nkEmpty
|
||||||
if immediateAsgn:
|
|
||||||
var v: TLoc
|
var v: TLoc
|
||||||
initLocExpr(p, a.sons[0], v)
|
initLocExpr(p, a.sons[0], v)
|
||||||
genLineDir(p, a)
|
genLineDir(p, a)
|
||||||
|
if immediateAsgn:
|
||||||
loadInto(p, a.sons[0], a.sons[2], v)
|
loadInto(p, a.sons[0], a.sons[2], v)
|
||||||
|
else:
|
||||||
|
constructLoc(p, v)
|
||||||
|
|
||||||
proc genVarStmt(p: BProc, n: PNode) =
|
proc genVarStmt(p: BProc, n: PNode) =
|
||||||
for it in n.sons:
|
for it in n.sons:
|
||||||
|
|
|
||||||
|
|
@ -1009,7 +1009,7 @@ proc stateFromGotoState(n: PNode): int =
|
||||||
assert(n.kind == nkGotoState)
|
assert(n.kind == nkGotoState)
|
||||||
result = n[0].intVal.int
|
result = n[0].intVal.int
|
||||||
|
|
||||||
proc tranformStateAssignments(ctx: var Ctx, n: PNode): PNode =
|
proc transformStateAssignments(ctx: var Ctx, n: PNode): PNode =
|
||||||
# This transforms 3 patterns:
|
# This transforms 3 patterns:
|
||||||
########################## 1
|
########################## 1
|
||||||
# yield e
|
# yield e
|
||||||
|
|
@ -1051,7 +1051,7 @@ proc tranformStateAssignments(ctx: var Ctx, n: PNode): PNode =
|
||||||
result.add(retStmt)
|
result.add(retStmt)
|
||||||
else:
|
else:
|
||||||
for i in 0 ..< n.len:
|
for i in 0 ..< n.len:
|
||||||
n[i] = ctx.tranformStateAssignments(n[i])
|
n[i] = ctx.transformStateAssignments(n[i])
|
||||||
|
|
||||||
of nkSkip:
|
of nkSkip:
|
||||||
discard
|
discard
|
||||||
|
|
@ -1071,7 +1071,7 @@ proc tranformStateAssignments(ctx: var Ctx, n: PNode): PNode =
|
||||||
|
|
||||||
else:
|
else:
|
||||||
for i in 0 ..< n.len:
|
for i in 0 ..< n.len:
|
||||||
n[i] = ctx.tranformStateAssignments(n[i])
|
n[i] = ctx.transformStateAssignments(n[i])
|
||||||
|
|
||||||
proc skipStmtList(ctx: Ctx; n: PNode): PNode =
|
proc skipStmtList(ctx: Ctx; n: PNode): PNode =
|
||||||
result = n
|
result = n
|
||||||
|
|
@ -1220,18 +1220,20 @@ proc wrapIntoStateLoop(ctx: var Ctx, n: PNode): PNode =
|
||||||
# while true:
|
# while true:
|
||||||
# block :stateLoop:
|
# block :stateLoop:
|
||||||
# gotoState :state
|
# gotoState :state
|
||||||
|
# local vars decl (if needed)
|
||||||
# body # Might get wrapped in try-except
|
# body # Might get wrapped in try-except
|
||||||
let loopBody = newNodeI(nkStmtList, n.info)
|
let loopBody = newNodeI(nkStmtList, n.info)
|
||||||
result = newTree(nkWhileStmt, newSymNode(ctx.g.getSysSym(n.info, "true")), loopBody)
|
result = newTree(nkWhileStmt, newSymNode(ctx.g.getSysSym(n.info, "true")), loopBody)
|
||||||
result.info = n.info
|
result.info = n.info
|
||||||
|
|
||||||
|
let localVars = newNodeI(nkStmtList, n.info)
|
||||||
if not ctx.stateVarSym.isNil:
|
if not ctx.stateVarSym.isNil:
|
||||||
let varSect = newNodeI(nkVarSection, n.info)
|
let varSect = newNodeI(nkVarSection, n.info)
|
||||||
addVar(varSect, newSymNode(ctx.stateVarSym))
|
addVar(varSect, newSymNode(ctx.stateVarSym))
|
||||||
loopBody.add(varSect)
|
localVars.add(varSect)
|
||||||
|
|
||||||
if not ctx.tempVars.isNil:
|
if not ctx.tempVars.isNil:
|
||||||
loopBody.add(ctx.tempVars)
|
localVars.add(ctx.tempVars)
|
||||||
|
|
||||||
let blockStmt = newNodeI(nkBlockStmt, n.info)
|
let blockStmt = newNodeI(nkBlockStmt, n.info)
|
||||||
blockStmt.add(newSymNode(ctx.stateLoopLabel))
|
blockStmt.add(newSymNode(ctx.stateLoopLabel))
|
||||||
|
|
@ -1240,7 +1242,7 @@ proc wrapIntoStateLoop(ctx: var Ctx, n: PNode): PNode =
|
||||||
gs.add(ctx.newStateAccess())
|
gs.add(ctx.newStateAccess())
|
||||||
gs.add(ctx.g.newIntLit(n.info, ctx.states.len - 1))
|
gs.add(ctx.g.newIntLit(n.info, ctx.states.len - 1))
|
||||||
|
|
||||||
var blockBody = newTree(nkStmtList, gs, n)
|
var blockBody = newTree(nkStmtList, gs, localVars, n)
|
||||||
if ctx.hasExceptions:
|
if ctx.hasExceptions:
|
||||||
blockBody = ctx.wrapIntoTryExcept(blockBody)
|
blockBody = ctx.wrapIntoTryExcept(blockBody)
|
||||||
|
|
||||||
|
|
@ -1292,7 +1294,6 @@ proc transformClosureIterator*(g: ModuleGraph; fn: PSym, n: PNode): PNode =
|
||||||
# should folllow the same logic.
|
# should folllow the same logic.
|
||||||
ctx.stateVarSym = newSym(skVar, getIdent(ctx.g.cache, ":state"), fn, fn.info)
|
ctx.stateVarSym = newSym(skVar, getIdent(ctx.g.cache, ":state"), fn, fn.info)
|
||||||
ctx.stateVarSym.typ = g.createClosureIterStateType(fn)
|
ctx.stateVarSym.typ = g.createClosureIterStateType(fn)
|
||||||
|
|
||||||
ctx.stateLoopLabel = newSym(skLabel, getIdent(ctx.g.cache, ":stateLoop"), fn, fn.info)
|
ctx.stateLoopLabel = newSym(skLabel, getIdent(ctx.g.cache, ":stateLoop"), fn, fn.info)
|
||||||
var n = n.toStmtList
|
var n = n.toStmtList
|
||||||
|
|
||||||
|
|
@ -1320,7 +1321,7 @@ proc transformClosureIterator*(g: ModuleGraph; fn: PSym, n: PNode): PNode =
|
||||||
result.add(s)
|
result.add(s)
|
||||||
result.add(body)
|
result.add(body)
|
||||||
|
|
||||||
result = ctx.tranformStateAssignments(result)
|
result = ctx.transformStateAssignments(result)
|
||||||
result = ctx.wrapIntoStateLoop(result)
|
result = ctx.wrapIntoStateLoop(result)
|
||||||
|
|
||||||
# echo "TRANSFORM TO STATES: "
|
# echo "TRANSFORM TO STATES: "
|
||||||
|
|
|
||||||
|
|
@ -218,7 +218,7 @@ when defineSsl:
|
||||||
var data = await recv(socket.fd.AsyncFD, BufferSize, flags)
|
var data = await recv(socket.fd.AsyncFD, BufferSize, flags)
|
||||||
let length = len(data)
|
let length = len(data)
|
||||||
if length > 0:
|
if length > 0:
|
||||||
let ret = bioWrite(socket.bioIn, addr data[0], data.len.cint)
|
let ret = bioWrite(socket.bioIn, addr data[0], length.cint)
|
||||||
if ret < 0:
|
if ret < 0:
|
||||||
raiseSSLError()
|
raiseSSLError()
|
||||||
elif length == 0:
|
elif length == 0:
|
||||||
|
|
|
||||||
|
|
@ -454,5 +454,18 @@ block: #9694 - yield in ObjConstr
|
||||||
|
|
||||||
test(it, 1, 2)
|
test(it, 1, 2)
|
||||||
|
|
||||||
|
block: #9716
|
||||||
|
iterator it(): int {.closure.} =
|
||||||
|
var a = 0
|
||||||
|
for i in 1 .. 3:
|
||||||
|
var a: int # Make sure the "local" var is reset
|
||||||
|
var b: string # ditto
|
||||||
|
yield 1
|
||||||
|
a += 5
|
||||||
|
b &= "hello"
|
||||||
|
doAssert(a == 5)
|
||||||
|
doAssert(b == "hello")
|
||||||
|
test(it, 1, 1, 1)
|
||||||
|
|
||||||
echo "ok"
|
echo "ok"
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue