json-as 1.4.0 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/CHANGELOG.md +50 -29
  2. package/README.md +84 -33
  3. package/assembly/custom/chars.ts +39 -78
  4. package/assembly/deserialize/index/arbitrary.ts +26 -8
  5. package/assembly/deserialize/index/float.ts +2 -4
  6. package/assembly/deserialize/index/integer.ts +2 -4
  7. package/assembly/deserialize/index/object.ts +6 -1
  8. package/assembly/deserialize/index/string.ts +2 -7
  9. package/assembly/deserialize/index/unsigned.ts +2 -4
  10. package/assembly/deserialize/naive/array/integer.ts +1 -1
  11. package/assembly/deserialize/naive/array/map.ts +1 -1
  12. package/assembly/deserialize/naive/array/object.ts +1 -1
  13. package/assembly/deserialize/naive/array/struct.ts +19 -1
  14. package/assembly/deserialize/naive/bool.ts +1 -5
  15. package/assembly/deserialize/naive/date.ts +1 -2
  16. package/assembly/deserialize/naive/float.ts +2 -7
  17. package/assembly/deserialize/naive/integer.ts +1 -2
  18. package/assembly/deserialize/naive/map.ts +5 -6
  19. package/assembly/deserialize/naive/object.ts +151 -13
  20. package/assembly/deserialize/naive/raw.ts +1 -5
  21. package/assembly/deserialize/naive/set.ts +2 -4
  22. package/assembly/deserialize/naive/staticarray.ts +1 -2
  23. package/assembly/deserialize/naive/string.ts +6 -9
  24. package/assembly/deserialize/naive/unsigned.ts +1 -2
  25. package/assembly/deserialize/simd/array/integer.ts +2 -7
  26. package/assembly/deserialize/simd/float.ts +3 -5
  27. package/assembly/deserialize/simd/integer.ts +2 -7
  28. package/assembly/deserialize/simd/string.ts +5 -22
  29. package/assembly/deserialize/swar/array/arbitrary.ts +1 -2
  30. package/assembly/deserialize/swar/array/array.ts +1 -2
  31. package/assembly/deserialize/swar/array/bool.ts +1 -2
  32. package/assembly/deserialize/swar/array/box.ts +1 -2
  33. package/assembly/deserialize/swar/array/float.ts +6 -18
  34. package/assembly/deserialize/swar/array/generic.ts +1 -2
  35. package/assembly/deserialize/swar/array/integer.ts +7 -16
  36. package/assembly/deserialize/swar/array/map.ts +1 -2
  37. package/assembly/deserialize/swar/array/object.ts +1 -2
  38. package/assembly/deserialize/swar/array/raw.ts +1 -2
  39. package/assembly/deserialize/swar/array/shared.ts +6 -13
  40. package/assembly/deserialize/swar/array/string.ts +3 -8
  41. package/assembly/deserialize/swar/array/struct.ts +2 -8
  42. package/assembly/deserialize/swar/array.ts +1 -3
  43. package/assembly/deserialize/swar/float.ts +4 -9
  44. package/assembly/deserialize/swar/integer.ts +2 -7
  45. package/assembly/deserialize/swar/string.ts +13 -15
  46. package/assembly/deserialize/swar/typedarray.ts +4 -4
  47. package/assembly/index.d.ts +29 -24
  48. package/assembly/index.ts +1362 -246
  49. package/assembly/serialize/index/arbitrary.ts +70 -4
  50. package/assembly/serialize/index/jsonarray.ts +51 -0
  51. package/assembly/serialize/index/object.ts +25 -3
  52. package/assembly/serialize/index/string.ts +1 -2
  53. package/assembly/serialize/index/typedarray.ts +1 -2
  54. package/assembly/serialize/index.ts +1 -0
  55. package/assembly/serialize/naive/array.ts +23 -34
  56. package/assembly/serialize/naive/bool.ts +0 -1
  57. package/assembly/serialize/naive/float.ts +16 -25
  58. package/assembly/serialize/naive/integer.ts +1 -5
  59. package/assembly/serialize/naive/raw.ts +1 -2
  60. package/assembly/serialize/naive/set.ts +0 -4
  61. package/assembly/serialize/naive/staticarray.ts +0 -5
  62. package/assembly/serialize/naive/string.ts +2 -5
  63. package/assembly/serialize/naive/typedarray.ts +0 -6
  64. package/assembly/serialize/simd/string.ts +1 -3
  65. package/assembly/serialize/swar/string.ts +1 -2
  66. package/assembly/util/atoi-fast.ts +4 -14
  67. package/assembly/util/bytes.ts +1 -2
  68. package/assembly/util/idofd.ts +1 -2
  69. package/assembly/util/isSpace.ts +1 -2
  70. package/assembly/util/itoa-fast.ts +6 -9
  71. package/assembly/util/nextPowerOf2.ts +1 -2
  72. package/assembly/util/parsefloat-fast.ts +3 -5
  73. package/assembly/util/ptrToStr.ts +1 -2
  74. package/assembly/util/scanValueEndSimd.ts +54 -16
  75. package/assembly/util/scanValueEndSwar.ts +67 -25
  76. package/assembly/util/scientific.ts +5 -8
  77. package/assembly/util/snp.ts +1 -2
  78. package/assembly/util/swar-int.ts +5 -10
  79. package/assembly/util/swar.ts +2 -4
  80. package/lib/as-bs.ts +23 -45
  81. package/package.json +14 -7
  82. package/transform/lib/index.js +108 -64
  83. package/transform/lib/types.d.ts +2 -1
  84. package/transform/lib/types.js +3 -0
  85. package/assembly/util/dragonbox-cache.ts +0 -445
  86. package/assembly/util/dragonbox.ts +0 -652
