diff options
author | rec <44084068+recloser@users.noreply.github.com> | 2018-12-20 08:24:57 +0100 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2018-12-20 08:24:57 +0100 |
commit | ca18dc2505d3e3429860bef89d7e6a353cf935de (patch) | |
tree | 80f79e8838619ae7b527161f82bdff3c118fb727 /compiler | |
parent | cd65e5328dc82ca74a2905641a12e2c84a82d1de (diff) | |
download | Nim-ca18dc2505d3e3429860bef89d7e6a353cf935de.tar.gz |
Make copies for params which are captured in closures. Fixes #7048 (#10050)
* Copy params which are captured in closures. Fixes #7048 * Forgot to emit a newline; minor adjustments to the test
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/jsgen.nim | 20 |
1 files changed, 19 insertions, 1 deletions
diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim index cd51aaddd..daaa145e1 100644 --- a/compiler/jsgen.nim +++ b/compiler/jsgen.nim @@ -94,6 +94,7 @@ type options: TOptions module: BModule g: PGlobals + generatedParamCopies: IntSet beforeRetNeeded: bool unique: int # for temp identifier generation blocks: seq[TBlock] @@ -924,7 +925,7 @@ const proc needsNoCopy(p: PProc; y: PNode): bool = return y.kind in nodeKindsNeedNoCopy or - (mapType(y.typ) != etyBaseIndex and + ((mapType(y.typ) != etyBaseIndex or y.sym.kind == skParam) and (skipTypes(y.typ, abstractInst).kind in {tyRef, tyPtr, tyLent, tyVar, tyCString, tyProc} + IntegralTypes)) @@ -1232,12 +1233,29 @@ proc genProcForSymIfNeeded(p: PProc, s: PSym) = if owner != nil: add(owner.locals, newp) else: attachProc(p, newp, s) +proc genCopyForParamIfNeeded(p: PProc, n: PNode) = + let s = n.sym + if p.prc == s.owner or needsNoCopy(p, n): + return + var owner = p.up + while true: + if owner == nil: + internalError(p.config, n.info, "couldn't find the owner proc of the closed over param: " & s.name.s) + if owner.prc == s.owner: + if not owner.generatedParamCopies.containsOrIncl(s.id): + let copy = "$1 = nimCopy(null, $1, $2);$n" % [s.loc.r, genTypeInfo(p, s.typ)] + add(owner.locals, owner.indentLine(copy)) + return + owner = owner.up + proc genSym(p: PProc, n: PNode, r: var TCompRes) = var s = n.sym case s.kind of skVar, skLet, skParam, skTemp, skResult, skForVar: if s.loc.r == nil: internalError(p.config, n.info, "symbol has no generated name: " & s.name.s) + if s.kind == skParam: + genCopyForParamIfNeeded(p, n) let k = mapType(p, s.typ) if k == etyBaseIndex: r.typ = etyBaseIndex |