json-as 1.3.5 → 1.3.7
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 +17 -1
- package/assembly/deserialize/helpers/uint.ts +4 -1
- package/assembly/deserialize/index/arbitrary.ts +5 -1
- package/assembly/deserialize/index/array.ts +13 -3
- package/assembly/deserialize/index/integer.ts +68 -1
- package/assembly/deserialize/index/string.ts +4 -1
- package/assembly/deserialize/index/typedarray.ts +13 -3
- package/assembly/deserialize/index/unsigned.ts +78 -1
- package/assembly/deserialize/simd/array/integer.ts +327 -50
- package/assembly/deserialize/simd/integer.ts +233 -0
- package/assembly/deserialize/simd/string.ts +45 -11
- package/assembly/deserialize/simple/arbitrary.ts +11 -4
- package/assembly/deserialize/simple/array/arbitrary.ts +24 -5
- package/assembly/deserialize/simple/array/array.ts +8 -2
- package/assembly/deserialize/simple/array/bool.ts +38 -7
- package/assembly/deserialize/simple/array/box.ts +8 -2
- package/assembly/deserialize/simple/array/float.ts +36 -9
- package/assembly/deserialize/simple/array/generic.ts +12 -4
- package/assembly/deserialize/simple/array/integer.ts +8 -2
- package/assembly/deserialize/simple/array/map.ts +26 -6
- package/assembly/deserialize/simple/array/object.ts +26 -6
- package/assembly/deserialize/simple/array/raw.ts +34 -7
- package/assembly/deserialize/simple/array/string.ts +8 -2
- package/assembly/deserialize/simple/array/struct.ts +26 -6
- package/assembly/deserialize/simple/array.ts +13 -3
- package/assembly/deserialize/simple/bool.ts +6 -2
- package/assembly/deserialize/simple/float.ts +6 -1
- package/assembly/deserialize/simple/integer.ts +10 -2
- package/assembly/deserialize/simple/map.ts +95 -22
- package/assembly/deserialize/simple/object.ts +63 -14
- package/assembly/deserialize/simple/raw.ts +4 -1
- package/assembly/deserialize/simple/set.ts +59 -14
- package/assembly/deserialize/simple/staticarray/string.ts +11 -3
- package/assembly/deserialize/simple/staticarray.ts +64 -14
- package/assembly/deserialize/simple/string.ts +5 -92
- package/assembly/deserialize/simple/struct.ts +5 -1
- package/assembly/deserialize/simple/typedarray.ts +16 -3
- package/assembly/deserialize/simple/unsigned.ts +10 -15
- package/assembly/deserialize/swar/array/arbitrary.ts +5 -1
- package/assembly/deserialize/swar/array/array.ts +30 -6
- package/assembly/deserialize/swar/array/bool.ts +22 -4
- package/assembly/deserialize/swar/array/box.ts +5 -1
- package/assembly/deserialize/swar/array/float.ts +15 -3
- package/assembly/deserialize/swar/array/generic.ts +24 -7
- package/assembly/deserialize/swar/array/integer.ts +328 -84
- package/assembly/deserialize/swar/array/map.ts +5 -1
- package/assembly/deserialize/swar/array/object.ts +27 -7
- package/assembly/deserialize/swar/array/raw.ts +5 -1
- package/assembly/deserialize/swar/array/shared.ts +36 -11
- package/assembly/deserialize/swar/array/string.ts +20 -4
- package/assembly/deserialize/swar/array/struct.ts +27 -7
- package/assembly/deserialize/swar/array.ts +19 -4
- package/assembly/deserialize/swar/integer.ts +246 -0
- package/assembly/deserialize/swar/string.ts +98 -194
- package/assembly/index.d.ts +3 -1
- package/assembly/index.ts +312 -81
- package/assembly/serialize/index/float.ts +5 -1
- package/assembly/serialize/index/typedarray.ts +25 -7
- package/assembly/serialize/simd/string.ts +6 -2
- package/assembly/serialize/simple/array.ts +179 -1
- package/assembly/serialize/simple/float.ts +4 -1
- package/assembly/serialize/simple/integer.ts +9 -9
- package/assembly/serialize/simple/map.ts +6 -2
- package/assembly/serialize/simple/raw.ts +5 -1
- package/assembly/serialize/simple/set.ts +6 -1
- package/assembly/serialize/simple/staticarray.ts +6 -1
- package/assembly/serialize/simple/string.ts +0 -1
- package/assembly/serialize/simple/typedarray.ts +10 -3
- package/assembly/serialize/swar/string.ts +25 -8
- package/assembly/tsconfig.json +1 -21
- 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 +43 -14
- package/assembly/util/itoa-fast.ts +230 -0
- package/assembly/util/masks.ts +18 -1
- package/assembly/util/parsefloat-fast.ts +167 -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 +13 -5
- package/package.json +12 -4
- 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 +1 -0
- package/transform/lib/index.d.ts.map +1 -1
- package/transform/lib/index.js +1030 -241
- 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
|
@@ -42,7 +42,10 @@ import { hex4_to_u16_swar } from "../../util/swar";
|
|
|
42
42
|
* @returns number of bytes written
|
|
43
43
|
*/
|
|
44
44
|
// @ts-expect-error: @inline is a valid decorator
|
|
45
|
-
@inline function copyStringFromSource(
|
|
45
|
+
@inline function copyStringFromSource(
|
|
46
|
+
srcStart: usize,
|
|
47
|
+
byteLength: usize,
|
|
48
|
+
): string {
|
|
46
49
|
if (byteLength == 0) return changetype<string>("");
|
|
47
50
|
const out = __new(byteLength, idof<string>());
|
|
48
51
|
memory.copy(out, srcStart, byteLength);
|
|
@@ -50,7 +53,11 @@ import { hex4_to_u16_swar } from "../../util/swar";
|
|
|
50
53
|
}
|
|
51
54
|
|
|
52
55
|
// @ts-expect-error: @inline is a valid decorator
|
|
53
|
-
@inline function deserializeEscapedString_SWAR(
|
|
56
|
+
@inline function deserializeEscapedString_SWAR(
|
|
57
|
+
payloadStart: usize,
|
|
58
|
+
escapeStart: usize,
|
|
59
|
+
srcEnd: usize,
|
|
60
|
+
): string {
|
|
54
61
|
const srcEnd8 = srcEnd - 8;
|
|
55
62
|
const prefixLen = <u32>(escapeStart - payloadStart);
|
|
56
63
|
const outStart = bs.offset - bs.buffer;
|
|
@@ -190,7 +197,9 @@ export function deserializeString_SWAR(srcStart: usize, srcEnd: usize): string {
|
|
|
190
197
|
// Detect false positive (code unit where low byte is 0x5C)
|
|
191
198
|
if ((header & 0xffff) !== 0x5c) continue;
|
|
192
199
|
|
|
193
|
-
return inline.always(
|
|
200
|
+
return inline.always(
|
|
201
|
+
deserializeEscapedString_SWAR(payloadStart, srcIdx, srcEnd),
|
|
202
|
+
);
|
|
194
203
|
} while (mask !== 0);
|
|
195
204
|
|
|
196
205
|
srcStart += 8;
|
|
@@ -198,7 +207,9 @@ export function deserializeString_SWAR(srcStart: usize, srcEnd: usize): string {
|
|
|
198
207
|
|
|
199
208
|
while (srcStart < srcEnd) {
|
|
200
209
|
if (load<u16>(srcStart) == BACK_SLASH) {
|
|
201
|
-
return inline.always(
|
|
210
|
+
return inline.always(
|
|
211
|
+
deserializeEscapedString_SWAR(payloadStart, srcStart, srcEnd),
|
|
212
|
+
);
|
|
202
213
|
}
|
|
203
214
|
srcStart += 2;
|
|
204
215
|
}
|
|
@@ -208,7 +219,11 @@ export function deserializeString_SWAR(srcStart: usize, srcEnd: usize): string {
|
|
|
208
219
|
|
|
209
220
|
// Writes into the destination field, reusing or resizing the backing string.
|
|
210
221
|
// @ts-expect-error: @inline is a valid decorator
|
|
211
|
-
@inline function writeStringToField(
|
|
222
|
+
@inline function writeStringToField(
|
|
223
|
+
dstFieldPtr: usize,
|
|
224
|
+
srcStart: usize,
|
|
225
|
+
byteLength: u32,
|
|
226
|
+
): void {
|
|
212
227
|
if (byteLength == 0) {
|
|
213
228
|
store<usize>(dstFieldPtr, changetype<usize>(""));
|
|
214
229
|
return;
|
|
@@ -230,101 +245,14 @@ export function deserializeString_SWAR(srcStart: usize, srcEnd: usize): string {
|
|
|
230
245
|
memory.copy(stringPtr, srcStart, byteLength);
|
|
231
246
|
}
|
|
232
247
|
|
|
233
|
-
// @ts-expect-error: @inline is a valid decorator
|
|
234
|
-
@inline function deserializeEscapedStringContinuation_SWAR(lastPtr: usize, srcStart: usize, srcEnd: usize, dstFieldPtr: usize, outStart: usize): usize {
|
|
235
|
-
const srcEnd8 = srcEnd - 8;
|
|
236
|
-
|
|
237
|
-
while (srcStart <= srcEnd8) {
|
|
238
|
-
const blockStart = srcStart;
|
|
239
|
-
let mask = inline.always(backslash_or_quote_mask(load<u64>(srcStart)));
|
|
240
|
-
if (mask === 0) {
|
|
241
|
-
srcStart += 8;
|
|
242
|
-
continue;
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
do {
|
|
246
|
-
const laneIdx = usize(ctz(mask) >> 3);
|
|
247
|
-
mask &= mask - 1;
|
|
248
|
-
const srcIdx = srcStart + laneIdx;
|
|
249
|
-
const char = load<u16>(srcIdx);
|
|
250
|
-
if (char == QUOTE) {
|
|
251
|
-
const runLen = <u32>(srcIdx - lastPtr);
|
|
252
|
-
if (runLen != 0) {
|
|
253
|
-
memory.copy(bs.offset, lastPtr, runLen);
|
|
254
|
-
bs.offset += runLen;
|
|
255
|
-
}
|
|
256
|
-
bs.toField(outStart, dstFieldPtr);
|
|
257
|
-
return srcIdx + 2;
|
|
258
|
-
}
|
|
259
|
-
if (char != BACK_SLASH) continue;
|
|
260
|
-
|
|
261
|
-
const runLen = <u32>(srcIdx - lastPtr);
|
|
262
|
-
if (runLen != 0) {
|
|
263
|
-
memory.copy(bs.offset, lastPtr, runLen);
|
|
264
|
-
bs.offset += runLen;
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
const chunk = load<u32>(srcIdx);
|
|
268
|
-
const code = <u16>(chunk >> 16);
|
|
269
|
-
if (code !== 0x75) {
|
|
270
|
-
store<u16>(bs.offset, load<u16>(DESERIALIZE_ESCAPE_TABLE + code));
|
|
271
|
-
bs.offset += 2;
|
|
272
|
-
lastPtr = srcIdx + 4;
|
|
273
|
-
} else {
|
|
274
|
-
store<u16>(bs.offset, hex4_to_u16_swar(load<u64>(srcIdx, 4)));
|
|
275
|
-
bs.offset += 2;
|
|
276
|
-
lastPtr = srcIdx + 12;
|
|
277
|
-
}
|
|
278
|
-
srcStart = lastPtr;
|
|
279
|
-
break;
|
|
280
|
-
} while (mask !== 0);
|
|
281
|
-
|
|
282
|
-
if (srcStart == blockStart) srcStart += 8;
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
while (srcStart < srcEnd) {
|
|
286
|
-
const char = load<u16>(srcStart);
|
|
287
|
-
if (char == QUOTE) {
|
|
288
|
-
const runLen = <u32>(srcStart - lastPtr);
|
|
289
|
-
if (runLen != 0) {
|
|
290
|
-
memory.copy(bs.offset, lastPtr, runLen);
|
|
291
|
-
bs.offset += runLen;
|
|
292
|
-
}
|
|
293
|
-
bs.toField(outStart, dstFieldPtr);
|
|
294
|
-
return srcStart + 2;
|
|
295
|
-
}
|
|
296
|
-
if (char != BACK_SLASH) {
|
|
297
|
-
srcStart += 2;
|
|
298
|
-
continue;
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
const runLen = <u32>(srcStart - lastPtr);
|
|
302
|
-
if (runLen != 0) {
|
|
303
|
-
memory.copy(bs.offset, lastPtr, runLen);
|
|
304
|
-
bs.offset += runLen;
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
const code = load<u16>(srcStart, 2);
|
|
308
|
-
if (code !== 0x75) {
|
|
309
|
-
store<u16>(bs.offset, load<u16>(DESERIALIZE_ESCAPE_TABLE + code));
|
|
310
|
-
bs.offset += 2;
|
|
311
|
-
srcStart += 4;
|
|
312
|
-
} else {
|
|
313
|
-
store<u16>(bs.offset, hex4_to_u16_swar(load<u64>(srcStart, 4)));
|
|
314
|
-
bs.offset += 2;
|
|
315
|
-
srcStart += 12;
|
|
316
|
-
}
|
|
317
|
-
lastPtr = srcStart;
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
bs.offset = bs.buffer + outStart;
|
|
321
|
-
abort("Unterminated string literal");
|
|
322
|
-
return srcStart;
|
|
323
|
-
}
|
|
324
|
-
|
|
325
248
|
// Scans a quoted string value, writes into the destination field, and returns next unread src pointer.
|
|
326
249
|
// @ts-expect-error: @inline is a valid decorator
|
|
327
|
-
@inline function deserializeEscapedStringScan_SWAR_SplitTuned(
|
|
250
|
+
@inline function deserializeEscapedStringScan_SWAR_SplitTuned(
|
|
251
|
+
payloadStart: usize,
|
|
252
|
+
escapeStart: usize,
|
|
253
|
+
srcEnd: usize,
|
|
254
|
+
dstFieldPtr: usize,
|
|
255
|
+
): usize {
|
|
328
256
|
const prefixLen = <u32>(escapeStart - payloadStart);
|
|
329
257
|
const srcEnd8 = srcEnd - 8;
|
|
330
258
|
bs.offset = bs.buffer;
|
|
@@ -356,7 +284,11 @@ export function deserializeString_SWAR(srcStart: usize, srcEnd: usize): string {
|
|
|
356
284
|
memory.copy(bs.offset, lastPtr, runLen);
|
|
357
285
|
bs.offset += runLen;
|
|
358
286
|
}
|
|
359
|
-
writeStringToField(
|
|
287
|
+
writeStringToField(
|
|
288
|
+
dstFieldPtr,
|
|
289
|
+
bs.buffer,
|
|
290
|
+
<u32>(bs.offset - bs.buffer),
|
|
291
|
+
);
|
|
360
292
|
bs.offset = bs.buffer;
|
|
361
293
|
return srcIdx + 2;
|
|
362
294
|
}
|
|
@@ -427,7 +359,12 @@ export function deserializeString_SWAR(srcStart: usize, srcEnd: usize): string {
|
|
|
427
359
|
}
|
|
428
360
|
|
|
429
361
|
// @ts-expect-error: @inline is a valid decorator
|
|
430
|
-
@inline function deserializeEscapedStringContinuation_SWAR_MergedTuned(
|
|
362
|
+
@inline function deserializeEscapedStringContinuation_SWAR_MergedTuned(
|
|
363
|
+
lastPtr: usize,
|
|
364
|
+
srcStart: usize,
|
|
365
|
+
srcEnd: usize,
|
|
366
|
+
dstFieldPtr: usize,
|
|
367
|
+
): usize {
|
|
431
368
|
const srcEnd8 = srcEnd - 8;
|
|
432
369
|
|
|
433
370
|
while (srcStart <= srcEnd8) {
|
|
@@ -449,7 +386,11 @@ export function deserializeString_SWAR(srcStart: usize, srcEnd: usize): string {
|
|
|
449
386
|
memory.copy(bs.offset, lastPtr, runLen);
|
|
450
387
|
bs.offset += runLen;
|
|
451
388
|
}
|
|
452
|
-
writeStringToField(
|
|
389
|
+
writeStringToField(
|
|
390
|
+
dstFieldPtr,
|
|
391
|
+
bs.buffer,
|
|
392
|
+
<u32>(bs.offset - bs.buffer),
|
|
393
|
+
);
|
|
453
394
|
bs.offset = bs.buffer;
|
|
454
395
|
return srcIdx + 2;
|
|
455
396
|
}
|
|
@@ -518,99 +459,31 @@ export function deserializeString_SWAR(srcStart: usize, srcEnd: usize): string {
|
|
|
518
459
|
return srcStart;
|
|
519
460
|
}
|
|
520
461
|
|
|
521
|
-
function
|
|
522
|
-
|
|
462
|
+
export function deserializeStringField_SWAR<T extends string | null>(
|
|
463
|
+
srcStart: usize,
|
|
464
|
+
srcEnd: usize,
|
|
465
|
+
dstFieldPtr: usize,
|
|
466
|
+
): usize {
|
|
467
|
+
if (srcStart + 2 > srcEnd || load<u16>(srcStart) != QUOTE)
|
|
468
|
+
abort("Expected leading quote");
|
|
523
469
|
|
|
524
470
|
const payloadStart = srcStart + 2;
|
|
525
|
-
const srcEnd8 = srcEnd - 8;
|
|
526
471
|
srcStart = payloadStart;
|
|
527
472
|
|
|
528
|
-
while
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
const srcIdx = srcStart + laneIdx;
|
|
539
|
-
const char = load<u16>(srcIdx);
|
|
540
|
-
|
|
541
|
-
if (char == QUOTE) {
|
|
542
|
-
writeStringToField(dstFieldPtr, payloadStart, <u32>(srcIdx - payloadStart));
|
|
543
|
-
return srcIdx + 2;
|
|
544
|
-
}
|
|
545
|
-
if (char != BACK_SLASH) continue;
|
|
546
|
-
|
|
547
|
-
bs.offset = bs.buffer;
|
|
548
|
-
bs.ensureSize(<u32>(srcEnd - payloadStart));
|
|
549
|
-
const prefixLen = <u32>(srcIdx - payloadStart);
|
|
550
|
-
if (prefixLen != 0) {
|
|
551
|
-
memory.copy(bs.buffer, payloadStart, prefixLen);
|
|
552
|
-
bs.offset += prefixLen;
|
|
553
|
-
}
|
|
554
|
-
|
|
555
|
-
const chunk = load<u32>(srcIdx);
|
|
556
|
-
const code = <u16>(chunk >> 16);
|
|
557
|
-
let lastPtr: usize;
|
|
558
|
-
if (code !== 0x75) {
|
|
559
|
-
store<u16>(bs.offset, load<u16>(DESERIALIZE_ESCAPE_TABLE + code));
|
|
560
|
-
bs.offset += 2;
|
|
561
|
-
lastPtr = srcIdx + 4;
|
|
562
|
-
} else {
|
|
563
|
-
store<u16>(bs.offset, hex4_to_u16_swar(load<u64>(srcIdx, 4)));
|
|
564
|
-
bs.offset += 2;
|
|
565
|
-
lastPtr = srcIdx + 12;
|
|
566
|
-
}
|
|
567
|
-
return inline.always(deserializeEscapedStringContinuation_SWAR_MergedTuned(lastPtr, lastPtr, srcEnd, dstFieldPtr));
|
|
568
|
-
} while (mask !== 0);
|
|
569
|
-
|
|
570
|
-
srcStart += 8;
|
|
571
|
-
}
|
|
572
|
-
|
|
573
|
-
while (srcStart < srcEnd) {
|
|
574
|
-
const char = load<u16>(srcStart);
|
|
575
|
-
if (char == QUOTE) {
|
|
576
|
-
writeStringToField(dstFieldPtr, payloadStart, <u32>(srcStart - payloadStart));
|
|
577
|
-
return srcStart + 2;
|
|
578
|
-
}
|
|
579
|
-
if (char == BACK_SLASH) {
|
|
580
|
-
bs.offset = bs.buffer;
|
|
581
|
-
bs.ensureSize(<u32>(srcEnd - payloadStart));
|
|
582
|
-
const prefixLen = <u32>(srcStart - payloadStart);
|
|
583
|
-
if (prefixLen != 0) {
|
|
584
|
-
memory.copy(bs.buffer, payloadStart, prefixLen);
|
|
585
|
-
bs.offset += prefixLen;
|
|
586
|
-
}
|
|
587
|
-
|
|
588
|
-
const code = load<u16>(srcStart, 2);
|
|
589
|
-
let lastPtr: usize;
|
|
590
|
-
if (code !== 0x75) {
|
|
591
|
-
store<u16>(bs.offset, load<u16>(DESERIALIZE_ESCAPE_TABLE + code));
|
|
592
|
-
bs.offset += 2;
|
|
593
|
-
lastPtr = srcStart + 4;
|
|
594
|
-
} else {
|
|
595
|
-
store<u16>(bs.offset, hex4_to_u16_swar(load<u64>(srcStart, 4)));
|
|
596
|
-
bs.offset += 2;
|
|
597
|
-
lastPtr = srcStart + 12;
|
|
598
|
-
}
|
|
599
|
-
return inline.always(deserializeEscapedStringContinuation_SWAR_MergedTuned(lastPtr, lastPtr, srcEnd, dstFieldPtr));
|
|
473
|
+
// Wide pre-scan: skip 16 bytes per iter while both halves are clean. The
|
|
474
|
+
// common case (plain ASCII payloads, no escape) hits this loop exclusively
|
|
475
|
+
// and is bound by load+SWAR throughput, not branch frequency.
|
|
476
|
+
if (srcEnd >= 16) {
|
|
477
|
+
const srcEnd16 = srcEnd - 16;
|
|
478
|
+
while (srcStart <= srcEnd16) {
|
|
479
|
+
const m0 = inline.always(backslash_or_quote_mask(load<u64>(srcStart)));
|
|
480
|
+
const m1 = inline.always(backslash_or_quote_mask(load<u64>(srcStart, 8)));
|
|
481
|
+
if ((m0 | m1) != 0) break;
|
|
482
|
+
srcStart += 16;
|
|
600
483
|
}
|
|
601
|
-
srcStart += 2;
|
|
602
484
|
}
|
|
603
485
|
|
|
604
|
-
return srcStart;
|
|
605
|
-
}
|
|
606
|
-
|
|
607
|
-
export function deserializeStringField_SWAR<T extends string | null>(srcStart: usize, srcEnd: usize, dstFieldPtr: usize): usize {
|
|
608
|
-
if (srcStart + 2 > srcEnd || load<u16>(srcStart) != QUOTE) abort("Expected leading quote");
|
|
609
|
-
|
|
610
|
-
const payloadStart = srcStart + 2;
|
|
611
486
|
const srcEnd8 = srcEnd - 8;
|
|
612
|
-
srcStart = payloadStart;
|
|
613
|
-
|
|
614
487
|
while (srcStart <= srcEnd8) {
|
|
615
488
|
let mask = inline.always(backslash_or_quote_mask(load<u64>(srcStart)));
|
|
616
489
|
if (mask === 0) {
|
|
@@ -624,11 +497,22 @@ export function deserializeStringField_SWAR<T extends string | null>(srcStart: u
|
|
|
624
497
|
const srcIdx = srcStart + laneIdx;
|
|
625
498
|
const char = load<u16>(srcIdx);
|
|
626
499
|
if (char == QUOTE) {
|
|
627
|
-
writeStringToField(
|
|
500
|
+
writeStringToField(
|
|
501
|
+
dstFieldPtr,
|
|
502
|
+
payloadStart,
|
|
503
|
+
<u32>(srcIdx - payloadStart),
|
|
504
|
+
);
|
|
628
505
|
return srcIdx + 2;
|
|
629
506
|
}
|
|
630
507
|
if (char != BACK_SLASH) continue;
|
|
631
|
-
return inline.always(
|
|
508
|
+
return inline.always(
|
|
509
|
+
deserializeEscapedStringScan_SWAR_SplitTuned(
|
|
510
|
+
payloadStart,
|
|
511
|
+
srcIdx,
|
|
512
|
+
srcEnd,
|
|
513
|
+
dstFieldPtr,
|
|
514
|
+
),
|
|
515
|
+
);
|
|
632
516
|
} while (mask !== 0);
|
|
633
517
|
|
|
634
518
|
srcStart += 8;
|
|
@@ -637,11 +521,22 @@ export function deserializeStringField_SWAR<T extends string | null>(srcStart: u
|
|
|
637
521
|
while (srcStart < srcEnd) {
|
|
638
522
|
const char = load<u16>(srcStart);
|
|
639
523
|
if (char == QUOTE) {
|
|
640
|
-
writeStringToField(
|
|
524
|
+
writeStringToField(
|
|
525
|
+
dstFieldPtr,
|
|
526
|
+
payloadStart,
|
|
527
|
+
<u32>(srcStart - payloadStart),
|
|
528
|
+
);
|
|
641
529
|
return srcStart + 2;
|
|
642
530
|
}
|
|
643
531
|
if (char == BACK_SLASH) {
|
|
644
|
-
return inline.always(
|
|
532
|
+
return inline.always(
|
|
533
|
+
deserializeEscapedStringScan_SWAR_SplitTuned(
|
|
534
|
+
payloadStart,
|
|
535
|
+
srcStart,
|
|
536
|
+
srcEnd,
|
|
537
|
+
dstFieldPtr,
|
|
538
|
+
),
|
|
539
|
+
);
|
|
645
540
|
}
|
|
646
541
|
srcStart += 2;
|
|
647
542
|
}
|
|
@@ -661,7 +556,10 @@ export function deserializeStringField_SWAR<T extends string | null>(srcStart: u
|
|
|
661
556
|
@inline function backslash_or_quote_mask(block: u64): u64 {
|
|
662
557
|
const b = block ^ 0x005c_005c_005c_005c;
|
|
663
558
|
const q = block ^ 0x0022_0022_0022_0022;
|
|
664
|
-
return (
|
|
559
|
+
return (
|
|
560
|
+
(((q - 0x0001_0001_0001_0001) & ~q) | ((b - 0x0001_0001_0001_0001) & ~b)) &
|
|
561
|
+
0x0080_0080_0080_0080
|
|
562
|
+
);
|
|
665
563
|
}
|
|
666
564
|
/**
|
|
667
565
|
* Computes a per-lane mask identifying UTF-16 code units whose **low byte**
|
|
@@ -677,8 +575,13 @@ export function deserializeStringField_SWAR<T extends string | null>(srcStart: u
|
|
|
677
575
|
// @ts-expect-error: @inline is a valid decorator
|
|
678
576
|
@inline function backslash_mask(block: u64): u64 {
|
|
679
577
|
const b = block ^ 0x005c_005c_005c_005c;
|
|
680
|
-
const backslash_mask =
|
|
681
|
-
|
|
578
|
+
const backslash_mask =
|
|
579
|
+
(b - 0x0001_0001_0001_0001) & ~b & 0x0080_0080_0080_0080;
|
|
580
|
+
const high_byte_mask =
|
|
581
|
+
~(
|
|
582
|
+
((block - 0x0100_0100_0100_0100) & ~block & 0x8000_8000_8000_8000) ^
|
|
583
|
+
0x8000_8000_8000_8000
|
|
584
|
+
) >> 8;
|
|
682
585
|
return backslash_mask & high_byte_mask;
|
|
683
586
|
}
|
|
684
587
|
|
|
@@ -694,6 +597,7 @@ export function deserializeStringField_SWAR<T extends string | null>(srcStart: u
|
|
|
694
597
|
// @ts-expect-error: @inline is a valid decorator
|
|
695
598
|
@inline function backslash_mask_unsafe(block: u64): u64 {
|
|
696
599
|
const b = block ^ 0x005c_005c_005c_005c;
|
|
697
|
-
const backslash_mask =
|
|
600
|
+
const backslash_mask =
|
|
601
|
+
(b - 0x0001_0001_0001_0001) & ~b & 0x0080_0080_0080_0080;
|
|
698
602
|
return backslash_mask;
|
|
699
603
|
}
|
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.
|