diff options
Diffstat (limited to 'compiler/closureiters.nim')
-rw-r--r-- | compiler/closureiters.nim | 35 |
1 files changed, 20 insertions, 15 deletions
diff --git a/compiler/closureiters.nim b/compiler/closureiters.nim index 567bb3b91..48088a609 100644 --- a/compiler/closureiters.nim +++ b/compiler/closureiters.nim @@ -153,6 +153,7 @@ type curExcHandlingState: int # Negative for except, positive for finally nearestFinally: int # Index of the nearest finally block. For try/except it # is their finally. For finally it is parent finally. Otherwise -1 + idgen: IdGenerator const nkSkip = {nkEmpty..nkNilLit, nkTemplateDef, nkTypeSection, nkStaticStmt, @@ -176,7 +177,7 @@ proc newStateAssgn(ctx: var Ctx, stateNo: int = -2): PNode = ctx.newStateAssgn(newIntTypeNode(stateNo, ctx.g.getSysType(TLineInfo(), tyInt))) proc newEnvVar(ctx: var Ctx, name: string, typ: PType): PSym = - result = newSym(skVar, getIdent(ctx.g.cache, name), ctx.fn, ctx.fn.info) + result = newSym(skVar, getIdent(ctx.g.cache, name), nextId(ctx.idgen), ctx.fn, ctx.fn.info) result.typ = typ assert(not typ.isNil) @@ -189,7 +190,7 @@ proc newEnvVar(ctx: var Ctx, name: string, typ: PType): PSym = else: let envParam = getEnvParam(ctx.fn) # let obj = envParam.typ.lastSon - result = addUniqueField(envParam.typ.lastSon, result, ctx.g.cache) + result = addUniqueField(envParam.typ.lastSon, result, ctx.g.cache, ctx.idgen) proc newEnvVarAccess(ctx: Ctx, s: PSym): PNode = if ctx.stateVarSym.isNil: @@ -804,7 +805,7 @@ proc newEndFinallyNode(ctx: var Ctx, info: TLineInfo): PNode = cmp.typ = ctx.g.getSysType(info, tyBool) let asgn = newTree(nkFastAsgn, - newSymNode(getClosureIterResult(ctx.g, ctx.fn), info), + newSymNode(getClosureIterResult(ctx.g, ctx.fn, ctx.idgen), info), ctx.newTmpResultAccess()) let retStmt = newTree(nkReturnStmt, asgn) @@ -1044,7 +1045,7 @@ proc transformStateAssignments(ctx: var Ctx, n: PNode): PNode = if n[0][0].kind != nkEmpty: var a = newNodeI(nkAsgn, n[0][0].info) var retVal = n[0][0] #liftCapturedVars(n[0], owner, d, c) - a.add newSymNode(getClosureIterResult(ctx.g, ctx.fn)) + a.add newSymNode(getClosureIterResult(ctx.g, ctx.fn, ctx.idgen)) a.add retVal retStmt.add(a) else: @@ -1116,10 +1117,10 @@ proc skipThroughEmptyStates(ctx: var Ctx, n: PNode): PNode= for i in 0..<n.len: n[i] = ctx.skipThroughEmptyStates(n[i]) -proc newArrayType(g: ModuleGraph; n: int, t: PType, owner: PSym): PType = - result = newType(tyArray, owner) +proc newArrayType(g: ModuleGraph; n: int, t: PType; idgen: IdGenerator; owner: PSym): PType = + result = newType(tyArray, nextId(idgen), owner) - let rng = newType(tyRange, owner) + let rng = newType(tyRange, nextId(idgen), owner) rng.n = newTree(nkRange, g.newIntLit(owner.info, 0), g.newIntLit(owner.info, n)) rng.rawAddSon(t) @@ -1128,7 +1129,7 @@ proc newArrayType(g: ModuleGraph; n: int, t: PType, owner: PSym): PType = proc createExceptionTable(ctx: var Ctx): PNode {.inline.} = result = newNodeI(nkBracket, ctx.fn.info) - result.typ = ctx.g.newArrayType(ctx.exceptionTable.len, ctx.g.getSysType(ctx.fn.info, tyInt16), ctx.fn) + result.typ = ctx.g.newArrayType(ctx.exceptionTable.len, ctx.g.getSysType(ctx.fn.info, tyInt16), ctx.idgen, ctx.fn) for i in ctx.exceptionTable: let elem = newIntNode(nkIntLit, i) @@ -1289,10 +1290,12 @@ type finallys: seq[PNode] config: ConfigRef blocks: seq[(PNode, int)] + idgen: IdGenerator FreshVarsContext = object tab: Table[int, PSym] config: ConfigRef info: TLineInfo + idgen: IdGenerator proc freshVars(n: PNode; c: var FreshVarsContext): PNode = case n.kind @@ -1311,7 +1314,7 @@ proc freshVars(n: PNode; c: var FreshVarsContext): PNode = let idefs = copyNode(it) for v in 0..it.len-3: if it[v].kind == nkSym: - let x = copySym(it[v].sym) + let x = copySym(it[v].sym, nextId(c.idgen)) c.tab[it[v].sym.id] = x idefs.add newSymNode(x) else: @@ -1371,27 +1374,29 @@ proc preprocess(c: var PreprocessContext; n: PNode): PNode = if fin >= 0: result = newNodeI(nkStmtList, n.info) for i in countdown(c.finallys.high, fin): - var vars = FreshVarsContext(tab: initTable[int, PSym](), config: c.config, info: n.info) + var vars = FreshVarsContext(tab: initTable[int, PSym](), config: c.config, info: n.info, idgen: c.idgen) result.add freshVars(preprocess(c, c.finallys[i]), vars) + c.idgen = vars.idgen result.add n of nkSkip: discard else: for i in 0 ..< n.len: result[i] = preprocess(c, n[i]) -proc transformClosureIterator*(g: ModuleGraph; fn: PSym, n: PNode): PNode = +proc transformClosureIterator*(g: ModuleGraph; idgen: IdGenerator; fn: PSym, n: PNode): PNode = var ctx: Ctx ctx.g = g ctx.fn = fn + ctx.idgen = idgen if getEnvParam(fn).isNil: # Lambda lifting was not done yet. Use temporary :state sym, which will # be handled specially by lambda lifting. Local temp vars (if needed) # should follow 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 pc = PreprocessContext(finallys: @[], config: g.config) + ctx.stateVarSym = newSym(skVar, getIdent(ctx.g.cache, ":state"), nextId(idgen), fn, fn.info) + ctx.stateVarSym.typ = g.createClosureIterStateType(fn, idgen) + ctx.stateLoopLabel = newSym(skLabel, getIdent(ctx.g.cache, ":stateLoop"), nextId(idgen), fn, fn.info) + var pc = PreprocessContext(finallys: @[], config: g.config, idgen: idgen) var n = preprocess(pc, n.toStmtList) #echo "transformed into ", n #var n = n.toStmtList |