json-as 1.3.1 → 1.3.3
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 +43 -19
- 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 +62 -12
- package/assembly/deserialize/simple/object.ts +1 -1
- package/assembly/deserialize/simple/set.ts +119 -134
- package/assembly/deserialize/simple/staticarray.ts +13 -1
- package/assembly/deserialize/simple/string.ts +15 -10
- package/assembly/deserialize/simple/struct.ts +9 -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 +6 -2
- package/assembly/deserialize/swar/array/float.ts +7 -3
- package/assembly/deserialize/swar/array/generic.ts +41 -0
- package/assembly/deserialize/swar/array/integer.ts +8 -4
- package/assembly/deserialize/swar/array/object.ts +21 -4
- package/assembly/deserialize/swar/array/shared.ts +19 -4
- package/assembly/deserialize/swar/array/string.ts +6 -2
- package/assembly/deserialize/swar/array/struct.ts +21 -4
- package/assembly/deserialize/swar/array.ts +57 -2
- package/assembly/deserialize/swar/string.ts +248 -372
- package/assembly/index.d.ts +1 -0
- package/assembly/index.ts +77 -19
- 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 +18 -6
- package/assembly/serialize/simple/float.ts +20 -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 +1 -0
- package/assembly/util/dragonbox-cache.ts +4 -0
- package/assembly/util/dragonbox.ts +624 -0
- package/lib/as-bs.ts +35 -24
- package/package.json +26 -18
- package/transform/lib/index.d.ts.map +1 -1
- package/transform/lib/index.js +508 -148
- 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,13 @@ export function deserializeString_SWAR(srcStart: usize, srcEnd: usize): string {
|
|
|
305
209
|
memory.copy(stringPtr, srcStart, byteLength);
|
|
306
210
|
}
|
|
307
211
|
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
const payloadStart = srcStart + 2;
|
|
313
|
-
const srcEnd8 = srcEnd >= 8 ? srcEnd - 8 : 0;
|
|
314
|
-
srcStart = payloadStart;
|
|
212
|
+
// @ts-expect-error: @inline is a valid decorator
|
|
213
|
+
@inline function deserializeEscapedStringContinuation_SWAR(lastPtr: usize, srcStart: usize, srcEnd: usize, dstFieldPtr: usize, outStart: usize): usize {
|
|
214
|
+
const srcEnd8 = srcEnd - 8;
|
|
315
215
|
|
|
316
216
|
while (srcStart <= srcEnd8) {
|
|
217
|
+
const blockStart = srcStart;
|
|
317
218
|
let mask = inline.always(backslash_or_quote_mask(load<u64>(srcStart)));
|
|
318
|
-
|
|
319
219
|
if (mask === 0) {
|
|
320
220
|
srcStart += 8;
|
|
321
221
|
continue;
|
|
@@ -323,294 +223,93 @@ export function deserializeStringField_SWAR<T extends string | null>(srcStart: u
|
|
|
323
223
|
|
|
324
224
|
do {
|
|
325
225
|
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.
|
|
226
|
+
mask &= mask - 1;
|
|
328
227
|
const srcIdx = srcStart + laneIdx;
|
|
329
228
|
const char = load<u16>(srcIdx);
|
|
330
|
-
|
|
331
229
|
if (char == QUOTE) {
|
|
332
|
-
|
|
230
|
+
const runLen = <u32>(srcIdx - lastPtr);
|
|
231
|
+
if (runLen != 0) {
|
|
232
|
+
memory.copy(bs.offset, lastPtr, runLen);
|
|
233
|
+
bs.offset += runLen;
|
|
234
|
+
}
|
|
235
|
+
bs.toField(outStart, dstFieldPtr);
|
|
333
236
|
return srcIdx + 2;
|
|
334
237
|
}
|
|
335
238
|
if (char != BACK_SLASH) continue;
|
|
336
239
|
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
memory.copy(bs.buffer, payloadStart, prefixLen);
|
|
342
|
-
bs.offset += prefixLen;
|
|
240
|
+
const runLen = <u32>(srcIdx - lastPtr);
|
|
241
|
+
if (runLen != 0) {
|
|
242
|
+
memory.copy(bs.offset, lastPtr, runLen);
|
|
243
|
+
bs.offset += runLen;
|
|
343
244
|
}
|
|
344
245
|
|
|
345
246
|
const chunk = load<u32>(srcIdx);
|
|
346
247
|
const code = <u16>(chunk >> 16);
|
|
347
|
-
|
|
348
248
|
if (code !== 0x75) {
|
|
349
249
|
store<u16>(bs.offset, load<u16>(DESERIALIZE_ESCAPE_TABLE + code));
|
|
350
250
|
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;
|
|
251
|
+
lastPtr = srcIdx + 4;
|
|
439
252
|
} else {
|
|
440
253
|
store<u16>(bs.offset, hex4_to_u16_swar(load<u64>(srcIdx, 4)));
|
|
441
254
|
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;
|
|
255
|
+
lastPtr = srcIdx + 12;
|
|
530
256
|
}
|
|
257
|
+
srcStart = lastPtr;
|
|
258
|
+
break;
|
|
531
259
|
} while (mask !== 0);
|
|
260
|
+
|
|
261
|
+
if (srcStart == blockStart) srcStart += 8;
|
|
532
262
|
}
|
|
533
263
|
|
|
534
264
|
while (srcStart < srcEnd) {
|
|
535
265
|
const char = load<u16>(srcStart);
|
|
536
266
|
if (char == QUOTE) {
|
|
537
|
-
|
|
267
|
+
const runLen = <u32>(srcStart - lastPtr);
|
|
268
|
+
if (runLen != 0) {
|
|
269
|
+
memory.copy(bs.offset, lastPtr, runLen);
|
|
270
|
+
bs.offset += runLen;
|
|
271
|
+
}
|
|
272
|
+
bs.toField(outStart, dstFieldPtr);
|
|
538
273
|
return srcStart + 2;
|
|
539
274
|
}
|
|
540
|
-
if (char
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
if (prefixLen != 0) {
|
|
545
|
-
memory.copy(bs.buffer, payloadStart, prefixLen);
|
|
546
|
-
bs.offset += prefixLen;
|
|
547
|
-
}
|
|
275
|
+
if (char != BACK_SLASH) {
|
|
276
|
+
srcStart += 2;
|
|
277
|
+
continue;
|
|
278
|
+
}
|
|
548
279
|
|
|
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
|
-
}
|
|
280
|
+
const runLen = <u32>(srcStart - lastPtr);
|
|
281
|
+
if (runLen != 0) {
|
|
282
|
+
memory.copy(bs.offset, lastPtr, runLen);
|
|
283
|
+
bs.offset += runLen;
|
|
284
|
+
}
|
|
578
285
|
|
|
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;
|
|
286
|
+
const code = load<u16>(srcStart, 2);
|
|
287
|
+
if (code !== 0x75) {
|
|
288
|
+
store<u16>(bs.offset, load<u16>(DESERIALIZE_ESCAPE_TABLE + code));
|
|
289
|
+
bs.offset += 2;
|
|
290
|
+
srcStart += 4;
|
|
291
|
+
} else {
|
|
292
|
+
store<u16>(bs.offset, hex4_to_u16_swar(load<u64>(srcStart, 4)));
|
|
293
|
+
bs.offset += 2;
|
|
294
|
+
srcStart += 12;
|
|
598
295
|
}
|
|
599
|
-
|
|
296
|
+
lastPtr = srcStart;
|
|
600
297
|
}
|
|
601
298
|
|
|
299
|
+
bs.offset = bs.buffer + outStart;
|
|
300
|
+
abort("Unterminated string literal");
|
|
602
301
|
return srcStart;
|
|
603
302
|
}
|
|
604
|
-
*/
|
|
605
303
|
|
|
304
|
+
// Scans a quoted string value, writes into the destination field, and returns next unread src pointer.
|
|
606
305
|
// @ts-expect-error: @inline is a valid decorator
|
|
607
|
-
@inline function
|
|
306
|
+
@inline function deserializeEscapedStringScan_SWAR_SplitTuned(payloadStart: usize, escapeStart: usize, srcEnd: usize, dstFieldPtr: usize): usize {
|
|
608
307
|
const prefixLen = <u32>(escapeStart - payloadStart);
|
|
609
|
-
const srcEnd8 = srcEnd
|
|
610
|
-
|
|
308
|
+
const srcEnd8 = srcEnd - 8;
|
|
309
|
+
bs.offset = bs.buffer;
|
|
611
310
|
bs.ensureSize(<u32>(srcEnd - payloadStart));
|
|
612
311
|
if (prefixLen != 0) {
|
|
613
|
-
memory.copy(bs.
|
|
312
|
+
memory.copy(bs.buffer, payloadStart, prefixLen);
|
|
614
313
|
bs.offset += prefixLen;
|
|
615
314
|
}
|
|
616
315
|
|
|
@@ -636,7 +335,8 @@ export function deserializeStringField_SWAR<T extends string | null>(srcStart: u
|
|
|
636
335
|
memory.copy(bs.offset, lastPtr, runLen);
|
|
637
336
|
bs.offset += runLen;
|
|
638
337
|
}
|
|
639
|
-
bs.
|
|
338
|
+
writeStringToField(dstFieldPtr, bs.buffer, <u32>(bs.offset - bs.buffer));
|
|
339
|
+
bs.offset = bs.buffer;
|
|
640
340
|
return srcIdx + 2;
|
|
641
341
|
}
|
|
642
342
|
if (char != BACK_SLASH) continue;
|
|
@@ -672,7 +372,8 @@ export function deserializeStringField_SWAR<T extends string | null>(srcStart: u
|
|
|
672
372
|
memory.copy(bs.offset, lastPtr, runLen);
|
|
673
373
|
bs.offset += runLen;
|
|
674
374
|
}
|
|
675
|
-
bs.
|
|
375
|
+
writeStringToField(dstFieldPtr, bs.buffer, <u32>(bs.offset - bs.buffer));
|
|
376
|
+
bs.offset = bs.buffer;
|
|
676
377
|
return srcStart + 2;
|
|
677
378
|
}
|
|
678
379
|
if (char != BACK_SLASH) {
|
|
@@ -696,21 +397,197 @@ export function deserializeStringField_SWAR<T extends string | null>(srcStart: u
|
|
|
696
397
|
bs.offset += 2;
|
|
697
398
|
srcStart += 12;
|
|
698
399
|
}
|
|
699
|
-
|
|
700
400
|
lastPtr = srcStart;
|
|
701
401
|
}
|
|
702
402
|
|
|
703
|
-
bs.offset = bs.buffer
|
|
403
|
+
bs.offset = bs.buffer;
|
|
704
404
|
abort("Unterminated string literal");
|
|
705
405
|
return srcStart;
|
|
706
406
|
}
|
|
707
407
|
|
|
708
|
-
//
|
|
408
|
+
// @ts-expect-error: @inline is a valid decorator
|
|
409
|
+
@inline function deserializeEscapedStringContinuation_SWAR_MergedTuned(lastPtr: usize, srcStart: usize, srcEnd: usize, dstFieldPtr: usize): usize {
|
|
410
|
+
const srcEnd8 = srcEnd - 8;
|
|
411
|
+
|
|
412
|
+
while (srcStart <= srcEnd8) {
|
|
413
|
+
const blockStart = srcStart;
|
|
414
|
+
let mask = inline.always(backslash_or_quote_mask(load<u64>(srcStart)));
|
|
415
|
+
if (mask === 0) {
|
|
416
|
+
srcStart += 8;
|
|
417
|
+
continue;
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
do {
|
|
421
|
+
const laneIdx = usize(ctz(mask) >> 3);
|
|
422
|
+
mask &= mask - 1;
|
|
423
|
+
const srcIdx = srcStart + laneIdx;
|
|
424
|
+
const char = load<u16>(srcIdx);
|
|
425
|
+
if (char == QUOTE) {
|
|
426
|
+
const runLen = <u32>(srcIdx - lastPtr);
|
|
427
|
+
if (runLen != 0) {
|
|
428
|
+
memory.copy(bs.offset, lastPtr, runLen);
|
|
429
|
+
bs.offset += runLen;
|
|
430
|
+
}
|
|
431
|
+
writeStringToField(dstFieldPtr, bs.buffer, <u32>(bs.offset - bs.buffer));
|
|
432
|
+
bs.offset = bs.buffer;
|
|
433
|
+
return srcIdx + 2;
|
|
434
|
+
}
|
|
435
|
+
if (char != BACK_SLASH) continue;
|
|
436
|
+
|
|
437
|
+
const runLen = <u32>(srcIdx - lastPtr);
|
|
438
|
+
if (runLen != 0) {
|
|
439
|
+
memory.copy(bs.offset, lastPtr, runLen);
|
|
440
|
+
bs.offset += runLen;
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
const chunk = load<u32>(srcIdx);
|
|
444
|
+
const code = <u16>(chunk >> 16);
|
|
445
|
+
if (code !== 0x75) {
|
|
446
|
+
store<u16>(bs.offset, load<u16>(DESERIALIZE_ESCAPE_TABLE + code));
|
|
447
|
+
bs.offset += 2;
|
|
448
|
+
lastPtr = srcIdx + 4;
|
|
449
|
+
} else {
|
|
450
|
+
store<u16>(bs.offset, hex4_to_u16_swar(load<u64>(srcIdx, 4)));
|
|
451
|
+
bs.offset += 2;
|
|
452
|
+
lastPtr = srcIdx + 12;
|
|
453
|
+
}
|
|
454
|
+
srcStart = lastPtr;
|
|
455
|
+
break;
|
|
456
|
+
} while (mask !== 0);
|
|
457
|
+
|
|
458
|
+
if (srcStart == blockStart) srcStart += 8;
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
while (srcStart < srcEnd) {
|
|
462
|
+
const tailChar = load<u16>(srcStart);
|
|
463
|
+
if (tailChar == QUOTE) {
|
|
464
|
+
const runLen = <u32>(srcStart - lastPtr);
|
|
465
|
+
if (runLen != 0) {
|
|
466
|
+
memory.copy(bs.offset, lastPtr, runLen);
|
|
467
|
+
bs.offset += runLen;
|
|
468
|
+
}
|
|
469
|
+
writeStringToField(dstFieldPtr, bs.buffer, <u32>(bs.offset - bs.buffer));
|
|
470
|
+
bs.offset = bs.buffer;
|
|
471
|
+
return srcStart + 2;
|
|
472
|
+
}
|
|
473
|
+
if (tailChar != BACK_SLASH) {
|
|
474
|
+
srcStart += 2;
|
|
475
|
+
continue;
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
const runLen = <u32>(srcStart - lastPtr);
|
|
479
|
+
if (runLen != 0) {
|
|
480
|
+
memory.copy(bs.offset, lastPtr, runLen);
|
|
481
|
+
bs.offset += runLen;
|
|
482
|
+
}
|
|
483
|
+
const tailCode = load<u16>(srcStart, 2);
|
|
484
|
+
if (tailCode !== 0x75) {
|
|
485
|
+
store<u16>(bs.offset, load<u16>(DESERIALIZE_ESCAPE_TABLE + tailCode));
|
|
486
|
+
bs.offset += 2;
|
|
487
|
+
srcStart += 4;
|
|
488
|
+
} else {
|
|
489
|
+
store<u16>(bs.offset, hex4_to_u16_swar(load<u64>(srcStart, 4)));
|
|
490
|
+
bs.offset += 2;
|
|
491
|
+
srcStart += 12;
|
|
492
|
+
}
|
|
493
|
+
lastPtr = srcStart;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
bs.offset = bs.buffer;
|
|
497
|
+
return srcStart;
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
function deserializeStringField_SWAR_MergedTuned(srcStart: usize, srcEnd: usize, dstFieldPtr: usize): usize {
|
|
501
|
+
if (srcStart + 2 > srcEnd || load<u16>(srcStart) != QUOTE) abort("Expected leading quote");
|
|
502
|
+
|
|
503
|
+
const payloadStart = srcStart + 2;
|
|
504
|
+
const srcEnd8 = srcEnd - 8;
|
|
505
|
+
srcStart = payloadStart;
|
|
506
|
+
|
|
507
|
+
while (srcStart <= srcEnd8) {
|
|
508
|
+
let mask = inline.always(backslash_or_quote_mask(load<u64>(srcStart)));
|
|
509
|
+
if (mask === 0) {
|
|
510
|
+
srcStart += 8;
|
|
511
|
+
continue;
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
do {
|
|
515
|
+
const laneIdx = usize(ctz(mask) >> 3);
|
|
516
|
+
mask &= ~(0xffff << (laneIdx << 3));
|
|
517
|
+
const srcIdx = srcStart + laneIdx;
|
|
518
|
+
const char = load<u16>(srcIdx);
|
|
519
|
+
|
|
520
|
+
if (char == QUOTE) {
|
|
521
|
+
writeStringToField(dstFieldPtr, payloadStart, <u32>(srcIdx - payloadStart));
|
|
522
|
+
return srcIdx + 2;
|
|
523
|
+
}
|
|
524
|
+
if (char != BACK_SLASH) continue;
|
|
525
|
+
|
|
526
|
+
bs.offset = bs.buffer;
|
|
527
|
+
bs.ensureSize(<u32>(srcEnd - payloadStart));
|
|
528
|
+
const prefixLen = <u32>(srcIdx - payloadStart);
|
|
529
|
+
if (prefixLen != 0) {
|
|
530
|
+
memory.copy(bs.buffer, payloadStart, prefixLen);
|
|
531
|
+
bs.offset += prefixLen;
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
const chunk = load<u32>(srcIdx);
|
|
535
|
+
const code = <u16>(chunk >> 16);
|
|
536
|
+
let lastPtr: usize;
|
|
537
|
+
if (code !== 0x75) {
|
|
538
|
+
store<u16>(bs.offset, load<u16>(DESERIALIZE_ESCAPE_TABLE + code));
|
|
539
|
+
bs.offset += 2;
|
|
540
|
+
lastPtr = srcIdx + 4;
|
|
541
|
+
} else {
|
|
542
|
+
store<u16>(bs.offset, hex4_to_u16_swar(load<u64>(srcIdx, 4)));
|
|
543
|
+
bs.offset += 2;
|
|
544
|
+
lastPtr = srcIdx + 12;
|
|
545
|
+
}
|
|
546
|
+
return inline.always(deserializeEscapedStringContinuation_SWAR_MergedTuned(lastPtr, lastPtr, srcEnd, dstFieldPtr));
|
|
547
|
+
} while (mask !== 0);
|
|
548
|
+
|
|
549
|
+
srcStart += 8;
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
while (srcStart < srcEnd) {
|
|
553
|
+
const char = load<u16>(srcStart);
|
|
554
|
+
if (char == QUOTE) {
|
|
555
|
+
writeStringToField(dstFieldPtr, payloadStart, <u32>(srcStart - payloadStart));
|
|
556
|
+
return srcStart + 2;
|
|
557
|
+
}
|
|
558
|
+
if (char == BACK_SLASH) {
|
|
559
|
+
bs.offset = bs.buffer;
|
|
560
|
+
bs.ensureSize(<u32>(srcEnd - payloadStart));
|
|
561
|
+
const prefixLen = <u32>(srcStart - payloadStart);
|
|
562
|
+
if (prefixLen != 0) {
|
|
563
|
+
memory.copy(bs.buffer, payloadStart, prefixLen);
|
|
564
|
+
bs.offset += prefixLen;
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
const code = load<u16>(srcStart, 2);
|
|
568
|
+
let lastPtr: usize;
|
|
569
|
+
if (code !== 0x75) {
|
|
570
|
+
store<u16>(bs.offset, load<u16>(DESERIALIZE_ESCAPE_TABLE + code));
|
|
571
|
+
bs.offset += 2;
|
|
572
|
+
lastPtr = srcStart + 4;
|
|
573
|
+
} else {
|
|
574
|
+
store<u16>(bs.offset, hex4_to_u16_swar(load<u64>(srcStart, 4)));
|
|
575
|
+
bs.offset += 2;
|
|
576
|
+
lastPtr = srcStart + 12;
|
|
577
|
+
}
|
|
578
|
+
return inline.always(deserializeEscapedStringContinuation_SWAR_MergedTuned(lastPtr, lastPtr, srcEnd, dstFieldPtr));
|
|
579
|
+
}
|
|
580
|
+
srcStart += 2;
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
return srcStart;
|
|
584
|
+
}
|
|
585
|
+
|
|
709
586
|
export function deserializeStringField_SWAR<T extends string | null>(srcStart: usize, srcEnd: usize, dstFieldPtr: usize): usize {
|
|
710
587
|
if (srcStart + 2 > srcEnd || load<u16>(srcStart) != QUOTE) abort("Expected leading quote");
|
|
711
588
|
|
|
712
589
|
const payloadStart = srcStart + 2;
|
|
713
|
-
const srcEnd8 = srcEnd
|
|
590
|
+
const srcEnd8 = srcEnd - 8;
|
|
714
591
|
srcStart = payloadStart;
|
|
715
592
|
|
|
716
593
|
while (srcStart <= srcEnd8) {
|
|
@@ -730,8 +607,7 @@ export function deserializeStringField_SWAR<T extends string | null>(srcStart: u
|
|
|
730
607
|
return srcIdx + 2;
|
|
731
608
|
}
|
|
732
609
|
if (char != BACK_SLASH) continue;
|
|
733
|
-
|
|
734
|
-
return deserializeEscapedStringScan_SWAR(payloadStart, srcIdx, srcEnd, dstFieldPtr);
|
|
610
|
+
return inline.always(deserializeEscapedStringScan_SWAR_SplitTuned(payloadStart, srcIdx, srcEnd, dstFieldPtr));
|
|
735
611
|
} while (mask !== 0);
|
|
736
612
|
|
|
737
613
|
srcStart += 8;
|
|
@@ -744,7 +620,7 @@ export function deserializeStringField_SWAR<T extends string | null>(srcStart: u
|
|
|
744
620
|
return srcStart + 2;
|
|
745
621
|
}
|
|
746
622
|
if (char == BACK_SLASH) {
|
|
747
|
-
return
|
|
623
|
+
return inline.always(deserializeEscapedStringScan_SWAR_SplitTuned(payloadStart, srcStart, srcEnd, dstFieldPtr));
|
|
748
624
|
}
|
|
749
625
|
srcStart += 2;
|
|
750
626
|
}
|