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
@@ -0,0 +1,224 @@
1
+ // SWAR-mode TypedArray / ArrayBuffer deserializer.
2
+ //
3
+ // The naive variant in `../naive/typedarray.ts` does two scalar passes
4
+ // (count digit-starts, then call `JSON.__deserialize` per element which
5
+ // re-scans the same digits). This rewrite replaces both passes:
6
+ //
7
+ // - **No count pass.** TypedArrays have a fixed length at construction,
8
+ // so the natural approach is to count first then allocate. We tried
9
+ // that with a SWAR comma counter — it cut the per-element cost but
10
+ // kept us ~30% below the top-level `f64[]` path because the count
11
+ // scan still touched the whole input twice. Instead we allocate
12
+ // worst-case (`(srcEnd - srcStart) >> 2 + 1` elements — each
13
+ // element needs >= "D," = 2 UTF-16 chars = 4 bytes) and `__renew`
14
+ // the underlying buffer down to the exact byte count after parsing.
15
+ // The over-allocation peaks at ~2-3× the final size for typical
16
+ // payloads; the trim is a single `memory.copy` on the GC's terms.
17
+ //
18
+ // - **Inline parse.** The integer parsers come from `./array/integer.ts`
19
+ // (refactored to take element type `E` so the same
20
+ // `parseSignedIntegerSWAR` serves `Array<i32>` and `Int32Array`).
21
+ // The float parser comes from `./array/float.ts`. Stores write
22
+ // directly to `dataStart + index * elementSize`, bypassing the
23
+ // typed-array's bounds-checked `[]=` setter.
24
+
25
+ import { isSpace } from "../../util";
26
+ import { BRACKET_LEFT, BRACKET_RIGHT, COMMA } from "../../custom/chars";
27
+ import { parseFloatElementSWAR } from "./array/float";
28
+ import {
29
+ parseSignedIntegerSWAR,
30
+ parseUnsignedIntegerSWAR,
31
+ } from "./array/integer";
32
+
33
+ /**
34
+ * SWAR TypedArray deserializer.
35
+ *
36
+ * Counts commas (with empty-body detection), allocates the typed array
37
+ * at the exact size, then parses each element inline with no per-call
38
+ * function dispatch. Stores write directly to `dataStart + idx *
39
+ * elementSize`, bypassing the typed-array's bounds-checked `[]=` setter.
40
+ *
41
+ * Falls through to the underlying SWAR float / integer parsers; the
42
+ * element type (`f32/f64/u8/i32/...`) is detected via `isFloat<E>()` /
43
+ * `isSigned<E>()` and AS folds the type dispatch at compile time.
44
+ */
45
+ /**
46
+ * Worst-case element count: each element occupies >= 1 digit + 1
47
+ * delimiter = 2 UTF-16 chars = 4 bytes. So `(srcEnd - srcStart) >> 2`
48
+ * upper-bounds the count. Allocating to worst-case lets us skip a
49
+ * full count pass over the input — at the cost of an over-allocated
50
+ * underlying buffer that we trim via `__renew` once we know the
51
+ * actual element count.
52
+ *
53
+ * For a top-level f64[] payload of ~64 MiB JSON encoding 6M floats,
54
+ * worst-case alloc is ~16M f64 = 128 MB temporarily. We trim back
55
+ * to ~48 MB after parse. The trim is a wasm `memory.copy` (or just
56
+ * a length update if the runtime supports in-place shrink), much
57
+ * cheaper than a second 64 MB scan over the input.
58
+ */
59
+ export function deserializeTypedArray_SWAR<T extends ArrayLike<number>>(
60
+ srcStart: usize,
61
+ srcEnd: usize,
62
+ dst: usize = 0,
63
+ ): T {
64
+ // Find the opening `[`, then skip whitespace to the first non-WS char.
65
+ while (srcStart < srcEnd) {
66
+ const ch = load<u16>(srcStart);
67
+ if (ch == BRACKET_LEFT) {
68
+ srcStart += 2;
69
+ break;
70
+ }
71
+ srcStart += 2;
72
+ }
73
+ while (srcStart < srcEnd && isSpace(load<u16>(srcStart))) srcStart += 2;
74
+
75
+ // Empty-array fast path.
76
+ if (srcStart >= srcEnd || load<u16>(srcStart) == BRACKET_RIGHT) {
77
+ let out = changetype<T>(dst || changetype<usize>(instantiate<T>(0)));
78
+ if (out.length != 0) out = changetype<T>(instantiate<T>(0));
79
+ return out;
80
+ }
81
+
82
+ const elementSize = sizeof<valueof<T>>();
83
+ const maxElements = i32((<usize>(srcEnd - srcStart)) >> 2) + 1;
84
+ let out = changetype<T>(
85
+ dst || changetype<usize>(instantiate<T>(maxElements)),
86
+ );
87
+ if (out.length != maxElements) {
88
+ out = changetype<T>(instantiate<T>(maxElements));
89
+ }
90
+
91
+ const dataStart = out.dataStart;
92
+ let writePtr = dataStart;
93
+
94
+ // Parse loop. Each element parses into the slot at `writePtr`, then
95
+ // the separator (`,` or `]`) is consumed. Whitespace surrounding the
96
+ // separator is skipped to match the naive variant's behaviour.
97
+ while (srcStart < srcEnd) {
98
+ let next: usize = 0;
99
+ if (isFloat<valueof<T>>()) {
100
+ next = parseFloatElementSWAR<valueof<T>>(srcStart, srcEnd, writePtr);
101
+ } else if (isSigned<valueof<T>>()) {
102
+ next = parseSignedIntegerSWAR<valueof<T>>(srcStart, srcEnd, writePtr);
103
+ } else {
104
+ next = parseUnsignedIntegerSWAR<valueof<T>>(srcStart, srcEnd, writePtr);
105
+ }
106
+ if (!next) break;
107
+ writePtr += elementSize;
108
+ srcStart = next;
109
+ if (srcStart >= srcEnd) break;
110
+
111
+ while (srcStart < srcEnd && isSpace(load<u16>(srcStart))) srcStart += 2;
112
+ if (srcStart >= srcEnd) break;
113
+ const ch = load<u16>(srcStart);
114
+ if (ch == COMMA) {
115
+ srcStart += 2;
116
+ while (srcStart < srcEnd && isSpace(load<u16>(srcStart))) srcStart += 2;
117
+ continue;
118
+ }
119
+ if (ch == BRACKET_RIGHT) break;
120
+ break;
121
+ }
122
+
123
+ // Trim to actual count. `out.length =` on a typed-array isn't legal
124
+ // (length is read-only), so we shrink the underlying ArrayBufferView
125
+ // directly: `__renew` the buffer to the actual byte length and
126
+ // update the view's `byteLength` and `dataStart`. AS's TypedArray
127
+ // structure has `buffer`, `dataStart` (= buffer), `byteLength`
128
+ // (capacity in bytes) in that order — same layout as ArrayBufferView.
129
+ const actualCount = i32(<usize>(writePtr - dataStart) / elementSize);
130
+ if (actualCount != maxElements) {
131
+ const actualBytes = <usize>actualCount * elementSize;
132
+ const oldBuffer = changetype<ArrayBuffer>(
133
+ load<usize>(changetype<usize>(out)),
134
+ );
135
+ const newBuffer = __renew(changetype<usize>(oldBuffer), actualBytes);
136
+ // Update buffer, dataStart, byteLength on the view.
137
+ store<usize>(changetype<usize>(out), newBuffer);
138
+ store<usize>(
139
+ changetype<usize>(out),
140
+ newBuffer,
141
+ offsetof<ArrayBufferView>("dataStart"),
142
+ );
143
+ store<i32>(
144
+ changetype<usize>(out),
145
+ i32(actualBytes),
146
+ offsetof<ArrayBufferView>("byteLength"),
147
+ );
148
+ __link(changetype<usize>(out), newBuffer, false);
149
+ }
150
+
151
+ return out;
152
+ }
153
+
154
+ /**
155
+ * SWAR ArrayBuffer deserializer. JSON encoding is `[u8, u8, ...]` so
156
+ * elements are always 1-3 ASCII digits (0..255). We can use the same
157
+ * comma-count + inline-parse strategy as above, but since the result
158
+ * is an `ArrayBuffer` rather than a `TypedArray<E>`, we use a plain
159
+ * `store<u8>` directly.
160
+ */
161
+ export function deserializeArrayBuffer_SWAR(
162
+ srcStart: usize,
163
+ srcEnd: usize,
164
+ dst: usize = 0,
165
+ ): ArrayBuffer {
166
+ while (srcStart < srcEnd) {
167
+ const ch = load<u16>(srcStart);
168
+ if (ch == BRACKET_LEFT) {
169
+ srcStart += 2;
170
+ break;
171
+ }
172
+ srcStart += 2;
173
+ }
174
+ while (srcStart < srcEnd && isSpace(load<u16>(srcStart))) srcStart += 2;
175
+
176
+ if (srcStart >= srcEnd || load<u16>(srcStart) == BRACKET_RIGHT) {
177
+ let out = dst ? changetype<ArrayBuffer>(dst) : new ArrayBuffer(0);
178
+ if (out.byteLength != 0) out = new ArrayBuffer(0);
179
+ return out;
180
+ }
181
+
182
+ // Worst-case byte count: each element is `D,` minimum = 4 bytes.
183
+ const maxBytes = i32((<usize>(srcEnd - srcStart)) >> 2) + 1;
184
+ let out = dst ? changetype<ArrayBuffer>(dst) : new ArrayBuffer(maxBytes);
185
+ if (out.byteLength != maxBytes) {
186
+ out = new ArrayBuffer(maxBytes);
187
+ }
188
+
189
+ const dataStart = changetype<usize>(out);
190
+ let writePtr: usize = 0;
191
+
192
+ while (srcStart < srcEnd) {
193
+ const next = parseUnsignedIntegerSWAR<u8>(
194
+ srcStart,
195
+ srcEnd,
196
+ dataStart + writePtr,
197
+ );
198
+ if (!next) break;
199
+ writePtr += 1;
200
+ srcStart = next;
201
+ if (srcStart >= srcEnd) break;
202
+
203
+ while (srcStart < srcEnd && isSpace(load<u16>(srcStart))) srcStart += 2;
204
+ if (srcStart >= srcEnd) break;
205
+ const ch = load<u16>(srcStart);
206
+ if (ch == COMMA) {
207
+ srcStart += 2;
208
+ while (srcStart < srcEnd && isSpace(load<u16>(srcStart))) srcStart += 2;
209
+ continue;
210
+ }
211
+ if (ch == BRACKET_RIGHT) break;
212
+ break;
213
+ }
214
+
215
+ // Trim to actual byte count via `__renew`.
216
+ const actualBytes = i32(writePtr);
217
+ if (actualBytes != maxBytes) {
218
+ out = changetype<ArrayBuffer>(
219
+ __renew(changetype<usize>(out), <usize>actualBytes),
220
+ );
221
+ }
222
+
223
+ return out;
224
+ }
@@ -24,7 +24,9 @@ declare function omit(..._): void;
24
24
  /**
25
25
  * Property decorator that allows a field to be omitted when equal to an Expression.
26
26
  */
27
- declare function omitif(condition: string | ((value: any) => boolean)): Function;
27
+ declare function omitif(
28
+ condition: string | ((value: any) => boolean),
29
+ ): Function;
28
30
 
29
31
  /**
30
32
  * Property decorator that allows a field to be omitted when a property is null.