json-as 1.3.6 → 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.
Files changed (106) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/assembly/deserialize/helpers/uint.ts +4 -1
  3. package/assembly/deserialize/index/arbitrary.ts +5 -1
  4. package/assembly/deserialize/index/array.ts +13 -3
  5. package/assembly/deserialize/index/integer.ts +68 -1
  6. package/assembly/deserialize/index/string.ts +4 -1
  7. package/assembly/deserialize/index/typedarray.ts +13 -3
  8. package/assembly/deserialize/index/unsigned.ts +78 -1
  9. package/assembly/deserialize/simd/array/integer.ts +327 -50
  10. package/assembly/deserialize/simd/integer.ts +233 -0
  11. package/assembly/deserialize/simd/string.ts +45 -11
  12. package/assembly/deserialize/simple/arbitrary.ts +11 -4
  13. package/assembly/deserialize/simple/array/arbitrary.ts +24 -5
  14. package/assembly/deserialize/simple/array/array.ts +8 -2
  15. package/assembly/deserialize/simple/array/bool.ts +38 -7
  16. package/assembly/deserialize/simple/array/box.ts +8 -2
  17. package/assembly/deserialize/simple/array/float.ts +36 -9
  18. package/assembly/deserialize/simple/array/generic.ts +12 -4
  19. package/assembly/deserialize/simple/array/integer.ts +8 -2
  20. package/assembly/deserialize/simple/array/map.ts +26 -6
  21. package/assembly/deserialize/simple/array/object.ts +26 -6
  22. package/assembly/deserialize/simple/array/raw.ts +34 -7
  23. package/assembly/deserialize/simple/array/string.ts +8 -2
  24. package/assembly/deserialize/simple/array/struct.ts +26 -6
  25. package/assembly/deserialize/simple/array.ts +13 -3
  26. package/assembly/deserialize/simple/bool.ts +6 -2
  27. package/assembly/deserialize/simple/float.ts +6 -1
  28. package/assembly/deserialize/simple/integer.ts +10 -2
  29. package/assembly/deserialize/simple/map.ts +95 -22
  30. package/assembly/deserialize/simple/object.ts +63 -14
  31. package/assembly/deserialize/simple/raw.ts +4 -1
  32. package/assembly/deserialize/simple/set.ts +59 -14
  33. package/assembly/deserialize/simple/staticarray/string.ts +11 -3
  34. package/assembly/deserialize/simple/staticarray.ts +64 -14
  35. package/assembly/deserialize/simple/string.ts +5 -92
  36. package/assembly/deserialize/simple/struct.ts +5 -1
  37. package/assembly/deserialize/simple/typedarray.ts +16 -3
  38. package/assembly/deserialize/simple/unsigned.ts +10 -15
  39. package/assembly/deserialize/swar/array/arbitrary.ts +5 -1
  40. package/assembly/deserialize/swar/array/array.ts +30 -6
  41. package/assembly/deserialize/swar/array/bool.ts +22 -4
  42. package/assembly/deserialize/swar/array/box.ts +5 -1
  43. package/assembly/deserialize/swar/array/float.ts +15 -3
  44. package/assembly/deserialize/swar/array/generic.ts +24 -7
  45. package/assembly/deserialize/swar/array/integer.ts +328 -84
  46. package/assembly/deserialize/swar/array/map.ts +5 -1
  47. package/assembly/deserialize/swar/array/object.ts +27 -7
  48. package/assembly/deserialize/swar/array/raw.ts +5 -1
  49. package/assembly/deserialize/swar/array/shared.ts +36 -11
  50. package/assembly/deserialize/swar/array/string.ts +20 -4
  51. package/assembly/deserialize/swar/array/struct.ts +27 -7
  52. package/assembly/deserialize/swar/array.ts +19 -4
  53. package/assembly/deserialize/swar/integer.ts +246 -0
  54. package/assembly/deserialize/swar/string.ts +98 -194
  55. package/assembly/index.d.ts +3 -1
  56. package/assembly/index.ts +312 -81
  57. package/assembly/serialize/index/float.ts +5 -1
  58. package/assembly/serialize/index/typedarray.ts +25 -7
  59. package/assembly/serialize/simd/string.ts +6 -2
  60. package/assembly/serialize/simple/array.ts +179 -1
  61. package/assembly/serialize/simple/float.ts +4 -1
  62. package/assembly/serialize/simple/integer.ts +8 -9
  63. package/assembly/serialize/simple/map.ts +6 -2
  64. package/assembly/serialize/simple/raw.ts +5 -1
  65. package/assembly/serialize/simple/set.ts +6 -1
  66. package/assembly/serialize/simple/staticarray.ts +6 -1
  67. package/assembly/serialize/simple/string.ts +0 -1
  68. package/assembly/serialize/simple/typedarray.ts +10 -3
  69. package/assembly/serialize/swar/string.ts +18 -5
  70. package/assembly/util/atoi-fast.ts +81 -0
  71. package/assembly/util/concat.ts +5 -1
  72. package/assembly/util/dragonbox-cache.ts +443 -2
  73. package/assembly/util/dragonbox.ts +43 -14
  74. package/assembly/util/itoa-fast.ts +230 -0
  75. package/assembly/util/masks.ts +18 -1
  76. package/assembly/util/parsefloat-fast.ts +167 -0
  77. package/assembly/util/simd-int.ts +191 -0
  78. package/assembly/util/snp.ts +4 -1
  79. package/assembly/util/swar-int.ts +248 -0
  80. package/assembly/util/swar.ts +13 -3
  81. package/lib/as-bs.ts +13 -5
  82. package/package.json +5 -2
  83. package/transform/lib/builder.d.ts.map +1 -1
  84. package/transform/lib/builder.js +13 -5
  85. package/transform/lib/builder.js.map +1 -1
  86. package/transform/lib/index.d.ts +1 -0
  87. package/transform/lib/index.d.ts.map +1 -1
  88. package/transform/lib/index.js +1030 -241
  89. package/transform/lib/index.js.map +1 -1
  90. package/transform/lib/linkers/alias.d.ts.map +1 -1
  91. package/transform/lib/linkers/alias.js.map +1 -1
  92. package/transform/lib/linkers/custom.d.ts.map +1 -1
  93. package/transform/lib/linkers/custom.js +3 -2
  94. package/transform/lib/linkers/custom.js.map +1 -1
  95. package/transform/lib/linkers/imports.d.ts.map +1 -1
  96. package/transform/lib/linkers/imports.js.map +1 -1
  97. package/transform/lib/types.d.ts.map +1 -1
  98. package/transform/lib/types.js +54 -16
  99. package/transform/lib/types.js.map +1 -1
  100. package/transform/lib/util.d.ts.map +1 -1
  101. package/transform/lib/util.js +1 -1
  102. package/transform/lib/util.js.map +1 -1
  103. package/transform/lib/visitor.d.ts.map +1 -1
  104. package/transform/lib/visitor.js +2 -1
  105. package/transform/lib/visitor.js.map +1 -1
  106. package/assembly/custom/util.ts +0 -310
