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.
Files changed (54) hide show
  1. package/CHANGELOG.md +9 -26
  2. package/README.md +41 -18
  3. package/assembly/deserialize/index/arbitrary.ts +1 -1
  4. package/assembly/deserialize/index/array.ts +6 -1
  5. package/assembly/deserialize/index/float.ts +1 -1
  6. package/assembly/deserialize/index/integer.ts +1 -1
  7. package/assembly/deserialize/index/unsigned.ts +1 -1
  8. package/assembly/deserialize/simd/string.ts +17 -13
  9. package/assembly/deserialize/simple/arbitrary.ts +1 -1
  10. package/assembly/deserialize/simple/array/generic.ts +42 -0
  11. package/assembly/deserialize/simple/array.ts +8 -1
  12. package/assembly/deserialize/{float.ts → simple/float.ts} +22 -2
  13. package/assembly/deserialize/{integer.ts → simple/integer.ts} +3 -2
  14. package/assembly/deserialize/simple/map.ts +60 -12
  15. package/assembly/deserialize/simple/object.ts +1 -1
  16. package/assembly/deserialize/simple/set.ts +119 -134
  17. package/assembly/deserialize/simple/staticarray.ts +12 -1
  18. package/assembly/deserialize/simple/string.ts +15 -10
  19. package/assembly/deserialize/simple/struct.ts +7 -157
  20. package/assembly/deserialize/simple/typedarray.ts +1 -1
  21. package/assembly/deserialize/{unsigned.ts → simple/unsigned.ts} +3 -2
  22. package/assembly/deserialize/swar/array/array.ts +42 -7
  23. package/assembly/deserialize/swar/array/bool.ts +5 -2
  24. package/assembly/deserialize/swar/array/float.ts +7 -3
  25. package/assembly/deserialize/swar/array/generic.ts +40 -0
  26. package/assembly/deserialize/swar/array/integer.ts +7 -4
  27. package/assembly/deserialize/swar/array/object.ts +20 -4
  28. package/assembly/deserialize/swar/array/shared.ts +18 -4
  29. package/assembly/deserialize/swar/array/string.ts +5 -2
  30. package/assembly/deserialize/swar/array/struct.ts +20 -4
  31. package/assembly/deserialize/swar/array.ts +56 -2
  32. package/assembly/deserialize/swar/string.ts +249 -371
  33. package/assembly/index.ts +74 -17
  34. package/assembly/serialize/index/arbitrary.ts +3 -3
  35. package/assembly/serialize/index/float.ts +1 -1
  36. package/assembly/serialize/index/object.ts +1 -5
  37. package/assembly/serialize/simd/string.ts +4 -5
  38. package/assembly/serialize/simple/arbitrary.ts +3 -3
  39. package/assembly/serialize/simple/array.ts +17 -6
  40. package/assembly/serialize/simple/float.ts +18 -4
  41. package/assembly/serialize/simple/map.ts +10 -27
  42. package/assembly/serialize/simple/object.ts +1 -5
  43. package/assembly/serialize/simple/set.ts +3 -4
  44. package/assembly/serialize/simple/staticarray.ts +4 -3
  45. package/assembly/serialize/simple/typedarray.ts +9 -7
  46. package/assembly/serialize/swar/string.ts +0 -1
  47. package/assembly/tsconfig.json +3 -2
  48. package/assembly/util/dragonbox-cache.ts +1322 -0
  49. package/assembly/util/dragonbox.ts +596 -0
  50. package/lib/as-bs.ts +10 -7
  51. package/package.json +17 -10
  52. package/transform/lib/index.d.ts.map +1 -1
  53. package/transform/lib/index.js +408 -191
  54. package/transform/lib/index.js.map +1 -1
@@ -1,10 +1,9 @@
1
- import { deserializeFloatField } from "../../float";
1
+ import { deserializeFloatField } from "../../simple/float";
2
2
  import { BRACKET_LEFT, BRACKET_RIGHT, COMMA } from "../../../custom/chars";
3
3
  import { ensureArrayElementSlot, ensureArrayField } from "./shared";
4
4
 
5
5
 