@@ -1,21 +1,77 @@
1
1
  import { JSON } from "../..";
2
2
  import { bs } from "../../../lib/as-bs";
3
- import { serializeArray } from "./array";
3
+ import { bytes } from "../../util/bytes";
4
+ import { QUOTE } from "../../custom/chars";
4
5
  import { serializeBool } from "./bool";
5
6
  import { serializeFloat32, serializeFloat64 } from "./float";
6
7
  import { serializeInteger } from "./integer";
8
+ import { serializeJsonArray } from "./jsonarray";
7
9
  import { serializeMap } from "./map";
8
10
  import { serializeObject } from "./object";
11
+ import { serializeRaw } from "../naive/raw";
9
12
  import { serializeString } from "./string";
10
13
  import { serializeDynamic } from "./typedarray";
11
14
 
15
+ // True if any code unit would need JSON-escaping on serialize: a quote,
16
+ // backslash, control char (< 0x20), or a surrogate (handled conservatively -
17
+ // even valid pairs route to the full path, since they can't be bulk-copied as a
18
+ // plain run). A clean string is none of these, so it emits as a verbatim memcpy.
19
+ // @ts-ignore: decorator
20
+ @inline function stringNeedsEscape(src: string): bool {
21
+ let ptr = changetype<usize>(src);
22
+ const end = ptr + <usize>bytes(src);
23
+ while (ptr < end) {
24
+ const code = load<u16>(ptr);
25
+ if (
26
+ code == 0x22 ||
27
+ code == 0x5c ||
28
+ code < 0x20 ||
29
+ (code >= 0xd800 && code <= 0xdfff)
30
+ )
31
+ return true;
32
+ ptr += 2;
33
+ }
34
+ return false;
35
+ }
36
+
37
+ // Fast path for a string already known to need no escaping: quote + a single
38
+ // bulk copy of the UTF-16 bytes + quote. Skips the per-char escape scan that
39
+ // serializeString would otherwise do (and its trailing second pass).
40
+ function serializeStringClean(src: string): void {
41
+ const size = <usize>bytes(src);
42
+ bs.proposeSize(size + 4);
43
+ store<u16>(bs.offset, QUOTE);
44
+ bs.offset += 2;
45
+ memory.copy(bs.offset, changetype<usize>(src), size);
46
+ bs.offset += size;
47
+ store<u16>(bs.offset, QUOTE);
48
+ bs.offset += 2;
49
+ }
50
+
12
51
  export function serializeArbitrary(src: JSON.Value): void {
52
+ // Verbatim passthrough: an untouched (still-deferred) value emits its original
53
+ // source bytes directly - no materialization, no re-encoding. Peek the slice
54
+ // without reading `src.type` (which would force materialization).
55
+ const lz = src.__lazySlice();
56
+ if (lz != 0) {
57
+ const start = <usize>(lz >>> 32);
58
+ const size = <usize>(<u32>lz) - start;
59
+ bs.proposeSize(size);
60
+ memory.copy(bs.offset, start, size);
61
+ bs.offset += size;
62
+ return;
63
+ }
13
64
  switch (src.type) {
14
65
  case JSON.Types.Null:
15
66
  bs.proposeSize(8);
16
67
  store<u64>(bs.offset, 30399761348886638);
17
68
  bs.offset += 8;
18
69
  break;
70
+ case JSON.Types.Raw:
71
+ // A materialized JSON.Raw value (e.g. set into a JSON.Obj/Arr) emits its
72
+ // pre-formatted bytes as-is - without this it fell into the struct default.
73
+ serializeRaw(src.get<JSON.Raw>());
74
+ break;
19
75
  case JSON.Types.U8:
20
76
  serializeInteger<u8>(src.get<u8>());
21
77
  break;
@@ -46,14 +102,24 @@ export function serializeArbitrary(src: JSON.Value): void {
46
102
  case JSON.Types.F64:
47
103
  serializeFloat64(src.get<f64>());
48
104
  break;
49
- case JSON.Types.String:
50
- serializeString(src.get<string>());
105
+ case JSON.Types.String: {
106
+ const str = src.get<string>();
107
+ // Reuse the cached escape class; classify once on first serialize. Clean
108
+ // strings (the common case) then emit as a single memcpy on every reuse.
109
+ let cls = src.__strClass();
110
+ if (cls == 0) {
111
+ cls = stringNeedsEscape(str) ? 2 : 1;
112
+ src.__setStrClass(cls);
113
+ }
114
+ if (cls == 1) serializeStringClean(str);
115
+ else serializeString(str);
51
116
  break;
117
+ }
52
118
  case JSON.Types.Bool:
53
119
  serializeBool(src.get<bool>());
54
120
  break;
55
121
  case JSON.Types.Array:
56
- serializeArray(src.get<JSON.Value[]>());
122
+ serializeJsonArray(src.get<JSON.Arr>());
57
123
  break;
58
124
  case JSON.Types.Object:
59
125
  serializeObject(src.get<JSON.Obj>());
@@ -0,0 +1,51 @@
1
+ import { bs } from "../../../lib/as-bs";
2
+ import { JSON } from "../..";
3
+ import { BRACKET_LEFT, BRACKET_RIGHT, COMMA } from "../../custom/chars";
4
+ import { serializeArbitrary } from "./arbitrary";
5
+
6
+ export function serializeJsonArray(src: JSON.Arr): void {
7
+ const n = src.length;
8
+
9
+ if (n == 0) {
10
+ bs.proposeSize(4);
11
+ store<u32>(bs.offset, 6094939); // "[]"
12
+ bs.offset += 4;
13
+ return;
14
+ }
15
+
16
+ const vals = src._vals;
17
+ // Source base + upper bound for resolving a deferred slot's value range.
18
+ const srcBase = changetype<usize>(src._src);
19
+ const srcEnd = srcBase + ((<usize>src._src.length) << 1);
20
+
21
+ bs.proposeSize(4 + <u32>(n - 1) * 2);
22
+ store<u16>(bs.offset, BRACKET_LEFT);
23
+ bs.offset += 2;
24
+
25
+ // A still-deferred slot is copied out verbatim from the source; an
26
+ // eager/materialized slot is serialized from its boxed bits.
27
+ for (let i = 0; i < n; i++) {
28
+ if (i != 0) {
29
+ store<u16>(bs.offset, COMMA);
30
+ bs.offset += 2;
31
+ }
32
+ const slot = unchecked(vals[i]);
33
+ if (JSON.Value.slotIsLazy(slot)) {
34
+ const start = JSON.Value.slotPtr(slot, srcBase);
35
+ const end = JSON.Value.slotEnd(slot, srcBase, srcEnd);
36
+ const size = end - start;
37
+ bs.proposeSize(size);
38
+ memory.copy(bs.offset, start, size);
39
+ bs.offset += size;
40
+ } else {
41
+ const v = JSON.Value.fromBits(slot);
42
+ serializeArbitrary(v);
43
+ // Persist a cached String escape-class back into the slot (see object.ts).
44
+ const nb = v.__bits();
45
+ if (nb != slot) unchecked((vals[i] = nb));
46
+ }
47
+ }
48
+
49
+ store<u16>(bs.offset, BRACKET_RIGHT);
50
+ bs.offset += 2;
51
+ }
@@ -17,13 +17,18 @@ export function serializeObject(src: JSON.Obj): void {
17
17
  const vals = src._vals;
18
18
  const kbuf = changetype<usize>(src._kbuf);
19
19
  const kused = src._kused;
20
+ // Source base + upper bound for resolving a deferred slot's value range.
21
+ const srcBase = changetype<usize>(src._src);
22
+ const srcEnd = srcBase + ((<usize>src._src.length) << 1);
20
23
 
21
24
  bs.proposeSize(4 + <u32>(srcSize - 1) * 2 + <u32>srcSize * 2);
22
25
  store<u16>(bs.offset, BRACE_LEFT);
23
26
  bs.offset += 2;
24
27
 
25
- // Walk the length-prefixed key buffer in lockstep with the values, emitting
26
- // each key straight from its slice (no per-key string materialization).
28
+ // Walk the length-prefixed key buffer in lockstep with the value slots,
29
+ // emitting each key straight from its slice (no per-key string
30
+ // materialization). A still-deferred slot is copied out verbatim from the
31
+ // source; an eager/materialized slot is serialized from its boxed bits.
27
32
  let pos = 0;
28
33
  let i = 0;
29
34
  while (pos < kused) {
@@ -35,7 +40,24 @@ export function serializeObject(src: JSON.Obj): void {
35
40
  serializeStringRange(kbuf + ((<usize>(pos + 1)) << 1), (<usize>len) << 1);
36
41
  store<u16>(bs.offset, COLON);
37
42
  bs.offset += 2;
38
- serializeArbitrary(unchecked(vals[i]));
43
+
44
+ const slot = unchecked(vals[i]);
45
+ if (JSON.Value.slotIsLazy(slot)) {
46
+ const start = JSON.Value.slotPtr(slot, srcBase);
47
+ const end = JSON.Value.slotEnd(slot, srcBase, srcEnd);
48
+ const size = end - start;
49
+ bs.proposeSize(size);
50
+ memory.copy(bs.offset, start, size);
51
+ bs.offset += size;
52
+ } else {
53
+ const v = JSON.Value.fromBits(slot);
54
+ serializeArbitrary(v);
55
+ // Persist any escape-class the serializer cached on a materialized String
56
+ // slot back into the flat slot, so re-serializing this object reuses it
57
+ // (the memcpy fast path) instead of re-scanning. No-op for other types.
58
+ const nb = v.__bits();
59
+ if (nb != slot) unchecked((vals[i] = nb));
60
+ }
39
61
  pos += 1 + len;
40
62
  i++;
41
63
  }
@@ -3,8 +3,7 @@ import { serializeString_NAIVE } from "../naive/string";
3
3
  import { serializeString_SIMD } from "../simd/string";
4
4
  import { serializeString_SWAR } from "../swar/string";
5
5
 
6
-
7
- @inline export function serializeString(src: string): void {
6
+ export function serializeString(src: string): void {
8
7
  if (JSON_MODE == JSONMode.SIMD) {
9
8
  serializeString_SIMD(src);
10
9
  } else if (JSON_MODE == JSONMode.NAIVE) {
@@ -9,8 +9,7 @@ import {
9
9
  serializeTypedArray,
10
10
  } from "../naive/typedarray";
11
11
 
12
-
13
- @inline export function serializeDynamic(type: u16, data: usize): void {
12
+ export function serializeDynamic(type: u16, data: usize): void {
14
13
  if (type == JSON.Types.ArrayBuffer) {
15
14
  serializeArrayBufferUnsafe(
16
15
  data,
@@ -4,6 +4,7 @@ export * from "./index/bool";
4
4
  export * from "./index/date";
5
5
  export * from "./index/float";
6
6
  export * from "./index/integer";
7
+ export * from "./index/jsonarray";
7
8
  export * from "./index/map";
8
9
  export * from "./index/object";
9
10
  export * from "./index/raw";
@@ -5,13 +5,8 @@ import { serializeBoolUnsafe } from "./bool";
5
5
  import { serializeFloat32Unsafe, serializeFloat64Unsafe } from "./float";
6
6
  import { serializeIntegerUnsafe } from "./integer";
7
7
  import { serializeString } from "../index/string";
8
- import {
9
- dragonbox_f32_buffered,
10
- dragonbox_f64_buffered,
11
- } from "../../util/dragonbox";
8
+ import { dtoa_buffered, ftoa_buffered } from "xjb-as";
12
9
 
13
-
14
- @inline
15
10
  function maxIntegerBytes<T extends number>(): u32 {
16
11
  if (sizeof<T>() == 1) return isSigned<T>() ? 8 : 6;
17
12
  if (sizeof<T>() == 2) return isSigned<T>() ? 12 : 10;
@@ -19,8 +14,6 @@ function maxIntegerBytes<T extends number>(): u32 {
19
14
  return isSigned<T>() ? 42 : 40;
20
15
  }
21
16
 
22
-
23
- @inline
24
17
  function reservePrimitiveArray<T>(len: i32): void {
25
18
  if (len <= 0) return;
26
19
  if (isBoolean<T>()) {
@@ -34,8 +27,6 @@ function reservePrimitiveArray<T>(len: i32): void {
34
27
  }
35
28
  }
36
29
 
37
-
38
- @inline
39
30
  function serializeArrayElement<T>(value: T): void {
40
31
  if (isString<T>()) {
41
32
  serializeString(value as string);
@@ -78,15 +69,13 @@ function serializeArrayElement<T>(value: T): void {
78
69
  // comma-store + advance per element that the generic `serializeArray` does.
79
70
 
80
71
  // `"true,"` packed UTF-16: `t,r,u,e,,` lanes 0..4 = bytes 0..9.
81
- @inline const TRUE_COMMA_LO: u64 = 0x0065_0075_0072_0074;
72
+ const TRUE_COMMA_LO: u64 = 0x0065_0075_0072_0074;
82
73
 
83
-
84
- @inline const TRUE_COMMA_HI: u16 = 0x002c;
74
+ const TRUE_COMMA_HI: u16 = 0x002c;
85
75
  // `"false,"` packed UTF-16: `f,a,l,s,e,,` lanes 0..5 = bytes 0..11.
86
- @inline const FALSE_COMMA_LO: u64 = 0x0073_006c_0061_0066;
87
-
76
+ const FALSE_COMMA_LO: u64 = 0x0073_006c_0061_0066;
88
77
 
89
- @inline const FALSE_COMMA_HI: u32 = 0x002c_0065;
78
+ const FALSE_COMMA_HI: u32 = 0x002c_0065;
90
79
 
91
80
  function serializeBoolArrayFast(src: bool[]): void {
92
81
  const len = src.length;
@@ -152,8 +141,7 @@ function initU8Lut(): void {
152
141
  _u8LutInited = true;
153
142
  }
154
143
 
155
-
156
- @inline function ensureU8Lut(): void {
144
+ function ensureU8Lut(): void {
157
145
  if (!_u8LutInited) initU8Lut();
158
146
  }
159
147
 
@@ -181,20 +169,20 @@ function serializeU8ArrayFast(src: u8[]): void {
181
169
  store<u16>(bs.offset - 2, BRACKET_RIGHT);
182
170
  }
183
171
 
184
- // Specialized float-array serializer: dragonbox + trailing comma in a
172
+ // Specialized float-array serializer: xjb writer + trailing comma in a
185
173
  // uniform per-iteration body, then overwrite the final comma with `]`. The
186
174
  // generic dispatcher splits the loop into "N-1 elements with comma, then
187
- // last element without, then `]`" the branch on each `i < end` check
175
+ // last element without, then `]`" - the branch on each `i < end` check
188
176
  // stalls the loop's tight bs.offset advance pattern. This variant runs the
189
- // same number of stores per iteration (dragonbox output + COMMA), but the
177
+ // same number of stores per iteration (xjb output + COMMA), but the
190
178
  // uniform loop body inlines better and the trailing `]` is a single fixed
191
179
  // overwrite outside the loop.
192
180
  function serializeF64ArrayFast(src: f64[]): void {
193
181
  const len = src.length;
194
- // Worst case per element: ~24 chars for f64 + comma = 50 bytes.
195
- // Slight over-reserve (66) matches the existing `reservePrimitiveArray`
196
- // budget and keeps a safety margin for any NaN/Inf spelling.
197
- bs.proposeSize(4 + <u32>len * 66);
182
+ // Worst case per element: a 21-char fixed integer (e.g. 1e20) or a ~24-char
183
+ // exponent form, + comma = ~52 bytes; plus the writer's SIMD stores can
184
+ // overshoot the logical end by up to 16 bytes. 80 covers both comfortably.
185
+ bs.proposeSize(4 + <u32>len * 80);
198
186
  store<u16>(bs.offset, BRACKET_LEFT);
199
187
  bs.offset += 2;
200
188
  if (len == 0) {
@@ -210,9 +198,9 @@ function serializeF64ArrayFast(src: f64[]): void {
210
198
  let offset = bs.offset;
211
199
  for (let i: i32 = 0; i < len; i++) {
212
200
  const v = load<f64>(dataStart + ((<usize>i) << 3));
213
- const size = dragonbox_f64_buffered(offset, v) << 1;
214
- store<u16>(offset + size, COMMA);
215
- offset += size + 2;
201
+ offset += dtoa_buffered(offset, v) << 1;
202
+ store<u16>(offset, COMMA);
203
+ offset += 2;
216
204
  }
217
205
  // Overwrite the final trailing comma with `]`.
218
206
  store<u16>(offset - 2, BRACKET_RIGHT);
@@ -221,9 +209,10 @@ function serializeF64ArrayFast(src: f64[]): void {
221
209
 
222
210
  function serializeF32ArrayFast(src: f32[]): void {
223
211
  const len = src.length;
224
- // Worst case for f32 is ~16 chars + comma = ~34 bytes; mirror the budget
225
- // used by `reservePrimitiveArray`.
226
- bs.proposeSize(4 + <u32>len * 34);
212
+ // Worst case for f32 is a 21-char fixed integer (e.g. 1e20 rounds to a
213
+ // 21-digit value), + comma = ~44 bytes, plus up to 16 bytes of SIMD store
214
+ // overshoot. 64 covers it.
215
+ bs.proposeSize(4 + <u32>len * 64);
227
216
  store<u16>(bs.offset, BRACKET_LEFT);
228
217
  bs.offset += 2;
229
218
  if (len == 0) {
@@ -236,9 +225,9 @@ function serializeF32ArrayFast(src: f32[]): void {
236
225
  let offset = bs.offset;
237
226
  for (let i: i32 = 0; i < len; i++) {
238
227
  const v = load<f32>(dataStart + ((<usize>i) << 2));
239
- const size = dragonbox_f32_buffered(offset, v) << 1;
240
- store<u16>(offset + size, COMMA);
241
- offset += size + 2;
228
+ offset += ftoa_buffered(offset, v) << 1;
229
+ store<u16>(offset, COMMA);
230
+ offset += 2;
242
231
  }
243
232
  store<u16>(offset - 2, BRACKET_RIGHT);
244
233
  bs.offset = offset;
@@ -4,7 +4,6 @@ import { bs } from "../../../lib/as-bs";
4
4
  * @param data data to serialize
5
5
  * @returns void
6
6
  */
7
- @inline
8
7
  export function serializeBoolUnsafe(data: bool): void {
9
8
  if (data === true) {
10
9
  store<u64>(bs.offset, 28429475166421108);
@@ -1,43 +1,34 @@
1
1
  import { bs } from "../../../lib/as-bs";
2
- import {
3
- dragonbox_f32_buffered,
4
- dragonbox_f64_buffered,
5
- } from "../../util/dragonbox";
2
+ import { dtoa_buffered, ftoa_buffered } from "xjb-as";
6
3
 
4
+ // Float serialization is backed by xjb-as (a Schubfach/xjb shortest-decimal
5
+ // writer with SWAR + WASM-SIMD digit kernels). The *_buffered writers emit
6
+ // UTF-16 straight into the `bs` buffer and return the number of characters
7
+ // written, so advancing the offset is `count << 1` bytes.
7
8
 
8
- @inline
9
9
  export function serializeFloat32Unsafe(data: f32): void {
10
- const size = dragonbox_f32_buffered(bs.offset, data) << 1;
11
- bs.offset += size;
10
+ bs.offset += ftoa_buffered(bs.offset, data) << 1;
12
11
  }
13
12
 
14
-
15
- @inline
16
13
  export function serializeFloat64Unsafe(data: f64): void {
17
- const size = dragonbox_f64_buffered(bs.offset, data) << 1;
18
- bs.offset += size;
14
+ bs.offset += dtoa_buffered(bs.offset, data) << 1;
19
15
  }
20
16
 
21
-
22
- @inline
23
17
  export function serializeFloat32(data: f32): void {
24
- bs.ensureSize(64);
25
- const size = dragonbox_f32_buffered(bs.offset, data) << 1;
26
- bs.stackSize += size;
27
- bs.offset += size;
18
+ bs.ensureSize(128);
19
+ const bytes = ftoa_buffered(bs.offset, data) << 1;
20
+ bs.stackSize += bytes;
21
+ bs.offset += bytes;
28
22
  }
29
23
 
30
-
31
- @inline
32
24
  export function serializeFloat64(data: f64): void {
33
- bs.ensureSize(64);
34
- const size = dragonbox_f64_buffered(bs.offset, data) << 1;
35
- bs.stackSize += size;
36
- bs.offset += size;
25
+ bs.ensureSize(128);
26
+ const bytes = dtoa_buffered(bs.offset, data) << 1;
27
+ bs.stackSize += bytes;
28
+ bs.offset += bytes;
37
29
  }
38
30
 
39
- // @ts-ignore: inline
40
- @inline export function serializeFloat<T extends number>(data: T): void {
31
+ export function serializeFloat<T extends number>(data: T): void {
41
32
  if (sizeof<T>() == 4) serializeFloat32(<f32>data);
42
33
  else serializeFloat64(<f64>data);
43
34
  }
@@ -1,16 +1,12 @@
1
1
  import { bs } from "../../../lib/as-bs";
2
2
  import { ensureItoaPairs, itoaFast } from "../../util/itoa-fast";
3
3
 
4
-
5
- @inline
6
4
  export function serializeIntegerUnsafe<T extends number>(data: T): void {
7
5
  ensureItoaPairs();
8
6
  const charsWritten = itoaFast<T>(bs.offset, data);
9
7
  bs.offset += (<usize>charsWritten) << 1;
10
8
  }
11
-
12
- // @ts-ignore: inline
13
- @inline export function serializeInteger<T extends number>(data: T): void {
9
+ export function serializeInteger<T extends number>(data: T): void {
14
10
  ensureItoaPairs();
15
11
  bs.ensureSize(sizeof<T>() << 3);
16
12
  const charsWritten = itoaFast<T>(bs.offset, data);
@@ -7,8 +7,7 @@ import { bytes } from "../../util";
7
7
  * @param data data to serialize
8
8
  * @returns void
9
9
  */
10
- // @ts-ignore: inline
11
- @inline export function serializeRaw(data: JSON.Raw): void {
10
+ export function serializeRaw(data: JSON.Raw): void {
12
11
  const dataSize = bytes(data.data);
13
12
  bs.proposeSize(dataSize);
14
13
  memory.copy(
@@ -6,8 +6,6 @@ import { serializeFloat32Unsafe, serializeFloat64Unsafe } from "./float";
6
6
  import { serializeIntegerUnsafe } from "./integer";
7
7
  import { serializeString } from "../index/string";
8
8
 
9
-
10
- @inline
11
9
  function maxIntegerBytes<T extends number>(): u32 {
12
10
  if (sizeof<T>() == 1) return isSigned<T>() ? 8 : 6;
13
11
  if (sizeof<T>() == 2) return isSigned<T>() ? 12 : 10;
@@ -15,8 +13,6 @@ function maxIntegerBytes<T extends number>(): u32 {
15
13
  return isSigned<T>() ? 42 : 40;
16
14
  }
17
15
 
18
-
19
- @inline
20
16
  function reservePrimitiveSet<T>(len: i32): void {
21
17
  if (len <= 0) return;
22
18
  if (isBoolean<T>()) {
@@ -6,17 +6,12 @@ import { serializeFloat32Unsafe, serializeFloat64Unsafe } from "./float";
6
6
  import { serializeIntegerUnsafe } from "./integer";
7
7
  import { serializeString } from "../index/string";
8
8
 
9
-
10
- @inline
11
9
  function maxIntegerBytes<T extends number>(): u32 {
12
10
  if (sizeof<T>() == 1) return isSigned<T>() ? 8 : 6;
13
11
  if (sizeof<T>() == 2) return isSigned<T>() ? 12 : 10;
14
12
  if (sizeof<T>() == 4) return isSigned<T>() ? 22 : 20;
15
13
  return isSigned<T>() ? 42 : 40;
16
14
  }
17
-
18
-
19
- @inline
20
15
  function reservePrimitiveStaticArray<T>(len: i32): void {
21
16
  if (len <= 0) return;
22
17
  if (isBoolean<T>()) {
@@ -15,8 +15,7 @@ import { serializeStruct } from "./struct";
15
15
  * @param src string
16
16
  * @returns void
17
17
  */
18
- // @ts-ignore: inline
19
- @inline export function serializeString_NAIVE(src: string): void {
18
+ export function serializeString_NAIVE(src: string): void {
20
19
  serializeStringRange(changetype<usize>(src), bytes(src));
21
20
  }
22
21
 
@@ -86,9 +85,7 @@ export function serializeStringRange(srcPtr: usize, srcSize: usize): void {
86
85
  store<u16>(bs.offset, QUOTE);
87
86
  bs.offset += 2;
88
87
  }
89
-
90
- // @ts-ignore: inline
91
- @inline function write_u_escape(code: u16): void {
88
+ function write_u_escape(code: u16): void {
92
89
  bs.growSize(10);
93
90
  store<u32>(bs.offset, U_MARKER); // "\u"
94
91
  store<u64>(bs.offset, u16_to_hex4_swar(code), 4);
@@ -3,8 +3,6 @@ import { BRACKET_LEFT, BRACKET_RIGHT, COMMA } from "../../custom/chars";
3
3
  import { serializeFloat32Unsafe, serializeFloat64Unsafe } from "./float";
4
4
  import { serializeIntegerUnsafe } from "./integer";
5
5
 
6
-
7
- @inline
8
6
  function maxIntegerBytes<T extends number>(): u32 {
9
7
  if (sizeof<T>() == 1) return isSigned<T>() ? 8 : 6;
10
8
  if (sizeof<T>() == 2) return isSigned<T>() ? 12 : 10;
@@ -12,8 +10,6 @@ function maxIntegerBytes<T extends number>(): u32 {
12
10
  return isSigned<T>() ? 42 : 40;
13
11
  }
14
12
 
15
-
16
- @inline
17
13
  function reserveTypedArray<T extends ArrayLike<number>>(len: i32): void {
18
14
  if (len <= 0) return;
19
15
  if (isFloat<valueof<T>>()) {
@@ -23,8 +19,6 @@ function reserveTypedArray<T extends ArrayLike<number>>(len: i32): void {
23
19
  }
24
20
  }
25
21
 
26
-
27
- @inline
28
22
  function serializeTypedArrayElement<T extends ArrayLike<number>>(
29
23
  src: T,
30
24
  index: i32,
@@ -207,9 +207,7 @@ export function serializeString_SIMD(src: string): void {
207
207
  store<u16>(bs.offset, 34); // "
208
208
  bs.offset += 2;
209
209
  }
210
-
211
- // @ts-expect-error: @inline is a valid decorator
212
- @inline function write_u_escape(code: u16): void {
210
+ function write_u_escape(code: u16): void {
213
211
  bs.growSize(10);
214
212
  store<u32>(bs.offset, U_MARKER); // "\u"
215
213
  store<u64>(bs.offset, u16_to_hex4_swar(code), 4);
@@ -174,8 +174,7 @@ export function serializeString_SWAR(src: string): void {
174
174
  bs.offset += 2;
175
175
  }
176
176
 
177
- // @ts-expect-error: @inline is a valid decorator
178
- @inline function write_u_escape(code: u16): void {
177
+ function write_u_escape(code: u16): void {
179
178
  bs.growSize(10);
180
179
  store<u32>(bs.offset, U_MARKER); // "\u"
181
180
  store<u64>(bs.offset, u16_to_hex4_swar(code), 4);
@@ -18,11 +18,7 @@ import {
18
18
  * @param srcEnd Pointer just past the last code unit.
19
19
  * @returns The parsed value, truncated to `T`.
20
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 {
21
+ export function atou<T extends number>(srcStart: usize, srcEnd: usize): T {
26
22
  return deserializeUnsigned_SWAR<T>(srcStart, srcEnd);
27
23
  }
28
24
 
@@ -34,11 +30,7 @@ import {
34
30
  * @param srcEnd Pointer just past the last code unit.
35
31
  * @returns The parsed value, truncated to `T`.
36
32
  */
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 {
33
+ export function atoi<T extends number>(srcStart: usize, srcEnd: usize): T {
42
34
  return deserializeInteger_SWAR<T>(srcStart, srcEnd);
43
35
  }
44
36
 
@@ -52,8 +44,7 @@ import {
52
44
  * @param dstPtr Destination pointer for the parsed value.
53
45
  * @returns The source position immediately after the last digit consumed.
54
46
  */
55
- // @ts-expect-error: @inline is a valid decorator
56
- @inline export function atouScan<T extends number>(
47
+ export function atouScan<T extends number>(
57
48
  srcStart: usize,
58
49
  srcEnd: usize,
59
50
  dstPtr: usize,
@@ -71,8 +62,7 @@ import {
71
62
  * @param dstPtr Destination pointer for the parsed value.
72
63
  * @returns The source position immediately after the last digit consumed.
73
64
  */
74
- // @ts-expect-error: @inline is a valid decorator
75
- @inline export function atoiScan<T extends number>(
65
+ export function atoiScan<T extends number>(
76
66
  srcStart: usize,
77
67
  srcEnd: usize,
78
68
  dstPtr: usize,
@@ -1,7 +1,6 @@
1
1
  import { OBJECT, TOTAL_OVERHEAD } from "rt/common";
2
2
 
3
- // @ts-ignore: Decorator valid here
4
- @inline export function bytes<T>(o: T): i32 {
3
+ export function bytes<T>(o: T): i32 {
5
4
  if (isInteger<T>() || isFloat<T>()) {
6
5
  return sizeof<T>();
7
6
  } else if (isManaged<T>() || isReference<T>()) {
@@ -1,6 +1,5 @@
1
1
  import { OBJECT, TOTAL_OVERHEAD } from "rt/common";
2
2
 
3
- // @ts-ignore: decorator
4
- @inline export function idofD<T>(value: T): usize {
3
+ export function idofD<T>(value: T): usize {
5
4
  return changetype<OBJECT>(changetype<usize>(value) - TOTAL_OVERHEAD).rtId;
6
5
  }
@@ -1,4 +1,3 @@
1
- // @ts-ignore
2
- @inline export function isSpace(code: u16): boolean {
1
+ export function isSpace(code: u16): boolean {
3
2
  return code == 0x20 || code - 9 <= 4;
4
3
  }