json-as 1.3.2 → 1.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/CHANGELOG.md +5 -0
  2. package/README.md +3 -2
  3. package/assembly/deserialize/simd/string.ts +20 -0
  4. package/assembly/deserialize/simple/map.ts +2 -0
  5. package/assembly/deserialize/simple/staticarray.ts +1 -0
  6. package/assembly/deserialize/simple/struct.ts +3 -1
  7. package/assembly/deserialize/swar/array/bool.ts +1 -0
  8. package/assembly/deserialize/swar/array/generic.ts +2 -1
  9. package/assembly/deserialize/swar/array/integer.ts +1 -0
  10. package/assembly/deserialize/swar/array/object.ts +1 -0
  11. package/assembly/deserialize/swar/array/shared.ts +18 -3
  12. package/assembly/deserialize/swar/array/string.ts +1 -0
  13. package/assembly/deserialize/swar/array/struct.ts +1 -0
  14. package/assembly/deserialize/swar/array.ts +1 -0
  15. package/assembly/deserialize/swar/string.ts +21 -2
  16. package/assembly/index.d.ts +1 -0
  17. package/assembly/index.ts +27 -22
  18. package/assembly/serialize/simd/string.ts +43 -16
  19. package/assembly/serialize/simple/array.ts +48 -6
  20. package/assembly/serialize/simple/bool.ts +12 -0
  21. package/assembly/serialize/simple/float.ts +16 -0
  22. package/assembly/serialize/simple/integer.ts +6 -0
  23. package/assembly/serialize/simple/set.ts +59 -5
  24. package/assembly/serialize/simple/staticarray.ts +57 -3
  25. package/assembly/serialize/simple/typedarray.ts +29 -9
  26. package/assembly/serialize/swar/string.ts +165 -18
  27. package/assembly/tsconfig.json +2 -2
  28. package/assembly/util/dragonbox-cache.ts +2 -1320
  29. package/assembly/util/dragonbox.ts +63 -35
  30. package/lib/as-bs.ts +26 -18
  31. package/package.json +11 -10
  32. package/transform/lib/index.d.ts.map +1 -1
  33. package/transform/lib/index.js +288 -73
  34. package/transform/lib/index.js.map +1 -1
@@ -1,6 +1,34 @@
1
1
  import { bs } from "../../../lib/as-bs";
2
2
  import { COMMA, BRACKET_RIGHT, BRACKET_LEFT } from "../../custom/chars";
3
3
  import { JSON } from "../..";
4
+ import { serializeBoolUnsafe } from "./bool";
5
+ import { serializeFloat32Unsafe, serializeFloat64Unsafe } from "./float";
6
+ import { serializeIntegerUnsafe } from "./integer";
7
+ import { serializeString } from "../index/string";
8
+
9
+
10
+ @inline
11
+ function maxIntegerBytes<T extends number>(): u32 {
12
+ if (sizeof<T>() == 1) return isSigned<T>() ? 8 : 6;
13
+ if (sizeof<T>() == 2) return isSigned<T>() ? 12 : 10;
14
+ if (sizeof<T>() == 4) return isSigned<T>() ? 22 : 20;
15
+ return isSigned<T>() ? 42 : 40;
16
+ }
17
+
18
+
19
+ @inline
20
+ function reservePrimitiveSet<T>(len: i32): void {
21
+ if (len <= 0) return;
22
+ if (isBoolean<T>()) {
23
+ bs.proposeSize(4 + <u32>len * 12);
24
+ } else if (isInteger<T>()) {
25
+ bs.proposeSize(4 + <u32>len * (maxIntegerBytes<T>() + 2));
26
+ } else if (isFloat<T>()) {
27
+ bs.proposeSize(4 + <u32>len * (sizeof<T>() == 4 ? 34 : 66));
28
+ } else {
29
+ bs.proposeSize(4 + <u32>(len - 1) * 2);
30
+ }
31
+ }
4
32
 
