JS strings have no trailing zero anymore (#8936)

This commit is contained in:
LemonBoy 2018-09-11 11:45:02 +02:00 • committed by Andreas Rumpf
commit 9ba80d2044
3 changed files with 22 additions and 35 deletions

View file

@ -1540,18 +1540,18 @@ proc genConStrStr(p: PProc, n: PNode, r: var TCompRes) =
if skipTypes(n.sons[1].typ, abstractVarRange).kind == tyChar: if skipTypes(n.sons[1].typ, abstractVarRange).kind == tyChar:
r.res.add("[$1].concat(" % [a.res]) r.res.add("[$1].concat(" % [a.res])
else: else:
r.res.add("($1.slice(0,-1)).concat(" % [a.res]) r.res.add("($1).concat(" % [a.res])
for i in countup(2, sonsLen(n) - 2): for i in countup(2, sonsLen(n) - 2):
gen(p, n.sons[i], a) gen(p, n.sons[i], a)
if skipTypes(n.sons[i].typ, abstractVarRange).kind == tyChar: if skipTypes(n.sons[i].typ, abstractVarRange).kind == tyChar:
r.res.add("[$1]," % [a.res]) r.res.add("[$1]," % [a.res])
else: else:
r.res.add("$1.slice(0,-1)," % [a.res]) r.res.add("$1," % [a.res])
gen(p, n.sons[sonsLen(n) - 1], a) gen(p, n.sons[sonsLen(n) - 1], a)
if skipTypes(n.sons[sonsLen(n) - 1].typ, abstractVarRange).kind == tyChar: if skipTypes(n.sons[sonsLen(n) - 1].typ, abstractVarRange).kind == tyChar:
r.res.add("[$1, 0])" % [a.res]) r.res.add("[$1])" % [a.res])
else: else:
r.res.add("$1)" % [a.res]) r.res.add("$1)" % [a.res])
@ -1658,13 +1658,13 @@ proc genMagic(p: PProc, n: PNode, r: var TCompRes) =
else: unaryExpr(p, n, r, "subInt", "subInt($1, 1)") else: unaryExpr(p, n, r, "subInt", "subInt($1, 1)")
of mAppendStrCh: of mAppendStrCh:
binaryExpr(p, n, r, "addChar", binaryExpr(p, n, r, "addChar",
"if ($1 != null) { addChar($1, $2); } else { $1 = [$2, 0]; }") "if ($1 != null) { addChar($1, $2); } else { $1 = [$2]; }")
of mAppendStrStr: of mAppendStrStr:
if skipTypes(n.sons[1].typ, abstractVarRange).kind == tyCString: if skipTypes(n.sons[1].typ, abstractVarRange).kind == tyCString:
binaryExpr(p, n, r, "", "if ($1 != null) { $1 += $2; } else { $1 = $2; }") binaryExpr(p, n, r, "", "if ($1 != null) { $1 += $2; } else { $1 = $2; }")
else: else:
binaryExpr(p, n, r, "", binaryExpr(p, n, r, "",
"if ($1 != null) { $1 = ($1.slice(0, -1)).concat($2); } else { $1 = $2;}") "if ($1 != null) { $1 = ($1).concat($2); } else { $1 = $2;}")
# XXX: make a copy of $2, because of Javascript's sucking semantics # XXX: make a copy of $2, because of Javascript's sucking semantics
of mAppendSeqElem: of mAppendSeqElem:
var x, y: TCompRes var x, y: TCompRes
@ -1694,20 +1694,15 @@ proc genMagic(p: PProc, n: PNode, r: var TCompRes) =
of mChr, mArrToSeq: gen(p, n.sons[1], r) # nothing to do of mChr, mArrToSeq: gen(p, n.sons[1], r) # nothing to do
of mOrd: genOrd(p, n, r) of mOrd: genOrd(p, n, r)
of mLengthStr: of mLengthStr:
if n.sons[1].typ.skipTypes(abstractInst).kind == tyCString: unaryExpr(p, n, r, "", "($1 != null ? $1.length : 0)")
unaryExpr(p, n, r, "", "($1 != null ? $1.length : 0)") of mXLenStr:
else: unaryExpr(p, n, r, "", "$1.length")
unaryExpr(p, n, r, "", "($1 != null ? $1.length-1 : 0)")
of mXLenStr: unaryExpr(p, n, r, "", "$1.length-1")
of mLengthSeq, mLengthOpenArray, mLengthArray: of mLengthSeq, mLengthOpenArray, mLengthArray:
unaryExpr(p, n, r, "", "($1 != null ? $1.length : 0)") unaryExpr(p, n, r, "", "($1 != null ? $1.length : 0)")
of mXLenSeq: of mXLenSeq:
unaryExpr(p, n, r, "", "$1.length") unaryExpr(p, n, r, "", "$1.length")
of mHigh: of mHigh:
if skipTypes(n.sons[1].typ, abstractVar).kind == tyString: unaryExpr(p, n, r, "", "($1 != null ? ($1.length-1) : -1)")
unaryExpr(p, n, r, "", "($1 != null ? ($1.length-2) : -1)")
else:
unaryExpr(p, n, r, "", "($1 != null ? ($1.length-1) : -1)")
of mInc: of mInc:
if n[1].typ.skipTypes(abstractRange).kind in tyUInt .. tyUInt64: if n[1].typ.skipTypes(abstractRange).kind in tyUInt .. tyUInt64:
binaryUintExpr(p, n, r, "+", true) binaryUintExpr(p, n, r, "+", true)
@ -1721,7 +1716,7 @@ proc genMagic(p: PProc, n: PNode, r: var TCompRes) =
if optOverflowCheck notin p.options: binaryExpr(p, n, r, "", "$1 -= $2") if optOverflowCheck notin p.options: binaryExpr(p, n, r, "", "$1 -= $2")
else: binaryExpr(p, n, r, "subInt", "$1 = subInt($1, $2)") else: binaryExpr(p, n, r, "subInt", "$1 = subInt($1, $2)")
of mSetLengthStr: of mSetLengthStr:
binaryExpr(p, n, r, "", "$1.length = $2+1; $1[$1.length-1] = 0") binaryExpr(p, n, r, "", "$1.length = $2")
of mSetLengthSeq: of mSetLengthSeq:
var x, y: TCompRes var x, y: TCompRes
gen(p, n.sons[1], x) gen(p, n.sons[1], x)
@ -1750,8 +1745,6 @@ proc genMagic(p: PProc, n: PNode, r: var TCompRes) =
localError(p.config, n.info, errXMustBeCompileTime % n.sons[0].sym.name.s) localError(p.config, n.info, errXMustBeCompileTime % n.sons[0].sym.name.s)
of mCopyStr: of mCopyStr:
binaryExpr(p, n, r, "", "($1.slice($2))") binaryExpr(p, n, r, "", "($1.slice($2))")
of mCopyStrLast:
ternaryExpr(p, n, r, "", "($1.slice($2, ($3)+1).concat(0))")
of mNewString: unaryExpr(p, n, r, "mnewString", "mnewString($1)") of mNewString: unaryExpr(p, n, r, "mnewString", "mnewString($1)")
of mNewStringOfCap: of mNewStringOfCap:
unaryExpr(p, n, r, "mnewString", "mnewString(0)") unaryExpr(p, n, r, "mnewString", "mnewString(0)")
@ -2076,8 +2069,11 @@ proc gen(p: PProc, n: PNode, r: var TCompRes) =
r.kind = resExpr r.kind = resExpr
of nkStrLit..nkTripleStrLit: of nkStrLit..nkTripleStrLit:
if skipTypes(n.typ, abstractVarRange).kind == tyString: if skipTypes(n.typ, abstractVarRange).kind == tyString:
useMagic(p, "makeNimstrLit") if n.strVal.len != 0:
r.res = "makeNimstrLit($1)" % [makeJSString(n.strVal)] useMagic(p, "makeNimstrLit")
r.res = "makeNimstrLit($1)" % [makeJSString(n.strVal)]
else:
r.res = rope"[]"
else: else:
r.res = makeJSString(n.strVal, false) r.res = makeJSString(n.strVal, false)
r.kind = resExpr r.kind = resExpr

View file

@ -2741,12 +2741,11 @@ type
when defined(JS): when defined(JS):
proc add*(x: var string, y: cstring) {.asmNoStackFrame.} = proc add*(x: var string, y: cstring) {.asmNoStackFrame.} =
asm """ asm """
var len = `x`.length-1; var len = `x`.length;
for (var i = 0; i < `y`.length; ++i) { for (var i = 0; i < `y`.length; ++i) {
`x`[len] = `y`.charCodeAt(i); `x`[len] = `y`.charCodeAt(i);
++len; ++len;
} }
`x`[len] = 0
""" """
proc add*(x: var cstring, y: cstring) {.magic: "AppendStrStr".} proc add*(x: var cstring, y: cstring) {.magic: "AppendStrStr".}

View file

@ -182,12 +182,10 @@ proc setConstr() {.varargs, asmNoStackFrame, compilerproc.} =
proc makeNimstrLit(c: cstring): string {.asmNoStackFrame, compilerproc.} = proc makeNimstrLit(c: cstring): string {.asmNoStackFrame, compilerproc.} =
{.emit: """ {.emit: """
var ln = `c`.length; var ln = `c`.length;
var result = new Array(ln + 1); var result = new Array(ln);
var i = 0; for (var i = 0; i < ln; ++i) {
for (; i < ln; ++i) {
result[i] = `c`.charCodeAt(i); result[i] = `c`.charCodeAt(i);
} }
result[i] = 0; // terminating zero
return result; return result;
""".} """.}
@ -225,13 +223,12 @@ proc cstrToNimstr(c: cstring): string {.asmNoStackFrame, compilerproc.} =
} }
++r; ++r;
} }
result[r] = 0; // terminating zero
return result; return result;
""".} """.}
proc toJSStr(s: string): cstring {.asmNoStackFrame, compilerproc.} = proc toJSStr(s: string): cstring {.asmNoStackFrame, compilerproc.} =
asm """ asm """
var len = `s`.length-1; var len = `s`.length;
var asciiPart = new Array(len); var asciiPart = new Array(len);
var fcc = String.fromCharCode; var fcc = String.fromCharCode;
var nonAsciiPart = null; var nonAsciiPart = null;
@ -262,10 +259,7 @@ proc toJSStr(s: string): cstring {.asmNoStackFrame, compilerproc.} =
proc mnewString(len: int): string {.asmNoStackFrame, compilerproc.} = proc mnewString(len: int): string {.asmNoStackFrame, compilerproc.} =
asm """ asm """
var result = new Array(`len`+1); return new Array(`len`);
result[0] = 0;
result[`len`] = 0;
return result;
""" """
proc SetCard(a: int): int {.compilerproc, asmNoStackFrame.} = proc SetCard(a: int): int {.compilerproc, asmNoStackFrame.} =
@ -323,7 +317,7 @@ proc cmpStrings(a, b: string): int {.asmNoStackFrame, compilerProc.} =
if (`a` == `b`) return 0; if (`a` == `b`) return 0;
if (!`a`) return -1; if (!`a`) return -1;
if (!`b`) return 1; if (!`b`) return 1;
for (var i = 0; i < `a`.length - 1 && i < `b`.length - 1; i++) { for (var i = 0; i < `a`.length && i < `b`.length; i++) {
var result = `a`[i] - `b`[i]; var result = `a`[i] - `b`[i];
if (result != 0) return result; if (result != 0) return result;
} }
@ -651,9 +645,7 @@ proc isObj(obj, subclass: PNimType): bool {.compilerproc.} =
return true return true
proc addChar(x: string, c: char) {.compilerproc, asmNoStackFrame.} = proc addChar(x: string, c: char) {.compilerproc, asmNoStackFrame.} =
asm """ asm "`x`.push(`c`);"
`x`[`x`.length-1] = `c`; `x`.push(0);
"""
{.pop.} {.pop.}