diff options
-rw-r--r-- | compiler/jsgen.nim | 19 | ||||
-rw-r--r-- | tests/js/tseqops.nim | 51 |
2 files changed, 68 insertions, 2 deletions
diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim index be7443dac..b31c3a6a7 100644 --- a/compiler/jsgen.nim +++ b/compiler/jsgen.nim @@ -944,7 +944,15 @@ proc genAsgn(p: PProc, n: PNode) = proc genFastAsgn(p: PProc, n: PNode) = genLineDir(p, n) - genAsgnAux(p, n.sons[0], n.sons[1], noCopyNeeded=true) + # 'shallowCopy' always produced 'noCopyNeeded = true' here but this is wrong + # for code like + # while j >= pos: + # dest[i].shallowCopy(dest[j]) + # See bug #5933. So we try to be more compatible with the C backend semantics + # here for 'shallowCopy'. This is an educated guess and might require further + # changes later: + let noCopy = n[0].typ.skipTypes(abstractInst).kind in {tySequence, tyString} + genAsgnAux(p, n.sons[0], n.sons[1], noCopyNeeded=noCopy) proc genSwap(p: PProc, n: PNode) = var a, b: TCompRes @@ -1841,7 +1849,14 @@ proc genMagic(p: PProc, n: PNode, r: var TCompRes) = else: binaryExpr(p, n, r, "subInt", "$1 = subInt($1, $2)") of mSetLengthStr: binaryExpr(p, n, r, "", "$1.length = $2+1; $1[$1.length-1] = 0" | "$1 = substr($1, 0, $2)") - of mSetLengthSeq: binaryExpr(p, n, r, "", "$1.length = $2" | "$1 = array_slice($1, 0, $2)") + of mSetLengthSeq: + var x, y: TCompRes + gen(p, n.sons[1], x) + gen(p, n.sons[2], y) + let t = skipTypes(n.sons[1].typ, abstractVar).sons[0] + r.res = """if ($1.length < $2) { for (var i=$1.length;i<$2;++i) $1.push($3); } + else { $1.length = $2; }""" % [x.rdLoc, y.rdLoc, createVar(p, t, false)] + r.kind = resExpr of mCard: unaryExpr(p, n, r, "SetCard", "SetCard($1)") of mLtSet: binaryExpr(p, n, r, "SetLt", "SetLt($1, $2)") of mLeSet: binaryExpr(p, n, r, "SetLe", "SetLe($1, $2)") diff --git a/tests/js/tseqops.nim b/tests/js/tseqops.nim new file mode 100644 index 000000000..d10e1ca6a --- /dev/null +++ b/tests/js/tseqops.nim @@ -0,0 +1,51 @@ +discard """ + output: '''(x: 0, y: 0) +(x: 5, y: 0) +@[(x: 2, y: 4), (x: 4, y: 5), (x: 4, y: 5)] +@[(a: 3, b: 3), (a: 1, b: 1), (a: 2, b: 2)] +''' +""" + +# bug #4139 + +type + TestO = object + x, y: int + +proc onLoad() = + var test: seq[TestO] = @[] + var foo = TestO(x: 0, y: 0) + test.add(foo) + foo.x = 5 + echo(test[0]) + echo foo + +onLoad() + +# 'setLen' bug (part of bug #5933) +type MyObj = object + x: cstring + y: int + +proc foo(x: var seq[MyObj]) = + let L = x.len + x.setLen L + 1 + x[L] = x[1] + +var s = @[MyObj(x: "2", y: 4), MyObj(x: "4", y: 5)] +foo(s) +echo s + +# bug #5933 +import sequtils + +type + Test = object + a: cstring + b: int + +var test = @[Test(a: "1", b: 1), Test(a: "2", b: 2)] + +test.insert(@[Test(a: "3", b: 3)], 0) + +echo test |