better tojsstr (#11954)

* JS: rewrote toJSStr
* JS: don't raise exceptions in primitives
This commit is contained in:
Andreas Rumpf 2019-08-16 12:18:51 +02:00 • committed by GitHub
commit ba577c7e1b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -120,7 +120,7 @@ proc unhandledException(e: ref Exception) {.
add(buf, "]\n") add(buf, "]\n")
when NimStackTrace: when NimStackTrace:
add(buf, rawWriteStackTrace()) add(buf, rawWriteStackTrace())
let cbuf : cstring = buf let cbuf = cstring(buf)
framePtr = nil framePtr = nil
{.emit: """ {.emit: """
if (typeof(Error) !== "undefined") { if (typeof(Error) !== "undefined") {
@ -228,37 +228,44 @@ proc cstrToNimstr(c: cstring): string {.asmNoStackFrame, compilerproc.} =
return result; return result;
""".} """.}
proc toJSStr(s: string): cstring {.asmNoStackFrame, compilerproc.} = proc toJSStr(s: string): cstring {.compilerproc.} =
asm """ proc fromCharCode(c: char): cstring {.importc: "String.fromCharCode".}
if (`s` === null) return ""; proc join(x: openArray[cstring]; d = cstring""): cstring {.
var len = `s`.length; importcpp: "#.join(@)".}
var asciiPart = new Array(len); proc decodeURIComponent(x: cstring): cstring {.
var fcc = String.fromCharCode; importc: "decodeURIComponent".}
var nonAsciiPart = null;
var nonAsciiOffset = 0; proc toHexString(c: char; d = 16): cstring {.importcpp: "#.toString(@)".}
for (var i = 0; i < len; ++i) {
if (nonAsciiPart !== null) { proc log(x: cstring) {.importc: "console.log".}
var offset = (i - nonAsciiOffset) * 2;
var code = `s`[i].toString(16); var res = newSeq[cstring](s.len)
if (code.length == 1) { var i = 0
code = "0"+code; var j = 0
} while i < s.len:
nonAsciiPart[offset] = "%"; var c = s[i]
nonAsciiPart[offset + 1] = code; if c < '\128':
} res[j] = fromCharCode(c)
else if (`s`[i] < 128) inc i
asciiPart[i] = fcc(`s`[i]); else:
else { var helper = newSeq[cstring]()
asciiPart.length = i; while true:
nonAsciiOffset = i; let code = toHexString(c)
nonAsciiPart = new Array((len - i) * 2); if code.len == 1:
--i; helper.add cstring"%0"
} else:
} helper.add cstring"%"
asciiPart = asciiPart.join(""); helper.add code
return (nonAsciiPart === null) ? inc i
asciiPart : asciiPart + decodeURIComponent(nonAsciiPart.join("")); if i >= s.len or s[i] < '\128': break
""" c = s[i]
try:
res[j] = decodeURIComponent join(helper)
except:
res[j] = join(helper)
inc j
setLen(res, j)
result = join(res)
proc mnewString(len: int): string {.asmNoStackFrame, compilerproc.} = proc mnewString(len: int): string {.asmNoStackFrame, compilerproc.} =
asm """ asm """