json-as 1.3.6 → 1.3.8

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 (155) hide show
  1. package/CHANGELOG.md +45 -0
  2. package/README.md +1 -1
  3. package/assembly/deserialize/helpers/uint.ts +4 -1
  4. package/assembly/deserialize/index/arbitrary.ts +7 -3
  5. package/assembly/deserialize/index/array.ts +42 -17
  6. package/assembly/deserialize/index/bool.ts +1 -1
  7. package/assembly/deserialize/index/date.ts +1 -1
  8. package/assembly/deserialize/index/float.ts +40 -1
  9. package/assembly/deserialize/index/integer.ts +68 -1
  10. package/assembly/deserialize/index/map.ts +1 -1
  11. package/assembly/deserialize/index/object.ts +1 -1
  12. package/assembly/deserialize/index/raw.ts +1 -1
  13. package/assembly/deserialize/index/set.ts +1 -1
  14. package/assembly/deserialize/index/staticarray.ts +4 -1
  15. package/assembly/deserialize/index/string.ts +32 -4
  16. package/assembly/deserialize/index/struct.ts +1 -1
  17. package/assembly/deserialize/index/typedarray.ts +30 -10
  18. package/assembly/deserialize/index/unsigned.ts +78 -1
  19. package/assembly/deserialize/index.ts +1 -0
  20. package/assembly/deserialize/{simple → naive}/array/arbitrary.ts +24 -5
  21. package/assembly/deserialize/{simple → naive}/array/array.ts +8 -2
  22. package/assembly/deserialize/naive/array/bool.ts +68 -0
  23. package/assembly/deserialize/{simple → naive}/array/box.ts +8 -2
  24. package/assembly/deserialize/naive/array/float.ts +63 -0
  25. package/assembly/deserialize/{simple → naive}/array/generic.ts +14 -7
  26. package/assembly/deserialize/naive/array/integer.ts +86 -0
  27. package/assembly/deserialize/naive/array/map.ts +47 -0
  28. package/assembly/deserialize/naive/array/object.ts +47 -0
  29. package/assembly/deserialize/{simple → naive}/array/raw.ts +34 -7
  30. package/assembly/deserialize/naive/array/string.ts +69 -0
  31. package/assembly/deserialize/naive/array/struct.ts +47 -0
  32. package/assembly/deserialize/{simple → naive}/array.ts +15 -10
  33. package/assembly/deserialize/{simple → naive}/bool.ts +6 -2
  34. package/assembly/deserialize/naive/float.ts +135 -0
  35. package/assembly/deserialize/{simple → naive}/integer.ts +10 -2
  36. package/assembly/deserialize/{simple → naive}/map.ts +106 -27
  37. package/assembly/deserialize/{simple → naive}/object.ts +65 -19
  38. package/assembly/deserialize/{simple → naive}/raw.ts +4 -1
  39. package/assembly/deserialize/{simple → naive}/set.ts +49 -19
  40. package/assembly/deserialize/{simple → naive}/staticarray/array.ts +1 -1
  41. package/assembly/deserialize/{simple → naive}/staticarray/bool.ts +1 -1
  42. package/assembly/deserialize/{simple → naive}/staticarray/float.ts +1 -1
  43. package/assembly/deserialize/{simple → naive}/staticarray/integer.ts +1 -1
  44. package/assembly/deserialize/{simple → naive}/staticarray/string.ts +11 -3
  45. package/assembly/deserialize/{simple → naive}/staticarray/struct.ts +1 -2
  46. package/assembly/deserialize/{simple → naive}/staticarray.ts +68 -18
  47. package/assembly/deserialize/naive/string.ts +199 -0
  48. package/assembly/deserialize/{simple → naive}/struct.ts +5 -1
  49. package/assembly/deserialize/{simple → naive}/typedarray.ts +17 -4
  50. package/assembly/deserialize/{simple → naive}/unsigned.ts +10 -15
  51. package/assembly/deserialize/simd/array/integer.ts +339 -62
  52. package/assembly/deserialize/simd/float.ts +303 -0
  53. package/assembly/deserialize/simd/integer.ts +233 -0
  54. package/assembly/deserialize/simd/string.ts +266 -107
  55. package/assembly/deserialize/swar/array/arbitrary.ts +11 -3
  56. package/assembly/deserialize/swar/array/array.ts +40 -9
  57. package/assembly/deserialize/swar/array/bool.ts +28 -5
  58. package/assembly/deserialize/swar/array/box.ts +11 -3
  59. package/assembly/deserialize/swar/array/float.ts +295 -7
  60. package/assembly/deserialize/swar/array/generic.ts +28 -7
  61. package/assembly/deserialize/swar/array/integer.ts +363 -112
  62. package/assembly/deserialize/swar/array/map.ts +11 -3
  63. package/assembly/deserialize/swar/array/object.ts +37 -25
  64. package/assembly/deserialize/swar/array/raw.ts +11 -3
  65. package/assembly/deserialize/swar/array/shared.ts +63 -14
  66. package/assembly/deserialize/swar/array/string.ts +140 -7
  67. package/assembly/deserialize/swar/array/struct.ts +66 -12
  68. package/assembly/deserialize/swar/array.ts +12 -51
  69. package/assembly/deserialize/swar/float.ts +304 -0
  70. package/assembly/deserialize/swar/integer.ts +246 -0
  71. package/assembly/deserialize/swar/string.ts +213 -294
  72. package/assembly/deserialize/swar/typedarray.ts +224 -0
  73. package/assembly/index.d.ts +3 -1
  74. package/assembly/index.ts +402 -261
  75. package/assembly/serialize/index/array.ts +1 -1
  76. package/assembly/serialize/index/bool.ts +1 -1
  77. package/assembly/serialize/index/date.ts +1 -1
  78. package/assembly/serialize/index/float.ts +5 -1
  79. package/assembly/serialize/index/integer.ts +1 -1
  80. package/assembly/serialize/index/map.ts +1 -1
  81. package/assembly/serialize/index/raw.ts +1 -1
  82. package/assembly/serialize/index/set.ts +1 -1
  83. package/assembly/serialize/index/staticarray.ts +1 -1
  84. package/assembly/serialize/index/string.ts +1 -1
  85. package/assembly/serialize/index/struct.ts +1 -1
  86. package/assembly/serialize/index/typedarray.ts +21 -12
  87. package/assembly/serialize/index.ts +1 -0
  88. package/assembly/serialize/naive/array.ts +351 -0
  89. package/assembly/serialize/{simple → naive}/float.ts +4 -1
  90. package/assembly/serialize/naive/integer.ts +19 -0
  91. package/assembly/serialize/{simple → naive}/map.ts +6 -2
  92. package/assembly/serialize/{simple → naive}/raw.ts +5 -1
  93. package/assembly/serialize/{simple → naive}/set.ts +6 -1
  94. package/assembly/serialize/{simple → naive}/staticarray.ts +6 -1
  95. package/assembly/serialize/{simple → naive}/string.ts +1 -2
  96. package/assembly/serialize/{simple → naive}/typedarray.ts +10 -3
  97. package/assembly/serialize/simd/string.ts +6 -2
  98. package/assembly/serialize/swar/string.ts +15 -141
  99. package/assembly/util/atoi-fast.ts +81 -0
  100. package/assembly/util/concat.ts +5 -1
  101. package/assembly/util/dragonbox-cache.ts +443 -2
  102. package/assembly/util/dragonbox.ts +53 -17
  103. package/assembly/util/itoa-fast.ts +241 -0
  104. package/assembly/util/masks.ts +18 -1
  105. package/assembly/util/parsefloat-fast.ts +167 -0
  106. package/assembly/util/scanValueEnd.ts +78 -0
  107. package/assembly/util/scientific.ts +132 -0
  108. package/assembly/util/simd-int.ts +191 -0
  109. package/assembly/util/snp.ts +4 -1
  110. package/assembly/util/swar-int.ts +248 -0
  111. package/assembly/util/swar.ts +13 -3
  112. package/lib/as-bs.ts +27 -6
  113. package/package.json +15 -11
  114. package/transform/lib/builder.d.ts.map +1 -1
  115. package/transform/lib/builder.js +13 -5
  116. package/transform/lib/builder.js.map +1 -1
  117. package/transform/lib/index.d.ts +5 -0
  118. package/transform/lib/index.d.ts.map +1 -1
  119. package/transform/lib/index.js +1046 -340
  120. package/transform/lib/index.js.map +1 -1
  121. package/transform/lib/linkers/alias.d.ts.map +1 -1
  122. package/transform/lib/linkers/alias.js.map +1 -1
  123. package/transform/lib/linkers/custom.d.ts.map +1 -1
  124. package/transform/lib/linkers/custom.js +3 -2
  125. package/transform/lib/linkers/custom.js.map +1 -1
  126. package/transform/lib/linkers/imports.d.ts.map +1 -1
  127. package/transform/lib/linkers/imports.js.map +1 -1
  128. package/transform/lib/types.d.ts.map +1 -1
  129. package/transform/lib/types.js +54 -16
  130. package/transform/lib/types.js.map +1 -1
  131. package/transform/lib/util.d.ts.map +1 -1
  132. package/transform/lib/util.js +1 -1
  133. package/transform/lib/util.js.map +1 -1
  134. package/transform/lib/visitor.d.ts.map +1 -1
  135. package/transform/lib/visitor.js +2 -1
  136. package/transform/lib/visitor.js.map +1 -1
  137. package/assembly/custom/util.ts +0 -310
  138. package/assembly/deserialize/simple/arbitrary.ts +0 -23
  139. package/assembly/deserialize/simple/array/bool.ts +0 -17
  140. package/assembly/deserialize/simple/array/float.ts +0 -28
  141. package/assembly/deserialize/simple/array/integer.ts +0 -27
  142. package/assembly/deserialize/simple/array/map.ts +0 -28
  143. package/assembly/deserialize/simple/array/object.ts +0 -28
  144. package/assembly/deserialize/simple/array/string.ts +0 -23
  145. package/assembly/deserialize/simple/array/struct.ts +0 -28
  146. package/assembly/deserialize/simple/float.ts +0 -201
  147. package/assembly/deserialize/simple/string.ts +0 -132
  148. package/assembly/serialize/simple/arbitrary.ts +0 -79
  149. package/assembly/serialize/simple/array.ts +0 -86
  150. package/assembly/serialize/simple/integer.ts +0 -20
  151. package/assembly/serialize/simple/object.ts +0 -42
  152. /package/assembly/deserialize/{simple → naive}/date.ts +0 -0
  153. /package/assembly/serialize/{simple → naive}/bool.ts +0 -0
  154. /package/assembly/serialize/{simple → naive}/date.ts +0 -0
  155. /package/assembly/serialize/{simple → naive}/struct.ts +0 -0
