diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim index 8abb830bd2..fd8ef583d0 100644 --- a/compiler/jsgen.nim +++ b/compiler/jsgen.nim @@ -2333,8 +2333,8 @@ proc genMagic(p: PProc, n: PNode, r: var TCompRes) = r.res = "if (null != $1) { if (null == $2) $2 = $3; else $2 += $3; }" % [b, lhs.rdLoc, tmp] else: - let (a, tmp) = maybeMakeTemp(p, n[1], lhs) - r.res = "$1.push.apply($3, $2);" % [a, rhs.rdLoc, tmp] + useMagic(p, "nimAddStrStr") + r.res = "nimAddStrStr($1, $2);" % [lhs.rdLoc, rhs.rdLoc] r.kind = resExpr of mAppendSeqElem: var x, y: TCompRes = default(TCompRes) diff --git a/lib/system/jssys.nim b/lib/system/jssys.nim index 6934e67ee4..b469c4695f 100644 --- a/lib/system/jssys.nim +++ b/lib/system/jssys.nim @@ -687,6 +687,14 @@ proc isObj(obj, subclass: PNimType): bool {.compilerproc.} = proc addChar(x: string, c: char) {.compilerproc, asmNoStackFrame.} = {.emit: "`x`.push(`c`);".} +proc nimAddStrStr(x, y: string) {.compilerproc, asmNoStackFrame.} = + {.emit: """ + var L = `y`.length; + for (var i = 0; i < L; ++i) { + `x`.push(`y`[i]); + } + """.} + {.pop.} proc tenToThePowerOf(b: int): BiggestFloat = diff --git a/tests/system/tconcat.nim b/tests/system/tconcat.nim index fdce3ea00d..8cf995c938 100644 --- a/tests/system/tconcat.nim +++ b/tests/system/tconcat.nim @@ -1,11 +1,33 @@ discard """ - output: "DabcD" + targets: "c cpp js" + output: ''' +DabcD +(8192, 8, 1024) +''' """ -const - x = "abc" +import std/assertions -var v = "D" & x & "D" +block: + const + x = "abc" -echo v + var v = "D" & x & "D" + doAssert v == "DabcD" + echo v + +block: # test large additions + var a = "abcdefgh" + let initialLen = a.len + let times = 10 + for i in 1..times: + let start = a.len + a.add(a) + doAssert a.len == 2 * start + let multiplier = 1 shl times + doAssert a.len == initialLen * multiplier + echo (a.len, initialLen, multiplier) + for i in 1 ..< multiplier: + for j in 0 ..< initialLen: + doAssert a[j] == a[i * initialLen + j]