Skip to content

Commit 02a9969

Browse files
committed
Make js work again!
1 parent 008d45f commit 02a9969

File tree

3 files changed

+95
-74
lines changed

3 files changed

+95
-74
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
!*.*
55

66
# normal ignores:
7+
*.js
78
*.exe
89
nimcache
910
*.pdb

src/jsony.nim

+89-71
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ type JsonError* = object of ValueError
55
const whiteSpace = {' ', '\n', '\t', '\r'}
66

77
when defined(release):
8-
{.push checks: off.}
8+
{.push checks: off, inline.}
99

1010
type SomeTable*[K, V] = Table[K, V] | OrderedTable[K, V] |
1111
TableRef[K, V] | OrderedTableRef[K, V]
@@ -486,36 +486,45 @@ const lookup = block:
486486
s.add($i)
487487
s
488488

489+
proc dumpNumberSlow(s: var string, v: uint|uint8|uint16|uint32|uint64) =
490+
s.add $v.uint64
491+
492+
proc dumpNumberFast(s: var string, v: uint|uint8|uint16|uint32|uint64) =
493+
# Its faster to not allocate a string for a number,
494+
# but to write it out the digits directly.
495+
if v == 0:
496+
s.add '0'
497+
return
498+
# Max size of a uin64 number is 20 digits.
499+
var digits: array[20, char]
500+
var v = v
501+
var p = 0
502+
while v != 0:
503+
# Its faster to look up 2 digits at a time, less int divisions.
504+
let idx = v mod 100
505+
digits[p] = lookup[idx*2+1]
506+
inc p
507+
digits[p] = lookup[idx*2]
508+
inc p
509+
v = v div 100
510+
var at = s.len
511+
if digits[p-1] == '0':
512+
dec p
513+
s.setLen(s.len + p)
514+
dec p
515+
while p >= 0:
516+
s[at] = digits[p]
517+
dec p
518+
inc at
519+
489520
proc dumpHook*(s: var string, v: uint|uint8|uint16|uint32|uint64) =
490521
when nimvm:
491-
s.add $v.uint64
522+
s.dumpNumberSlow(v)
492523
else:
493-
# Its faster to not allocate a string for a number,
494-
# but to write it out the digits directly.
495-
if v == 0:
496-
s.add '0'
497-
return
498-
# Max size of a uin64 number is 20 digits.
499-
var digits: array[20, char]
500-
var v = v
501-
var p = 0
502-
while v != 0:
503-
# Its faster to look up 2 digits at a time, less int divisions.
504-
let idx = v mod 100
505-
digits[p] = lookup[idx*2+1]
506-
inc p
507-
digits[p] = lookup[idx*2]
508-
inc p
509-
v = v div 100
510-
var at = s.len
511-
if digits[p-1] == '0':
512-
dec p
513-
s.setLen(s.len + p)
514-
dec p
515-
while p >= 0:
516-
s[at] = digits[p]
517-
dec p
518-
inc at
524+
when defined(js):
525+
s.dumpNumberSlow(v)
526+
else:
527+
s.dumpNumberFast(v)
519528

520529
proc dumpHook*(s: var string, v: int|int8|int16|int32|int64) =
521530
if v < 0:
@@ -527,52 +536,61 @@ proc dumpHook*(s: var string, v: int|int8|int16|int32|int64) =
527536
proc dumpHook*(s: var string, v: SomeFloat) =
528537
s.add $v
529538

