mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-29 01:14:41 +00:00
Fixes 9716 [backport] (#9790)
* reuse temporary variable * fixes #9716 [backport] * Declare local vars in safer place
This commit is contained in:
committed by
Andreas Rumpf
parent
47d0582ebf
commit
410fd1deae
@@ -307,11 +307,13 @@ proc genSingleVar(p: BProc, a: PNode) =
|
||||
|
||||
proc genClosureVar(p: BProc, a: PNode) =
|
||||
var immediateAsgn = a.sons[2].kind != nkEmpty
|
||||
var v: TLoc
|
||||
initLocExpr(p, a.sons[0], v)
|
||||
genLineDir(p, a)
|
||||
if immediateAsgn:
|
||||
var v: TLoc
|
||||
initLocExpr(p, a.sons[0], v)
|
||||
genLineDir(p, a)
|
||||
loadInto(p, a.sons[0], a.sons[2], v)
|
||||
else:
|
||||
constructLoc(p, v)
|
||||
|
||||
proc genVarStmt(p: BProc, n: PNode) =
|
||||
for it in n.sons:
|
||||
@@ -609,7 +611,7 @@ proc genRaiseStmt(p: BProc, t: PNode) =
|
||||
lineF(p, cpsStmts, "throw $1;$n", [e])
|
||||
else:
|
||||
lineCg(p, cpsStmts, "#raiseExceptionEx((#Exception*)$1, $2, $3, $4, $5);$n",
|
||||
[e, makeCString(typ.sym.name.s),
|
||||
[e, makeCString(typ.sym.name.s),
|
||||
makeCString(if p.prc != nil: p.prc.name.s else: p.module.module.name.s),
|
||||
makeCString(toFileName(p.config, t.info)), rope(toLinenumber(t.info))])
|
||||
else:
|
||||
|
||||
@@ -1009,7 +1009,7 @@ proc stateFromGotoState(n: PNode): int =
|
||||
assert(n.kind == nkGotoState)
|
||||
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:
|
||||
########################## 1
|
||||
# yield e
|
||||
@@ -1051,7 +1051,7 @@ proc tranformStateAssignments(ctx: var Ctx, n: PNode): PNode =
|
||||
result.add(retStmt)
|
||||
else:
|
||||
for i in 0 ..< n.len:
|
||||
n[i] = ctx.tranformStateAssignments(n[i])
|
||||
n[i] = ctx.transformStateAssignments(n[i])
|
||||
|
||||
of nkSkip:
|
||||
discard
|
||||
@@ -1071,7 +1071,7 @@ proc tranformStateAssignments(ctx: var Ctx, n: PNode): PNode =
|
||||
|
||||
else:
|
||||
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 =
|
||||
result = n
|
||||
@@ -1220,18 +1220,20 @@ proc wrapIntoStateLoop(ctx: var Ctx, n: PNode): PNode =
|
||||
# while true:
|
||||
# block :stateLoop:
|
||||
# gotoState :state
|
||||
# local vars decl (if needed)
|
||||
# body # Might get wrapped in try-except
|
||||
let loopBody = newNodeI(nkStmtList, n.info)
|
||||
result = newTree(nkWhileStmt, newSymNode(ctx.g.getSysSym(n.info, "true")), loopBody)
|
||||
result.info = n.info
|
||||
|
||||
let localVars = newNodeI(nkStmtList, n.info)
|
||||
if not ctx.stateVarSym.isNil:
|
||||
let varSect = newNodeI(nkVarSection, n.info)
|
||||
addVar(varSect, newSymNode(ctx.stateVarSym))
|
||||
loopBody.add(varSect)
|
||||
localVars.add(varSect)
|
||||
|
||||
if not ctx.tempVars.isNil:
|
||||
loopBody.add(ctx.tempVars)
|
||||
localVars.add(ctx.tempVars)
|
||||
|
||||
let blockStmt = newNodeI(nkBlockStmt, n.info)
|
||||
blockStmt.add(newSymNode(ctx.stateLoopLabel))
|
||||
@@ -1240,7 +1242,7 @@ proc wrapIntoStateLoop(ctx: var Ctx, n: PNode): PNode =
|
||||
gs.add(ctx.newStateAccess())
|
||||
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:
|
||||
blockBody = ctx.wrapIntoTryExcept(blockBody)
|
||||
|
||||
@@ -1292,7 +1294,6 @@ proc transformClosureIterator*(g: ModuleGraph; fn: PSym, n: PNode): PNode =
|
||||
# should folllow the same logic.
|
||||
ctx.stateVarSym = newSym(skVar, getIdent(ctx.g.cache, ":state"), fn, fn.info)
|
||||
ctx.stateVarSym.typ = g.createClosureIterStateType(fn)
|
||||
|
||||
ctx.stateLoopLabel = newSym(skLabel, getIdent(ctx.g.cache, ":stateLoop"), fn, fn.info)
|
||||
var n = n.toStmtList
|
||||
|
||||
@@ -1320,7 +1321,7 @@ proc transformClosureIterator*(g: ModuleGraph; fn: PSym, n: PNode): PNode =
|
||||
result.add(s)
|
||||
result.add(body)
|
||||
|
||||
result = ctx.tranformStateAssignments(result)
|
||||
result = ctx.transformStateAssignments(result)
|
||||
result = ctx.wrapIntoStateLoop(result)
|
||||
|
||||
# echo "TRANSFORM TO STATES: "
|
||||
|
||||
@@ -218,7 +218,7 @@ when defineSsl:
|
||||
var data = await recv(socket.fd.AsyncFD, BufferSize, flags)
|
||||
let length = len(data)
|
||||
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:
|
||||
raiseSSLError()
|
||||
elif length == 0:
|
||||
|
||||
@@ -403,7 +403,7 @@ block: # yield in blockexpr
|
||||
|
||||
test(it, 1, 2, 3)
|
||||
|
||||
block: #8851
|
||||
block: #8851
|
||||
type
|
||||
Foo = ref object of RootObj
|
||||
template someFoo(): Foo =
|
||||
@@ -454,5 +454,18 @@ block: #9694 - yield in ObjConstr
|
||||
|
||||
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"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user