6
- @inline export function deserializeFloatArrayField<T extends number[]>(srcStart: usize, srcEnd: usize, fieldPtr: usize): usize {
7
- const out = ensureArrayField<T>(fieldPtr);
6
+ @inline export function deserializeFloatArrayInto<T extends number[]>(srcStart: usize, srcEnd: usize, out: T): usize {
8
7
  let index = 0;
9
8
 
10
9
  do {
@@ -37,3 +36,8 @@ import { ensureArrayElementSlot, ensureArrayField } from "./shared";
37
36
 
38
37
  throw new Error("Failed to parse JSON!");
39
38
  }
39
+
40
+
41
+ @inline export function deserializeFloatArrayField<T extends number[]>(srcStart: usize, srcEnd: usize, fieldPtr: usize): usize {
42
+ return deserializeFloatArrayInto<T>(srcStart, srcEnd, ensureArrayField<T>(fieldPtr));
43
+ }
@@ -0,0 +1,40 @@
1
+ import { JSON } from "../../..";
2
+ import { BRACKET_LEFT, BRACKET_RIGHT, COMMA } from "../../../custom/chars";
3
+ import { ensureArrayElementSlot, ensureArrayField, scanValueEnd } from "./shared";
4
+
5
+ @inline export function deserializeGenericArrayInto<T extends unknown[]>(srcStart: usize, srcEnd: usize, out: T): usize {
6
+
7
+ if (srcStart >= srcEnd || load<u16>(srcStart) != BRACKET_LEFT) throw new Error("Failed to parse JSON!");
8
+ srcStart += 2;
9
+ if (srcStart >= srcEnd) throw new Error("Failed to parse JSON!");
10
+ if (load<u16>(srcStart) == BRACKET_RIGHT) return srcStart + 2;
11
+
12
+ let index = 0;
13
+
14
+ while (srcStart < srcEnd) {
15
+ const valueEnd = scanValueEnd(srcStart, srcEnd);
16
+ if (!valueEnd || valueEnd <= srcStart) break;
17
+
18
+ const slot = ensureArrayElementSlot<T>(out, index++);
19
+ store<valueof<T>>(slot, JSON.__deserialize<valueof<T>>(srcStart, valueEnd));
20
+ srcStart = valueEnd;
21
+
22
+ if (srcStart >= srcEnd) break;
23
+ const code = load<u16>(srcStart);
24
+ if (code == COMMA) {
25
+ srcStart += 2;
26
+ continue;
27
+ }
28
+ if (code == BRACKET_RIGHT) {
29
+ out.length = index;
30
+ return srcStart + 2;
31
+ }
32
+ break;
33
+ }
34
+
35
+ throw new Error("Failed to parse JSON!");
36
+ }
37
+
38
+ @inline export function deserializeGenericArrayField<T extends unknown[]>(srcStart: usize, srcEnd: usize, fieldPtr: usize): usize {
39
+ return deserializeGenericArrayInto<T>(srcStart, srcEnd, ensureArrayField<T>(fieldPtr));
40
+ }
@@ -1,5 +1,5 @@
1
- import { deserializeIntegerField } from "../../integer";
2
- import { deserializeUnsignedField } from "../../unsigned";
1
+ import { deserializeIntegerField } from "../../simple/integer";
2
+ import { deserializeUnsignedField } from "../../simple/unsigned";
3
3
  import { BRACKET_LEFT, BRACKET_RIGHT, COMMA } from "../../../custom/chars";
4
4
  import { isSpace } from "../../../util";
5
5
  import { ensureArrayElementSlot, ensureArrayField } from "./shared";
@@ -425,8 +425,7 @@ export function deserializeIntegerArray_SWAR<T extends number[]>(srcStart: usize
425
425
  }
426
426
 
427
427
 
428
- @inline export function deserializeIntegerArrayField<T extends number[]>(srcStart: usize, srcEnd: usize, fieldPtr: usize): usize {
429
- const out = ensureArrayField<T>(fieldPtr);
428
+ @inline export function deserializeIntegerArrayInto<T extends number[]>(srcStart: usize, srcEnd: usize, out: T): usize {
430
429
  let index = 0;
431
430
 
432
431
  do {
@@ -459,3 +458,7 @@ export function deserializeIntegerArray_SWAR<T extends number[]>(srcStart: usize
459
458
 
460
459
  throw new Error("Failed to parse JSON!");
461
460
  }
461
+
462
+ @inline export function deserializeIntegerArrayField<T extends number[]>(srcStart: usize, srcEnd: usize, fieldPtr: usize): usize {
463
+ return deserializeIntegerArrayInto<T>(srcStart, srcEnd, ensureArrayField<T>(fieldPtr));
464
+ }
@@ -2,8 +2,7 @@ import { BRACKET_LEFT, BRACKET_RIGHT, COMMA } from "../../../custom/chars";
2
2
  import { ensureArrayElementSlot, ensureArrayField } from "./shared";
3
3
 
4
4
 
5
- @inline export function deserializeObjectArrayField<T extends unknown[]>(srcStart: usize, srcEnd: usize, fieldPtr: usize): usize {
6
- const out = ensureArrayField<T>(fieldPtr);
5
+ @inline export function deserializeObjectArrayInto<T extends unknown[]>(srcStart: usize, srcEnd: usize, out: T): usize {
7
6
  let index = 0;
8
7
 
9
8
  do {
@@ -19,11 +18,24 @@ import { ensureArrayElementSlot, ensureArrayField } from "./shared";
19
18
  const slot = ensureArrayElementSlot<T>(out, index);
20
19
  let value = load<valueof<T>>(slot);
21
20
  if (changetype<usize>(value) == 0) {
22
- value = changetype<valueof<T>>(instantiate<nonnull<valueof<T>>>());
21
+ value = changetype<valueof<T>>(__new(offsetof<nonnull<valueof<T>>>(), idof<nonnull<valueof<T>>>()));
22
+ // @ts-ignore: supplied by transform
23
+ if (isDefined(changetype<nonnull<valueof<T>>>(value).__INITIALIZE)) {
24
+ // @ts-ignore: supplied by transform
25
+ changetype<nonnull<valueof<T>>>(value).__INITIALIZE();
26
+ }
23
27
  store<valueof<T>>(slot, value);
24
28
  }
25
29
 
26
- srcStart = changetype<nonnull<valueof<T>>>(value).__DESERIALIZE<valueof<T>>(srcStart, srcEnd, value);
30
+ const valueStart = srcStart;
31
+ // @ts-ignore: supplied by transform
32
+ if (isDefined(changetype<nonnull<valueof<T>>>(value).__DESERIALIZE_FAST)) {
33
+ // @ts-ignore: supplied by transform
34
+ srcStart = changetype<nonnull<valueof<T>>>(value).__DESERIALIZE_FAST<valueof<T>>(valueStart, srcEnd, value);
35
+ } else {
36
+ // @ts-ignore: supplied by transform
37
+ srcStart = changetype<nonnull<valueof<T>>>(value).__DESERIALIZE_SLOW<valueof<T>>(valueStart, srcEnd, value);
38
+ }
27
39
  if (!srcStart || srcStart >= srcEnd) break;
28
40
 
29
41
  const code = load<u16>(srcStart);
@@ -42,3 +54,7 @@ import { ensureArrayElementSlot, ensureArrayField } from "./shared";
42
54
 
43
55
  throw new Error("Failed to parse JSON!");
44
56
  }
57
+
58
+ @inline export function deserializeObjectArrayField<T extends unknown[]>(srcStart: usize, srcEnd: usize, fieldPtr: usize): usize {
59
+ return deserializeObjectArrayInto<T>(srcStart, srcEnd, ensureArrayField<T>(fieldPtr));
60
+ }
@@ -6,8 +6,15 @@ import { BACK_SLASH, BRACE_LEFT, BRACE_RIGHT, BRACKET_LEFT, BRACKET_RIGHT, COMMA
6
6
  if (!changetype<usize>(out)) {
7
7
  out = changetype<T>(instantiate<T>());
8
8
  store<T>(fieldPtr, out);
9
- } else {
10
- out.length = 0;
9
+ }
10
+ return out;
11
+ }
12
+
13
+ @inline export function ensureArrayFieldAt<T extends Array<any>>(dstObj: usize, dstOffset: usize): T {
14
+ let out = load<T>(dstObj, dstOffset);
15
+ if (!changetype<usize>(out)) {
16
+ out = changetype<T>(instantiate<T>());
17
+ store<T>(dstObj, out, dstOffset);
11
18
  }
12
19
  return out;
13
20
  }
@@ -22,7 +29,14 @@ import { BACK_SLASH, BRACE_LEFT, BRACE_RIGHT, BRACKET_LEFT, BRACKET_RIGHT, COMMA
22
29
 
23
30
  @inline export function ensureArrayElementSlot<T extends Array<any>>(out: T, index: i32): usize {
24
31
  const nextLength = index + 1;
25
- if (out.length < nextLength) out.length = nextLength;
32
+ if (out.length < nextLength) {
33
+ out.length = nextLength;
34
+ const slot = out.dataStart + <usize>index * sizeof<valueof<T>>();
35
+ // Reference arrays can allocate recursively before the caller stores the new element.
36
+ // Zero the newly exposed slot immediately so incremental GC never observes a garbage pointer.
37
+ if (isManaged<valueof<T>>() || isReference<valueof<T>>()) store<usize>(slot, 0);
38
+ return slot;
39
+ }
26
40
  return out.dataStart + <usize>index * sizeof<valueof<T>>();
27
41
  }
28
42
 
@@ -88,7 +102,7 @@ import { BACK_SLASH, BRACE_LEFT, BRACE_RIGHT, BRACKET_LEFT, BRACKET_RIGHT, COMMA
88
102
 
89
103
  while (srcStart < srcEnd) {
90
104
  const code = load<u16>(srcStart);
91
- if (code == COMMA || code == BRACKET_RIGHT) return srcStart;
105
+ if (code == COMMA || code == BRACKET_RIGHT || code == BRACE_RIGHT) return srcStart;
92
106
  srcStart += 2;
93
107
  }
94
108
 
@@ -3,8 +3,7 @@ import { ensureArrayElementSlot, ensureArrayField } from "./shared";
3
3
  import { deserializeStringField_SWAR } from "../string";
4
4
 
5
5
 
6
- @inline export function deserializeStringArrayField<T extends string[]>(srcStart: usize, srcEnd: usize, fieldPtr: usize): usize {
7
- const out = ensureArrayField<T>(fieldPtr);
6
+ @inline export function deserializeStringArrayInto<T extends string[]>(srcStart: usize, srcEnd: usize, out: T): usize {
8
7
  let index = 0;
9
8
 
10
9
  do {
@@ -37,3 +36,7 @@ import { deserializeStringField_SWAR } from "../string";
37
36
 
38
37
  throw new Error("Failed to parse JSON!");
39
38
  }
39
+
40
+ @inline export function deserializeStringArrayField<T extends string[]>(srcStart: usize, srcEnd: usize, fieldPtr: usize): usize {
41
+ return deserializeStringArrayInto<T>(srcStart, srcEnd, ensureArrayField<T>(fieldPtr));
42
+ }
@@ -2,8 +2,7 @@ import { BRACKET_LEFT, BRACKET_RIGHT, COMMA } from "../../../custom/chars";
2
2
  import { ensureArrayElementSlot, ensureArrayField } from "./shared";
3
3
 
4
4
 
5
- @inline export function deserializeStructArrayField<T extends unknown[]>(srcStart: usize, srcEnd: usize, fieldPtr: usize): usize {
6
- const out = ensureArrayField<T>(fieldPtr);
5
+ @inline export function deserializeStructArrayInto<T extends unknown[]>(srcStart: usize, srcEnd: usize, out: T): usize {
7
6
  let index = 0;
8
7
 
9
8
  do {
@@ -19,11 +18,24 @@ import { ensureArrayElementSlot, ensureArrayField } from "./shared";
19
18
  const slot = ensureArrayElementSlot<T>(out, index);
20
19
  let value = load<valueof<T>>(slot);
21
20
  if (changetype<usize>(value) == 0) {
22
- value = changetype<valueof<T>>(instantiate<nonnull<valueof<T>>>());
21
+ value = changetype<valueof<T>>(__new(offsetof<nonnull<valueof<T>>>(), idof<nonnull<valueof<T>>>()));
22
+ // @ts-ignore: supplied by transform
23
+ if (isDefined(changetype<nonnull<valueof<T>>>(value).__INITIALIZE)) {
24
+ // @ts-ignore: supplied by transform
25
+ changetype<nonnull<valueof<T>>>(value).__INITIALIZE();
26
+ }
23
27
  store<valueof<T>>(slot, value);
24
28
  }
25
29
 
26
- srcStart = changetype<nonnull<valueof<T>>>(value).__DESERIALIZE<valueof<T>>(srcStart, srcEnd, value);
30
+ const valueStart = srcStart;
31
+ // @ts-ignore: supplied by transform
32
+ if (isDefined(changetype<nonnull<valueof<T>>>(value).__DESERIALIZE_FAST)) {
33
+ // @ts-ignore: supplied by transform
34
+ srcStart = changetype<nonnull<valueof<T>>>(value).__DESERIALIZE_FAST<valueof<T>>(valueStart, srcEnd, value);
35
+ } else {
36
+ // @ts-ignore: supplied by transform
37
+ srcStart = changetype<nonnull<valueof<T>>>(value).__DESERIALIZE_SLOW<valueof<T>>(valueStart, srcEnd, value);
38
+ }
27
39
  if (!srcStart || srcStart >= srcEnd) break;
28
40
 
29
41
  const code = load<u16>(srcStart);
@@ -42,3 +54,7 @@ import { ensureArrayElementSlot, ensureArrayField } from "./shared";
42
54
 
43
55
  throw new Error("Failed to parse JSON!");
44
56
  }
57
+
58
+ @inline export function deserializeStructArrayField<T extends unknown[]>(srcStart: usize, srcEnd: usize, fieldPtr: usize): usize {
59
+ return deserializeStructArrayInto<T>(srcStart, srcEnd, ensureArrayField<T>(fieldPtr));
60
+ }
@@ -4,15 +4,25 @@ import { deserializeArrayArrayField } from "./array/array";
4
4
  import { deserializeBooleanArrayField } from "./array/bool";
5
5
  import { deserializeBoxArrayField } from "./array/box";
6
6
  import { deserializeFloatArrayField } from "./array/float";
7
+ import { deserializeGenericArrayField } from "./array/generic";
7
8
  import { deserializeIntegerArrayField } from "./array/integer";
8
9
  import { deserializeMapArrayField } from "./array/map";
9
10
  import { deserializeObjectArrayField } from "./array/object";
10
11
  import { deserializeRawArrayField } from "./array/raw";
11
12
  import { deserializeStringArrayField } from "./array/string";
12
13
  import { deserializeStructArrayField } from "./array/struct";
14
+ import { deserializeArrayArrayInto } from "./array/array";
15
+ import { deserializeBooleanArrayInto } from "./array/bool";
16
+ import { deserializeFloatArrayInto } from "./array/float";
17
+ import { deserializeGenericArrayInto } from "./array/generic";
18
+ import { deserializeIntegerArrayInto } from "./array/integer";
19
+ import { deserializeObjectArrayInto } from "./array/object";
20
+ import { deserializeStringArrayInto } from "./array/string";
21
+ import { deserializeStructArrayInto } from "./array/struct";
13
22
 
14
23
 
15
- @inline export function deserializeArrayField<T extends unknown[]>(srcStart: usize, srcEnd: usize, fieldPtr: usize): usize {
24
+ @inline export function deserializeArrayField<T extends unknown[]>(srcStart: usize, srcEnd: usize, dstObj: usize, dstOffset: usize = 0): usize {
25
+ const fieldPtr = dstObj + dstOffset;
16
26
  if (isString<valueof<T>>()) {
17
27
  return deserializeStringArrayField<T>(srcStart, srcEnd, fieldPtr);
18
28
  } else if (isBoolean<valueof<T>>()) {
@@ -33,13 +43,17 @@ import { deserializeStructArrayField } from "./array/struct";
33
43
  return deserializeObjectArrayField<T>(srcStart, srcEnd, fieldPtr);
34
44
  } else if (type instanceof JSON.Raw) {
35
45
  return deserializeRawArrayField(srcStart, srcEnd, fieldPtr);
46
+ } else if (type instanceof Date) {
47
+ return deserializeGenericArrayField<T>(srcStart, srcEnd, fieldPtr);
48
+ } else if (type instanceof Set) {
49
+ return deserializeGenericArrayField<T>(srcStart, srcEnd, fieldPtr);
36
50
  } else if (type instanceof Map) {
37
51
  return deserializeMapArrayField<T>(srcStart, srcEnd, fieldPtr);
38
52
  // @ts-ignore: defined by transform
39
53
  } else if (isDefined(type.__DESERIALIZE_CUSTOM)) {
40
54
  return deserializeStructArrayField<T>(srcStart, srcEnd, fieldPtr);
41
55
  // @ts-ignore: defined by transform
42
- } else if (isDefined(type.__DESERIALIZE)) {
56
+ } else if (isDefined(type.__DESERIALIZE_SLOW) || isDefined(type.__DESERIALIZE_FAST)) {
43
57
  return deserializeStructArrayField<T>(srcStart, srcEnd, fieldPtr);
44
58
  }
45
59
  throw new Error("Could not parse array field of type " + nameof<T>() + "!");
@@ -47,3 +61,43 @@ import { deserializeStructArrayField } from "./array/struct";
47
61
  throw new Error("Could not parse array field of type " + nameof<T>() + "!");
48
62
  }
49
63
  }
64
+
65
+ @inline export function deserializeArrayInto_SWAR<T extends unknown[]>(srcStart: usize, srcEnd: usize, out: T): usize {
66
+ if (isString<valueof<T>>()) {
67
+ return deserializeStringArrayInto<T>(srcStart, srcEnd, out);
68
+ } else if (isBoolean<valueof<T>>()) {
69
+ return deserializeBooleanArrayInto<T>(srcStart, srcEnd, out);
70
+ } else if (isInteger<valueof<T>>()) {
71
+ return deserializeIntegerArrayInto<T>(srcStart, srcEnd, out);
72
+ } else if (isFloat<valueof<T>>()) {
73
+ return deserializeFloatArrayInto<T>(srcStart, srcEnd, out);
74
+ } else if (isArray<valueof<T>>()) {
75
+ return deserializeArrayArrayInto<T>(srcStart, srcEnd, out);
76
+ } else if (isManaged<valueof<T>>() || isReference<valueof<T>>()) {
77
+ const type = changetype<nonnull<valueof<T>>>(0);
78
+ if (type instanceof JSON.Value) {
79
+ return deserializeGenericArrayInto<T>(srcStart, srcEnd, out);
80
+ } else if (type instanceof JSON.Box) {
81
+ throw new Error("Failed to parse JSON!");
82
+ } else if (type instanceof JSON.Obj) {
83
+ return deserializeObjectArrayInto<T>(srcStart, srcEnd, out);
84
+ } else if (type instanceof JSON.Raw) {
85
+ throw new Error("Failed to parse JSON!");
86
+ } else if (type instanceof Date) {
87
+ return deserializeGenericArrayInto<T>(srcStart, srcEnd, out);
88
+ } else if (type instanceof Set) {
89
+ return deserializeGenericArrayInto<T>(srcStart, srcEnd, out);
90
+ } else if (type instanceof Map) {
91
+ throw new Error("Failed to parse JSON!");
92
+ // @ts-ignore: defined by transform
93
+ } else if (isDefined(type.__DESERIALIZE_CUSTOM)) {
94
+ return deserializeStructArrayInto<T>(srcStart, srcEnd, out);
95
+ // @ts-ignore: defined by transform
96
+ } else if (isDefined(type.__DESERIALIZE_SLOW) || isDefined(type.__DESERIALIZE_FAST)) {
97
+ return deserializeStructArrayInto<T>(srcStart, srcEnd, out);
98
+ }
99
+ throw new Error("Could not parse array field of type " + nameof<T>() + "!");
100
+ } else {
101
+ throw new Error("Could not parse array field of type " + nameof<T>() + "!");
102
+ }
103
+ }