5
33
  export function serializeSet<T extends Set<any>>(src: T): void {
6
34
  const srcSize = src.size;
@@ -10,7 +38,11 @@ export function serializeSet<T extends Set<any>>(src: T): void {
10
38
  bs.offset += 4;
11
39
  return;
12
40
  }
13
- bs.proposeSize(4 + <u32>(srcSize - 1) * 2);
41
+ if (isBoolean<indexof<T>>() || isInteger<indexof<T>>() || isFloat<indexof<T>>() || isString<indexof<T>>()) {
42
+ reservePrimitiveSet<indexof<T>>(srcSize);
43
+ } else {
44
+ bs.proposeSize(4 + <u32>(srcSize - 1) * 2);
45
+ }
14
46
 
15
47
  const values = src.values();
16
48
  store<u16>(bs.offset, BRACKET_LEFT);
@@ -19,15 +51,37 @@ export function serializeSet<T extends Set<any>>(src: T): void {
19
51
  const end = srcSize - 1;
20
52
  for (let i = 0; i < end; i++) {
21
53
  const block = unchecked(values[i]);
22
- // @ts-ignore: type
23
- JSON.__serialize<indexof<T>>(block);
54
+ if (isString<indexof<T>>()) {
55
+ serializeString(block as string);
56
+ } else if (isBoolean<indexof<T>>()) {
57
+ serializeBoolUnsafe(<bool>block);
58
+ } else if (isInteger<indexof<T>>()) {
59
+ serializeIntegerUnsafe<indexof<T>>(block);
60
+ } else if (isFloat<indexof<T>>()) {
61
+ if (sizeof<indexof<T>>() == 4) serializeFloat32Unsafe(<f32>block);
62
+ else serializeFloat64Unsafe(<f64>block);
63
+ } else {
64
+ // @ts-ignore: type
65
+ JSON.__serialize<indexof<T>>(block);
66
+ }
24
67
  store<u16>(bs.offset, COMMA);
25
68
  bs.offset += 2;
26
69
  }
27
70
 
28
71
  const lastBlock = unchecked(values[end]);
29
- // @ts-ignore: type
30
- JSON.__serialize<indexof<T>>(lastBlock);
72
+ if (isString<indexof<T>>()) {
73
+ serializeString(lastBlock as string);
74
+ } else if (isBoolean<indexof<T>>()) {
75
+ serializeBoolUnsafe(<bool>lastBlock);
76
+ } else if (isInteger<indexof<T>>()) {
77
+ serializeIntegerUnsafe<indexof<T>>(lastBlock);
78
+ } else if (isFloat<indexof<T>>()) {
79
+ if (sizeof<indexof<T>>() == 4) serializeFloat32Unsafe(<f32>lastBlock);
80
+ else serializeFloat64Unsafe(<f64>lastBlock);
81
+ } else {
82
+ // @ts-ignore: type
83
+ JSON.__serialize<indexof<T>>(lastBlock);
84
+ }
31
85
  store<u16>(bs.offset, BRACKET_RIGHT);
32
86
  bs.offset += 2;
33
87
  }
@@ -1,6 +1,34 @@
1
1
  import { bs } from "../../../lib/as-bs";
2
2
  import { COMMA, BRACKET_RIGHT, BRACKET_LEFT } from "../../custom/chars";
3
3
  import { JSON } from "../..";
4
+ import { serializeBoolUnsafe } from "./bool";
5
+ import { serializeFloat32Unsafe, serializeFloat64Unsafe } from "./float";
6
+ import { serializeIntegerUnsafe } from "./integer";
7
+ import { serializeString } from "../index/string";
8
+
9
+
10
+ @inline
11
+ function maxIntegerBytes<T extends number>(): u32 {
12
+ if (sizeof<T>() == 1) return isSigned<T>() ? 8 : 6;
13
+ if (sizeof<T>() == 2) return isSigned<T>() ? 12 : 10;
14
+ if (sizeof<T>() == 4) return isSigned<T>() ? 22 : 20;
15
+ return isSigned<T>() ? 42 : 40;
16
+ }
17
+
18
+
19
+ @inline
20
+ function reservePrimitiveStaticArray<T>(len: i32): void {
21
+ if (len <= 0) return;
22
+ if (isBoolean<T>()) {
23
+ bs.proposeSize(4 + <u32>len * 12);
24
+ } else if (isInteger<T>()) {
25
+ bs.proposeSize(4 + <u32>len * (maxIntegerBytes<T>() + 2));
26
+ } else if (isFloat<T>()) {
27
+ bs.proposeSize(4 + <u32>len * (sizeof<T>() == 4 ? 34 : 66));
28
+ } else {
29
+ bs.proposeSize(4 + <u32>(len - 1) * 2);
30
+ }
31
+ }
4
32
 
5
33
  export function serializeStaticArray<T extends StaticArray<any>>(src: T): void {
6
34
  const len = src.length;
@@ -12,20 +40,46 @@ export function serializeStaticArray<T extends StaticArray<any>>(src: T): void {
12
40
  bs.offset += 4;
13
41
  return;
14
42
  }
15
- bs.proposeSize(4 + <u32>(len - 1) * 2);
43
+ if (isBoolean<valueof<T>>() || isInteger<valueof<T>>() || isFloat<valueof<T>>() || isString<valueof<T>>()) {
44
+ reservePrimitiveStaticArray<valueof<T>>(len);
45
+ } else {
46
+ bs.proposeSize(4 + <u32>(len - 1) * 2);
47
+ }
16
48
 
17
49
  store<u16>(bs.offset, BRACKET_LEFT);
18
50
  bs.offset += 2;
19
51
 
20
52
  while (i < end) {
21
53
  const block = unchecked(src[i++]);
22
- JSON.__serialize<valueof<T>>(block);
54
+ if (isString<valueof<T>>()) {
55
+ serializeString(block as string);
56
+ } else if (isBoolean<valueof<T>>()) {
57
+ serializeBoolUnsafe(<bool>block);
58
+ } else if (isInteger<valueof<T>>()) {
59
+ serializeIntegerUnsafe<valueof<T>>(block);
60
+ } else if (isFloat<valueof<T>>()) {
61
+ if (sizeof<valueof<T>>() == 4) serializeFloat32Unsafe(<f32>block);
62
+ else serializeFloat64Unsafe(<f64>block);
63
+ } else {
64
+ JSON.__serialize<valueof<T>>(block);
65
+ }
23
66
  store<u16>(bs.offset, COMMA);
24
67
  bs.offset += 2;
25
68
  }
26
69
 
27
70
  const lastBlock = unchecked(src[end]);
28
- JSON.__serialize<valueof<T>>(lastBlock);
71
+ if (isString<valueof<T>>()) {
72
+ serializeString(lastBlock as string);
73
+ } else if (isBoolean<valueof<T>>()) {
74
+ serializeBoolUnsafe(<bool>lastBlock);
75
+ } else if (isInteger<valueof<T>>()) {
76
+ serializeIntegerUnsafe<valueof<T>>(lastBlock);
77
+ } else if (isFloat<valueof<T>>()) {
78
+ if (sizeof<valueof<T>>() == 4) serializeFloat32Unsafe(<f32>lastBlock);
79
+ else serializeFloat64Unsafe(<f64>lastBlock);
80
+ } else {
81
+ JSON.__serialize<valueof<T>>(lastBlock);
82
+ }
29
83
  store<u16>(bs.offset, BRACKET_RIGHT);
30
84
  bs.offset += 2;
31
85
  }
@@ -1,16 +1,36 @@
1
1
  import { bs } from "../../../lib/as-bs";
2
2
  import { BRACKET_LEFT, BRACKET_RIGHT, COMMA } from "../../custom/chars";
3
- import { serializeFloat32, serializeFloat64 } from "./float";
4
- import { serializeInteger } from "./integer";
3
+ import { serializeFloat32Unsafe, serializeFloat64Unsafe } from "./float";
4
+ import { serializeIntegerUnsafe } from "./integer";
5
+
6
+
7
+ @inline
8
+ function maxIntegerBytes<T extends number>(): u32 {
9
+ if (sizeof<T>() == 1) return isSigned<T>() ? 8 : 6;
10
+ if (sizeof<T>() == 2) return isSigned<T>() ? 12 : 10;
11
+ if (sizeof<T>() == 4) return isSigned<T>() ? 22 : 20;
12
+ return isSigned<T>() ? 42 : 40;
13
+ }
14
+
15
+
16
+ @inline
17
+ function reserveTypedArray<T extends ArrayLike<number>>(len: i32): void {
18
+ if (len <= 0) return;
19
+ if (isFloat<valueof<T>>()) {
20
+ bs.proposeSize(4 + <u32>len * (sizeof<valueof<T>>() == 4 ? 34 : 66));
21
+ } else {
22
+ bs.proposeSize(4 + <u32>len * (maxIntegerBytes<valueof<T>>() + 2));
23
+ }
24
+ }
5
25
 
6
26
 
7
27
  @inline
8
28
  function serializeTypedArrayElement<T extends ArrayLike<number>>(src: T, index: i32): void {
9
29
  if (isFloat<valueof<T>>()) {
10
- if (sizeof<valueof<T>>() == 4) serializeFloat32(<f32>unchecked(src[index]));
11
- else serializeFloat64(<f64>unchecked(src[index]));
30
+ if (sizeof<valueof<T>>() == 4) serializeFloat32Unsafe(<f32>unchecked(src[index]));
31
+ else serializeFloat64Unsafe(<f64>unchecked(src[index]));
12
32
  } else {
13
- serializeInteger<valueof<T>>(unchecked(src[index]));
33
+ serializeIntegerUnsafe<valueof<T>>(unchecked(src[index]));
14
34
  }
15
35
  }
16
36
 
@@ -23,7 +43,7 @@ export function serializeTypedArray<T extends ArrayLike<number>>(src: T): void {
23
43
  bs.offset += 4;
24
44
  return;
25
45
  }
26
- bs.proposeSize(4 + <u32>(len - 1) * 2);
46
+ reserveTypedArray<T>(len);
27
47
 
28
48
  store<u16>(bs.offset, BRACKET_LEFT);
29
49
  bs.offset += 2;
@@ -48,18 +68,18 @@ export function serializeArrayBufferUnsafe(srcStart: usize, byteLength: i32): vo
48
68
  bs.offset += 4;
49
69
  return;
50
70
  }
