json-as 1.3.1 → 1.3.2
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 +9 -26
- package/README.md +41 -18
- package/assembly/deserialize/index/arbitrary.ts +1 -1
- package/assembly/deserialize/index/array.ts +6 -1
- package/assembly/deserialize/index/float.ts +1 -1
- package/assembly/deserialize/index/integer.ts +1 -1
- package/assembly/deserialize/index/unsigned.ts +1 -1
- package/assembly/deserialize/simd/string.ts +17 -13
- package/assembly/deserialize/simple/arbitrary.ts +1 -1
- package/assembly/deserialize/simple/array/generic.ts +42 -0
- package/assembly/deserialize/simple/array.ts +8 -1
- package/assembly/deserialize/{float.ts → simple/float.ts} +22 -2
- package/assembly/deserialize/{integer.ts → simple/integer.ts} +3 -2
- package/assembly/deserialize/simple/map.ts +60 -12
- package/assembly/deserialize/simple/object.ts +1 -1
- package/assembly/deserialize/simple/set.ts +119 -134
- package/assembly/deserialize/simple/staticarray.ts +12 -1
- package/assembly/deserialize/simple/string.ts +15 -10
- package/assembly/deserialize/simple/struct.ts +7 -157
- package/assembly/deserialize/simple/typedarray.ts +1 -1
- package/assembly/deserialize/{unsigned.ts → simple/unsigned.ts} +3 -2
- package/assembly/deserialize/swar/array/array.ts +42 -7
- package/assembly/deserialize/swar/array/bool.ts +5 -2
- package/assembly/deserialize/swar/array/float.ts +7 -3
- package/assembly/deserialize/swar/array/generic.ts +40 -0
- package/assembly/deserialize/swar/array/integer.ts +7 -4
- package/assembly/deserialize/swar/array/object.ts +20 -4
- package/assembly/deserialize/swar/array/shared.ts +18 -4
- package/assembly/deserialize/swar/array/string.ts +5 -2
- package/assembly/deserialize/swar/array/struct.ts +20 -4
- package/assembly/deserialize/swar/array.ts +56 -2
- package/assembly/deserialize/swar/string.ts +249 -371
- package/assembly/index.ts +74 -17
- package/assembly/serialize/index/arbitrary.ts +3 -3
- package/assembly/serialize/index/float.ts +1 -1
- package/assembly/serialize/index/object.ts +1 -5
- package/assembly/serialize/simd/string.ts +4 -5
- package/assembly/serialize/simple/arbitrary.ts +3 -3
- package/assembly/serialize/simple/array.ts +17 -6
- package/assembly/serialize/simple/float.ts +18 -4
- package/assembly/serialize/simple/map.ts +10 -27
- package/assembly/serialize/simple/object.ts +1 -5
- package/assembly/serialize/simple/set.ts +3 -4
- package/assembly/serialize/simple/staticarray.ts +4 -3
- package/assembly/serialize/simple/typedarray.ts +9 -7
- package/assembly/serialize/swar/string.ts +0 -1
- package/assembly/tsconfig.json +3 -2
- package/assembly/util/dragonbox-cache.ts +1322 -0
- package/assembly/util/dragonbox.ts +596 -0
- package/lib/as-bs.ts +10 -7
- package/package.json +17 -10
- package/transform/lib/index.d.ts.map +1 -1
- package/transform/lib/index.js +408 -191
- package/transform/lib/index.js.map +1 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { bs } from "../../../lib/as-bs";
|
|
2
2
|
import { OBJECT, TOTAL_OVERHEAD } from "rt/common";
|
|
3
|
+
import { __heap_base } from "memory";
|
|
3
4
|
import { BACK_SLASH, QUOTE } from "../../custom/chars";
|
|
4
5
|
import { DESERIALIZE_ESCAPE_TABLE } from "../../globals/tables";
|
|
5
6
|
import { hex4_to_u16_swar } from "../../util/swar";
|
|
@@ -184,106 +185,7 @@ export function deserializeString_SWAR(srcStart: usize, srcEnd: usize): string {
|
|
|
184
185
|
return copyStringFromSource(payloadStart, srcEnd - payloadStart);
|
|
185
186
|
}
|
|
186
187
|
|
|
187
|
-
//
|
|
188
|
-
// * Deserializes a quoted JSON string into a reused/renewed destination string buffer.
|
|
189
|
-
// * @param srcStart pointer to opening quote
|
|
190
|
-
// * @param srcEnd pointer to closing quote
|
|
191
|
-
// * @param outPtr existing destination string pointer (or 0)
|
|
192
|
-
// * @returns next unread source pointer
|
|
193
|
-
// */
|
|
194
|
-
// export function deserializeString_SWAR_TO(srcStart: usize, srcEnd: usize, outPtr: usize): usize {
|
|
195
|
-
// srcStart += 2;
|
|
196
|
-
// let dst = outPtr;
|
|
197
|
-
// const srcEnd8 = srcEnd - 8;
|
|
198
|
-
// const byteSize = srcEnd - srcStart;
|
|
199
|
-
// if (!dst) {
|
|
200
|
-
// dst = __new(byteSize, idof<string>());
|
|
201
|
-
// } else if (changetype<OBJECT>(dst - TOTAL_OVERHEAD).rtSize < <u32>byteSize) {
|
|
202
|
-
// dst = __renew(dst, byteSize);
|
|
203
|
-
// }
|
|
204
|
-
// let offset = dst;
|
|
205
|
-
|
|
206
|
-
// while (srcStart < srcEnd8) {
|
|
207
|
-
// const block = load<u64>(srcStart);
|
|
208
|
-
// store<u64>(offset, block);
|
|
209
|
-
|
|
210
|
-
// let mask = inline.always(backslash_mask_unsafe(block));
|
|
211
|
-
|
|
212
|
-
// if (mask === 0) {
|
|
213
|
-
// srcStart += 8;
|
|
214
|
-
// offset += 8;
|
|
215
|
-
// continue;
|
|
216
|
-
// }
|
|
217
|
-
|
|
218
|
-
// do {
|
|
219
|
-
// const laneIdx = usize(ctz(mask) >> 3); // 0 2 4 6
|
|
220
|
-
// mask &= mask - 1;
|
|
221
|
-
// const srcIdx = srcStart + laneIdx;
|
|
222
|
-
// const dstIdx = offset + laneIdx;
|
|
223
|
-
// const header = load<u32>(srcIdx);
|
|
224
|
-
// const code = <u16>(header >> 16);
|
|
225
|
-
|
|
226
|
-
// if ((header & 0xffff) !== 0x5c) continue;
|
|
227
|
-
|
|
228
|
-
// if (code !== 0x75) {
|
|
229
|
-
// const escaped = load<u16>(DESERIALIZE_ESCAPE_TABLE + code);
|
|
230
|
-
// mask &= mask - usize(escaped === 0x5c);
|
|
231
|
-
// store<u16>(dstIdx, escaped);
|
|
232
|
-
// const copyStart = srcIdx + 4;
|
|
233
|
-
// if (copyStart < srcEnd) {
|
|
234
|
-
// const copyBytes = min<usize>(4, srcEnd - copyStart);
|
|
235
|
-
// memory.copy(dstIdx + 2, copyStart, copyBytes);
|
|
236
|
-
// }
|
|
237
|
-
|
|
238
|
-
// const l6 = usize(laneIdx === 6);
|
|
239
|
-
// offset -= (1 - l6) << 1;
|
|
240
|
-
// srcStart += l6 << 1;
|
|
241
|
-
// continue;
|
|
242
|
-
// }
|
|
243
|
-
|
|
244
|
-
// const block = load<u64>(srcIdx, 4); // XXXX
|
|
245
|
-
// const escaped = hex4_to_u16_swar(block);
|
|
246
|
-
// store<u16>(dstIdx, escaped);
|
|
247
|
-
// srcStart += 4 + laneIdx;
|
|
248
|
-
// offset -= 6 - laneIdx;
|
|
249
|
-
// } while (mask !== 0);
|
|
250
|
-
|
|
251
|
-
// offset += 8;
|
|
252
|
-
// srcStart += 8;
|
|
253
|
-
// }
|
|
254
|
-
|
|
255
|
-
// while (srcStart < srcEnd) {
|
|
256
|
-
// const block = load<u16>(srcStart);
|
|
257
|
-
// store<u16>(offset, block);
|
|
258
|
-
// srcStart += 2;
|
|
259
|
-
|
|
260
|
-
// if (block !== 0x5c) {
|
|
261
|
-
// offset += 2;
|
|
262
|
-
// continue;
|
|
263
|
-
// }
|
|
264
|
-
|
|
265
|
-
// const code = load<u16>(srcStart);
|
|
266
|
-
// if (code !== 0x75) {
|
|
267
|
-
// const block = load<u16>(srcStart);
|
|
268
|
-
// const escape = load<u16>(DESERIALIZE_ESCAPE_TABLE + block);
|
|
269
|
-
// store<u16>(offset, escape);
|
|
270
|
-
// srcStart += 2;
|
|
271
|
-
// } else {
|
|
272
|
-
// const block = load<u64>(srcStart, 2); // XXXX
|
|
273
|
-
// const escaped = hex4_to_u16_swar(block);
|
|
274
|
-
// store<u16>(offset, escaped);
|
|
275
|
-
// srcStart += 10;
|
|
276
|
-
// }
|
|
277
|
-
|
|
278
|
-
// offset += 2;
|
|
279
|
-
// }
|
|
280
|
-
// if (offset - dst != byteSize) {
|
|
281
|
-
// dst = __renew(dst, offset - dst);
|
|
282
|
-
// }
|
|
283
|
-
// return srcEnd + 2;
|
|
284
|
-
// }
|
|
285
|
-
|
|
286
|
-
// Scans a quoted string value, writes into the destination field, and returns next unread src pointer.
|
|
188
|
+
// Writes into the destination field, reusing or resizing the backing string.
|
|
287
189
|
// @ts-expect-error: @inline is a valid decorator
|
|
288
190
|
@inline function writeStringToField(dstFieldPtr: usize, srcStart: usize, byteLength: u32): void {
|
|
289
191
|
if (byteLength == 0) {
|
|
@@ -293,11 +195,13 @@ export function deserializeString_SWAR(srcStart: usize, srcEnd: usize): string {
|
|
|
293
195
|
|
|
294
196
|
const current = load<usize>(dstFieldPtr);
|
|
295
197
|
let stringPtr: usize;
|
|
296
|
-
if (current
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
198
|
+
if (current >= __heap_base) {
|
|
199
|
+
if (changetype<OBJECT>(current - TOTAL_OVERHEAD).rtSize == byteLength) {
|
|
200
|
+
stringPtr = current;
|
|
201
|
+
} else {
|
|
202
|
+
stringPtr = __renew(current, byteLength);
|
|
203
|
+
store<usize>(dstFieldPtr, stringPtr);
|
|
204
|
+
}
|
|
301
205
|
} else {
|
|
302
206
|
stringPtr = __new(byteLength, idof<string>());
|
|
303
207
|
store<usize>(dstFieldPtr, stringPtr);
|
|
@@ -305,17 +209,14 @@ export function deserializeString_SWAR(srcStart: usize, srcEnd: usize): string {
|
|
|
305
209
|
memory.copy(stringPtr, srcStart, byteLength);
|
|
306
210
|
}
|
|
307
211
|
|
|
308
|
-
/*
|
|
309
|
-
export function deserializeStringField_SWAR<T extends string | null>(srcStart: usize, srcEnd: usize, dstFieldPtr: usize): usize {
|
|
310
|
-
if (srcStart + 2 > srcEnd || load<u16>(srcStart) != QUOTE) abort("Expected leading quote");
|
|
311
212
|
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
213
|
+
// @ts-expect-error: @inline is a valid decorator
|
|
214
|
+
@inline function deserializeEscapedStringContinuation_SWAR(lastPtr: usize, srcStart: usize, srcEnd: usize, dstFieldPtr: usize, outStart: usize): usize {
|
|
215
|
+
const srcEnd8 = srcEnd - 8;
|
|
315
216
|
|
|
316
217
|
while (srcStart <= srcEnd8) {
|
|
218
|
+
const blockStart = srcStart;
|
|
317
219
|
let mask = inline.always(backslash_or_quote_mask(load<u64>(srcStart)));
|
|
318
|
-
|
|
319
220
|
if (mask === 0) {
|
|
320
221
|
srcStart += 8;
|
|
321
222
|
continue;
|
|
@@ -323,294 +224,93 @@ export function deserializeStringField_SWAR<T extends string | null>(srcStart: u
|
|
|
323
224
|
|
|
324
225
|
do {
|
|
325
226
|
const laneIdx = usize(ctz(mask) >> 3);
|
|
326
|
-
mask &=
|
|
327
|
-
// since we clear the entire byte, we can guarentee that any discovered lane where char == QUOTE is unescaped and a terminator.
|
|
227
|
+
mask &= mask - 1;
|
|
328
228
|
const srcIdx = srcStart + laneIdx;
|
|
329
229
|
const char = load<u16>(srcIdx);
|
|
330
|
-
|
|
331
230
|
if (char == QUOTE) {
|
|
332
|
-
|
|
231
|
+
const runLen = <u32>(srcIdx - lastPtr);
|
|
232
|
+
if (runLen != 0) {
|
|
233
|
+
memory.copy(bs.offset, lastPtr, runLen);
|
|
234
|
+
bs.offset += runLen;
|
|
235
|
+
}
|
|
236
|
+
bs.toField(outStart, dstFieldPtr);
|
|
333
237
|
return srcIdx + 2;
|
|
334
238
|
}
|
|
335
239
|
if (char != BACK_SLASH) continue;
|
|
336
240
|
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
memory.copy(bs.buffer, payloadStart, prefixLen);
|
|
342
|
-
bs.offset += prefixLen;
|
|
241
|
+
const runLen = <u32>(srcIdx - lastPtr);
|
|
242
|
+
if (runLen != 0) {
|
|
243
|
+
memory.copy(bs.offset, lastPtr, runLen);
|
|
244
|
+
bs.offset += runLen;
|
|
343
245
|
}
|
|
344
246
|
|
|
345
247
|
const chunk = load<u32>(srcIdx);
|
|
346
248
|
const code = <u16>(chunk >> 16);
|
|
347
|
-
|
|
348
249
|
if (code !== 0x75) {
|
|
349
250
|
store<u16>(bs.offset, load<u16>(DESERIALIZE_ESCAPE_TABLE + code));
|
|
350
251
|
bs.offset += 2;
|
|
351
|
-
|
|
352
|
-
srcStart = lastPtr;
|
|
353
|
-
while (srcStart <= srcEnd8) {
|
|
354
|
-
const blockStart = srcStart;
|
|
355
|
-
let escapedMask = inline.always(backslash_or_quote_mask(load<u64>(srcStart)));
|
|
356
|
-
if (escapedMask === 0) {
|
|
357
|
-
srcStart += 8;
|
|
358
|
-
continue;
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
do {
|
|
362
|
-
const escapedLaneIdx = usize(ctz(escapedMask) >> 3);
|
|
363
|
-
escapedMask &= escapedMask - 1;
|
|
364
|
-
const escapedIdx = srcStart + escapedLaneIdx;
|
|
365
|
-
const escapedChar = load<u16>(escapedIdx);
|
|
366
|
-
|
|
367
|
-
if (escapedChar == QUOTE) {
|
|
368
|
-
const runLen = <u32>(escapedIdx - lastPtr);
|
|
369
|
-
if (runLen != 0) {
|
|
370
|
-
memory.copy(bs.offset, lastPtr, runLen);
|
|
371
|
-
bs.offset += runLen;
|
|
372
|
-
}
|
|
373
|
-
writeStringToField(dstFieldPtr, bs.buffer, <u32>(bs.offset - bs.buffer));
|
|
374
|
-
bs.offset = bs.buffer;
|
|
375
|
-
return escapedIdx + 2;
|
|
376
|
-
}
|
|
377
|
-
if (escapedChar != BACK_SLASH) continue;
|
|
378
|
-
|
|
379
|
-
const runLen = <u32>(escapedIdx - lastPtr);
|
|
380
|
-
if (runLen != 0) {
|
|
381
|
-
memory.copy(bs.offset, lastPtr, runLen);
|
|
382
|
-
bs.offset += runLen;
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
const escapedChunk = load<u32>(escapedIdx);
|
|
386
|
-
const escapedCode = <u16>(escapedChunk >> 16);
|
|
387
|
-
if (escapedCode !== 0x75) {
|
|
388
|
-
store<u16>(bs.offset, load<u16>(DESERIALIZE_ESCAPE_TABLE + escapedCode));
|
|
389
|
-
bs.offset += 2;
|
|
390
|
-
lastPtr = escapedIdx + 4;
|
|
391
|
-
} else {
|
|
392
|
-
store<u16>(bs.offset, hex4_to_u16_swar(load<u64>(escapedIdx, 4)));
|
|
393
|
-
bs.offset += 2;
|
|
394
|
-
lastPtr = escapedIdx + 12;
|
|
395
|
-
}
|
|
396
|
-
srcStart = lastPtr;
|
|
397
|
-
break;
|
|
398
|
-
} while (escapedMask !== 0);
|
|
399
|
-
|
|
400
|
-
if (srcStart == blockStart) srcStart += 8;
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
while (srcStart < srcEnd) {
|
|
404
|
-
const tailChar = load<u16>(srcStart);
|
|
405
|
-
if (tailChar == QUOTE) {
|
|
406
|
-
const runLen = <u32>(srcStart - lastPtr);
|
|
407
|
-
if (runLen != 0) {
|
|
408
|
-
memory.copy(bs.offset, lastPtr, runLen);
|
|
409
|
-
bs.offset += runLen;
|
|
410
|
-
}
|
|
411
|
-
writeStringToField(dstFieldPtr, bs.buffer, <u32>(bs.offset - bs.buffer));
|
|
412
|
-
bs.offset = bs.buffer;
|
|
413
|
-
return srcStart + 2;
|
|
414
|
-
}
|
|
415
|
-
if (tailChar != BACK_SLASH) {
|
|
416
|
-
srcStart += 2;
|
|
417
|
-
continue;
|
|
418
|
-
}
|
|
419
|
-
|
|
420
|
-
const runLen = <u32>(srcStart - lastPtr);
|
|
421
|
-
if (runLen != 0) {
|
|
422
|
-
memory.copy(bs.offset, lastPtr, runLen);
|
|
423
|
-
bs.offset += runLen;
|
|
424
|
-
}
|
|
425
|
-
const tailCode = load<u16>(srcStart, 2);
|
|
426
|
-
if (tailCode !== 0x75) {
|
|
427
|
-
store<u16>(bs.offset, load<u16>(DESERIALIZE_ESCAPE_TABLE + tailCode));
|
|
428
|
-
bs.offset += 2;
|
|
429
|
-
srcStart += 4;
|
|
430
|
-
} else {
|
|
431
|
-
store<u16>(bs.offset, hex4_to_u16_swar(load<u64>(srcStart, 4)));
|
|
432
|
-
bs.offset += 2;
|
|
433
|
-
srcStart += 12;
|
|
434
|
-
}
|
|
435
|
-
lastPtr = srcStart;
|
|
436
|
-
}
|
|
437
|
-
bs.offset = bs.buffer;
|
|
438
|
-
return srcStart;
|
|
252
|
+
lastPtr = srcIdx + 4;
|
|
439
253
|
} else {
|
|
440
254
|
store<u16>(bs.offset, hex4_to_u16_swar(load<u64>(srcIdx, 4)));
|
|
441
255
|
bs.offset += 2;
|
|
442
|
-
|
|
443
|
-
srcStart = lastPtr;
|
|
444
|
-
while (srcStart <= srcEnd8) {
|
|
445
|
-
const blockStart = srcStart;
|
|
446
|
-
let escapedMask = inline.always(backslash_or_quote_mask(load<u64>(srcStart)));
|
|
447
|
-
if (escapedMask === 0) {
|
|
448
|
-
srcStart += 8;
|
|
449
|
-
continue;
|
|
450
|
-
}
|
|
451
|
-
|
|
452
|
-
do {
|
|
453
|
-
const escapedLaneIdx = usize(ctz(escapedMask) >> 3);
|
|
454
|
-
escapedMask &= escapedMask - 1;
|
|
455
|
-
const escapedIdx = srcStart + escapedLaneIdx;
|
|
456
|
-
const escapedChar = load<u16>(escapedIdx);
|
|
457
|
-
|
|
458
|
-
if (escapedChar == QUOTE) {
|
|
459
|
-
const runLen = <u32>(escapedIdx - lastPtr);
|
|
460
|
-
if (runLen != 0) {
|
|
461
|
-
memory.copy(bs.offset, lastPtr, runLen);
|
|
462
|
-
bs.offset += runLen;
|
|
463
|
-
}
|
|
464
|
-
writeStringToField(dstFieldPtr, bs.buffer, <u32>(bs.offset - bs.buffer));
|
|
465
|
-
bs.offset = bs.buffer;
|
|
466
|
-
return escapedIdx + 2;
|
|
467
|
-
}
|
|
468
|
-
if (escapedChar != BACK_SLASH) continue;
|
|
469
|
-
|
|
470
|
-
const runLen = <u32>(escapedIdx - lastPtr);
|
|
471
|
-
if (runLen != 0) {
|
|
472
|
-
memory.copy(bs.offset, lastPtr, runLen);
|
|
473
|
-
bs.offset += runLen;
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
const escapedChunk = load<u32>(escapedIdx);
|
|
477
|
-
const escapedCode = <u16>(escapedChunk >> 16);
|
|
478
|
-
if (escapedCode !== 0x75) {
|
|
479
|
-
store<u16>(bs.offset, load<u16>(DESERIALIZE_ESCAPE_TABLE + escapedCode));
|
|
480
|
-
bs.offset += 2;
|
|
481
|
-
lastPtr = escapedIdx + 4;
|
|
482
|
-
} else {
|
|
483
|
-
store<u16>(bs.offset, hex4_to_u16_swar(load<u64>(escapedIdx, 4)));
|
|
484
|
-
bs.offset += 2;
|
|
485
|
-
lastPtr = escapedIdx + 12;
|
|
486
|
-
}
|
|
487
|
-
srcStart = lastPtr;
|
|
488
|
-
break;
|
|
489
|
-
} while (escapedMask !== 0);
|
|
490
|
-
|
|
491
|
-
if (srcStart == blockStart) srcStart += 8;
|
|
492
|
-
}
|
|
493
|
-
|
|
494
|
-
while (srcStart < srcEnd) {
|
|
495
|
-
const tailChar = load<u16>(srcStart);
|
|
496
|
-
if (tailChar == QUOTE) {
|
|
497
|
-
const runLen = <u32>(srcStart - lastPtr);
|
|
498
|
-
if (runLen != 0) {
|
|
499
|
-
memory.copy(bs.offset, lastPtr, runLen);
|
|
500
|
-
bs.offset += runLen;
|
|
501
|
-
}
|
|
502
|
-
writeStringToField(dstFieldPtr, bs.buffer, <u32>(bs.offset - bs.buffer));
|
|
503
|
-
bs.offset = bs.buffer;
|
|
504
|
-
return srcStart + 2;
|
|
505
|
-
}
|
|
506
|
-
if (tailChar != BACK_SLASH) {
|
|
507
|
-
srcStart += 2;
|
|
508
|
-
continue;
|
|
509
|
-
}
|
|
510
|
-
|
|
511
|
-
const runLen = <u32>(srcStart - lastPtr);
|
|
512
|
-
if (runLen != 0) {
|
|
513
|
-
memory.copy(bs.offset, lastPtr, runLen);
|
|
514
|
-
bs.offset += runLen;
|
|
515
|
-
}
|
|
516
|
-
const tailCode = load<u16>(srcStart, 2);
|
|
517
|
-
if (tailCode !== 0x75) {
|
|
518
|
-
store<u16>(bs.offset, load<u16>(DESERIALIZE_ESCAPE_TABLE + tailCode));
|
|
519
|
-
bs.offset += 2;
|
|
520
|
-
srcStart += 4;
|
|
521
|
-
} else {
|
|
522
|
-
store<u16>(bs.offset, hex4_to_u16_swar(load<u64>(srcStart, 4)));
|
|
523
|
-
bs.offset += 2;
|
|
524
|
-
srcStart += 12;
|
|
525
|
-
}
|
|
526
|
-
lastPtr = srcStart;
|
|
527
|
-
}
|
|
528
|
-
bs.offset = bs.buffer;
|
|
529
|
-
return srcStart;
|
|
256
|
+
lastPtr = srcIdx + 12;
|
|
530
257
|
}
|
|
258
|
+
srcStart = lastPtr;
|
|
259
|
+
break;
|
|
531
260
|
} while (mask !== 0);
|
|
261
|
+
|
|
262
|
+
if (srcStart == blockStart) srcStart += 8;
|
|
532
263
|
}
|
|
533
264
|
|
|
534
265
|
while (srcStart < srcEnd) {
|
|
535
266
|
const char = load<u16>(srcStart);
|
|
536
267
|
if (char == QUOTE) {
|
|
537
|
-
|
|
268
|
+
const runLen = <u32>(srcStart - lastPtr);
|
|
269
|
+
if (runLen != 0) {
|
|
270
|
+
memory.copy(bs.offset, lastPtr, runLen);
|
|
271
|
+
bs.offset += runLen;
|
|
272
|
+
}
|
|
273
|
+
bs.toField(outStart, dstFieldPtr);
|
|
538
274
|
return srcStart + 2;
|
|
539
275
|
}
|
|
540
|
-
if (char
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
if (prefixLen != 0) {
|
|
545
|
-
memory.copy(bs.buffer, payloadStart, prefixLen);
|
|
546
|
-
bs.offset += prefixLen;
|
|
547
|
-
}
|
|
276
|
+
if (char != BACK_SLASH) {
|
|
277
|
+
srcStart += 2;
|
|
278
|
+
continue;
|
|
279
|
+
}
|
|
548
280
|
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
srcStart += 4;
|
|
555
|
-
} else {
|
|
556
|
-
store<u16>(bs.offset, hex4_to_u16_swar(load<u64>(srcStart, 4)));
|
|
557
|
-
bs.offset += 2;
|
|
558
|
-
srcStart += 12;
|
|
559
|
-
}
|
|
560
|
-
lastPtr = srcStart;
|
|
561
|
-
|
|
562
|
-
while (srcStart < srcEnd) {
|
|
563
|
-
const tailChar = load<u16>(srcStart);
|
|
564
|
-
if (tailChar == QUOTE) {
|
|
565
|
-
const runLen = <u32>(srcStart - lastPtr);
|
|
566
|
-
if (runLen != 0) {
|
|
567
|
-
memory.copy(bs.offset, lastPtr, runLen);
|
|
568
|
-
bs.offset += runLen;
|
|
569
|
-
}
|
|
570
|
-
writeStringToField(dstFieldPtr, bs.buffer, <u32>(bs.offset - bs.buffer));
|
|
571
|
-
bs.offset = bs.buffer;
|
|
572
|
-
return srcStart + 2;
|
|
573
|
-
}
|
|
574
|
-
if (tailChar != BACK_SLASH) {
|
|
575
|
-
srcStart += 2;
|
|
576
|
-
continue;
|
|
577
|
-
}
|
|
281
|
+
const runLen = <u32>(srcStart - lastPtr);
|
|
282
|
+
if (runLen != 0) {
|
|
283
|
+
memory.copy(bs.offset, lastPtr, runLen);
|
|
284
|
+
bs.offset += runLen;
|
|
285
|
+
}
|
|
578
286
|
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
srcStart += 4;
|
|
589
|
-
} else {
|
|
590
|
-
store<u16>(bs.offset, hex4_to_u16_swar(load<u64>(srcStart, 4)));
|
|
591
|
-
bs.offset += 2;
|
|
592
|
-
srcStart += 12;
|
|
593
|
-
}
|
|
594
|
-
lastPtr = srcStart;
|
|
595
|
-
}
|
|
596
|
-
bs.offset = bs.buffer;
|
|
597
|
-
return srcStart;
|
|
287
|
+
const code = load<u16>(srcStart, 2);
|
|
288
|
+
if (code !== 0x75) {
|
|
289
|
+
store<u16>(bs.offset, load<u16>(DESERIALIZE_ESCAPE_TABLE + code));
|
|
290
|
+
bs.offset += 2;
|
|
291
|
+
srcStart += 4;
|
|
292
|
+
} else {
|
|
293
|
+
store<u16>(bs.offset, hex4_to_u16_swar(load<u64>(srcStart, 4)));
|
|
294
|
+
bs.offset += 2;
|
|
295
|
+
srcStart += 12;
|
|
598
296
|
}
|
|
599
|
-
|
|
297
|
+
lastPtr = srcStart;
|
|
600
298
|
}
|
|
601
299
|
|
|
300
|
+
bs.offset = bs.buffer + outStart;
|
|
301
|
+
abort("Unterminated string literal");
|
|
602
302
|
return srcStart;
|
|
603
303
|
}
|
|
604
|
-
*/
|
|
605
304
|
|
|
305
|
+
// Scans a quoted string value, writes into the destination field, and returns next unread src pointer.
|
|
606
306
|
// @ts-expect-error: @inline is a valid decorator
|
|
607
|
-
@inline function
|
|
307
|
+
@inline function deserializeEscapedStringScan_SWAR_SplitTuned(payloadStart: usize, escapeStart: usize, srcEnd: usize, dstFieldPtr: usize): usize {
|
|
608
308
|
const prefixLen = <u32>(escapeStart - payloadStart);
|
|
609
|
-
const srcEnd8 = srcEnd
|
|
610
|
-
|
|
309
|
+
const srcEnd8 = srcEnd - 8;
|
|
310
|
+
bs.offset = bs.buffer;
|
|
611
311
|
bs.ensureSize(<u32>(srcEnd - payloadStart));
|
|
612
312
|
if (prefixLen != 0) {
|
|
613
|
-
memory.copy(bs.
|
|
313
|
+
memory.copy(bs.buffer, payloadStart, prefixLen);
|
|
614
314
|
bs.offset += prefixLen;
|
|
615
315
|
}
|
|
616
316
|
|
|
@@ -636,7 +336,8 @@ export function deserializeStringField_SWAR<T extends string | null>(srcStart: u
|
|
|
636
336
|
memory.copy(bs.offset, lastPtr, runLen);
|
|
637
337
|
bs.offset += runLen;
|
|
638
338
|
}
|
|
639
|
-
bs.
|
|
339
|
+
writeStringToField(dstFieldPtr, bs.buffer, <u32>(bs.offset - bs.buffer));
|
|
340
|
+
bs.offset = bs.buffer;
|
|
640
341
|
return srcIdx + 2;
|
|
641
342
|
}
|
|
642
343
|
if (char != BACK_SLASH) continue;
|
|
@@ -672,7 +373,8 @@ export function deserializeStringField_SWAR<T extends string | null>(srcStart: u
|
|
|
672
373
|
memory.copy(bs.offset, lastPtr, runLen);
|
|
673
374
|
bs.offset += runLen;
|
|
674
375
|
}
|
|
675
|
-
bs.
|
|
376
|
+
writeStringToField(dstFieldPtr, bs.buffer, <u32>(bs.offset - bs.buffer));
|
|
377
|
+
bs.offset = bs.buffer;
|
|
676
378
|
return srcStart + 2;
|
|
677
379
|
}
|
|
678
380
|
if (char != BACK_SLASH) {
|
|
@@ -696,21 +398,197 @@ export function deserializeStringField_SWAR<T extends string | null>(srcStart: u
|
|
|
696
398
|
bs.offset += 2;
|
|
697
399
|
srcStart += 12;
|
|
698
400
|
}
|
|
699
|
-
|
|
700
401
|
lastPtr = srcStart;
|
|
701
402
|
}
|
|
702
403
|
|
|
703
|
-
bs.offset = bs.buffer
|
|
404
|
+
bs.offset = bs.buffer;
|
|
704
405
|
abort("Unterminated string literal");
|
|
705
406
|
return srcStart;
|
|
706
407
|
}
|
|
707
408
|
|
|
708
|
-
//
|
|
409
|
+
// @ts-expect-error: @inline is a valid decorator
|
|
410
|
+
@inline function deserializeEscapedStringContinuation_SWAR_MergedTuned(lastPtr: usize, srcStart: usize, srcEnd: usize, dstFieldPtr: usize): usize {
|
|
411
|
+
const srcEnd8 = srcEnd - 8;
|
|
412
|
+
|
|
413
|
+
while (srcStart <= srcEnd8) {
|
|
414
|
+
const blockStart = srcStart;
|
|
415
|
+
let mask = inline.always(backslash_or_quote_mask(load<u64>(srcStart)));
|
|
416
|
+
if (mask === 0) {
|
|
417
|
+
srcStart += 8;
|
|
418
|
+
continue;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
do {
|
|
422
|
+
const laneIdx = usize(ctz(mask) >> 3);
|
|
423
|
+
mask &= mask - 1;
|
|
424
|
+
const srcIdx = srcStart + laneIdx;
|
|
425
|
+
const char = load<u16>(srcIdx);
|
|
426
|
+
if (char == QUOTE) {
|
|
427
|
+
const runLen = <u32>(srcIdx - lastPtr);
|
|
428
|
+
if (runLen != 0) {
|
|
429
|
+
memory.copy(bs.offset, lastPtr, runLen);
|
|
430
|
+
bs.offset += runLen;
|
|
431
|
+
}
|
|
432
|
+
writeStringToField(dstFieldPtr, bs.buffer, <u32>(bs.offset - bs.buffer));
|
|
433
|
+
bs.offset = bs.buffer;
|
|
434
|
+
return srcIdx + 2;
|
|
435
|
+
}
|
|
436
|
+
if (char != BACK_SLASH) continue;
|
|
437
|
+
|
|
438
|
+
const runLen = <u32>(srcIdx - lastPtr);
|
|
439
|
+
if (runLen != 0) {
|
|
440
|
+
memory.copy(bs.offset, lastPtr, runLen);
|
|
441
|
+
bs.offset += runLen;
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
const chunk = load<u32>(srcIdx);
|
|
445
|
+
const code = <u16>(chunk >> 16);
|
|
446
|
+
if (code !== 0x75) {
|
|
447
|
+
store<u16>(bs.offset, load<u16>(DESERIALIZE_ESCAPE_TABLE + code));
|
|
448
|
+
bs.offset += 2;
|
|
449
|
+
lastPtr = srcIdx + 4;
|
|
450
|
+
} else {
|
|
451
|
+
store<u16>(bs.offset, hex4_to_u16_swar(load<u64>(srcIdx, 4)));
|
|
452
|
+
bs.offset += 2;
|
|
453
|
+
lastPtr = srcIdx + 12;
|
|
454
|
+
}
|
|
455
|
+
srcStart = lastPtr;
|
|
456
|
+
break;
|
|
457
|
+
} while (mask !== 0);
|
|
458
|
+
|
|
459
|
+
if (srcStart == blockStart) srcStart += 8;
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
while (srcStart < srcEnd) {
|
|
463
|
+
const tailChar = load<u16>(srcStart);
|
|
464
|
+
if (tailChar == QUOTE) {
|
|
465
|
+
const runLen = <u32>(srcStart - lastPtr);
|
|
466
|
+
if (runLen != 0) {
|
|
467
|
+
memory.copy(bs.offset, lastPtr, runLen);
|
|
468
|
+
bs.offset += runLen;
|
|
469
|
+
}
|
|
470
|
+
writeStringToField(dstFieldPtr, bs.buffer, <u32>(bs.offset - bs.buffer));
|
|
471
|
+
bs.offset = bs.buffer;
|
|
472
|
+
return srcStart + 2;
|
|
473
|
+
}
|
|
474
|
+
if (tailChar != BACK_SLASH) {
|
|
475
|
+
srcStart += 2;
|
|
476
|
+
continue;
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
const runLen = <u32>(srcStart - lastPtr);
|
|
480
|
+
if (runLen != 0) {
|
|
481
|
+
memory.copy(bs.offset, lastPtr, runLen);
|
|
482
|
+
bs.offset += runLen;
|
|
483
|
+
}
|
|
484
|
+
const tailCode = load<u16>(srcStart, 2);
|
|
485
|
+
if (tailCode !== 0x75) {
|
|
486
|
+
store<u16>(bs.offset, load<u16>(DESERIALIZE_ESCAPE_TABLE + tailCode));
|
|
487
|
+
bs.offset += 2;
|
|
488
|
+
srcStart += 4;
|
|
489
|
+
} else {
|
|
490
|
+
store<u16>(bs.offset, hex4_to_u16_swar(load<u64>(srcStart, 4)));
|
|
491
|
+
bs.offset += 2;
|
|
492
|
+
srcStart += 12;
|
|
493
|
+
}
|
|
494
|
+
lastPtr = srcStart;
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
bs.offset = bs.buffer;
|
|
498
|
+
return srcStart;
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
function deserializeStringField_SWAR_MergedTuned(srcStart: usize, srcEnd: usize, dstFieldPtr: usize): usize {
|
|
502
|
+
if (srcStart + 2 > srcEnd || load<u16>(srcStart) != QUOTE) abort("Expected leading quote");
|
|
503
|
+
|
|
504
|
+
const payloadStart = srcStart + 2;
|
|
505
|
+
const srcEnd8 = srcEnd - 8;
|
|
506
|
+
srcStart = payloadStart;
|
|
507
|
+
|
|
508
|
+
while (srcStart <= srcEnd8) {
|
|
509
|
+
let mask = inline.always(backslash_or_quote_mask(load<u64>(srcStart)));
|
|
510
|
+
if (mask === 0) {
|
|
511
|
+
srcStart += 8;
|
|
512
|
+
continue;
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
do {
|
|
516
|
+
const laneIdx = usize(ctz(mask) >> 3);
|
|
517
|
+
mask &= ~(0xffff << (laneIdx << 3));
|
|
518
|
+
const srcIdx = srcStart + laneIdx;
|
|
519
|
+
const char = load<u16>(srcIdx);
|
|
520
|
+
|
|
521
|
+
if (char == QUOTE) {
|
|
522
|
+
writeStringToField(dstFieldPtr, payloadStart, <u32>(srcIdx - payloadStart));
|
|
523
|
+
return srcIdx + 2;
|
|
524
|
+
}
|
|
525
|
+
if (char != BACK_SLASH) continue;
|
|
526
|
+
|
|
527
|
+
bs.offset = bs.buffer;
|
|
528
|
+
bs.ensureSize(<u32>(srcEnd - payloadStart));
|
|
529
|
+
const prefixLen = <u32>(srcIdx - payloadStart);
|
|
530
|
+
if (prefixLen != 0) {
|
|
531
|
+
memory.copy(bs.buffer, payloadStart, prefixLen);
|
|
532
|
+
bs.offset += prefixLen;
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
const chunk = load<u32>(srcIdx);
|
|
536
|
+
const code = <u16>(chunk >> 16);
|
|
537
|
+
let lastPtr: usize;
|
|
538
|
+
if (code !== 0x75) {
|
|
539
|
+
store<u16>(bs.offset, load<u16>(DESERIALIZE_ESCAPE_TABLE + code));
|
|
540
|
+
bs.offset += 2;
|
|
541
|
+
lastPtr = srcIdx + 4;
|
|
542
|
+
} else {
|
|
543
|
+
store<u16>(bs.offset, hex4_to_u16_swar(load<u64>(srcIdx, 4)));
|
|
544
|
+
bs.offset += 2;
|
|
545
|
+
lastPtr = srcIdx + 12;
|
|
546
|
+
}
|
|
547
|
+
return inline.always(deserializeEscapedStringContinuation_SWAR_MergedTuned(lastPtr, lastPtr, srcEnd, dstFieldPtr));
|
|
548
|
+
} while (mask !== 0);
|
|
549
|
+
|
|
550
|
+
srcStart += 8;
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
while (srcStart < srcEnd) {
|
|
554
|
+
const char = load<u16>(srcStart);
|
|
555
|
+
if (char == QUOTE) {
|
|
556
|
+
writeStringToField(dstFieldPtr, payloadStart, <u32>(srcStart - payloadStart));
|
|
557
|
+
return srcStart + 2;
|
|
558
|
+
}
|
|
559
|
+
if (char == BACK_SLASH) {
|
|
560
|
+
bs.offset = bs.buffer;
|
|
561
|
+
bs.ensureSize(<u32>(srcEnd - payloadStart));
|
|
562
|
+
const prefixLen = <u32>(srcStart - payloadStart);
|
|
563
|
+
if (prefixLen != 0) {
|
|
564
|
+
memory.copy(bs.buffer, payloadStart, prefixLen);
|
|
565
|
+
bs.offset += prefixLen;
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
const code = load<u16>(srcStart, 2);
|
|
569
|
+
let lastPtr: usize;
|
|
570
|
+
if (code !== 0x75) {
|
|
571
|
+
store<u16>(bs.offset, load<u16>(DESERIALIZE_ESCAPE_TABLE + code));
|
|
572
|
+
bs.offset += 2;
|
|
573
|
+
lastPtr = srcStart + 4;
|
|
574
|
+
} else {
|
|
575
|
+
store<u16>(bs.offset, hex4_to_u16_swar(load<u64>(srcStart, 4)));
|
|
576
|
+
bs.offset += 2;
|
|
577
|
+
lastPtr = srcStart + 12;
|
|
578
|
+
}
|
|
579
|
+
return inline.always(deserializeEscapedStringContinuation_SWAR_MergedTuned(lastPtr, lastPtr, srcEnd, dstFieldPtr));
|
|
580
|
+
}
|
|
581
|
+
srcStart += 2;
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
return srcStart;
|
|
585
|
+
}
|
|
586
|
+
|
|
709
587
|
export function deserializeStringField_SWAR<T extends string | null>(srcStart: usize, srcEnd: usize, dstFieldPtr: usize): usize {
|
|
710
588
|
if (srcStart + 2 > srcEnd || load<u16>(srcStart) != QUOTE) abort("Expected leading quote");
|
|
711
589
|
|
|
712
590
|
const payloadStart = srcStart + 2;
|
|
713
|
-
const srcEnd8 = srcEnd
|
|
591
|
+
const srcEnd8 = srcEnd - 8;
|
|
714
592
|
srcStart = payloadStart;
|
|
715
593
|
|
|
716
594
|
while (srcStart <= srcEnd8) {
|
|
@@ -730,8 +608,7 @@ export function deserializeStringField_SWAR<T extends string | null>(srcStart: u
|
|
|
730
608
|
return srcIdx + 2;
|
|
731
609
|
}
|
|
732
610
|
if (char != BACK_SLASH) continue;
|
|
733
|
-
|
|
734
|
-
return deserializeEscapedStringScan_SWAR(payloadStart, srcIdx, srcEnd, dstFieldPtr);
|
|
611
|
+
return inline.always(deserializeEscapedStringScan_SWAR_SplitTuned(payloadStart, srcIdx, srcEnd, dstFieldPtr));
|
|
735
612
|
} while (mask !== 0);
|
|
736
613
|
|
|
737
614
|
srcStart += 8;
|
|
@@ -744,7 +621,7 @@ export function deserializeStringField_SWAR<T extends string | null>(srcStart: u
|
|
|
744
621
|
return srcStart + 2;
|
|
745
622
|
}
|
|
746
623
|
if (char == BACK_SLASH) {
|
|
747
|
-
return
|
|
624
|
+
return inline.always(deserializeEscapedStringScan_SWAR_SplitTuned(payloadStart, srcStart, srcEnd, dstFieldPtr));
|
|
748
625
|
}
|
|
749
626
|
srcStart += 2;
|
|
750
627
|
}
|
|
@@ -753,6 +630,7 @@ export function deserializeStringField_SWAR<T extends string | null>(srcStart: u
|
|
|
753
630
|
return srcStart;
|
|
754
631
|
}
|
|
755
632
|
|
|
633
|
+
|
|
756
634
|
/**
|
|
757
635
|
* Computes a per-byte mask identifying ASCII backslash or quote bytes.
|
|
758
636
|
*
|