diff options
-rw-r--r-- | compiler/ccgexprs.nim | 46 |
1 files changed, 39 insertions, 7 deletions
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index c50fd4536..15f7f0f34 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -212,22 +212,36 @@ proc optAsgnLoc(a: TLoc, t: PType, field: PRope): TLoc = result.heapRoot = a.heapRoot proc genOptAsgnTuple(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) = + let newflags = + if src.k == locData: + flags + { needToCopy } + elif tfShallow in dest.t.flags: + flags - { needToCopy } + else: + flags for i in 0 .. <dest.t.len: let t = dest.t.sons[i] let field = ropef("Field$1", i.toRope) genAssignment(p, optAsgnLoc(dest, t, field), - optAsgnLoc(src, t, field), flags) + optAsgnLoc(src, t, field), newflags) proc genOptAsgnObject(p: BProc, dest, src: TLoc, flags: TAssignmentFlags, t: PNode) = if t == nil: return + let newflags = + if src.k == locData: + flags + { needToCopy } + elif tfShallow in dest.t.flags: + flags - { needToCopy } + else: + flags case t.kind of nkSym: let field = t.sym genAssignment(p, optAsgnLoc(dest, field.typ, field.loc.r), - optAsgnLoc(src, field.typ, field.loc.r), flags) + optAsgnLoc(src, field.typ, field.loc.r), newflags) of nkRecList: - for child in items(t): genOptAsgnObject(p, dest, src, flags, child) + for child in items(t): genOptAsgnObject(p, dest, src, newflags, child) else: nil proc genGenericAsgn(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) = @@ -263,13 +277,13 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) = of tyRef: genRefAssign(p, dest, src, flags) of tySequence: - if needToCopy notin flags: + if needToCopy notin flags and src.k != locData: genRefAssign(p, dest, src, flags) else: linefmt(p, cpsStmts, "#genericSeqAssign($1, $2, $3);$n", addrLoc(dest), rdLoc(src), genTypeInfo(p.module, dest.t)) of tyString: - if needToCopy notin flags: + if needToCopy notin flags and src.k != locData: genRefAssign(p, dest, src, flags) else: if dest.s == OnStack or not usesNativeGC(): @@ -351,6 +365,22 @@ proc putLocIntoDest(p: BProc, d: var TLoc, s: TLoc) = else: d = s # ``d`` is free, so fill it with ``s`` +proc putDataIntoDest(p: BProc, d: var TLoc, t: PType, r: PRope) = + var a: TLoc + if d.k != locNone: + # need to generate an assignment here + initLoc(a, locData, getUniqueType(t), OnUnknown) + a.r = r + if lfNoDeepCopy in d.flags: genAssignment(p, d, a, {}) + else: genAssignment(p, d, a, {needToCopy}) + else: + # we cannot call initLoc() here as that would overwrite + # the flags field! + d.k = locData + d.t = getUniqueType(t) + d.r = r + d.a = -1 + proc putIntoDest(p: BProc, d: var TLoc, t: PType, r: PRope) = var a: TLoc if d.k != locNone: @@ -1766,7 +1796,7 @@ proc exprComplexConst(p: BProc, n: PNode, d: var TLoc) = if d.k == locNone: fillLoc(d, locData, t, tmp, OnHeap) else: - putIntoDest(p, d, t, tmp) + putDataIntoDest(p, d, t, tmp) proc expr(p: BProc, n: PNode, d: var TLoc) = case n.kind @@ -1820,7 +1850,9 @@ proc expr(p: BProc, n: PNode, d: var TLoc) = of nkNilLit: if not isEmptyType(n.typ): putIntoDest(p, d, n.typ, genLiteral(p, n)) - of nkStrLit..nkTripleStrLit, nkIntLit..nkUInt64Lit, + of nkStrLit..nkTripleStrLit: + putDataIntoDest(p, d, n.typ, genLiteral(p, n)) + of nkIntLit..nkUInt64Lit, nkFloatLit..nkFloat128Lit, nkCharLit: putIntoDest(p, d, n.typ, genLiteral(p, n)) of nkCall, nkHiddenCallConv, nkInfix, nkPrefix, nkPostfix, nkCommand, |