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.
- package/CHANGELOG.md +45 -0
- package/README.md +1 -1
- package/assembly/deserialize/helpers/uint.ts +4 -1
- package/assembly/deserialize/index/arbitrary.ts +7 -3
- package/assembly/deserialize/index/array.ts +42 -17
- package/assembly/deserialize/index/bool.ts +1 -1
- package/assembly/deserialize/index/date.ts +1 -1
- package/assembly/deserialize/index/float.ts +40 -1
- package/assembly/deserialize/index/integer.ts +68 -1
- package/assembly/deserialize/index/map.ts +1 -1
- package/assembly/deserialize/index/object.ts +1 -1
- package/assembly/deserialize/index/raw.ts +1 -1
- package/assembly/deserialize/index/set.ts +1 -1
- package/assembly/deserialize/index/staticarray.ts +4 -1
- package/assembly/deserialize/index/string.ts +32 -4
- package/assembly/deserialize/index/struct.ts +1 -1
- package/assembly/deserialize/index/typedarray.ts +30 -10
- package/assembly/deserialize/index/unsigned.ts +78 -1
- package/assembly/deserialize/index.ts +1 -0
- package/assembly/deserialize/{simple → naive}/array/arbitrary.ts +24 -5
- package/assembly/deserialize/{simple → naive}/array/array.ts +8 -2
- package/assembly/deserialize/naive/array/bool.ts +68 -0
- package/assembly/deserialize/{simple → naive}/array/box.ts +8 -2
- package/assembly/deserialize/naive/array/float.ts +63 -0
- package/assembly/deserialize/{simple → naive}/array/generic.ts +14 -7
- package/assembly/deserialize/naive/array/integer.ts +86 -0
- package/assembly/deserialize/naive/array/map.ts +47 -0
- package/assembly/deserialize/naive/array/object.ts +47 -0
- package/assembly/deserialize/{simple → naive}/array/raw.ts +34 -7
- package/assembly/deserialize/naive/array/string.ts +69 -0
- package/assembly/deserialize/naive/array/struct.ts +47 -0
- package/assembly/deserialize/{simple → naive}/array.ts +15 -10
- package/assembly/deserialize/{simple → naive}/bool.ts +6 -2
- package/assembly/deserialize/naive/float.ts +135 -0
- package/assembly/deserialize/{simple → naive}/integer.ts +10 -2
- package/assembly/deserialize/{simple → naive}/map.ts +106 -27
- package/assembly/deserialize/{simple → naive}/object.ts +65 -19
- package/assembly/deserialize/{simple → naive}/raw.ts +4 -1
- package/assembly/deserialize/{simple → naive}/set.ts +49 -19
- package/assembly/deserialize/{simple → naive}/staticarray/array.ts +1 -1
- package/assembly/deserialize/{simple → naive}/staticarray/bool.ts +1 -1
- package/assembly/deserialize/{simple → naive}/staticarray/float.ts +1 -1
- package/assembly/deserialize/{simple → naive}/staticarray/integer.ts +1 -1
- package/assembly/deserialize/{simple → naive}/staticarray/string.ts +11 -3
- package/assembly/deserialize/{simple → naive}/staticarray/struct.ts +1 -2
- package/assembly/deserialize/{simple → naive}/staticarray.ts +68 -18
- package/assembly/deserialize/naive/string.ts +199 -0
- package/assembly/deserialize/{simple → naive}/struct.ts +5 -1
- package/assembly/deserialize/{simple → naive}/typedarray.ts +17 -4
- package/assembly/deserialize/{simple → naive}/unsigned.ts +10 -15
- package/assembly/deserialize/simd/array/integer.ts +339 -62
- package/assembly/deserialize/simd/float.ts +303 -0
- package/assembly/deserialize/simd/integer.ts +233 -0
- package/assembly/deserialize/simd/string.ts +266 -107
- package/assembly/deserialize/swar/array/arbitrary.ts +11 -3
- package/assembly/deserialize/swar/array/array.ts +40 -9
- package/assembly/deserialize/swar/array/bool.ts +28 -5
- package/assembly/deserialize/swar/array/box.ts +11 -3
- package/assembly/deserialize/swar/array/float.ts +295 -7
- package/assembly/deserialize/swar/array/generic.ts +28 -7
- package/assembly/deserialize/swar/array/integer.ts +363 -112
- package/assembly/deserialize/swar/array/map.ts +11 -3
- package/assembly/deserialize/swar/array/object.ts +37 -25
- package/assembly/deserialize/swar/array/raw.ts +11 -3
- package/assembly/deserialize/swar/array/shared.ts +63 -14
- package/assembly/deserialize/swar/array/string.ts +140 -7
- package/assembly/deserialize/swar/array/struct.ts +66 -12
- package/assembly/deserialize/swar/array.ts +12 -51
- package/assembly/deserialize/swar/float.ts +304 -0
- package/assembly/deserialize/swar/integer.ts +246 -0
- package/assembly/deserialize/swar/string.ts +213 -294
- package/assembly/deserialize/swar/typedarray.ts +224 -0
- package/assembly/index.d.ts +3 -1
- package/assembly/index.ts +402 -261
- package/assembly/serialize/index/array.ts +1 -1
- package/assembly/serialize/index/bool.ts +1 -1
- package/assembly/serialize/index/date.ts +1 -1
- package/assembly/serialize/index/float.ts +5 -1
- package/assembly/serialize/index/integer.ts +1 -1
- package/assembly/serialize/index/map.ts +1 -1
- package/assembly/serialize/index/raw.ts +1 -1
- package/assembly/serialize/index/set.ts +1 -1
- package/assembly/serialize/index/staticarray.ts +1 -1
- package/assembly/serialize/index/string.ts +1 -1
- package/assembly/serialize/index/struct.ts +1 -1
- package/assembly/serialize/index/typedarray.ts +21 -12
- package/assembly/serialize/index.ts +1 -0
- package/assembly/serialize/naive/array.ts +351 -0
- package/assembly/serialize/{simple → naive}/float.ts +4 -1
- package/assembly/serialize/naive/integer.ts +19 -0
- package/assembly/serialize/{simple → naive}/map.ts +6 -2
- package/assembly/serialize/{simple → naive}/raw.ts +5 -1
- package/assembly/serialize/{simple → naive}/set.ts +6 -1
- package/assembly/serialize/{simple → naive}/staticarray.ts +6 -1
- package/assembly/serialize/{simple → naive}/string.ts +1 -2
- package/assembly/serialize/{simple → naive}/typedarray.ts +10 -3
- package/assembly/serialize/simd/string.ts +6 -2
- package/assembly/serialize/swar/string.ts +15 -141
- package/assembly/util/atoi-fast.ts +81 -0
- package/assembly/util/concat.ts +5 -1
- package/assembly/util/dragonbox-cache.ts +443 -2
- package/assembly/util/dragonbox.ts +53 -17
- package/assembly/util/itoa-fast.ts +241 -0
- package/assembly/util/masks.ts +18 -1
- package/assembly/util/parsefloat-fast.ts +167 -0
- package/assembly/util/scanValueEnd.ts +78 -0
- package/assembly/util/scientific.ts +132 -0
- package/assembly/util/simd-int.ts +191 -0
- package/assembly/util/snp.ts +4 -1
- package/assembly/util/swar-int.ts +248 -0
- package/assembly/util/swar.ts +13 -3
- package/lib/as-bs.ts +27 -6
- package/package.json +15 -11
- package/transform/lib/builder.d.ts.map +1 -1
- package/transform/lib/builder.js +13 -5
- package/transform/lib/builder.js.map +1 -1
- package/transform/lib/index.d.ts +5 -0
- package/transform/lib/index.d.ts.map +1 -1
- package/transform/lib/index.js +1046 -340
- package/transform/lib/index.js.map +1 -1
- package/transform/lib/linkers/alias.d.ts.map +1 -1
- package/transform/lib/linkers/alias.js.map +1 -1
- package/transform/lib/linkers/custom.d.ts.map +1 -1
- package/transform/lib/linkers/custom.js +3 -2
- package/transform/lib/linkers/custom.js.map +1 -1
- package/transform/lib/linkers/imports.d.ts.map +1 -1
- package/transform/lib/linkers/imports.js.map +1 -1
- package/transform/lib/types.d.ts.map +1 -1
- package/transform/lib/types.js +54 -16
- package/transform/lib/types.js.map +1 -1
- package/transform/lib/util.d.ts.map +1 -1
- package/transform/lib/util.js +1 -1
- package/transform/lib/util.js.map +1 -1
- package/transform/lib/visitor.d.ts.map +1 -1
- package/transform/lib/visitor.js +2 -1
- package/transform/lib/visitor.js.map +1 -1
- package/assembly/custom/util.ts +0 -310
- package/assembly/deserialize/simple/arbitrary.ts +0 -23
- package/assembly/deserialize/simple/array/bool.ts +0 -17
- package/assembly/deserialize/simple/array/float.ts +0 -28
- package/assembly/deserialize/simple/array/integer.ts +0 -27
- package/assembly/deserialize/simple/array/map.ts +0 -28
- package/assembly/deserialize/simple/array/object.ts +0 -28
- package/assembly/deserialize/simple/array/string.ts +0 -23
- package/assembly/deserialize/simple/array/struct.ts +0 -28
- package/assembly/deserialize/simple/float.ts +0 -201
- package/assembly/deserialize/simple/string.ts +0 -132
- package/assembly/serialize/simple/arbitrary.ts +0 -79
- package/assembly/serialize/simple/array.ts +0 -86
- package/assembly/serialize/simple/integer.ts +0 -20
- package/assembly/serialize/simple/object.ts +0 -42
- /package/assembly/deserialize/{simple → naive}/date.ts +0 -0
- /package/assembly/serialize/{simple → naive}/bool.ts +0 -0
- /package/assembly/serialize/{simple → naive}/date.ts +0 -0
- /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
|
+
}
|
package/assembly/index.d.ts
CHANGED
|
@@ -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(
|
|
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.
|