@@ -1,5 +1,14 @@
1
1
  import { JSON } from "../..";
2
- import { BRACKET_LEFT, BRACKET_RIGHT, BRACE_LEFT, BRACE_RIGHT, CHAR_F, CHAR_T, COMMA, QUOTE } from "../../custom/chars";
2
+ import {
3
+ BRACKET_LEFT,
4
+ BRACKET_RIGHT,
5
+ BRACE_LEFT,
6
+ BRACE_RIGHT,
7
+ CHAR_F,
8
+ CHAR_T,
9
+ COMMA,
10
+ QUOTE,
11
+ } from "../../custom/chars";
3
12
  import { isSpace, atoi, scanStringEnd } from "../../util";
4
13
 
5
14
  // @ts-expect-error: Decorator valid here
@@ -41,16 +50,21 @@ import { isSpace, atoi, scanStringEnd } from "../../util";
41
50
  return 0;
42
51
  }
43
52
 
44
- function deserializeSetDirect<T extends Set<any>>(srcStart: usize, srcEnd: usize, out: nonnull<T>, allowWhitespace: bool = false): usize {
45
- if (srcStart >= srcEnd || load<u16>(srcStart) != BRACKET_LEFT) throw new Error("Expected '[' at start of set");
53
+ function deserializeSetDirect<T extends Set<any>>(
54
+ srcStart: usize,
55
+ srcEnd: usize,
56
+ out: nonnull<T>,
57
+ ): usize {
58
+ if (srcStart >= srcEnd || load<u16>(srcStart) != BRACKET_LEFT)
59
+ throw new Error("Expected '[' at start of set");
46
60
 
47
61
  srcStart += 2;
48
- if (allowWhitespace) while (srcStart < srcEnd && isSpace(load<u16>(srcStart))) srcStart += 2;
62
+ while (srcStart < srcEnd && isSpace(load<u16>(srcStart))) srcStart += 2;
49
63
  if (srcStart >= srcEnd) throw new Error("Unterminated set");
50
64
  if (load<u16>(srcStart) == BRACKET_RIGHT) return srcStart + 2;
51
65
 
52
66
  while (srcStart < srcEnd) {
53
- if (allowWhitespace) while (srcStart < srcEnd && isSpace(load<u16>(srcStart))) srcStart += 2;
67
+ while (srcStart < srcEnd && isSpace(load<u16>(srcStart))) srcStart += 2;
54
68
  const code = load<u16>(srcStart);
55
69
 
56
70
  // @ts-ignore: type
@@ -80,7 +94,7 @@ function deserializeSetDirect<T extends Set<any>>(srcStart: usize, srcEnd: usize
80
94
  let ptr = srcStart + 2;
81
95
  while (ptr < srcEnd) {
82
96
  const next = load<u16>(ptr);
83
- if (next == COMMA || next == BRACKET_RIGHT || (allowWhitespace && isSpace(next))) break;
97
+ if (next == COMMA || next == BRACKET_RIGHT || isSpace(next)) break;
84
98
  ptr += 2;
85
99
  }
86
100
  // @ts-ignore: type
@@ -92,7 +106,7 @@ function deserializeSetDirect<T extends Set<any>>(srcStart: usize, srcEnd: usize
92
106
  let ptr = srcStart + 2;
93
107
  while (ptr < srcEnd) {
94
108
  const next = load<u16>(ptr);
95
- if (next == COMMA || next == BRACKET_RIGHT || (allowWhitespace && isSpace(next))) break;
109
+ if (next == COMMA || next == BRACKET_RIGHT || isSpace(next)) break;
96
110
  ptr += 2;
97
111
  }
98
112
  // @ts-ignore: type
@@ -109,12 +123,12 @@ function deserializeSetDirect<T extends Set<any>>(srcStart: usize, srcEnd: usize
109
123
  break;
110
124
  }
111
125
 
112
- if (allowWhitespace) while (srcStart < srcEnd && isSpace(load<u16>(srcStart))) srcStart += 2;
126
+ while (srcStart < srcEnd && isSpace(load<u16>(srcStart))) srcStart += 2;
113
127
  if (srcStart >= srcEnd) break;
114
128
  const next = load<u16>(srcStart);
115
129
  if (next == COMMA) {
116
130
  srcStart += 2;
117
- if (allowWhitespace) while (srcStart < srcEnd && isSpace(load<u16>(srcStart))) srcStart += 2;
131
+ while (srcStart < srcEnd && isSpace(load<u16>(srcStart))) srcStart += 2;
118
132
  continue;
119
133
  }
120
134
  if (next == BRACKET_RIGHT) return srcStart + 2;
@@ -124,31 +138,47 @@ function deserializeSetDirect<T extends Set<any>>(srcStart: usize, srcEnd: usize
124
138
  throw new Error("Failed to parse JSON!");
125
139
  }
126
140
 
127
- export function deserializeSet<T extends Set<any>>(srcStart: usize, srcEnd: usize, dst: usize): T {
128
- const out = changetype<nonnull<T>>(dst || changetype<usize>(instantiate<T>()));
141
+ export function deserializeSet<T extends Set<any>>(
142
+ srcStart: usize,
143
+ srcEnd: usize,
144
+ dst: usize,
145
+ ): T {
146
+ const out = changetype<nonnull<T>>(
147
+ dst || changetype<usize>(instantiate<T>()),
148
+ );
129
149
  out.clear();
130
150
 
131
- while (srcStart < srcEnd && isSpace(load<u16>(srcStart))) srcStart += 2;
132
151
  while (srcEnd > srcStart && isSpace(load<u16>(srcEnd - 2))) srcEnd -= 2;
133
152
 
134
- if (srcStart >= srcEnd) throw new Error("Input string had zero length or was all whitespace");
135
- const end = deserializeSetDirect<T>(srcStart, srcEnd, out, true);
153
+ if (srcStart >= srcEnd)
154
+ throw new Error("Input string had zero length or was all whitespace");
155
+ const end = deserializeSetDirect<T>(srcStart, srcEnd, out);
136
156
  if (end != srcEnd) throw new Error("Expected ']' at end of set");
137
157
  return out;
138
158
  }
139
159
 
140
160
  // @ts-expect-error: Decorator valid here
141
- @inline export function deserializeSetInto<T extends Set<any>>(srcStart: usize, srcEnd: usize, out: T): usize {
161
+ @inline function deserializeSetBody<T extends Set<any>>(
162
+ srcStart: usize,
163
+ srcEnd: usize,
164
+ out: T,
165
+ ): usize {
142
166
  changetype<nonnull<T>>(out).clear();
143
167
  return deserializeSetDirect<T>(srcStart, srcEnd, changetype<nonnull<T>>(out));
144
168
  }
145
169
 
146
170
  // @ts-expect-error: Decorator valid here
147
- @inline export function deserializeSetField<T extends Set<any>>(srcStart: usize, srcEnd: usize, dstObj: usize, dstOffset: usize = 0): usize {
148
- let out = load<T>(dstObj, dstOffset);
171
+ @inline export function deserializeSetField<T extends Set<any>>(
172
+ srcStart: usize,
173
+ srcEnd: usize,
174
+ dstObj: usize,
175
+ dstOffset: usize = 0,
176
+ ): usize {
177
+ const fieldPtr = dstObj + dstOffset;
178
+ let out = load<T>(fieldPtr);
149
179
  if (!changetype<usize>(out)) {
150
180
  out = changetype<T>(instantiate<T>());
151
- store<T>(dstObj, out, dstOffset);
181
+ store<T>(fieldPtr, out);
152
182
  }
153
- return deserializeSetInto<T>(srcStart, srcEnd, out);
183
+ return deserializeSetBody<T>(srcStart, srcEnd, out);
154
184
  }
@@ -19,7 +19,7 @@ export function deserializeStaticArrayArray<T extends StaticArray<any>>(
19
19
  ptr += 2;
20
20
  }
21
21
 
22
- const outSize = count << (alignof<valueof<T>>());
22
+ const outSize = count * sizeof<valueof<T>>();
23
23
  const out = changetype<nonnull<T>>(dst || __new(outSize, idof<T>()));
24
24
 
25
25
  // Second pass: populate values
@@ -20,7 +20,7 @@ export function deserializeStaticArrayBoolean<T extends StaticArray<any>>(
20
20
  }
21
21
 
22
22
  // Allocate StaticArray with correct size
23
- const outSize = count << (alignof<valueof<T>>());
23
+ const outSize = count * sizeof<valueof<T>>();
24
24
  const out = changetype<nonnull<T>>(dst || __new(outSize, idof<T>()));
25
25
 
26
26
  // Second pass: populate values
@@ -23,7 +23,7 @@ export function deserializeStaticArrayFloat<T extends StaticArray<any>>(
23
23
  ptr += 2;
24
24
  }
25
25
 
26
- const outSize = count << (alignof<valueof<T>>());
26
+ const outSize = count * sizeof<valueof<T>>();
27
27
  const out = changetype<nonnull<T>>(dst || __new(outSize, idof<T>()));
28
28
 
29
29
  let index = 0;
@@ -22,7 +22,7 @@ export function deserializeStaticArrayInteger<T extends StaticArray<any>>(
22
22
  ptr += 2;
23
23
  }
24
24
 
25
- const outSize = count << (alignof<valueof<T>>());
25
+ const outSize = count * sizeof<valueof<T>>();
26
26
  const out = changetype<nonnull<T>>(dst || __new(outSize, idof<T>()));
27
27
 
28
28
  // Second pass: populate values
@@ -2,7 +2,11 @@ import { JSON } from "../../..";
2
2
  import { QUOTE } from "../../../custom/chars";
3
3
  import { isUnescapedQuote } from "../../../util";
4
4
 
5
- export function deserializeStaticArrayString(srcStart: usize, srcEnd: usize, dst: usize): StaticArray<string> {
5
+ export function deserializeStaticArrayString(
6
+ srcStart: usize,
7
+ srcEnd: usize,
8
+ dst: usize,
9
+ ): StaticArray<string> {
6
10
  // First pass: count elements using same logic as Array deserializer
7
11
  let count: i32 = 0;
8
12
  let ptr = srcStart;
@@ -22,7 +26,9 @@ export function deserializeStaticArrayString(srcStart: usize, srcEnd: usize, dst
22
26
 
23
27
  // Allocate StaticArray with correct size
24
28
  const outSize = (<usize>count) << alignof<string>();
25
- const out = changetype<StaticArray<string>>(dst || __new(outSize, idof<StaticArray<string>>()));
29
+ const out = changetype<StaticArray<string>>(
30
+ dst || __new(outSize, idof<StaticArray<string>>()),
31
+ );
26
32
 
27
33
  // Second pass: populate values
28
34
  let index = 0;
@@ -35,7 +41,9 @@ export function deserializeStaticArrayString(srcStart: usize, srcEnd: usize, dst
35
41
  inString = true;
36
42
  lastPos = srcStart;
37
43
  } else if (isUnescapedQuote(srcStart)) {
38
- unchecked((out[index++] = JSON.__deserialize<string>(lastPos, srcStart + 2)));
44
+ unchecked(
45
+ (out[index++] = JSON.__deserialize<string>(lastPos, srcStart + 2)),
46
+ );
39
47
  inString = false;
40
48
  }
41
49
  }
@@ -12,7 +12,6 @@ export function deserializeStaticArrayStruct<T extends StaticArray<any>>(
12
12
  srcEnd: usize,
13
13
  dst: usize,
14
14
  ): T {
15
- while (srcStart < srcEnd && isSpace(load<u16>(srcStart))) srcStart += 2;
16
15
  while (srcEnd > srcStart && isSpace(load<u16>(srcEnd - 2))) srcEnd -= 2;
17
16
 
18
17
  if (srcStart - srcEnd == 0)
@@ -44,7 +43,7 @@ export function deserializeStaticArrayStruct<T extends StaticArray<any>>(
44
43
  }
45
44
 
46
45
  // Allocate StaticArray with correct size
47
- const outSize = count << (alignof<valueof<T>>());
46
+ const outSize = count * sizeof<valueof<T>>();
48
47
  const out = changetype<nonnull<T>>(dst || __new(outSize, idof<T>()));
49
48
 
50
49
  // Second pass: populate values
@@ -4,21 +4,24 @@ import { deserializeArbitraryArray } from "./array/arbitrary";
4
4
  import { deserializeArrayArray } from "./array/array";
5
5
  import { deserializeBooleanArray } from "./array/bool";
6
6
  import { deserializeBoxArray } from "./array/box";
7
- import { deserializeFloatArray } from "./array/float";
8
- import { deserializeIntegerArray } from "./array/integer";
7
+ import { deserializeFloatArray_NAIVE } from "./array/float";
8
+ import { deserializeIntegerArray_NAIVE } from "./array/integer";
9
9
  import { deserializeMapArray } from "./array/map";
10
10
  import { deserializeObjectArray } from "./array/object";
11
11
  import { deserializeRawArray } from "./array/raw";
12
12
  import { deserializeStructArray } from "./array/struct";
13
- import { deserializeStringArray } from "./array/string";
13
+ import { deserializeStringArray_NAIVE } from "./array/string";
14
14
  import { deserializeStaticArrayBoolean } from "./staticarray/bool";
15
15
  import { deserializeStaticArrayFloat } from "./staticarray/float";
16
16
  import { deserializeStaticArrayInteger } from "./staticarray/integer";
17
17
  import { deserializeStaticArrayString } from "./staticarray/string";
18
- import { scanValueEnd } from "../swar/array/shared";
18
+ import { scanValueEnd } from "../../util/scanValueEnd";
19
19
 
20
20
 
21
- @inline function materializeStaticArray<T extends StaticArray<any>>(src: valueof<T>[], dst: usize): T {
21
+ @inline function materializeStaticArray<T extends StaticArray<any>>(
22
+ src: valueof<T>[],
23
+ dst: usize,
24
+ ): T {
22
25
  const byteLength = <usize>src.length * sizeof<valueof<T>>();
23
26
  let out = dst;
24
27
 
@@ -35,7 +38,11 @@ import { scanValueEnd } from "../swar/array/shared";
35
38
  return typed;
36
39
  }
37
40
 
38
- export function deserializeStaticArray<T extends StaticArray<any>>(srcStart: usize, srcEnd: usize, dst: usize): T {
41
+ export function deserializeStaticArray<T extends StaticArray<any>>(
42
+ srcStart: usize,
43
+ srcEnd: usize,
44
+ dst: usize,
45
+ ): T {
39
46
  if (isString<valueof<T>>()) {
40
47
  return changetype<T>(deserializeStaticArrayString(srcStart, srcEnd, dst));
41
48
  } else if (isBoolean<valueof<T>>()) {
@@ -45,27 +52,61 @@ export function deserializeStaticArray<T extends StaticArray<any>>(srcStart: usi
45
52
  } else if (isFloat<valueof<T>>()) {
46
53
  return deserializeStaticArrayFloat<T>(srcStart, srcEnd, dst);
47
54
  } else if (isArray<valueof<T>>()) {
48
- return materializeStaticArray<T>(deserializeArrayArray<valueof<T>[]>(srcStart, srcEnd, 0), dst);
55
+ return materializeStaticArray<T>(
56
+ deserializeArrayArray<valueof<T>[]>(srcStart, srcEnd, 0),
57
+ dst,
58
+ );
49
59
  } else if (isManaged<valueof<T>>() || isReference<valueof<T>>()) {
50
60
  const type = changetype<nonnull<valueof<T>>>(0);
51
61
  if (type instanceof StaticArray) {
52
- return materializeStaticArray<T>(deserializeArrayArray<valueof<T>[]>(srcStart, srcEnd, 0), dst);
62
+ return materializeStaticArray<T>(
63
+ deserializeArrayArray<valueof<T>[]>(srcStart, srcEnd, 0),
64
+ dst,
65
+ );
53
66
  } else if (type instanceof JSON.Value) {
54
- return materializeStaticArray<T>(changetype<valueof<T>[]>(deserializeArbitraryArray(srcStart, srcEnd, 0)), dst);
67
+ return materializeStaticArray<T>(
68
+ changetype<valueof<T>[]>(
69
+ deserializeArbitraryArray(srcStart, srcEnd, 0),
70
+ ),
71
+ dst,
72
+ );
55
73
  } else if (type instanceof JSON.Box) {
56
- return materializeStaticArray<T>(changetype<valueof<T>[]>(deserializeBoxArray<valueof<T>[]>(srcStart, srcEnd, 0)), dst);
74
+ return materializeStaticArray<T>(
75
+ changetype<valueof<T>[]>(
76
+ deserializeBoxArray<valueof<T>[]>(srcStart, srcEnd, 0),
77
+ ),
78
+ dst,
79
+ );
57
80
  } else if (type instanceof JSON.Obj) {
58
- return materializeStaticArray<T>(deserializeObjectArray<valueof<T>[]>(srcStart, srcEnd, 0), dst);
81
+ return materializeStaticArray<T>(
82
+ deserializeObjectArray<valueof<T>[]>(srcStart, srcEnd, 0),
83
+ dst,
84
+ );
59
85
  } else if (type instanceof JSON.Raw) {
60
- return materializeStaticArray<T>(changetype<valueof<T>[]>(deserializeRawArray(srcStart, srcEnd, 0)), dst);
86
+ return materializeStaticArray<T>(
87
+ changetype<valueof<T>[]>(deserializeRawArray(srcStart, srcEnd, 0)),
88
+ dst,
89
+ );
61
90
  } else if (type instanceof Map) {
62
- return materializeStaticArray<T>(deserializeMapArray<valueof<T>[]>(srcStart, srcEnd, 0), dst);
91
+ return materializeStaticArray<T>(
92
+ deserializeMapArray<valueof<T>[]>(srcStart, srcEnd, 0),
93
+ dst,
94
+ );
63
95
  // @ts-ignore: supplied by transform
64
96
  } else if (isDefined(type.__DESERIALIZE_CUSTOM)) {
65
- return materializeStaticArray<T>(deserializeStructArray<valueof<T>[]>(srcStart, srcEnd, 0), dst);
97
+ return materializeStaticArray<T>(
98
+ deserializeStructArray<valueof<T>[]>(srcStart, srcEnd, 0),
99
+ dst,
100
+ );
66
101
  // @ts-ignore: supplied by transform
67
- } else if (isDefined(type.__DESERIALIZE_SLOW) || isDefined(type.__DESERIALIZE_FAST)) {
68
- return materializeStaticArray<T>(deserializeStructArray<valueof<T>[]>(srcStart, srcEnd, 0), dst);
102
+ } else if (
103
+ isDefined(type.__DESERIALIZE_SLOW) ||
104
+ isDefined(type.__DESERIALIZE_FAST)
105
+ ) {
106
+ return materializeStaticArray<T>(
107
+ deserializeStructArray<valueof<T>[]>(srcStart, srcEnd, 0),
108
+ dst,
109
+ );
69
110
  }
70
111
  }
71
112
 
@@ -73,12 +114,21 @@ export function deserializeStaticArray<T extends StaticArray<any>>(srcStart: usi
73
114
  }
74
115
 
75
116
 
76
- @inline export function deserializeStaticArrayField<T extends StaticArray<any>>(srcStart: usize, srcEnd: usize, dstObj: usize, dstOffset: usize = 0): usize {
117
+ @inline export function deserializeStaticArrayField<T extends StaticArray<any>>(
118
+ srcStart: usize,
119
+ srcEnd: usize,
120
+ dstObj: usize,
121
+ dstOffset: usize = 0,
122
+ ): usize {
77
123
  const valueEnd = scanValueEnd(srcStart, srcEnd);
78
124
  if (!valueEnd) throw new Error("Failed to parse JSON!");
79
125
 
80
126
  const fieldPtr = dstObj + dstOffset;
81
- const out = deserializeStaticArray<T>(srcStart, valueEnd, load<usize>(fieldPtr));
127
+ const out = deserializeStaticArray<T>(
128
+ srcStart,
129
+ valueEnd,
130
+ load<usize>(fieldPtr),
131
+ );
82
132
  store<T>(fieldPtr, out);
83
133
  return valueEnd;
84
134
  }
@@ -0,0 +1,199 @@
1
+ import { bs } from "../../../lib/as-bs";
2
+ import { OBJECT, TOTAL_OVERHEAD } from "rt/common";
3
+ import { __heap_base } from "memory";
4
+ import { BACK_SLASH, QUOTE } from "../../custom/chars";
5
+ import { DESERIALIZE_ESCAPE_TABLE } from "../../globals/tables";
6
+
7
+ // @ts-ignore: inline
8
+ @inline function hexDigit(c: u16): u32 {
9
+ if (c <= 0x39) return c - 0x30; // '0'-'9'
10
+ if (c <= 0x46) return c - 0x37; // 'A'-'F'
11
+ return c - 0x57; // 'a'-'f'
12
+ }
13
+
14
+ // @ts-ignore: inline
15
+ @inline function hex4ToU16(srcStart: usize): u16 {
16
+ return <u16>(
17
+ ((hexDigit(load<u16>(srcStart)) << 12) |
18
+ (hexDigit(load<u16>(srcStart, 2)) << 8) |
19
+ (hexDigit(load<u16>(srcStart, 4)) << 4) |
20
+ hexDigit(load<u16>(srcStart, 6)))
21
+ );
22
+ }
23
+
24
+ // @ts-ignore: inline
25
+ @inline function isHexDigit(c: u16): bool {
26
+ return (
27
+ (c >= 0x30 && c <= 0x39) ||
28
+ (c >= 0x41 && c <= 0x46) ||
29
+ (c >= 0x61 && c <= 0x66)
30
+ );
31
+ }
32
+
33
+ // Strict RFC 8259 check for the char following a backslash, at [escPtr, srcEnd).
34
+ // Legal escapes: " \ / b f n r t and \uXXXX (4 hex digits). Throws otherwise:
35
+ // unknown escape letter, a trailing backslash, or a short / non-hex \u.
36
+ // @ts-ignore: inline
37
+ @inline function validateEscape(escPtr: usize, srcEnd: usize): void {
38
+ if (escPtr >= srcEnd)
39
+ throw new Error("Invalid JSON string: incomplete escape");
40
+ const code = load<u16>(escPtr);
41
+ if (code == 0x75) {
42
+ // \uXXXX
43
+ if (escPtr + 10 > srcEnd)
44
+ throw new Error("Invalid JSON string: incomplete \\u escape");
45
+ if (
46
+ !isHexDigit(load<u16>(escPtr, 2)) ||
47
+ !isHexDigit(load<u16>(escPtr, 4)) ||
48
+ !isHexDigit(load<u16>(escPtr, 6)) ||
49
+ !isHexDigit(load<u16>(escPtr, 8))
50
+ )
51
+ throw new Error("Invalid JSON string: \\u escape needs 4 hex digits");
52
+ return;
53
+ }
54
+ // short escapes: " \ / b f n r t
55
+ if (
56
+ code != 0x22 &&
57
+ code != 0x5c &&
58
+ code != 0x2f &&
59
+ code != 0x62 &&
60
+ code != 0x66 &&
61
+ code != 0x6e &&
62
+ code != 0x72 &&
63
+ code != 0x74
64
+ )
65
+ throw new Error("Invalid JSON string: illegal escape");
66
+ }
67
+
68
+ // @ts-ignore: inline
69
+ @inline export function deserializeString_NAIVE(
70
+ srcStart: usize,
71
+ srcEnd: usize,
72
+ ): string {
73
+ // RFC 8259: a string is quote-framed. All callers pass quote-inclusive
74
+ // bounds, so the first and last chars must be `"` (rejects `"` alone and
75
+ // trailing garbage like `""x`).
76
+ if (
77
+ srcEnd - srcStart < 4 ||
78
+ load<u16>(srcStart) != QUOTE ||
79
+ load<u16>(srcEnd - 2) != QUOTE
80
+ )
81
+ throw new Error("Invalid JSON string: missing surrounding quotes");
82
+ // Strip quotes
83
+ srcStart += 2;
84
+ srcEnd -= 2;
85
+ const outStart = bs.offset - bs.buffer;
86
+ bs.ensureSize(u32(srcEnd - srcStart));
87
+
88
+ while (srcStart < srcEnd) {
89
+ const block = load<u16>(srcStart);
90
+ store<u16>(bs.offset, block);
91
+ srcStart += 2;
92
+
93
+ // Early exit
94
+ if (block !== 0x5c) {
95
+ // RFC 8259: literal control chars (U+0000..U+001F) must be escaped.
96
+ if (block < 0x20)
97
+ throw new Error("Invalid JSON string: unescaped control character");
98
+ bs.offset += 2;
99
+ continue;
100
+ }
101
+
102
+ validateEscape(srcStart, srcEnd);
103
+ const code = load<u16>(srcStart);
104
+ if (code !== 0x75) {
105
+ // Short escapes (\n \t \" \\)
106
+ const block = load<u16>(srcStart);
107
+ const escape = load<u16>(DESERIALIZE_ESCAPE_TABLE + block);
108
+ store<u16>(bs.offset, escape);
109
+ srcStart += 2;
110
+ } else {
111
+ // Unicode escape (\uXXXX)
112
+ const escaped = hex4ToU16(srcStart + 2);
113
+ store<u16>(bs.offset, escaped);
114
+ srcStart += 10;
115
+ }
116
+
117
+ bs.offset += 2;
118
+ }
119
+ return bs.sliceOut<string>(outStart);
120
+ }
121
+
122
+ // Writes into the destination field, reusing or resizing the backing string.
123
+ // Mirrors `writeStringToField` in ../swar/string.ts.
124
+ // @ts-ignore: inline
125
+ @inline function writeStringToField(
126
+ dstFieldPtr: usize,
127
+ srcStart: usize,
128
+ byteLength: u32,
129
+ ): void {
130
+ if (byteLength == 0) {
131
+ store<usize>(dstFieldPtr, changetype<usize>(""));
132
+ return;
133
+ }
134
+
135
+ const current = load<usize>(dstFieldPtr);
136
+ let stringPtr: usize;
137
+ if (current >= __heap_base) {
138
+ if (changetype<OBJECT>(current - TOTAL_OVERHEAD).rtSize == byteLength) {
139
+ stringPtr = current;
140
+ } else {
141
+ stringPtr = __renew(current, byteLength);
142
+ store<usize>(dstFieldPtr, stringPtr);
143
+ }
144
+ } else {
145
+ stringPtr = __new(byteLength, idof<string>());
146
+ store<usize>(dstFieldPtr, stringPtr);
147
+ }
148
+ memory.copy(stringPtr, srcStart, byteLength);
149
+ }
150
+
151
+ // @ts-ignore: inline
152
+ @inline export function deserializeStringField_NAIVE<T extends string | null>(
153
+ srcStart: usize,
154
+ srcEnd: usize,
155
+ dstObj: usize,
156
+ dstOffset: usize = 0,
157
+ ): usize {
158
+ const dstFieldPtr = dstObj + dstOffset;
159
+ if (srcStart + 2 > srcEnd || load<u16>(srcStart) != QUOTE)
160
+ abort("Expected leading quote");
161
+
162
+ const payloadStart = srcStart + 2;
163
+ srcStart = payloadStart;
164
+
165
+ bs.offset = bs.buffer;
166
+ bs.ensureSize(<u32>(srcEnd - payloadStart));
167
+
168
+ while (srcStart < srcEnd) {
169
+ const block = load<u16>(srcStart);
170
+
171
+ if (block == QUOTE) {
172
+ writeStringToField(dstFieldPtr, bs.buffer, <u32>(bs.offset - bs.buffer));
173
+ bs.offset = bs.buffer;
174
+ return srcStart + 2;
175
+ }
176
+
177
+ if (block != BACK_SLASH) {
178
+ store<u16>(bs.offset, block);
179
+ bs.offset += 2;
180
+ srcStart += 2;
181
+ continue;
182
+ }
183
+
184
+ const code = load<u16>(srcStart, 2);
185
+ if (code !== 0x75) {
186
+ // Short escapes (\n \t \" \\)
187
+ store<u16>(bs.offset, load<u16>(DESERIALIZE_ESCAPE_TABLE + code));
188
+ srcStart += 4;
189
+ } else {
190
+ // Unicode escape (\uXXXX)
191
+ store<u16>(bs.offset, hex4ToU16(srcStart + 4));
192
+ srcStart += 12;
193
+ }
194
+ bs.offset += 2;
195
+ }
196
+
197
+ abort("Expected closing quote");
198
+ return 0;
199
+ }
@@ -1,4 +1,8 @@
1
- export function deserializeStruct<T>(srcStart: usize, srcEnd: usize, dst: usize): T {
1
+ export function deserializeStruct<T>(
2
+ srcStart: usize,
3
+ srcEnd: usize,
4
+ dst: usize,
5
+ ): T {
2
6
  const out = changetype<nonnull<T>>(dst || __new(offsetof<T>(), idof<T>()));
3
7
 
4
8
  // @ts-ignore: supplied by transform
@@ -1,5 +1,5 @@
1
1
  import { COMMA, BRACKET_RIGHT } from "../../custom/chars";
2
- import { deserializeFloat } from "./float";
2
+ import { deserializeFloat_NAIVE } from "./float";
3
3
  import { atoi, isSpace } from "../../util";
4
4
 
5
5
 
@@ -25,7 +25,11 @@ import { atoi, isSpace } from "../../util";
25
25
  return count;
26
26
  }
27
27
 
28
- export function deserializeTypedArray<T extends ArrayLike<number>>(srcStart: usize, srcEnd: usize, dst: usize = 0): T {
28
+ export function deserializeTypedArray_NAIVE<T extends ArrayLike<number>>(
29
+ srcStart: usize,
30
+ srcEnd: usize,
31
+ dst: usize = 0,
32
+ ): T {
29
33
  const count = countTypedArrayElements(srcStart, srcEnd);
30
34
  let out = changetype<T>(dst || changetype<usize>(instantiate<T>(count)));
31
35
 
@@ -44,7 +48,12 @@ export function deserializeTypedArray<T extends ArrayLike<number>>(srcStart: usi
44
48
  const code = load<u16>(srcStart);
45
49
  if (code == COMMA || code == BRACKET_RIGHT || isSpace(code)) {
46
50
  if (isFloat<valueof<T>>()) {
47
- unchecked((out[index++] = deserializeFloat<valueof<T>>(lastIndex, srcStart)));
51
+ unchecked(
52
+ (out[index++] = deserializeFloat_NAIVE<valueof<T>>(
53
+ lastIndex,
54
+ srcStart,
55
+ )),
56
+ );
48
57
  } else {
49
58
  unchecked((out[index++] = atoi<valueof<T>>(lastIndex, srcStart)));
50
59
  }
@@ -60,7 +69,11 @@ export function deserializeTypedArray<T extends ArrayLike<number>>(srcStart: usi
60
69
  return out;
61
70
  }
62
71
 
63
- export function deserializeArrayBuffer(srcStart: usize, srcEnd: usize, dst: usize = 0): ArrayBuffer {
72
+ export function deserializeArrayBuffer_NAIVE(
73
+ srcStart: usize,
74
+ srcEnd: usize,
75
+ dst: usize = 0,
76
+ ): ArrayBuffer {
64
77
  const count = countTypedArrayElements(srcStart, srcEnd);
65
78
  let out = dst ? changetype<ArrayBuffer>(dst) : new ArrayBuffer(count);
66
79
 
@@ -1,12 +1,20 @@
1
1
  import { atoi } from "../../util/atoi";
2
2
 
3
3
  // @ts-ignore: inline
4
- @inline export function deserializeUnsigned<T>(srcStart: usize, srcEnd: usize): T {
4
+ @inline export function deserializeUnsigned_NAIVE<T extends number>(
5
+ srcStart: usize,
6
+ srcEnd: usize,
7
+ ): T {
5
8
  return atoi<T>(srcStart, srcEnd);
6
9
  }
7
10
 
8
11
  // @ts-ignore: inline
9
- @inline export function deserializeUnsignedField<T extends number>(srcStart: usize, srcEnd: usize, dstObj: usize, dstOffset: usize = 0): usize {
12
+ @inline export function deserializeUnsignedField_NAIVE<T extends number>(
13
+ srcStart: usize,
14
+ srcEnd: usize,
15
+ dstObj: usize,
16
+ dstOffset: usize = 0,
17
+ ): usize {
10
18
  const fieldPtr = dstObj + dstOffset;
11
19
  let digit = <u32>load<u16>(srcStart) - 48;
12
20
  if (digit > 9) unreachable();
@@ -61,16 +69,3 @@ import { atoi } from "../../util/atoi";
61
69
  return srcStart;
62
70
  }
63
71
  }
64
-
65
- export function deserializeUnsignedScan<T extends number>(src: usize, dst: usize): usize {
66
- let digit = <T>load<u16>(src) - 48;
67
- if (digit > 9) abort("Found invalid digit");
68
- let val = digit;
69
- src += 2;
70
- while ((digit = <u32>load<u16>(src) - 48) < 10) {
71
- val = val * 10 + digit;
72
- src += 2;
73
- }
74
- store<T>(dst, val);
75
- return src;
76
- }