json-as 1.3.9 → 1.4.0
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 +20 -0
- package/README.md +49 -1
- package/assembly/deserialize/index/arbitrary.ts +2 -2
- package/assembly/deserialize/naive/array/arbitrary.ts +3 -136
- package/assembly/deserialize/naive/array/array.ts +30 -1
- package/assembly/deserialize/naive/array/integer.ts +1 -6
- package/assembly/deserialize/naive/array/map.ts +10 -14
- package/assembly/deserialize/naive/array/object.ts +10 -14
- package/assembly/deserialize/naive/float.ts +2 -4
- package/assembly/deserialize/naive/integer.ts +1 -2
- package/assembly/deserialize/naive/map.ts +40 -202
- package/assembly/deserialize/naive/object.ts +153 -174
- package/assembly/deserialize/naive/set.ts +1 -2
- package/assembly/deserialize/naive/staticarray.ts +1 -2
- package/assembly/deserialize/naive/string.ts +65 -18
- package/assembly/deserialize/naive/typedarray.ts +1 -2
- package/assembly/deserialize/naive/unsigned.ts +1 -2
- package/assembly/deserialize/simd/array/integer.ts +3 -6
- package/assembly/deserialize/simd/float.ts +2 -7
- package/assembly/deserialize/simd/integer.ts +4 -8
- package/assembly/deserialize/simd/string.ts +16 -21
- package/assembly/deserialize/swar/array/array.ts +1 -2
- package/assembly/deserialize/swar/array/bool.ts +1 -2
- package/assembly/deserialize/swar/array/float.ts +2 -3
- package/assembly/deserialize/swar/array/generic.ts +1 -2
- package/assembly/deserialize/swar/array/integer.ts +6 -11
- package/assembly/deserialize/swar/array/object.ts +1 -2
- package/assembly/deserialize/swar/array/shared.ts +3 -8
- package/assembly/deserialize/swar/array/string.ts +1 -2
- package/assembly/deserialize/swar/array/struct.ts +1 -1
- package/assembly/deserialize/swar/float.ts +3 -8
- package/assembly/deserialize/swar/integer.ts +4 -8
- package/assembly/deserialize/swar/string.ts +29 -41
- package/assembly/index.d.ts +248 -15
- package/assembly/index.ts +468 -146
- package/assembly/serialize/index/object.ts +18 -15
- package/assembly/serialize/naive/string.ts +9 -2
- package/assembly/serialize/swar/string.ts +1 -2
- package/assembly/util/atoi.ts +1 -2
- package/assembly/util/dragonbox.ts +0 -8
- package/assembly/util/itoa-fast.ts +3 -6
- package/assembly/util/parsefloat-fast.ts +1 -2
- package/assembly/util/scanValueEnd.ts +1 -2
- package/assembly/util/scanValueEndSimd.ts +160 -0
- package/assembly/util/scanValueEndSwar.ts +142 -0
- package/assembly/util/scientific.ts +3 -6
- package/assembly/util/simd-int.ts +4 -8
- package/assembly/util/snp.ts +1 -5
- package/assembly/util/stringScan.ts +2 -4
- package/assembly/util/swar-int.ts +3 -6
- package/lib/as-bs.ts +37 -0
- package/package.json +14 -4
- package/transform/lib/builder.d.ts +0 -1
- package/transform/lib/builder.js +0 -1
- package/transform/lib/index.d.ts +0 -1
- package/transform/lib/index.js +535 -288
- package/transform/lib/linkers/alias.d.ts +0 -1
- package/transform/lib/linkers/alias.js +0 -1
- package/transform/lib/linkers/custom.d.ts +0 -1
- package/transform/lib/linkers/custom.js +0 -1
- package/transform/lib/linkers/imports.d.ts +0 -1
- package/transform/lib/linkers/imports.js +0 -1
- package/transform/lib/types.d.ts +3 -2
- package/transform/lib/types.js +2 -1
- package/transform/lib/util.d.ts +0 -1
- package/transform/lib/util.js +0 -1
- package/transform/lib/visitor.d.ts +0 -1
- package/transform/lib/visitor.js +0 -1
- package/transform/lib/builder.d.ts.map +0 -1
- package/transform/lib/builder.js.map +0 -1
- package/transform/lib/index.d.ts.map +0 -1
- package/transform/lib/index.js.map +0 -1
- package/transform/lib/linkers/alias.d.ts.map +0 -1
- package/transform/lib/linkers/alias.js.map +0 -1
- package/transform/lib/linkers/custom.d.ts.map +0 -1
- package/transform/lib/linkers/custom.js.map +0 -1
- package/transform/lib/linkers/imports.d.ts.map +0 -1
- package/transform/lib/linkers/imports.js.map +0 -1
- package/transform/lib/types.d.ts.map +0 -1
- package/transform/lib/types.js.map +0 -1
- package/transform/lib/util.d.ts.map +0 -1
- package/transform/lib/util.js.map +0 -1
- package/transform/lib/visitor.d.ts.map +0 -1
- package/transform/lib/visitor.js.map +0 -1
|
@@ -33,8 +33,7 @@ import { DESERIALIZE_ESCAPE_TABLE } from "../../globals/tables";
|
|
|
33
33
|
// Strict RFC 8259 check for the char following a backslash, at [escPtr, srcEnd).
|
|
34
34
|
// Legal escapes: " \ / b f n r t and \uXXXX (4 hex digits). Throws otherwise:
|
|
35
35
|
// unknown escape letter, a trailing backslash, or a short / non-hex \u.
|
|
36
|
-
|
|
37
|
-
@inline function validateEscape(escPtr: usize, srcEnd: usize): void {
|
|
36
|
+
function validateEscape(escPtr: usize, srcEnd: usize): void {
|
|
38
37
|
if (escPtr >= srcEnd)
|
|
39
38
|
throw new Error("Invalid JSON string: incomplete escape");
|
|
40
39
|
const code = load<u16>(escPtr);
|
|
@@ -65,8 +64,7 @@ import { DESERIALIZE_ESCAPE_TABLE } from "../../globals/tables";
|
|
|
65
64
|
throw new Error("Invalid JSON string: illegal escape");
|
|
66
65
|
}
|
|
67
66
|
|
|
68
|
-
|
|
69
|
-
@inline export function deserializeString_NAIVE(
|
|
67
|
+
export function deserializeString_NAIVE(
|
|
70
68
|
srcStart: usize,
|
|
71
69
|
srcEnd: usize,
|
|
72
70
|
): string {
|
|
@@ -121,8 +119,7 @@ import { DESERIALIZE_ESCAPE_TABLE } from "../../globals/tables";
|
|
|
121
119
|
|
|
122
120
|
// Writes into the destination field, reusing or resizing the backing string.
|
|
123
121
|
// Mirrors `writeStringToField` in ../swar/string.ts.
|
|
124
|
-
|
|
125
|
-
@inline function writeStringToField(
|
|
122
|
+
function writeStringToField(
|
|
126
123
|
dstFieldPtr: usize,
|
|
127
124
|
srcStart: usize,
|
|
128
125
|
byteLength: u32,
|
|
@@ -148,23 +145,26 @@ import { DESERIALIZE_ESCAPE_TABLE } from "../../globals/tables";
|
|
|
148
145
|
memory.copy(stringPtr, srcStart, byteLength);
|
|
149
146
|
}
|
|
150
147
|
|
|
151
|
-
//
|
|
152
|
-
|
|
153
|
-
|
|
148
|
+
// Escape-bearing tail of the field parse: the clean prefix [payloadStart,
|
|
149
|
+
// escPos) is bulk-copied into the scratch buffer, then escapes are decoded into
|
|
150
|
+
// it, and the result is written to the field. Only reached when a backslash is
|
|
151
|
+
// actually present — the common escape-free case never touches `bs`.
|
|
152
|
+
function deserializeEscapedStringField_NAIVE(
|
|
153
|
+
payloadStart: usize,
|
|
154
|
+
escPos: usize,
|
|
154
155
|
srcEnd: usize,
|
|
155
|
-
|
|
156
|
-
dstOffset: usize = 0,
|
|
156
|
+
dstFieldPtr: usize,
|
|
157
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
158
|
bs.offset = bs.buffer;
|
|
166
159
|
bs.ensureSize(<u32>(srcEnd - payloadStart));
|
|
167
160
|
|
|
161
|
+
const prefixLen = escPos - payloadStart;
|
|
162
|
+
if (prefixLen) {
|
|
163
|
+
memory.copy(bs.offset, payloadStart, prefixLen);
|
|
164
|
+
bs.offset += prefixLen;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
let srcStart = escPos;
|
|
168
168
|
while (srcStart < srcEnd) {
|
|
169
169
|
const block = load<u16>(srcStart);
|
|
170
170
|
|
|
@@ -197,3 +197,50 @@ import { DESERIALIZE_ESCAPE_TABLE } from "../../globals/tables";
|
|
|
197
197
|
abort("Expected closing quote");
|
|
198
198
|
return 0;
|
|
199
199
|
}
|
|
200
|
+
|
|
201
|
+
// NOT @inline: this is a loop-bearing scanner called per string field. As an
|
|
202
|
+
// always-inline entry it gets inlined into every field call site inside the
|
|
203
|
+
// @inline __DESERIALIZE_FAST, exploding binaryen's optimize phase on large
|
|
204
|
+
// schemas (~118s on the `large` bench). Kept as a single shared function — one
|
|
205
|
+
// call per field — matching the non-inline SWAR/SIMD field deserializers.
|
|
206
|
+
export function deserializeStringField_NAIVE<T extends string | null>(
|
|
207
|
+
srcStart: usize,
|
|
208
|
+
srcEnd: usize,
|
|
209
|
+
dstObj: usize,
|
|
210
|
+
dstOffset: usize = 0,
|
|
211
|
+
): usize {
|
|
212
|
+
const dstFieldPtr = dstObj + dstOffset;
|
|
213
|
+
if (srcStart + 2 > srcEnd || load<u16>(srcStart) != QUOTE)
|
|
214
|
+
abort("Expected leading quote");
|
|
215
|
+
|
|
216
|
+
const payloadStart = srcStart + 2;
|
|
217
|
+
srcStart = payloadStart;
|
|
218
|
+
|
|
219
|
+
// Scan for the closing quote without touching the scratch buffer. For the
|
|
220
|
+
// common escape-free case the bytes are a verbatim slice of the source, so we
|
|
221
|
+
// copy source -> field directly (mirrors the SWAR/SIMD field paths). Only a
|
|
222
|
+
// backslash diverts to the escape-decoding tail above.
|
|
223
|
+
while (srcStart < srcEnd) {
|
|
224
|
+
const block = load<u16>(srcStart);
|
|
225
|
+
if (block == QUOTE) {
|
|
226
|
+
writeStringToField(
|
|
227
|
+
dstFieldPtr,
|
|
228
|
+
payloadStart,
|
|
229
|
+
<u32>(srcStart - payloadStart),
|
|
230
|
+
);
|
|
231
|
+
return srcStart + 2;
|
|
232
|
+
}
|
|
233
|
+
if (block == BACK_SLASH) {
|
|
234
|
+
return deserializeEscapedStringField_NAIVE(
|
|
235
|
+
payloadStart,
|
|
236
|
+
srcStart,
|
|
237
|
+
srcEnd,
|
|
238
|
+
dstFieldPtr,
|
|
239
|
+
);
|
|
240
|
+
}
|
|
241
|
+
srcStart += 2;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
abort("Expected closing quote");
|
|
245
|
+
return 0;
|
|
246
|
+
}
|
|
@@ -2,8 +2,7 @@ import { COMMA, BRACKET_RIGHT } from "../../custom/chars";
|
|
|
2
2
|
import { deserializeFloat_NAIVE } from "./float";
|
|
3
3
|
import { atoi, isSpace } from "../../util";
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
@inline function countTypedArrayElements(srcStart: usize, srcEnd: usize): i32 {
|
|
5
|
+
function countTypedArrayElements(srcStart: usize, srcEnd: usize): i32 {
|
|
7
6
|
let count = 0;
|
|
8
7
|
|
|
9
8
|
while (srcStart < srcEnd) {
|
|
@@ -8,8 +8,7 @@ import { atoi } from "../../util/atoi";
|
|
|
8
8
|
return atoi<T>(srcStart, srcEnd);
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
@inline export function deserializeUnsignedField_NAIVE<T extends number>(
|
|
11
|
+
export function deserializeUnsignedField_NAIVE<T extends number>(
|
|
13
12
|
srcStart: usize,
|
|
14
13
|
srcEnd: usize,
|
|
15
14
|
dstObj: usize,
|
|
@@ -76,8 +76,7 @@ const ASCII_ZERO_4: u64 = 0x0030003000300030;
|
|
|
76
76
|
}
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
-
|
|
80
|
-
@inline function tryParseEightDigitsSIMD(srcStart: usize, value: u64): u64 {
|
|
79
|
+
function tryParseEightDigitsSIMD(srcStart: usize, value: u64): u64 {
|
|
81
80
|
const block = load<v128>(srcStart);
|
|
82
81
|
const digits = i16x8.sub(block, SPLAT_30);
|
|
83
82
|
if (v128.any_true(i16x8.gt_u(digits, SPLAT_09))) return 0;
|
|
@@ -96,8 +95,7 @@ const ASCII_ZERO_4: u64 = 0x0030003000300030;
|
|
|
96
95
|
// As in the SWAR variant: the parse helpers take a `slot` (`writePtr`) and
|
|
97
96
|
// store directly. The dispatcher owns `out.length = maxElements` and the
|
|
98
97
|
// per-element `writePtr` advance so `Array.push` is removed for every
|
|
99
|
-
|
|
100
|
-
@inline function parseSignedIntegerSIMD<T extends number[]>(
|
|
98
|
+
function parseSignedIntegerSIMD<T extends number[]>(
|
|
101
99
|
srcStart: usize,
|
|
102
100
|
srcEnd: usize,
|
|
103
101
|
slot: usize,
|
|
@@ -135,8 +133,7 @@ const ASCII_ZERO_4: u64 = 0x0030003000300030;
|
|
|
135
133
|
return srcStart;
|
|
136
134
|
}
|
|
137
135
|
|
|
138
|
-
|
|
139
|
-
@inline function parseUnsignedIntegerSIMD<T extends number[]>(
|
|
136
|
+
function parseUnsignedIntegerSIMD<T extends number[]>(
|
|
140
137
|
srcStart: usize,
|
|
141
138
|
srcEnd: usize,
|
|
142
139
|
slot: usize,
|
|
@@ -48,11 +48,7 @@ const ASCII_E_LO: u16 = 101;
|
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
|
|
52
|
-
@inline export function deserializeFloat_SIMD<T>(
|
|
53
|
-
srcStart: usize,
|
|
54
|
-
srcEnd: usize,
|
|
55
|
-
): T {
|
|
51
|
+
export function deserializeFloat_SIMD<T>(srcStart: usize, srcEnd: usize): T {
|
|
56
52
|
const origStart = srcStart;
|
|
57
53
|
let p = srcStart;
|
|
58
54
|
let negative = false;
|
|
@@ -168,8 +164,7 @@ const ASCII_E_LO: u16 = 101;
|
|
|
168
164
|
return <T>(<f32>result);
|
|
169
165
|
}
|
|
170
166
|
|
|
171
|
-
|
|
172
|
-
@inline export function deserializeFloatField_SIMD<T extends number>(
|
|
167
|
+
export function deserializeFloatField_SIMD<T extends number>(
|
|
173
168
|
srcStart: usize,
|
|
174
169
|
srcEnd: usize,
|
|
175
170
|
dstObj: usize,
|
|
@@ -88,8 +88,7 @@ const ASCII_ZERO: u16 = 48;
|
|
|
88
88
|
* @param srcEnd Pointer just past the last code unit.
|
|
89
89
|
* @returns The parsed value, two's-complement truncated to `T`.
|
|
90
90
|
*/
|
|
91
|
-
|
|
92
|
-
@inline export function deserializeInteger_SIMD<T extends number>(
|
|
91
|
+
export function deserializeInteger_SIMD<T extends number>(
|
|
93
92
|
srcStart: usize,
|
|
94
93
|
srcEnd: usize,
|
|
95
94
|
): T {
|
|
@@ -130,8 +129,7 @@ const ASCII_ZERO: u16 = 48;
|
|
|
130
129
|
* @param dstOffset Byte offset of the field within `dstObj`.
|
|
131
130
|
* @returns The source position immediately after the last digit consumed.
|
|
132
131
|
*/
|
|
133
|
-
|
|
134
|
-
@inline export function deserializeIntegerField_SIMD<T extends number>(
|
|
132
|
+
export function deserializeIntegerField_SIMD<T extends number>(
|
|
135
133
|
srcStart: usize,
|
|
136
134
|
srcEnd: usize,
|
|
137
135
|
dstObj: usize,
|
|
@@ -170,8 +168,7 @@ const ASCII_ZERO: u16 = 48;
|
|
|
170
168
|
* @param srcEnd Pointer just past the last code unit.
|
|
171
169
|
* @returns The parsed value, truncated to `T`.
|
|
172
170
|
*/
|
|
173
|
-
|
|
174
|
-
@inline export function deserializeUnsigned_SIMD<T extends number>(
|
|
171
|
+
export function deserializeUnsigned_SIMD<T extends number>(
|
|
175
172
|
srcStart: usize,
|
|
176
173
|
srcEnd: usize,
|
|
177
174
|
): T {
|
|
@@ -207,8 +204,7 @@ const ASCII_ZERO: u16 = 48;
|
|
|
207
204
|
* @param dstOffset Byte offset of the field within `dstObj`.
|
|
208
205
|
* @returns The source position immediately after the last digit consumed.
|
|
209
206
|
*/
|
|
210
|
-
|
|
211
|
-
@inline export function deserializeUnsignedField_SIMD<T extends number>(
|
|
207
|
+
export function deserializeUnsignedField_SIMD<T extends number>(
|
|
212
208
|
srcStart: usize,
|
|
213
209
|
srcEnd: usize,
|
|
214
210
|
dstObj: usize,
|
|
@@ -75,8 +75,7 @@ import { hex4_to_u16_swar } from "../../util/swar";
|
|
|
75
75
|
return changetype<string>(out);
|
|
76
76
|
}
|
|
77
77
|
|
|
78
|
-
|
|
79
|
-
@inline function writeStringToField_SIMD(
|
|
78
|
+
function writeStringToField_SIMD(
|
|
80
79
|
dstFieldPtr: usize,
|
|
81
80
|
srcStart: usize,
|
|
82
81
|
byteLength: u32,
|
|
@@ -233,16 +232,16 @@ export function deserializeString_SIMD(srcStart: usize, srcEnd: usize): string {
|
|
|
233
232
|
}
|
|
234
233
|
|
|
235
234
|
const laneIdx = usize(ctz(mask) << 1);
|
|
236
|
-
return
|
|
237
|
-
|
|
235
|
+
return deserializeEscapedString_SIMD(
|
|
236
|
+
payloadStart,
|
|
237
|
+
srcStart + laneIdx,
|
|
238
|
+
srcEnd,
|
|
238
239
|
);
|
|
239
240
|
}
|
|
240
241
|
|
|
241
242
|
while (srcStart < srcEnd) {
|
|
242
243
|
if (load<u16>(srcStart) == BACK_SLASH) {
|
|
243
|
-
return
|
|
244
|
-
deserializeEscapedString_SIMD(payloadStart, srcStart, srcEnd),
|
|
245
|
-
);
|
|
244
|
+
return deserializeEscapedString_SIMD(payloadStart, srcStart, srcEnd);
|
|
246
245
|
}
|
|
247
246
|
srcStart += 2;
|
|
248
247
|
}
|
|
@@ -427,13 +426,11 @@ export function deserializeStringField_SIMD<T extends string | null>(
|
|
|
427
426
|
return srcIdx + 2;
|
|
428
427
|
}
|
|
429
428
|
// backslash → vectorized escaped scan (no more SWAR fallback)
|
|
430
|
-
return
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
dstFieldPtr,
|
|
436
|
-
),
|
|
429
|
+
return deserializeEscapedStringField_SIMD(
|
|
430
|
+
payloadStart,
|
|
431
|
+
srcIdx,
|
|
432
|
+
srcEnd,
|
|
433
|
+
dstFieldPtr,
|
|
437
434
|
);
|
|
438
435
|
}
|
|
439
436
|
|
|
@@ -448,13 +445,11 @@ export function deserializeStringField_SIMD<T extends string | null>(
|
|
|
448
445
|
return srcStart + 2;
|
|
449
446
|
}
|
|
450
447
|
if (char == BACK_SLASH) {
|
|
451
|
-
return
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
dstFieldPtr,
|
|
457
|
-
),
|
|
448
|
+
return deserializeEscapedStringField_SIMD(
|
|
449
|
+
payloadStart,
|
|
450
|
+
srcStart,
|
|
451
|
+
srcEnd,
|
|
452
|
+
dstFieldPtr,
|
|
458
453
|
);
|
|
459
454
|
}
|
|
460
455
|
srcStart += 2;
|
|
@@ -3,8 +3,7 @@ import { BRACKET_LEFT, BRACKET_RIGHT, COMMA } from "../../../custom/chars";
|
|
|
3
3
|
import { deserializeFloatArrayBody } from "./float";
|
|
4
4
|
import { ensureArrayField, scanValueEnd, skipWhitespace } from "./shared";
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
@inline export function deserializeArrayArrayBody<T extends unknown[][]>(
|
|
6
|
+
export function deserializeArrayArrayBody<T extends unknown[][]>(
|
|
8
7
|
srcStart: usize,
|
|
9
8
|
srcEnd: usize,
|
|
10
9
|
out: T,
|
|
@@ -8,8 +8,7 @@ import {
|
|
|
8
8
|
import { isSpace } from "../../../util";
|
|
9
9
|
import { ensureArrayElementSlot, ensureArrayField } from "./shared";
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
@inline function deserializeBooleanArrayBody<T extends boolean[]>(
|
|
11
|
+
function deserializeBooleanArrayBody<T extends boolean[]>(
|
|
13
12
|
srcStart: usize,
|
|
14
13
|
srcEnd: usize,
|
|
15
14
|
out: T,
|
|
@@ -46,8 +46,7 @@ import { isSpace } from "../../../util";
|
|
|
46
46
|
* digit, lone minus, malformed exponent suffix). Valid-but-out-of-range
|
|
47
47
|
* numbers are handled inline.
|
|
48
48
|
*/
|
|
49
|
-
|
|
50
|
-
@inline export function parseFloatElementSWAR<E>(
|
|
49
|
+
export function parseFloatElementSWAR<E>(
|
|
51
50
|
srcStart: usize,
|
|
52
51
|
srcEnd: usize,
|
|
53
52
|
slot: usize,
|
|
@@ -265,7 +264,7 @@ export function deserializeFloatArray_SWAR<T extends number[]>(
|
|
|
265
264
|
* `[lon,lat]` would over-allocate megabytes of f64 capacity. Instead we
|
|
266
265
|
* use `ensureArrayElementSlot`'s grow-or-reuse strategy.
|
|
267
266
|
*/
|
|
268
|
-
|
|
267
|
+
export function deserializeFloatArrayBody<T extends number[]>(
|
|
269
268
|
srcStart: usize,
|
|
270
269
|
srcEnd: usize,
|
|
271
270
|
out: T,
|
|
@@ -53,7 +53,7 @@ import { parse4Digits_PairMul } from "../../../util/swar-int";
|
|
|
53
53
|
// Parsers are also E-parameterised so they're shareable with
|
|
54
54
|
// `swar/typedarray.ts`. The body is byte-identical to the prior version
|
|
55
55
|
// modulo s/valueof<T>/E/.
|
|
56
|
-
|
|
56
|
+
export function parseSignedIntegerScalar<E extends number>(
|
|
57
57
|
srcStart: usize,
|
|
58
58
|
srcEnd: usize,
|
|
59
59
|
slot: usize,
|
|
@@ -83,8 +83,7 @@ import { parse4Digits_PairMul } from "../../../util/swar-int";
|
|
|
83
83
|
return srcStart;
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
-
|
|
87
|
-
@inline export function parseUnsignedIntegerScalar<E extends number>(
|
|
86
|
+
export function parseUnsignedIntegerScalar<E extends number>(
|
|
88
87
|
srcStart: usize,
|
|
89
88
|
srcEnd: usize,
|
|
90
89
|
slot: usize,
|
|
@@ -105,8 +104,7 @@ import { parse4Digits_PairMul } from "../../../util/swar-int";
|
|
|
105
104
|
return srcStart;
|
|
106
105
|
}
|
|
107
106
|
|
|
108
|
-
|
|
109
|
-
@inline export function parseSignedIntegerSWAR<E extends number>(
|
|
107
|
+
export function parseSignedIntegerSWAR<E extends number>(
|
|
110
108
|
srcStart: usize,
|
|
111
109
|
srcEnd: usize,
|
|
112
110
|
slot: usize,
|
|
@@ -154,8 +152,7 @@ import { parse4Digits_PairMul } from "../../../util/swar-int";
|
|
|
154
152
|
return srcStart;
|
|
155
153
|
}
|
|
156
154
|
|
|
157
|
-
|
|
158
|
-
@inline export function parseUnsignedIntegerSWAR<E extends number>(
|
|
155
|
+
export function parseUnsignedIntegerSWAR<E extends number>(
|
|
159
156
|
srcStart: usize,
|
|
160
157
|
srcEnd: usize,
|
|
161
158
|
slot: usize,
|
|
@@ -309,8 +306,7 @@ export function deserializeIntegerArray_SLOW<T extends number[]>(
|
|
|
309
306
|
throw new Error("Failed to parse JSON!");
|
|
310
307
|
}
|
|
311
308
|
|
|
312
|
-
|
|
313
|
-
@inline function deserializeIntegerArrayImpl<T extends number[]>(
|
|
309
|
+
function deserializeIntegerArrayImpl<T extends number[]>(
|
|
314
310
|
srcStart: usize,
|
|
315
311
|
srcEnd: usize,
|
|
316
312
|
dst: usize,
|
|
@@ -644,8 +640,7 @@ function deserializeNarrowIntegerArray_SWAR<T extends number[]>(
|
|
|
644
640
|
return out;
|
|
645
641
|
}
|
|
646
642
|
|
|
647
|
-
|
|
648
|
-
@inline function deserializeIntegerArrayBody<T extends number[]>(
|
|
643
|
+
function deserializeIntegerArrayBody<T extends number[]>(
|
|
649
644
|
srcStart: usize,
|
|
650
645
|
srcEnd: usize,
|
|
651
646
|
out: T,
|
|
@@ -77,16 +77,12 @@ import { isSpace } from "../../../util";
|
|
|
77
77
|
return out.dataStart + <usize>index * sizeof<valueof<T>>();
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
-
|
|
81
|
-
@inline export function scanQuotedValueEnd_SWAR(
|
|
82
|
-
srcStart: usize,
|
|
83
|
-
srcEnd: usize,
|
|
84
|
-
): usize {
|
|
80
|
+
export function scanQuotedValueEnd_SWAR(srcStart: usize, srcEnd: usize): usize {
|
|
85
81
|
srcStart += 2;
|
|
86
82
|
const srcEnd8 = srcEnd >= 8 ? srcEnd - 8 : 0;
|
|
87
83
|
|
|
88
84
|
while (srcStart <= srcEnd8) {
|
|
89
|
-
let mask =
|
|
85
|
+
let mask = backslashOrQuoteMask(load<u64>(srcStart));
|
|
90
86
|
if (mask === 0) {
|
|
91
87
|
srcStart += 8;
|
|
92
88
|
continue;
|
|
@@ -114,8 +110,7 @@ import { isSpace } from "../../../util";
|
|
|
114
110
|
return 0;
|
|
115
111
|
}
|
|
116
112
|
|
|
117
|
-
|
|
118
|
-
@inline export function scanValueEnd(srcStart: usize, srcEnd: usize): usize {
|
|
113
|
+
export function scanValueEnd<T = usize>(srcStart: usize, srcEnd: usize): usize {
|
|
119
114
|
if (srcStart >= srcEnd) return 0;
|
|
120
115
|
const first = load<u16>(srcStart);
|
|
121
116
|
|
|
@@ -17,8 +17,7 @@ import { deserializeStringField_SWAR } from "../string";
|
|
|
17
17
|
return srcStart;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
@inline function deserializeStringArrayBody<T extends string[]>(
|
|
20
|
+
function deserializeStringArrayBody<T extends string[]>(
|
|
22
21
|
srcStart: usize,
|
|
23
22
|
srcEnd: usize,
|
|
24
23
|
out: T,
|
|
@@ -26,7 +26,7 @@ import { ensureArrayElementSlot, ensureArrayField } from "./shared";
|
|
|
26
26
|
// - Whitespace is skipped at each separator boundary so struct-array
|
|
27
27
|
// fields tolerate the same `[ {...} , {...} ]` shape that top-level
|
|
28
28
|
// `JSON.parse` does.
|
|
29
|
-
|
|
29
|
+
function deserializeStructArrayBody<T extends unknown[]>(
|
|
30
30
|
srcStart: usize,
|
|
31
31
|
srcEnd: usize,
|
|
32
32
|
out: T,
|
|
@@ -65,11 +65,7 @@ const ASCII_E_LO: u16 = 101;
|
|
|
65
65
|
}
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
-
|
|
69
|
-
@inline export function deserializeFloat_SWAR<T>(
|
|
70
|
-
srcStart: usize,
|
|
71
|
-
srcEnd: usize,
|
|
72
|
-
): T {
|
|
68
|
+
export function deserializeFloat_SWAR<T>(srcStart: usize, srcEnd: usize): T {
|
|
73
69
|
const origStart = srcStart;
|
|
74
70
|
let p = srcStart;
|
|
75
71
|
let negative = false;
|
|
@@ -98,7 +94,7 @@ const ASCII_E_LO: u16 = 101;
|
|
|
98
94
|
if (p < srcEnd && load<u16>(p) == ASCII_DOT) {
|
|
99
95
|
p += 2;
|
|
100
96
|
while (p + 6 < srcEnd) {
|
|
101
|
-
const parsed =
|
|
97
|
+
const parsed = parse4Digits_PairMul(load<u64>(p));
|
|
102
98
|
if (parsed == U32.MAX_VALUE) break;
|
|
103
99
|
mantissa = mantissa * 10_000 + <u64>parsed;
|
|
104
100
|
fracDigits += 4;
|
|
@@ -181,8 +177,7 @@ const ASCII_E_LO: u16 = 101;
|
|
|
181
177
|
return <T>(<f32>result);
|
|
182
178
|
}
|
|
183
179
|
|
|
184
|
-
|
|
185
|
-
@inline export function deserializeFloatField_SWAR<T extends number>(
|
|
180
|
+
export function deserializeFloatField_SWAR<T extends number>(
|
|
186
181
|
srcStart: usize,
|
|
187
182
|
srcEnd: usize,
|
|
188
183
|
dstObj: usize,
|
|
@@ -90,8 +90,7 @@ const ASCII_ZERO: u16 = 48;
|
|
|
90
90
|
* @param srcEnd Pointer just past the last code unit.
|
|
91
91
|
* @returns The parsed value, two's-complement truncated to `T`.
|
|
92
92
|
*/
|
|
93
|
-
|
|
94
|
-
@inline export function deserializeInteger_SWAR<T extends number>(
|
|
93
|
+
export function deserializeInteger_SWAR<T extends number>(
|
|
95
94
|
srcStart: usize,
|
|
96
95
|
srcEnd: usize,
|
|
97
96
|
): T {
|
|
@@ -137,8 +136,7 @@ const ASCII_ZERO: u16 = 48;
|
|
|
137
136
|
* @param dstOffset Byte offset of the field within `dstObj`.
|
|
138
137
|
* @returns The source position immediately after the last digit consumed.
|
|
139
138
|
*/
|
|
140
|
-
|
|
141
|
-
@inline export function deserializeIntegerField_SWAR<T extends number>(
|
|
139
|
+
export function deserializeIntegerField_SWAR<T extends number>(
|
|
142
140
|
srcStart: usize,
|
|
143
141
|
srcEnd: usize,
|
|
144
142
|
dstObj: usize,
|
|
@@ -178,8 +176,7 @@ const ASCII_ZERO: u16 = 48;
|
|
|
178
176
|
* @param srcEnd Pointer just past the last code unit.
|
|
179
177
|
* @returns The parsed value, truncated to `T`.
|
|
180
178
|
*/
|
|
181
|
-
|
|
182
|
-
@inline export function deserializeUnsigned_SWAR<T extends number>(
|
|
179
|
+
export function deserializeUnsigned_SWAR<T extends number>(
|
|
183
180
|
srcStart: usize,
|
|
184
181
|
srcEnd: usize,
|
|
185
182
|
): T {
|
|
@@ -217,8 +214,7 @@ const ASCII_ZERO: u16 = 48;
|
|
|
217
214
|
* @param dstOffset Byte offset of the field within `dstObj`.
|
|
218
215
|
* @returns The source position immediately after the last digit consumed.
|
|
219
216
|
*/
|
|
220
|
-
|
|
221
|
-
@inline export function deserializeUnsignedField_SWAR<T extends number>(
|
|
217
|
+
export function deserializeUnsignedField_SWAR<T extends number>(
|
|
222
218
|
srcStart: usize,
|
|
223
219
|
srcEnd: usize,
|
|
224
220
|
dstObj: usize,
|