@@ -1,12 +1,21 @@
1
1
  import { OBJECT, TOTAL_OVERHEAD } from "rt/common";
2
2
  import { JSON } from "../..";
3
- export { serializeArrayBufferUnsafe, serializeTypedArray } from "../simple/typedarray";
4
- import { serializeArrayBufferUnsafe, serializeTypedArray } from "../simple/typedarray";
3
+ export {
4
+ serializeArrayBufferUnsafe,
5
+ serializeTypedArray,
6
+ } from "../simple/typedarray";
7
+ import {
8
+ serializeArrayBufferUnsafe,
9
+ serializeTypedArray,
10
+ } from "../simple/typedarray";
5
11
 
6
12
 
7
13
  @inline export function serializeDynamic(type: u16, data: usize): void {
8
14
  if (type == JSON.Types.ArrayBuffer) {
9
- serializeArrayBufferUnsafe(data, changetype<OBJECT>(data - TOTAL_OVERHEAD).rtSize);
15
+ serializeArrayBufferUnsafe(
16
+ data,
17
+ changetype<OBJECT>(data - TOTAL_OVERHEAD).rtSize,
18
+ );
10
19
  } else if (type == JSON.Types.TypedArray) {
11
20
  const id = changetype<OBJECT>(data - TOTAL_OVERHEAD).rtId;
12
21
  if (id == idof<Int8Array>()) {
@@ -14,7 +23,9 @@ import { serializeArrayBufferUnsafe, serializeTypedArray } from "../simple/typed
14
23
  } else if (id == idof<Uint8Array>()) {
15
24
  serializeTypedArray<Uint8Array>(changetype<Uint8Array>(data));
16
25
  } else if (id == idof<Uint8ClampedArray>()) {
17
- serializeTypedArray<Uint8ClampedArray>(changetype<Uint8ClampedArray>(data));
26
+ serializeTypedArray<Uint8ClampedArray>(
27
+ changetype<Uint8ClampedArray>(data),
28
+ );
18
29
  } else if (id == idof<Int16Array>()) {
19
30
  serializeTypedArray<Int16Array>(changetype<Int16Array>(data));
20
31
  } else if (id == idof<Uint16Array>()) {
@@ -35,8 +46,12 @@ import { serializeArrayBufferUnsafe, serializeTypedArray } from "../simple/typed
35
46
  serializeTypedArray<Int8Array>(changetype<Int8Array>(data));
36
47
  } else if (changetype<Uint8Array>(data) instanceof Uint8Array) {
37
48
  serializeTypedArray<Uint8Array>(changetype<Uint8Array>(data));
38
- } else if (changetype<Uint8ClampedArray>(data) instanceof Uint8ClampedArray) {
39
- serializeTypedArray<Uint8ClampedArray>(changetype<Uint8ClampedArray>(data));
49
+ } else if (
50
+ changetype<Uint8ClampedArray>(data) instanceof Uint8ClampedArray
51
+ ) {
52
+ serializeTypedArray<Uint8ClampedArray>(
53
+ changetype<Uint8ClampedArray>(data),
54
+ );
40
55
  } else if (changetype<Int16Array>(data) instanceof Int16Array) {
41
56
  serializeTypedArray<Int16Array>(changetype<Int16Array>(data));
42
57
  } else if (changetype<Uint16Array>(data) instanceof Uint16Array) {
@@ -62,5 +77,8 @@ import { serializeArrayBufferUnsafe, serializeTypedArray } from "../simple/typed
62
77
 
63
78
  @inline export function serializeArrayBuffer(data: ArrayBuffer): void {
64
79
  const dataStart = changetype<usize>(data);
65
- serializeArrayBufferUnsafe(dataStart, changetype<OBJECT>(dataStart - TOTAL_OVERHEAD).rtSize);
80
+ serializeArrayBufferUnsafe(
81
+ dataStart,
82
+ changetype<OBJECT>(dataStart - TOTAL_OVERHEAD).rtSize,
83
+ );
66
84
  }
@@ -39,7 +39,9 @@ export function serializeString_SIMD(src: string): void {
39
39
  const lt20 = i16x8.lt_u(block, SPLAT_0020);
40
40
  const gteD8 = i8x16.gt_u(block, SPLAT_FFD8);
41
41
 
42
- const mask = i8x16.bitmask(v128.or(eq22, v128.or(eq5C, v128.or(lt20, gteD8))));
42
+ const mask = i8x16.bitmask(
43
+ v128.or(eq22, v128.or(eq5C, v128.or(lt20, gteD8))),
44
+ );
43
45
  if (mask != 0) break;
44
46
 
45
47
  store<v128>(dst, block);
@@ -83,7 +85,9 @@ export function serializeString_SIMD(src: string): void {
83
85
  // console.log("lt20 : " + mask_to_string_v128(lt20) + " -> " + mask_to_string_v128(SPLAT_0020));
84
86
  // console.log("gteD8 : " + mask_to_string_v128(gteD8) + " -> " + mask_to_string_v128(SPLAT_FFD8));
85
87
 
86
- let mask = i8x16.bitmask(v128.or(eq22, v128.or(eq5C, v128.or(lt20, gteD8))));
88
+ let mask = i8x16.bitmask(
89
+ v128.or(eq22, v128.or(eq5C, v128.or(lt20, gteD8))),
90
+ );
87
91
 
88
92
  if (mask == 0) {
89
93
  store<v128>(bs.offset, block);
@@ -53,7 +53,180 @@ function serializeArrayElement<T>(value: T): void {
53
53
  JSON.__serialize<T>(value);
54
54
  }
55
55
 
56
+ // ---------------------------------------------------------------------------
57
+ // Specialized fast paths
58
+ // ---------------------------------------------------------------------------
59
+ //
60
+ // `bool[]` and `u8[]` / `i8[]` serializers fold the element write and the
61
+ // trailing comma into a single per-element store. The outer dispatcher
62
+ // emits `[` once, the loop emits `VALUE,` once per element, and the closing
63
+ // `]` overwrites the trailing comma. This eliminates the separate
64
+ // comma-store + advance per element that the generic `serializeArray` does.
65
+
66
+ // `"true,"` packed UTF-16: `t,r,u,e,,` lanes 0..4 = bytes 0..9.
67
+ @inline const TRUE_COMMA_LO: u64 = 0x0065_0075_0072_0074;
68
+
69
+
70
+ @inline const TRUE_COMMA_HI: u16 = 0x002c;
71
+ // `"false,"` packed UTF-16: `f,a,l,s,e,,` lanes 0..5 = bytes 0..11.
72
+ @inline const FALSE_COMMA_LO: u64 = 0x0073_006c_0061_0066;
73
+
74
+
75
+ @inline const FALSE_COMMA_HI: u32 = 0x002c_0065;
76
+
77
+ function serializeBoolArrayFast(src: bool[]): void {
78
+ const len = src.length;
79
+ // Worst case: every element is `"false,"` = 12 bytes; plus 4 for `[]`.
80
+ bs.proposeSize(4 + <u32>len * 12);
81
+ store<u16>(bs.offset, BRACKET_LEFT);
82
+ bs.offset += 2;
83
+ if (len == 0) {
84
+ store<u16>(bs.offset, BRACKET_RIGHT);
85
+ bs.offset += 2;
86
+ return;
87
+ }
88
+
89
+ const dataStart = src.dataStart;
90
+ for (let i: i32 = 0; i < len; i++) {
91
+ if (load<bool>(dataStart + <usize>i)) {
92
+ store<u64>(bs.offset, TRUE_COMMA_LO);
93
+ store<u16>(bs.offset, TRUE_COMMA_HI, 8);
94
+ bs.offset += 10;
95
+ } else {
96
+ store<u64>(bs.offset, FALSE_COMMA_LO);
97
+ store<u32>(bs.offset, FALSE_COMMA_HI, 8);
98
+ bs.offset += 12;
99
+ }
100
+ }
101
+ // Overwrite the final trailing comma with `]`.
102
+ store<u16>(bs.offset - 2, BRACKET_RIGHT);
103
+ }
104
+
105
+ // 256-entry table mapping `u8` value -> UTF-16 chars of `"DDD,"` packed in a
106
+ // u64. Unused lanes hold garbage that the next element's store overwrites.
107
+ const U8_SERIALIZE_LUT: usize = memory.data(2048); // 256 * sizeof<u64>
108
+ // 256-entry table mapping `u8` value -> byte count of the packed encoding.
109
+ const U8_SERIALIZE_LEN_LUT: usize = memory.data(256);
110
+ let _u8LutInited: bool = false;
111
+
112
+ function initU8Lut(): void {
113
+ for (let i: i32 = 0; i < 256; i++) {
114
+ let chars: u64;
115
+ let bytes: u8;
116
+ if (i < 10) {
117
+ chars = u64(0x30 + i) | (u64(0x2c) << 16);
118
+ bytes = 4;
119
+ } else if (i < 100) {
120
+ const d0 = i / 10;
121
+ const d1 = i % 10;
122
+ chars = u64(0x30 + d0) | (u64(0x30 + d1) << 16) | (u64(0x2c) << 32);
123
+ bytes = 6;
124
+ } else {
125
+ const d0 = i / 100;
126
+ const d1 = (i / 10) % 10;
127
+ const d2 = i % 10;
128
+ chars =
129
+ u64(0x30 + d0) |
130
+ (u64(0x30 + d1) << 16) |
131
+ (u64(0x30 + d2) << 32) |
132
+ (u64(0x2c) << 48);
133
+ bytes = 8;
134
+ }
135
+ store<u64>(U8_SERIALIZE_LUT + ((<usize>i) << 3), chars);
136
+ store<u8>(U8_SERIALIZE_LEN_LUT + <usize>i, bytes);
137
+ }
138
+ _u8LutInited = true;
139
+ }
140
+
141
+
142
+ @inline function ensureU8Lut(): void {
143
+ if (!_u8LutInited) initU8Lut();
144
+ }
145
+
146
+ function serializeU8ArrayFast(src: u8[]): void {
147
+ const len = src.length;
148
+ // Worst case: every element is 3 digits + comma = 8 bytes; plus 4 for `[]`.
149
+ bs.proposeSize(4 + <u32>len * 8);
150
+ store<u16>(bs.offset, BRACKET_LEFT);
151
+ bs.offset += 2;
152
+ if (len == 0) {
153
+ store<u16>(bs.offset, BRACKET_RIGHT);
154
+ bs.offset += 2;
155
+ return;
156
+ }
157
+ ensureU8Lut();
158
+
159
+ const dataStart = src.dataStart;
160
+ for (let i: i32 = 0; i < len; i++) {
161
+ const v = <usize>load<u8>(dataStart + <usize>i);
162
+ const chars = load<u64>(U8_SERIALIZE_LUT + (v << 3));
163
+ const byteCount = <usize>load<u8>(U8_SERIALIZE_LEN_LUT + v);
164
+ store<u64>(bs.offset, chars);
165
+ bs.offset += byteCount;
166
+ }
167
+ store<u16>(bs.offset - 2, BRACKET_RIGHT);
168
+ }
169
+
170
+ function serializeI8ArrayFast(src: i8[]): void {
171
+ const len = src.length;
172
+ // Worst case: every element is `-DDD,` = 5 chars = 10 bytes; plus 4 for `[]`.
173
+ bs.proposeSize(4 + <u32>len * 10);
174
+ store<u16>(bs.offset, BRACKET_LEFT);
175
+ bs.offset += 2;
176
+ if (len == 0) {
177
+ store<u16>(bs.offset, BRACKET_RIGHT);
178
+ bs.offset += 2;
179
+ return;
180
+ }
181
+ ensureU8Lut();
182
+
183
+ const dataStart = src.dataStart;
184
+ for (let i: i32 = 0; i < len; i++) {
185
+ let signed = load<i8>(dataStart + <usize>i);
186
+ let absVal: u32;
187
+ if (signed < 0) {
188
+ store<u16>(bs.offset, 0x2d); // '-'
189
+ bs.offset += 2;
190
+ absVal = <u32>-(<i32>signed);
191
+ } else {
192
+ absVal = <u32>signed;
193
+ }
194
+ const chars = load<u64>(U8_SERIALIZE_LUT + ((<usize>absVal) << 3));
195
+ const byteCount = <usize>load<u8>(U8_SERIALIZE_LEN_LUT + <usize>absVal);
196
+ store<u64>(bs.offset, chars);
197
+ bs.offset += byteCount;
198
+ }
199
+ store<u16>(bs.offset - 2, BRACKET_RIGHT);
200
+ }
201
+
56
202
  export function serializeArray<T extends any[]>(src: T): void {
203
+ // Specialized fast paths fold the per-element comma into the element write,
204
+ // saving one `store<u16>` + advance per iteration. AS folds the type checks
205
+ // at compile time so the non-matching branches don't ship.
206
+ if (isBoolean<valueof<T>>()) {
207
+ // @ts-expect-error: T is bool[]
208
+ serializeBoolArrayFast(changetype<bool[]>(src));
209
+ return;
210
+ }
211
+ if (
212
+ isInteger<valueof<T>>() &&
213
+ !isSigned<valueof<T>>() &&
214
+ sizeof<valueof<T>>() == 1
215
+ ) {
216
+ // @ts-expect-error: T is u8[]
217
+ serializeU8ArrayFast(changetype<u8[]>(src));
218
+ return;
219
+ }
220
+ if (
221
+ isInteger<valueof<T>>() &&
222
+ isSigned<valueof<T>>() &&
223
+ sizeof<valueof<T>>() == 1
224
+ ) {
225
+ // @ts-expect-error: T is i8[]
226
+ serializeI8ArrayFast(changetype<i8[]>(src));
227
+ return;
228
+ }
229
+
57
230
  const len = src.length;
58
231
  const end = len - 1;
59
232
  let i = 0;
@@ -63,7 +236,12 @@ export function serializeArray<T extends any[]>(src: T): void {
63
236
  bs.offset += 4;
64
237
  return;
65
238
  }
66
- if (isBoolean<valueof<T>>() || isInteger<valueof<T>>() || isFloat<valueof<T>>() || isString<valueof<T>>()) {
239
+ if (
240
+ isBoolean<valueof<T>>() ||
241
+ isInteger<valueof<T>>() ||
242
+ isFloat<valueof<T>>() ||
243
+ isString<valueof<T>>()
244
+ ) {
67
245
  reservePrimitiveArray<valueof<T>>(len);
68
246
  } else {
69
247
  bs.proposeSize(4 + <u32>(len - 1) * 2);
@@ -1,5 +1,8 @@
1
1
  import { bs } from "../../../lib/as-bs";
2
- import { dragonbox_f32_buffered, dragonbox_f64_buffered } from "../../util/dragonbox";
2
+ import {
3
+ dragonbox_f32_buffered,
4
+ dragonbox_f64_buffered,
5
+ } from "../../util/dragonbox";
3
6
 
4
7
 
5
8
  @inline
@@ -1,20 +1,19 @@
1
1
  import { bs } from "../../../lib/as-bs";
2
- import { itoa_buffered } from "util/number";
2
+ import { ensureItoaPairs, itoaFast } from "../../util/itoa-fast";
3
3
 
4
4
 
5
5
  @inline
6
6
  export function serializeIntegerUnsafe<T extends number>(data: T): void {
7
- const bytesWritten = itoa_buffered(bs.offset, data) << 1;
8
- bs.offset += bytesWritten;
7
+ ensureItoaPairs();
8
+ const charsWritten = itoaFast<T>(bs.offset, data);
9
+ bs.offset += (<usize>charsWritten) << 1;
9
10
  }
10
11
 
11
12
  // @ts-ignore: inline
12
13
  @inline export function serializeInteger<T extends number>(data: T): void {
14
+ ensureItoaPairs();
13
15
  bs.ensureSize(sizeof<T>() << 3);
14
- const bytesWritten = itoa_buffered(bs.offset, data) << 1;
15
- bs.growSize(bytesWritten);
16
- bs.offset += bytesWritten;
16
+ const charsWritten = itoaFast<T>(bs.offset, data);
17
+ bs.growSize((<u32>charsWritten) << 1);
18
+ bs.offset += (<usize>charsWritten) << 1;
17
19
  }
18
-
19
- // 32 {"x":,"y":,"z"}
20
- // 18 3.41.28.3
@@ -26,7 +26,9 @@ export function serializeMap<T extends Map<any, any>>(src: T): void {
26
26
  if (keyIsString) {
27
27
  JSON.__serialize(unchecked(keys[i]));
28
28
  } else {
29
- JSON.__serialize<string>(JSON.internal.stringify<indexof<T>>(unchecked(keys[i])));
29
+ JSON.__serialize<string>(
30
+ JSON.internal.stringify<indexof<T>>(unchecked(keys[i])),
31
+ );
30
32
  }
31
33
  store<u16>(bs.offset, COLON);
32
34
  bs.offset += 2;
@@ -38,7 +40,9 @@ export function serializeMap<T extends Map<any, any>>(src: T): void {
38
40
  if (keyIsString) {
39
41
  JSON.__serialize(unchecked(keys[srcEnd]));
40
42
  } else {
41
- JSON.__serialize<string>(JSON.internal.stringify<indexof<T>>(unchecked(keys[srcEnd])));
43
+ JSON.__serialize<string>(
44
+ JSON.internal.stringify<indexof<T>>(unchecked(keys[srcEnd])),
45
+ );
42
46
  }
43
47
  store<u16>(bs.offset, COLON);
44
48
  bs.offset += 2;
@@ -11,6 +11,10 @@ import { bytes } from "../../util";
11
11
  @inline export function serializeRaw(data: JSON.Raw): void {
12
12
  const dataSize = bytes(data.data);
13
13
  bs.proposeSize(dataSize);
14
- memory.copy(changetype<usize>(bs.offset), changetype<usize>(data.data), dataSize);
14
+ memory.copy(
15
+ changetype<usize>(bs.offset),
16
+ changetype<usize>(data.data),
17
+ dataSize,
18
+ );
15
19
  bs.offset += dataSize;
16
20
  }
@@ -38,7 +38,12 @@ export function serializeSet<T extends Set<any>>(src: T): void {
38
38
  bs.offset += 4;
39
39
  return;
40
40
  }
41
- if (isBoolean<indexof<T>>() || isInteger<indexof<T>>() || isFloat<indexof<T>>() || isString<indexof<T>>()) {
41
+ if (
42
+ isBoolean<indexof<T>>() ||
43
+ isInteger<indexof<T>>() ||
44
+ isFloat<indexof<T>>() ||
45
+ isString<indexof<T>>()
46
+ ) {
42
47
  reservePrimitiveSet<indexof<T>>(srcSize);
43
48
  } else {
44
49
  bs.proposeSize(4 + <u32>(srcSize - 1) * 2);
@@ -40,7 +40,12 @@ export function serializeStaticArray<T extends StaticArray<any>>(src: T): void {
40
40
  bs.offset += 4;
41
41
  return;
42
42
  }
43
- if (isBoolean<valueof<T>>() || isInteger<valueof<T>>() || isFloat<valueof<T>>() || isString<valueof<T>>()) {
43
+ if (
44
+ isBoolean<valueof<T>>() ||
45
+ isInteger<valueof<T>>() ||
46
+ isFloat<valueof<T>>() ||
47
+ isString<valueof<T>>()
48
+ ) {
44
49
  reservePrimitiveStaticArray<valueof<T>>(len);
45
50
  } else {
46
51
  bs.proposeSize(4 + <u32>(len - 1) * 2);
@@ -1,5 +1,4 @@
1
1
  import { bs } from "../../../lib/as-bs";
2
- import { _intTo16 } from "../../custom/util";
3
2
  import { bytes } from "../../util/bytes";
4
3
  import { BACK_SLASH, QUOTE } from "../../custom/chars";
5
4
  import { SERIALIZE_ESCAPE_TABLE } from "../../globals/tables";
@@ -25,9 +25,13 @@ function reserveTypedArray<T extends ArrayLike<number>>(len: i32): void {
25
25
 
26
26
 
27
27
  @inline
28
- function serializeTypedArrayElement<T extends ArrayLike<number>>(src: T, index: i32): void {
28
+ function serializeTypedArrayElement<T extends ArrayLike<number>>(
29
+ src: T,
30
+ index: i32,
31
+ ): void {
29
32
  if (isFloat<valueof<T>>()) {
30
- if (sizeof<valueof<T>>() == 4) serializeFloat32Unsafe(<f32>unchecked(src[index]));
33
+ if (sizeof<valueof<T>>() == 4)
34
+ serializeFloat32Unsafe(<f32>unchecked(src[index]));
31
35
  else serializeFloat64Unsafe(<f64>unchecked(src[index]));
32
36
  } else {
33
37
  serializeIntegerUnsafe<valueof<T>>(unchecked(src[index]));
@@ -59,7 +63,10 @@ export function serializeTypedArray<T extends ArrayLike<number>>(src: T): void {
59
63
  bs.offset += 2;
60
64
  }
61
65
 
62
- export function serializeArrayBufferUnsafe(srcStart: usize, byteLength: i32): void {
66
+ export function serializeArrayBufferUnsafe(
67
+ srcStart: usize,
68
+ byteLength: i32,
69
+ ): void {
63
70
  const end = byteLength - 1;
64
71
 
65
72
  if (end == -1) {
@@ -25,7 +25,11 @@ export function serializeString_SWAR(src: string): void {
25
25
  const block = load<u64>(srcStart);
26
26
  if ((block & 0xff00_ff00_ff00_ff00) != 0) break;
27
27
  const lo = block & 0x00ff_00ff_00ff_00ff;
28
- const asciiMask = ((lo - 0x0020_0020_0020_0020) | ((lo ^ 0x0022_0022_0022_0022) - 0x0001_0001_0001_0001) | ((lo ^ 0x005c_005c_005c_005c) - 0x0001_0001_0001_0001)) & (0x0080_0080_0080_0080 & ~lo);
28
+ const asciiMask =
29
+ ((lo - 0x0020_0020_0020_0020) |
30
+ ((lo ^ 0x0022_0022_0022_0022) - 0x0001_0001_0001_0001) |
31
+ ((lo ^ 0x005c_005c_005c_005c) - 0x0001_0001_0001_0001)) &
32
+ (0x0080_0080_0080_0080 & ~lo);
29
33
  if (asciiMask != 0) break;
30
34
  store<u64>(dst, block);
31
35
  srcStart += 8;
@@ -35,7 +39,8 @@ export function serializeString_SWAR(src: string): void {
35
39
 
36
40
  while (srcStart <= srcEnd - 2) {
37
41
  const code = load<u16>(srcStart);
38
- if (code > 0x7f || code == BACK_SLASH || code == QUOTE || code < 32) break;
42
+ if (code > 0x7f || code == BACK_SLASH || code == QUOTE || code < 32)
43
+ break;
39
44
  store<u16>(dst, code);
40
45
  srcStart += 2;
41
46
  dst += 2;
@@ -169,7 +174,9 @@ export function serializeString_SWAR(src: string): void {
169
174
  bs.offset += 2;
170
175
  }
171
176
 
172
- export function serializeString_SWAR_ExperimentalTableEscapes(src: string): void {
177
+ export function serializeString_SWAR_ExperimentalTableEscapes(
178
+ src: string,
179
+ ): void {
173
180
  let srcStart = changetype<usize>(src);
174
181
  const srcSize = changetype<OBJECT>(srcStart - TOTAL_OVERHEAD).rtSize;
175
182
  const srcEnd = srcStart + srcSize;
@@ -308,9 +315,15 @@ export function serializeString_SWAR_ExperimentalTableEscapes(src: string): void
308
315
  // Setting bit 8 of each 16-bit lane (high byte LSB) prevents borrow from a
309
316
  // low byte underflow from propagating across lane boundaries into the next lane.
310
317
  const loSafe = lo | 0x0100_0100_0100_0100;
311
- const ascii_mask = ((loSafe - 0x0020_0020_0020_0020) | ((loSafe ^ 0x0022_0022_0022_0022) - 0x0001_0001_0001_0001) | ((loSafe ^ 0x005c_005c_005c_005c) - 0x0001_0001_0001_0001)) & (0x0080_0080_0080_0080 & ~lo);
318
+ const ascii_mask =
319
+ ((loSafe - 0x0020_0020_0020_0020) |
320
+ ((loSafe ^ 0x0022_0022_0022_0022) - 0x0001_0001_0001_0001) |
321
+ ((loSafe ^ 0x005c_005c_005c_005c) - 0x0001_0001_0001_0001)) &
322
+ (0x0080_0080_0080_0080 & ~lo);
312
323
  if (hi == 0) return ascii_mask;
313
- const hi_mask = ((block - 0x0100_0100_0100_0100) & ~block & 0x8000_8000_8000_8000) ^ 0x8000_8000_8000_8000;
324
+ const hi_mask =
325
+ ((block - 0x0100_0100_0100_0100) & ~block & 0x8000_8000_8000_8000) ^
326
+ 0x8000_8000_8000_8000;
314
327
  return (ascii_mask & (~hi_mask >> 8)) | hi_mask;
315
328
  }
316
329
 
@@ -0,0 +1,81 @@
1
+ // Back-compat shim. The canonical fast SWAR atoi/atou implementations live
2
+ // in `deserialize/swar/integer.ts`, using the full tiered stride hierarchy
3
+ // (parse16 -> parse8 -> parse4 -> scalar). These thin wrappers preserve the
4
+ // original `(srcStart, srcEnd, [dstPtr])` signatures used by existing tests
5
+ // and benches.
6
+
7
+ import {
8
+ deserializeInteger_SWAR,
9
+ deserializeIntegerField_SWAR,
10
+ deserializeUnsigned_SWAR,
11
+ deserializeUnsignedField_SWAR,
12
+ } from "../deserialize/swar/integer";
13
+
14
+ /**
15
+ * Parse an unsigned integer by consuming the whole range as digits.
16
+ *
17
+ * @param srcStart Pointer to the first UTF-16 code unit.
18
+ * @param srcEnd Pointer just past the last code unit.
19
+ * @returns The parsed value, truncated to `T`.
20
+ */
21
+ // @ts-expect-error: @inline is a valid decorator
22
+ @inline export function atou<T extends number>(
23
+ srcStart: usize,
24
+ srcEnd: usize,
25
+ ): T {
26
+ return deserializeUnsigned_SWAR<T>(srcStart, srcEnd);
27
+ }
28
+
29
+ /**
30
+ * Parse a signed integer by consuming the whole range as digits, with an
31
+ * optional leading `-`.
32
+ *
33
+ * @param srcStart Pointer to the first UTF-16 code unit.
34
+ * @param srcEnd Pointer just past the last code unit.
35
+ * @returns The parsed value, truncated to `T`.
36
+ */
37
+ // @ts-expect-error: @inline is a valid decorator
38
+ @inline export function atoi<T extends number>(
39
+ srcStart: usize,
40
+ srcEnd: usize,
41
+ ): T {
42
+ return deserializeInteger_SWAR<T>(srcStart, srcEnd);
43
+ }
44
+
45
+ /**
46
+ * Scan an unsigned integer, stopping at the first non-digit. Writes the
47
+ * parsed value through `dstPtr` and returns the source position immediately
48
+ * after the last digit.
49
+ *
50
+ * @param srcStart Pointer to the first UTF-16 code unit.
51
+ * @param srcEnd Pointer just past the last code unit.
52
+ * @param dstPtr Destination pointer for the parsed value.
53
+ * @returns The source position immediately after the last digit consumed.
54
+ */
55
+ // @ts-expect-error: @inline is a valid decorator
56
+ @inline export function atouScan<T extends number>(
57
+ srcStart: usize,
58
+ srcEnd: usize,
59
+ dstPtr: usize,
60
+ ): usize {
61
+ return deserializeUnsignedField_SWAR<T>(srcStart, srcEnd, dstPtr, 0);
62
+ }
63
+
64
+ /**
65
+ * Scan a signed integer, stopping at the first non-digit. Handles an
66
+ * optional leading `-`. Writes the parsed value through `dstPtr` and
67
+ * returns the source position immediately after the last digit.
68
+ *
69
+ * @param srcStart Pointer to the first UTF-16 code unit.
70
+ * @param srcEnd Pointer just past the last code unit.
71
+ * @param dstPtr Destination pointer for the parsed value.
72
+ * @returns The source position immediately after the last digit consumed.
73
+ */
74
+ // @ts-expect-error: @inline is a valid decorator
75
+ @inline export function atoiScan<T extends number>(
76
+ srcStart: usize,
77
+ srcEnd: usize,
78
+ dstPtr: usize,
79
+ ): usize {
80
+ return deserializeIntegerField_SWAR<T>(srcStart, srcEnd, dstPtr, 0);
81
+ }
@@ -4,6 +4,10 @@ export function concat(left: string, right: string): string {
4
4
  const rightSize: usize = bytes(right);
5
5
  const jointSize: usize = leftSize + rightSize;
6
6
  const jointPtr = __renew(changetype<usize>(left), jointSize);
7
- memory.copy(changetype<usize>(left) + leftSize, changetype<usize>(right), rightSize);
7
+ memory.copy(
8
+ changetype<usize>(left) + leftSize,
9
+ changetype<usize>(right),
10
+ rightSize,
11
+ );
8
12
  return changetype<string>(jointPtr);
9
13
  }