diff options
author | recloser <44084068+recloser@users.noreply.github.com> | 2018-12-15 22:57:18 +0100 |
---|---|---|
committer | recloser <44084068+recloser@users.noreply.github.com> | 2018-12-15 22:57:18 +0100 |
commit | 19f5835d5c12b0ba77f58959b642c85cfdbba995 (patch) | |
tree | 7772c247923da6e7100140e8a3f88c59da6cd7d7 | |
parent | b53327c92a1c685ab71917cabedbf441f7f5fd2d (diff) | |
download | Nim-19f5835d5c12b0ba77f58959b642c85cfdbba995.tar.gz |
Fixes #10005
-rw-r--r-- | compiler/jsgen.nim | 49 | ||||
-rw-r--r-- | tests/js/testobjs.nim | 17 |
2 files changed, 33 insertions, 33 deletions
diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim index 4d22c4224..cd51aaddd 100644 --- a/compiler/jsgen.nim +++ b/compiler/jsgen.nim @@ -918,35 +918,15 @@ proc countJsParams(typ: PType): int = const nodeKindsNeedNoCopy = {nkCharLit..nkInt64Lit, nkStrLit..nkTripleStrLit, nkFloatLit..nkFloat64Lit, nkCurly, nkPar, nkStringToCString, + nkObjConstr, nkTupleConstr, nkBracket, nkCStringToString, nkCall, nkPrefix, nkPostfix, nkInfix, nkCommand, nkHiddenCallConv, nkCallStrLit} proc needsNoCopy(p: PProc; y: PNode): bool = - # if the node is a literal object constructor we have to recursively - # check the expressions passed into it - case y.kind - of nkObjConstr: - for arg in y.sons[1..^1]: - if not needsNoCopy(p, arg[1]): - return false - of nkTupleConstr: - for arg in y.sons: - var arg = arg - if arg.kind == nkExprColonExpr: - arg = arg[1] - if not needsNoCopy(p, arg): - return false - of nkBracket: - for arg in y.sons: - if not needsNoCopy(p, arg): - return false - of nodeKindsNeedNoCopy: - return true - else: - return (mapType(y.typ) != etyBaseIndex and - (skipTypes(y.typ, abstractInst).kind in - {tyRef, tyPtr, tyLent, tyVar, tyCString, tyProc} + IntegralTypes)) - return true + return y.kind in nodeKindsNeedNoCopy or + (mapType(y.typ) != etyBaseIndex and + (skipTypes(y.typ, abstractInst).kind in + {tyRef, tyPtr, tyLent, tyVar, tyCString, tyProc} + IntegralTypes)) proc genAsgnAux(p: PProc, x, y: PNode, noCopyNeeded: bool) = var a, b: TCompRes @@ -2005,6 +1985,10 @@ proc genArrayConstr(p: PProc, n: PNode, r: var TCompRes) = if a.typ == etyBaseIndex: addf(r.res, "[$1, $2]", [a.address, a.res]) else: + if not needsNoCopy(p, n[i]): + let typ = n[i].typ.skipTypes(abstractInst) + useMagic(p, "nimCopy") + a.res = "nimCopy(null, $1, $2)" % [a.rdLoc, genTypeInfo(p, typ)] add(r.res, a.res) add(r.res, "]") @@ -2017,9 +2001,13 @@ proc genTupleConstr(p: PProc, n: PNode, r: var TCompRes) = var it = n.sons[i] if it.kind == nkExprColonExpr: it = it.sons[1] gen(p, it, a) + let typ = it.typ.skipTypes(abstractInst) if a.typ == etyBaseIndex: addf(r.res, "Field$#: [$#, $#]", [i.rope, a.address, a.res]) else: + if not needsNoCopy(p, it): + useMagic(p, "nimCopy") + a.res = "nimCopy(null, $1, $2)" % [a.rdLoc, genTypeInfo(p, typ)] addf(r.res, "Field$#: $#", [i.rope, a.res]) r.res.add("}") @@ -2039,17 +2027,12 @@ proc genObjConstr(p: PProc, n: PNode, r: var TCompRes) = fieldIDs.incl(f.id) let typ = val.typ.skipTypes(abstractInst) - if (typ.kind in IntegralTypes+{tyCstring, tyRef, tyPtr} and - mapType(p, typ) != etyBaseIndex) or - a.typ == etyBaseIndex or - needsNoCopy(p, it.sons[1]): - discard - else: - useMagic(p, "nimCopy") - a.res = "nimCopy(null, $1, $2)" % [a.rdLoc, genTypeInfo(p, typ)] if a.typ == etyBaseIndex: addf(initList, "$#: [$#, $#]", [f.loc.r, a.address, a.res]) else: + if not needsNoCopy(p, val): + useMagic(p, "nimCopy") + a.res = "nimCopy(null, $1, $2)" % [a.rdLoc, genTypeInfo(p, typ)] addf(initList, "$#: $#", [f.loc.r, a.res]) let t = skipTypes(n.typ, abstractInst + skipPtrs) createObjInitList(p, t, fieldIDs, initList) diff --git a/tests/js/testobjs.nim b/tests/js/testobjs.nim index 78f0b4766..b61d06471 100644 --- a/tests/js/testobjs.nim +++ b/tests/js/testobjs.nim @@ -54,3 +54,20 @@ let test2 = test1 echo toJSON(test1) echo toJSON(test2) + +block issue10005: + type + Player = ref object of RootObj + id*: string + nickname*: string + color*: string + + proc newPlayer(nickname: string, color: string): Player = + let pl = Player(color: "#123", nickname: nickname) + return Player( + id: "foo", + nickname: nickname, + color: color, + ) + + doAssert newPlayer("foo", "#1232").nickname == "foo" |