51
- bs.proposeSize(4 + <u32>(end) * 2);
71
+ bs.proposeSize(4 + <u32>byteLength * 8);
52
72
 
53
73
  store<u16>(bs.offset, BRACKET_LEFT);
54
74
  bs.offset += 2;
55
75
 
56
76
  for (let i = 0; i < end; i++) {
57
- serializeInteger<u8>(load<u8>(srcStart + <usize>i));
77
+ serializeIntegerUnsafe<u8>(load<u8>(srcStart + <usize>i));
58
78
  store<u16>(bs.offset, COMMA);
59
79
  bs.offset += 2;
60
80
  }
61
81
 
62
- serializeInteger<u8>(load<u8>(srcStart + <usize>end));
82
+ serializeIntegerUnsafe<u8>(load<u8>(srcStart + <usize>end));
63
83
  store<u16>(bs.offset, BRACKET_RIGHT);
64
84
  bs.offset += 2;
65
85
  }
@@ -1,5 +1,5 @@
1
- import { bs, sc } from "../../../lib/as-bs";
2
- import { BACK_SLASH } from "../../custom/chars";
1
+ import { bs } from "../../../lib/as-bs";
2
+ import { BACK_SLASH, QUOTE } from "../../custom/chars";
3
3
  import { SERIALIZE_ESCAPE_TABLE } from "../../globals/tables";