539+
proc dumpStrSlow(s: var string, v: string) =
540+
s.add '"'
541+
for c in v:
542+
case c:
543+
of '\\': s.add r"\\"
544+
of '\b': s.add r"\b"
545+
of '\f': s.add r"\f"
546+
of '\n': s.add r"\n"
547+
of '\r': s.add r"\r"
548+
of '\t': s.add r"\t"
549+
of '"': s.add r"\"""
550+
else:
551+
s.add c
552+
s.add '"'
553+
554+
proc dumpStrFast(s: var string, v: string) =
555+
# Its faster to grow the string only once.
556+
# Then fill the string with pointers.
557+
# Then cap it off to right length.
558+
var at = s.len
559+
s.setLen(s.len + v.len*2+2)
560+
561+
var ss = cast[ptr UncheckedArray[char]](s[0].addr)
562+
template add(ss: ptr UncheckedArray[char], c: char) =
563+
ss[at] = c
564+
inc at
565+
template add(ss: ptr UncheckedArray[char], c1, c2: char) =
566+
ss[at] = c1
567+
inc at
568+
ss[at] = c2
569+
inc at
570+
571+
ss.add '"'
572+
for c in v:
573+
case c:
574+
of '\\': ss.add '\\', '\\'
575+
of '\b': ss.add '\\', 'b'
576+
of '\f': ss.add '\\', 'f'
577+
of '\n': ss.add '\\', 'n'
578+
of '\r': ss.add '\\', 'r'
579+
of '\t': ss.add '\\', 't'
580+
of '"': ss.add '\\', '"'
581+
else:
582+
ss.add c
583+
ss.add '"'
584+
s.setLen(at)
585+
530586
proc dumpHook*(s: var string, v: string) =
531587
when nimvm:
532-
s.add '"'
533-
for c in v:
534-
case c:
535-
of '\\': s.add r"\\"
536-
of '\b': s.add r"\b"
537-
of '\f': s.add r"\f"
538-
of '\n': s.add r"\n"
539-
of '\r': s.add r"\r"
540-
of '\t': s.add r"\t"
541-
of '"': s.add r"\"""
542-
else:
543-
s.add c
544-
s.add '"'
588+
s.dumpStrSlow(v)
545589
else:
546-
# Its faster to grow the string only once.
547-
# Then fill the string with pointers.
548-
# Then cap it off to right length.
549-
var at = s.len
550-
s.setLen(s.len + v.len*2+2)
551-
552-
var ss = cast[ptr UncheckedArray[char]](s[0].addr)
553-
template add(ss: ptr UncheckedArray[char], c: char) =
554-
ss[at] = c
555-
inc at
556-
template add(ss: ptr UncheckedArray[char], c1, c2: char) =
557-
ss[at] = c1
558-
inc at
559-
ss[at] = c2
560-
inc at
561-
562-
ss.add '"'
563-
for c in v:
564-
case c:
565-
of '\\': ss.add '\\', '\\'
566-
of '\b': ss.add '\\', 'b'
567-
of '\f': ss.add '\\', 'f'
568-
of '\n': ss.add '\\', 'n'
569-
of '\r': ss.add '\\', 'r'
570-
of '\t': ss.add '\\', 't'
571-
of '"': ss.add '\\', '"'
572-
else:
573-
ss.add c
574-
ss.add '"'
575-
s.setLen(at)
590+
when defined(js):
591+
s.dumpStrSlow(v)
592+
else:
593+
s.dumpStrFast(v)
576594

577595
template dumpKey(s: var string, v: string) =
578596
const v2 = v.toJson() & ":"

tests/test_tojson.nim

+5-3
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,16 @@ proc match[T](what: T) =
66
doAssert 1.uint8.toJson() == "1"
77
doAssert 1.uint16.toJson() == "1"
88
doAssert 1.uint32.toJson() == "1"
9-
doAssert 1.uint64.toJson() == "1"
109
doAssert 1.int8.toJson() == "1"
1110
doAssert 1.int16.toJson() == "1"
1211
doAssert 1.int32.toJson() == "1"
13-
doAssert 1.int64.toJson() == "1"
14-
doAssert 3.14.float32.toJson() == "3.140000104904175"
1512
doAssert 3.14.float64.toJson() == "3.14"
1613

14+
when not defined(js):
15+
doAssert 1.int64.toJson() == "1"
16+
doAssert 1.uint64.toJson() == "1"
17+
doAssert 3.14.float32.toJson() == "3.140000104904175"
18+
1719
match 1
1820
match 3.14.float32
1921
match 3.14.float64

0 commit comments

Comments
 (0)