4
4
  import { u16_to_hex4_swar } from "../../util/swar";
5
5
  import { OBJECT, TOTAL_OVERHEAD } from "rt/common";
@@ -11,18 +11,166 @@ import { OBJECT, TOTAL_OVERHEAD } from "rt/common";
11
11
 
12
12
  export function serializeString_SWAR(src: string): void {
13
13
  let srcStart = changetype<usize>(src);
14
+ const srcInitial = srcStart;
15
+ const srcSize = changetype<OBJECT>(srcStart - TOTAL_OVERHEAD).rtSize;
16
+ const srcEnd = srcStart + srcSize;
17
+ do {
18
+ const srcEnd8Fast = srcEnd - 8;
19
+ bs.proposeSize(srcSize + 4);
20
+
21
+ const dstStart = bs.offset;
22
+ let dst = dstStart + 2;
23
+
24
+ while (srcStart < srcEnd8Fast) {
25
+ const block = load<u64>(srcStart);
26
+ if ((block & 0xff00_ff00_ff00_ff00) != 0) break;
27
+ const lo = block & 0x00ff_00ff_00ff_00ff;
28
+ const asciiMask = ((lo - 0x0020_0020_0020_0020) | ((lo ^ 0x0022_0022_0022_0022) - 0x0001_0001_0001_0001) | ((lo ^ 0x005c_005c_005c_005c) - 0x0001_0001_0001_0001)) & (0x0080_0080_0080_0080 & ~lo);
29
+ if (asciiMask != 0) break;
30
+ store<u64>(dst, block);
31
+ srcStart += 8;
32
+ dst += 8;
33
+ }
34
+ if (srcStart < srcEnd8Fast) break;
35
+
36
+ while (srcStart <= srcEnd - 2) {
37
+ const code = load<u16>(srcStart);
38
+ if (code > 0x7f || code == BACK_SLASH || code == QUOTE || code < 32) break;
39
+ store<u16>(dst, code);
40
+ srcStart += 2;
41
+ dst += 2;
42
+ }
43
+ if (srcStart <= srcEnd - 2) break;
44
+
45
+ store<u16>(dstStart, QUOTE);
46
+ store<u16>(dst, QUOTE);
47
+ bs.offset = dst + 2;
48
+ return;
49
+ } while (false);
50
+
51
+ srcStart = srcInitial;
52
+ const srcEnd8 = srcEnd - 8;
53
+
54
+ bs.proposeSize(srcSize + 4);
55
+ store<u16>(bs.offset, 34); // "
56
+ bs.offset += 2;
57
+
58
+ while (srcStart < srcEnd8) {
59
+ const block = load<u64>(srcStart);
60
+ let mask = detect_escapable_u64_swar_safe(block);
61
+ store<u64>(bs.offset, block);
62
+
63
+ if (mask === 0) {
64
+ srcStart += 8;
65
+ bs.offset += 8;
66
+ continue;
67
+ }
68
+
69
+ do {
70
+ const laneIdx = usize(ctz(mask) >> 3);
71
+ const srcIdx = srcStart + laneIdx;
72
+ // Even (0 2 4 6) -> Confirmed ASCII Escape
73
+ // Odd (1 3 5 7) -> Possibly a Unicode code unit or surrogate
74
+ if ((laneIdx & 1) === 0) {
75
+ mask &= mask - 1;
76
+ const code = load<u16>(srcIdx);
77
+ const escaped = load<u32>(SERIALIZE_ESCAPE_TABLE + (code << 2));
78
+
79
+ if ((escaped & 0xffff) != BACK_SLASH) {
80
+ bs.growSize(10);
81
+ const dstIdx = bs.offset + laneIdx;
82
+ store<u64>(dstIdx, U00_MARKER);
83
+ store<u32>(dstIdx, escaped, 8);
84
+ store<u64>(dstIdx, load<u64>(srcIdx, 2), 12);
85
+ bs.offset += 10;
86
+ } else {
87
+ bs.growSize(2);
88
+ const dstIdx = bs.offset + laneIdx;
89
+ store<u32>(dstIdx, escaped);
90
+ store<u64>(dstIdx, load<u64>(srcIdx, 2), 4);
91
+ bs.offset += 2;
92
+ }
93
+ continue;
94
+ }
95
+ mask &= mask - 1;
96
+
97
+ const code = load<u16>(srcIdx - 1);
98
+ if (code < 0xd800 || code > 0xdfff) continue;
99
+
100
+ if (code <= 0xdbff && srcIdx + 2 < srcEnd) {
101
+ const next = load<u16>(srcIdx, 1);
102
+ if (next >= 0xdc00 && next <= 0xdfff) {
103
+ // paired surrogate
104
+ // mask &= ~(0xFF << ((laneIdx+2) << 3));
105
+ mask &= mask - 1;
106
+ continue;
107
+ }
108
+ }
109
+
110
+ bs.growSize(10);
111
+
112
+ // unpaired high/low surrogate
113
+ const dstIdx = bs.offset + laneIdx - 1;
114
+ store<u32>(dstIdx, U_MARKER); // \u
115
+ store<u64>(dstIdx, u16_to_hex4_swar(code), 4);
116
+ store<u64>(dstIdx, load<u64>(srcIdx, 1), 12);
117
+ bs.offset += 10;
118
+ } while (mask !== 0);
119
+
120
+ srcStart += 8;
121
+ bs.offset += 8;
122
+ }
123
+
124
+ while (srcStart <= srcEnd - 2) {
125
+ const code = load<u16>(srcStart);
126
+
127
+ if (code == BACK_SLASH || code == QUOTE || code < 32) {
128
+ const escaped = load<u32>(SERIALIZE_ESCAPE_TABLE + (code << 2));
129
+ if ((escaped & 0xffff) != BACK_SLASH) {
130
+ bs.growSize(10);
131
+ store<u64>(bs.offset, U00_MARKER);
132
+ store<u32>(bs.offset, escaped, 8);
133
+ bs.offset += 12;
134
+ } else {
135
+ bs.growSize(2);
136
+ store<u32>(bs.offset, escaped);
137
+ bs.offset += 4;
138
+ }
139
+ srcStart += 2;
140
+ continue;
141
+ }
142
+
143
+ if (code < 0xd800 || code > 0xdfff) {
144
+ store<u16>(bs.offset, code);
145
+ bs.offset += 2;
146
+ srcStart += 2;
147
+ continue;
148
+ }
14
149
 
15
- if (isDefined(JSON_CACHE)) {
16
- const e = unchecked(sc.entries[i32((srcStart >> 4) & sc.CACHE_MASK)]);
17
- if (e.key == srcStart) {
18
- bs.offset += e.len;
19
- bs.stackSize += e.len;
20
- bs.cacheOutput = e.ptr;
21
- bs.cacheOutputLen = e.len;
22
- return;
150
+ if (code <= 0xdbff && srcStart + 2 <= srcEnd - 2) {
151
+ const next = load<u16>(srcStart, 2);
152
+ if (next >= 0xdc00 && next <= 0xdfff) {
153
+ // valid surrogate pair
154
+ store<u16>(bs.offset, code);
155
+ store<u16>(bs.offset + 2, next);
156
+ bs.offset += 4;
157
+ srcStart += 4;
158
+ continue;
159
+ }
23
160
  }
161
+
162
+ // unpaired high/low surrogate
163
+ write_u_escape(code);
164
+ srcStart += 2;
165
+ continue;
24
166
  }
25
167
 
168
+ store<u16>(bs.offset, 34); // "
169
+ bs.offset += 2;
170
+ }
171
+
172
+ export function serializeString_SWAR_ExperimentalTableEscapes(src: string): void {
173
+ let srcStart = changetype<usize>(src);
26
174
  const srcSize = changetype<OBJECT>(srcStart - TOTAL_OVERHEAD).rtSize;
27
175
  const srcEnd = srcStart + srcSize;
28
176
  const srcEnd8 = srcEnd - 8;
@@ -32,10 +180,9 @@ export function serializeString_SWAR(src: string): void {
32
180
  bs.offset += 2;
33
181
 
34
182
  while (srcStart < srcEnd8) {
35
- let block = load<u64>(srcStart);
36
- store<u64>(bs.offset, block);
37
-
183
+ const block = load<u64>(srcStart);
38
184
  let mask = detect_escapable_u64_swar_safe(block);
185
+ store<u64>(bs.offset, block);
39
186
 
40
187
  if (mask === 0) {
41
188
  srcStart += 8;
@@ -49,7 +196,7 @@ export function serializeString_SWAR(src: string): void {
49
196
  // Even (0 2 4 6) -> Confirmed ASCII Escape
50
197
  // Odd (1 3 5 7) -> Possibly a Unicode code unit or surrogate
51
198
  if ((laneIdx & 1) === 0) {
52
- mask &= ~(0xffff << (laneIdx << 3));
199
+ mask &= mask - 1;
53
200
  const code = load<u16>(srcIdx);
54
201
  const escaped = load<u32>(SERIALIZE_ESCAPE_TABLE + (code << 2));
55
202
 
@@ -69,7 +216,7 @@ export function serializeString_SWAR(src: string): void {
69
216
  }
70
217
  continue;
71
218
  }
72
- mask &= ~(0xffff << (laneIdx << 3));
219
+ mask &= mask - 1;
73
220
 
74
221
  const code = load<u16>(srcIdx - 1);
75
222
  if (code < 0xd800 || code > 0xdfff) continue;
@@ -101,7 +248,7 @@ export function serializeString_SWAR(src: string): void {
101
248
  while (srcStart <= srcEnd - 2) {
102
249
  const code = load<u16>(srcStart);
103
250
 
104
- if (code == 92 || code == 34 || code < 32) {
251
+ if (code == BACK_SLASH || code == QUOTE || code < 32) {
105
252
  const escaped = load<u32>(SERIALIZE_ESCAPE_TABLE + (code << 2));
106
253
  if ((escaped & 0xffff) != BACK_SLASH) {
107
254
  bs.growSize(10);
@@ -144,8 +291,6 @@ export function serializeString_SWAR(src: string): void {
144
291
 
145
292
  store<u16>(bs.offset, 34); // "
146
293
  bs.offset += 2;
147
-
148
- if (isDefined(JSON_CACHE)) sc.insertCached(changetype<usize>(src), srcStart, srcSize);
149
294
  }
150
295
 
151
296
  // @ts-expect-error: @inline is a valid decorator
@@ -158,8 +303,10 @@ export function serializeString_SWAR(src: string): void {
158
303
 
159
304
  // @ts-expect-error: @inline is a valid decorator
160
305
  @inline export function detect_escapable_u64_swar_safe(block: u64): u64 {
306
+ const hi = block & 0xff00_ff00_ff00_ff00;
161
307
  const lo = block & 0x00ff_00ff_00ff_00ff;
162
308
  const ascii_mask = ((lo - 0x0020_0020_0020_0020) | ((lo ^ 0x0022_0022_0022_0022) - 0x0001_0001_0001_0001) | ((lo ^ 0x005c_005c_005c_005c) - 0x0001_0001_0001_0001)) & (0x0080_0080_0080_0080 & ~lo);
309
+ if (hi == 0) return ascii_mask;
163
310
  const hi_mask = ((block - 0x0100_0100_0100_0100) & ~block & 0x8000_8000_8000_8000) ^ 0x8000_8000_8000_8000;
164
311
  return (ascii_mask & (~hi_mask >> 8)) | hi_mask;
165
312
  }
@@ -19,6 +19,6 @@
19
19
  "noUnusedParameters": false,
20
20
  "noImplicitReturns": true,
21
21
  "noFallthroughCasesInSwitch": true,
22
- "noUncheckedIndexedAccess": false,
23
- },
22
+ "noUncheckedIndexedAccess": false
23
+ }
24
24
  }