json-as 1.1.26 → 1.1.27

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 (51) hide show
  1. package/.github/workflows/benchmark.yml +64 -0
  2. package/.prettierrc.json +1 -0
  3. package/README.md +40 -63
  4. package/assembly/__benches__/abc.bench.ts +5 -9
  5. package/assembly/__benches__/large.bench.ts +114 -120
  6. package/assembly/__benches__/lib/bench.ts +44 -1
  7. package/assembly/__benches__/medium.bench.ts +108 -29
  8. package/assembly/__benches__/small.bench.ts +28 -18
  9. package/assembly/__benches__/throughput.ts +172 -0
  10. package/assembly/__benches__/vec3.bench.ts +8 -3
  11. package/assembly/__tests__/string.spec.ts +4 -0
  12. package/assembly/deserialize/simple/arbitrary.ts +5 -2
  13. package/assembly/deserialize/simple/object.ts +3 -1
  14. package/assembly/deserialize/swar/string.ts +62 -62
  15. package/assembly/index.ts +6 -2
  16. package/assembly/serialize/swar/number.ts +0 -0
  17. package/assembly/serialize/swar/string.ts +72 -70
  18. package/assembly/test.tmp.ts +5 -9
  19. package/assembly/test.ts +3 -6
  20. package/bench/abc.bench.ts +6 -8
  21. package/bench/large.bench.ts +119 -118
  22. package/bench/lib/bench.d.ts +27 -0
  23. package/bench/lib/bench.js +53 -0
  24. package/bench/lib/chart.ts +217 -0
  25. package/bench/medium.bench.ts +55 -30
  26. package/bench/runners/assemblyscript.js +6 -1
  27. package/bench/small.bench.ts +7 -3
  28. package/bench/throughput.ts +87 -0
  29. package/bench/tsconfig.json +3 -2
  30. package/bench/vec3.bench.ts +7 -3
  31. package/ci/bench/runners/assemblyscript.js +29 -0
  32. package/ci/run-bench.as.sh +63 -0
  33. package/data/chart01.svg +258 -0
  34. package/data/chart02.svg +246 -0
  35. package/data/chart03.svg +193 -0
  36. package/data/chart05.svg +142 -0
  37. package/dump.txt +41590 -0
  38. package/package.json +4 -2
  39. package/run-bench.as.sh +21 -13
  40. package/run-bench.js.sh +9 -7
  41. package/run-tests.sh +34 -14
  42. package/scripts/build-chart01.ts +38 -0
  43. package/scripts/build-chart02.ts +38 -0
  44. package/scripts/build-chart03.ts +139 -0
  45. package/scripts/build-chart05.ts +47 -0
  46. package/scripts/generate-as-class.ts +50 -0
  47. package/scripts/lib/bench-utils.ts +308 -0
  48. package/transform/lib/index.js +2 -2
  49. package/transform/lib/index.js.map +1 -1
  50. package/transform/src/index.ts +2 -2
  51. /package/{bench → ci/bench}/lib/bench.ts +0 -0
@@ -1,3 +1,4 @@
1
+ import { bs } from "../../../lib/as-bs";
1
2
  import { BACK_SLASH } from "../../custom/chars";
2
3
  import { DESERIALIZE_ESCAPE_TABLE, ESCAPE_HEX_TABLE } from "../../globals/tables";
3
4
 
@@ -23,68 +24,69 @@ import { DESERIALIZE_ESCAPE_TABLE, ESCAPE_HEX_TABLE } from "../../globals/tables
23
24
  * @returns number of bytes written
24
25
  */
25
26
  // todo: optimize and stuff. it works, its not pretty. ideally, i'd like this to be (nearly) branchless
26
- export function deserializeString_SWAR(srcStart: usize, srcEnd: usize, dst: usize): usize {
27
+ export function deserializeString_SWAR(srcStart: usize, srcEnd: usize): void {
27
28
  srcStart += 2;
28
29
  srcEnd -= 2;
29
- let dst_ptr = changetype<usize>(dst);
30
- const src_end_15 = srcEnd - 15;
30
+ bs.proposeSize(u32(srcEnd - srcStart));
31
31
 
32
- while (srcStart < src_end_15) {
33
- const block = v128.load(srcStart);
34
- v128.store(dst_ptr, block);
32
+ // const src_end_15 = srcEnd - 15;
33
+ // while (srcStart < src_end_15) {
34
+ // const block = load<u64>(srcStart);
35
+ // store<u64>(dst_ptr, block);
35
36
 
36
- const backslash_indices = i16x8.eq(block, SPLAT_92);
37
- let mask = i16x8.bitmask(backslash_indices);
37
+ // let mask = v64x4_eq(block, BACKSLASH_MASK);
38
38
 
39
- while (mask != 0) {
40
- const lane_index = ctz(mask) << 1;
41
- const dst_offset = dst_ptr + lane_index;
42
- const src_offset = srcStart + lane_index;
43
- const code = load<u16>(src_offset, 2);
39
+ // while (mask != 0) {
40
+ // const lane_index = usize(ctz(mask) >> 3);
41
+ // const dst_offset = dst_ptr + lane_index;
42
+ // const src_offset = srcStart + lane_index;
43
+ // const code = load<u16>(src_offset, 2);
44
44
 
45
- mask &= mask - 1;
46
- if (code == 117 && load<u32>(src_offset, 4) == 3145776) {
47
- const block = load<u32>(src_offset, 8);
48
- const codeA = block & 0xffff;
49
- const codeB = (block >> 16) & 0xffff;
50
- const escapedA = load<u8>(ESCAPE_HEX_TABLE + codeA);
51
- const escapedB = load<u8>(ESCAPE_HEX_TABLE + codeB);
52
- const escaped = (escapedA << 4) + escapedB;
53
- // console.log("Escaped:");
54
- // console.log(" a: " + escapedA.toString())
55
- // console.log(" b: " + escapedB.toString());
56
- // console.log(" c: " + escaped.toString());
57
- // console.log(" o: " + (dst_ptr - dst).toString());
58
- // console.log(" d: " + (dst_offset - dst).toString())
59
- // console.log(" l: " + (lane_index).toString())
60
- store<u16>(dst_offset, escaped);
61
- v128.store(dst_offset, v128.load(src_offset, 4), 2);
62
- if (lane_index >= 6) {
63
- const bytes_left = lane_index - 4;
64
- srcStart += bytes_left;
65
- dst_ptr += bytes_left;
66
- // console.log(" e: " + (bytes_left).toString())
67
- }
68
- dst_ptr -= 10;
69
- } else {
70
- const escaped = load<u8>(DESERIALIZE_ESCAPE_TABLE + code);
71
- store<u16>(dst_offset, escaped);
72
- v128.store(dst_offset, v128.load(src_offset, 4), 2);
73
- // console.log("Escaped:");
74
- if (lane_index == 14) {
75
- srcStart += 2;
76
- } else {
77
- dst_ptr -= 2;
78
- }
79
- }
80
- }
45
+ // mask &= mask - 1;
46
+ // if (code == 117 && load<u32>(src_offset, 4) == 3145776) {
47
+ // const block = load<u32>(src_offset, 8);
48
+ // const codeA = block & 0xffff;
49
+ // const codeB = (block >> 16) & 0xffff;
50
+ // const escapedA = load<u8>(ESCAPE_HEX_TABLE + codeA);
51
+ // const escapedB = load<u8>(ESCAPE_HEX_TABLE + codeB);
52
+ // const escaped = (escapedA << 4) + escapedB;
53
+ // // console.log("Escaped:");
54
+ // // console.log(" a: " + escapedA.toString())
55
+ // // console.log(" b: " + escapedB.toString());
56
+ // // console.log(" c: " + escaped.toString());
57
+ // // console.log(" o: " + (dst_ptr - dst).toString());
58
+ // // console.log(" d: " + (dst_offset - dst).toString())
59
+ // // console.log(" l: " + (lane_index).toString())
60
+ // store<u16>(dst_offset, escaped);
61
+ // memory.copy(dst_offset + 2, src_offset + 4, (4 - lane_index) << 1);
62
+ // // v128.store(dst_offset, v128.load(src_offset, 4), 2);
63
+ // if (lane_index >= 6) {
64
+ // const bytes_left = lane_index - 4;
65
+ // srcStart += bytes_left;
66
+ // dst_ptr += bytes_left;
67
+ // // console.log(" e: " + (bytes_left).toString())
68
+ // }
69
+ // dst_ptr -= 10;
70
+ // } else {
71
+ // const escaped = load<u8>(DESERIALIZE_ESCAPE_TABLE + code);
72
+ // store<u16>(dst_offset, escaped);
73
+ // memory.copy(dst_offset + 2, src_offset + 4, (4 - lane_index) << 1);
74
+ // // v128.store(dst_offset, v128.load(src_offset, 4), 2);
75
+ // // console.log("Escaped:");
76
+ // if (lane_index == 14) {
77
+ // srcStart += 2;
78
+ // } else {
79
+ // dst_ptr -= 2;
80
+ // }
81
+ // }
82
+ // }
81
83
 
82
- srcStart += 16;
83
- dst_ptr += 16;
84
+ // srcStart += 16;
85
+ // dst_ptr += 16;
84
86
 
85
- // console.log("src: " + (srcStart - changetype<usize>(src)).toString());
86
- // console.log("dst: " + (dst_ptr - dst).toString());
87
- }
87
+ // // console.log("src: " + (srcStart - changetype<usize>(src)).toString());
88
+ // // console.log("dst: " + (dst_ptr - dst).toString());
89
+ // }
88
90
  while (srcStart < srcEnd) {
89
91
  let code = load<u16>(srcStart);
90
92
  if (code == BACK_SLASH) {
@@ -96,22 +98,20 @@ export function deserializeString_SWAR(srcStart: usize, srcEnd: usize, dst: usiz
96
98
  const escapedA = load<u8>(ESCAPE_HEX_TABLE + codeA);
97
99
  const escapedB = load<u8>(ESCAPE_HEX_TABLE + codeB);
98
100
  const escaped = (escapedA << 4) + escapedB;
99
- store<u16>(dst_ptr, escaped);
100
- dst_ptr += 2;
101
+ store<u16>(bs.offset, escaped);
102
+ bs.offset += 2;
101
103
  srcStart += 12;
102
104
  } else {
103
- store<u16>(dst_ptr, code);
104
- dst_ptr += 2;
105
+ store<u16>(bs.offset, code);
106
+ bs.offset += 2;
105
107
  srcStart += 4;
106
108
  }
107
109
  } else {
108
- store<u16>(dst_ptr, code);
109
- dst_ptr += 2;
110
+ store<u16>(bs.offset, code);
111
+ bs.offset += 2;
110
112
  srcStart += 2;
111
113
  }
112
114
  }
113
-
114
- return dst_ptr - dst;
115
115
  }
116
116
 
117
117
  // @ts-ignore: decorators allowed
package/assembly/index.ts CHANGED
@@ -11,7 +11,7 @@ import { deserializeFloat } from "./deserialize/simple/float";
11
11
  import { deserializeMap } from "./deserialize/simple/map";
12
12
  import { deserializeDate } from "./deserialize/simple/date";
13
13
  import { deserializeInteger } from "./deserialize/simple/integer";
14
- import { deserializeString } from "./deserialize/simple/string";
14
+ // import { deserializeString } from "./deserialize/simple/string";
15
15
  import { serializeArbitrary } from "./serialize/simple/arbitrary";
16
16
 
17
17
  import { NULL_WORD, QUOTE } from "./custom/chars";
@@ -29,6 +29,8 @@ import { serializeRaw } from "./serialize/simple/raw";
29
29
  import { deserializeRaw } from "./deserialize/simple/raw";
30
30
  import { serializeString_SIMD } from "./serialize/simd/string";
31
31
  import { serializeString_SWAR } from "./serialize/swar/string";
32
+ import { deserializeString_SWAR } from "./deserialize/swar/string";
33
+ import { deserializeString } from "./deserialize/simple/string";
32
34
  // import { deserializeString_SIMD } from "./deserialize/simd/string";
33
35
 
34
36
  /**
@@ -185,8 +187,9 @@ export namespace JSON {
185
187
  // // @ts-ignore
186
188
  // return changetype<string>(deserializeString_SIMD(dataPtr, dataPtr + dataSize, __new(dataSize - 4, idof<string>())));
187
189
  // } else {
190
+
188
191
  // @ts-ignore
189
- return deserializeString(dataPtr, dataPtr + dataSize, __new(dataSize - 4, idof<string>()));
192
+ return deserializeString(dataPtr, dataPtr + dataSize, 0);
190
193
  // }
191
194
  } else if (isArray<T>()) {
192
195
  // @ts-ignore
@@ -605,6 +608,7 @@ export namespace JSON {
605
608
  return deserializeFloat<T>(srcStart, srcEnd);
606
609
  } else if (isString<T>()) {
607
610
  if (srcEnd - srcStart < 4) throw new Error("Cannot parse data as string because it was formatted incorrectly!");
611
+
608
612
  // @ts-ignore: type
609
613
  return deserializeString(srcStart, srcEnd, dst);
610
614
  } else if (isNullable<T>() && srcEnd - srcStart == 8 && load<u64>(srcStart) == 30399761348886638) {
File without changes
@@ -2,14 +2,17 @@ import { bs } from "../../../lib/as-bs";
2
2
  import { BACK_SLASH } from "../../custom/chars";
3
3
  import { SERIALIZE_ESCAPE_TABLE } from "../../globals/tables";
4
4
  import { bytes } from "../../util/bytes";
5
+ import { serializeString } from "../simple/string";
5
6
 
6
7
 
7
8
  // @ts-ignore: decorator allowed
8
9
  @lazy const LANE_MASK_HIGH = 0xFF00_FF00_FF00_FF00;
9
10
  // @ts-ignore: decorator allowed
11
+ @lazy const ONES: u64 = 0x0101010101010101;
12
+ // @ts-ignore: decorator allowed
10
13
  @lazy const LANE_MASK_LOW = 0x00FF_00FF_00FF_00FF;
11
14
  // @ts-ignore: decorator allowed
12
- @lazy const UINT64_H8 = 0x8080808080808080;
15
+ @lazy const HIGHS = 0x8080808080808080;
13
16
  // @ts-ignore: decorator allowed
14
17
  @lazy const QUOTE_MASK = 0x0022_0022_0022_0022;
15
18
  // @ts-ignore: decorator allowed
@@ -19,91 +22,90 @@ import { bytes } from "../../util/bytes";
19
22
  // @ts-ignore: decorator allowed
20
23
  @lazy const U00_MARKER = 13511005048209500;
21
24
 
22
- export function serializeString_SWAR(src: string): void {
23
- const srcSize = bytes(src);
24
- let srcStart = changetype<usize>(src);
25
- const srcEnd = srcStart + srcSize;
26
- const srcEnd8 = srcEnd - 8;
25
+ // @ts-ignore: decorator valid here
26
+ @inline export function serializeString_SWAR(src: string): void {
27
+ serializeString(src);
28
+
29
+ // const srcSize = bytes(src);
30
+ // let srcStart = changetype<usize>(src);
31
+ // const srcEnd = srcStart + srcSize;
32
+ // const srcEnd8 = srcEnd - 8;
27
33
 
28
- bs.proposeSize(srcSize + 4);
29
- store<u16>(bs.offset, 34); // "
30
- bs.offset += 2;
34
+ // bs.proposeSize(srcSize + 4);
35
+ // store<u16>(bs.offset, 34); // "
36
+ // bs.offset += 2;
31
37
 
32
- while (srcStart <= srcEnd8) {
33
- const block = load<u64>(srcStart);
34
- store<u64>(bs.offset, block);
38
+ // while (srcStart <= srcEnd8) {
39
+ // const block = load<u64>(srcStart);
40
+ // store<u64>(bs.offset, block);
35
41
 
36
- let mask = (
37
- v64x4_eq(block, QUOTE_MASK) |
38
- v64x4_eq(block, BACKSLASH_MASK) |
39
- v64x4_ltu(block & LANE_MASK_LOW, CONTROL_MASK)
40
- ) & UINT64_H8
42
+ // let mask = (
43
+ // v64x4_eq(block, QUOTE_MASK) |
44
+ // v64x4_eq(block, BACKSLASH_MASK) |
45
+ // v64x4_ltu(block & LANE_MASK_LOW, CONTROL_MASK)
46
+ // ) & HIGHS
41
47
 
42
- while (mask != 0) {
43
- const lane_index = usize(ctz(mask) >> 3);
44
- // console.log("lane index " + lane_index.toString());
45
- const src_offset = srcStart + lane_index;
46
- const code = load<u16>(src_offset) << 2;
47
- const escaped = load<u32>(SERIALIZE_ESCAPE_TABLE + code);
48
+ // while (mask != 0) {
49
+ // const lane_index = usize(ctz(mask) >> 3);
50
+ // const src_offset = srcStart + lane_index;
51
+ // const dst_offset = bs.offset + lane_index;
52
+ // const code = load<u16>(src_offset) << 2;
53
+ // const escaped = load<u32>(SERIALIZE_ESCAPE_TABLE + code);
48
54
 
49
- if ((escaped & 0xffff) != BACK_SLASH) {
50
- bs.growSize(10);
51
- const dst_offset = bs.offset + lane_index;
52
- store<u64>(dst_offset, U00_MARKER);
53
- store<u32>(dst_offset, escaped, 8);
54
- // store<u64>(dst_offset, load<u64>(src_offset, 2), 12); // unsafe. can overflow here
55
- memory.copy(dst_offset + 12, src_offset + 2, (4 - lane_index) << 1);
56
- bs.offset += 10;
57
- } else {
58
- bs.growSize(2);
59
- const dst_offset = bs.offset + lane_index;
60
- store<u32>(dst_offset, escaped);
61
- // store<u64>(dst_offset, load<u64>(src_offset, 2), 4);
62
- memory.copy(dst_offset + 4, src_offset + 2, (4 - lane_index) << 1);
63
- bs.offset += 2;
64
- }
55
+ // if ((escaped & 0xffff) != BACK_SLASH) {
56
+ // bs.growSize(10);
57
+ // store<u64>(dst_offset, U00_MARKER);
58
+ // store<u32>(dst_offset, escaped, 8);
59
+ // // store<u64>(dst_offset, load<u64>(src_offset, 2), 12); // unsafe. can overflow here
60
+ // memory.copy(dst_offset + 12, src_offset + 2, (4 - lane_index) << 1);
61
+ // bs.offset += 10;
62
+ // } else {
63
+ // bs.growSize(2);
64
+ // store<u32>(dst_offset, escaped);
65
+ // // store<u64>(dst_offset, load<u64>(src_offset, 2), 4);
66
+ // memory.copy(dst_offset + 4, src_offset + 2, (4 - lane_index) << 1);
67
+ // bs.offset += 2;
68
+ // }
65
69
 
66
- mask &= mask - 1;
67
- }
70
+ // mask &= mask - 1;
71
+ // }
68
72
 
69
- srcStart += 8;
70
- bs.offset += 8;
71
- }
73
+ // srcStart += 8;
74
+ // bs.offset += 8;
75
+ // }
72
76
 
73
- while (srcStart <= srcEnd - 2) {
74
- const code = load<u16>(srcStart);
75
- if (code == 92 || code == 34 || code < 32) {
76
- const escaped = load<u32>(SERIALIZE_ESCAPE_TABLE + (code << 2));
77
- if ((escaped & 0xffff) != BACK_SLASH) {
78
- bs.growSize(10);
79
- store<u64>(bs.offset, U00_MARKER);
80
- store<u32>(bs.offset, escaped, 8);
81
- bs.offset += 12;
82
- } else {
83
- bs.growSize(2);
84
- store<u32>(bs.offset, escaped);
85
- bs.offset += 4;
86
- }
87
- } else {
88
- store<u16>(bs.offset, code);
89
- bs.offset += 2;
90
- }
91
- srcStart += 2;
92
- }
77
+ // while (srcStart <= srcEnd - 2) {
78
+ // const code = load<u16>(srcStart);
79
+ // if (code == 92 || code == 34 || code < 32) {
80
+ // const escaped = load<u32>(SERIALIZE_ESCAPE_TABLE + (code << 2));
81
+ // if ((escaped & 0xffff) != BACK_SLASH) {
82
+ // bs.growSize(10);
83
+ // store<u64>(bs.offset, U00_MARKER);
84
+ // store<u32>(bs.offset, escaped, 8);
85
+ // bs.offset += 12;
86
+ // } else {
87
+ // bs.growSize(2);
88
+ // store<u32>(bs.offset, escaped);
89
+ // bs.offset += 4;
90
+ // }
91
+ // } else {
92
+ // store<u16>(bs.offset, code);
93
+ // bs.offset += 2;
94
+ // }
95
+ // srcStart += 2;
96
+ // }
93
97
 
94
- store<u16>(bs.offset, 34); // "
95
- bs.offset += 2;
98
+ // store<u16>(bs.offset, 34); // "
99
+ // bs.offset += 2;
96
100
  }
97
101
 
98
102
  // @ts-ignore: decorators allowed
99
103
  @inline function v64x4_eq(x: u64, y: u64): u64 {
100
104
  const xored = (x ^ LANE_MASK_HIGH) ^ y;
101
- const mask = (((xored >> 1) | UINT64_H8) - xored) & UINT64_H8;
105
+ const mask = (((xored >> 1) | HIGHS) - xored) & HIGHS;
102
106
  return (mask << 1) - (mask >> 7);
103
107
  }
104
-
105
108
  // @ts-ignore: decorators allowed
106
109
  @inline function v64x4_ltu(a: u64, b: u64): u64 {
107
- // Vigna's algorithm - fastest SWAR unsigned less-than
108
- return (((a | UINT64_H8) - (b & ~UINT64_H8)) | (a ^ b)) ^ (a | ~b);
110
+ return (((a | HIGHS) - (b & ~HIGHS)) | (a ^ b)) ^ (a | ~b);
109
111
  }
@@ -1,11 +1,7 @@
1
1
  import {
2
- bs
3
- } from "../lib/as-bs";
2
+ JSON
3
+ } from ".";
4
4
  import {
5
- serializeString_SIMD
6
- } from "./serialize/simd/string";
7
- import {
8
- serializeString_SWAR
9
- } from "./serialize/swar/string";
10
- serializeString_SWAR("a\"cd");
11
- console.log(bs.out<string>());
5
+ expect
6
+ } from "./__tests__/lib";
7
+ expect(JSON.stringify(JSON.parse<string>(JSON.stringify("abcdYZ12345890sdfw\"vie91kfESDFOK12i9i12dsf./?")))).toBe("\"abcdYZ12345890sdfw\b\"vie91kfESDFOK12i9i12dsf./?\"");
package/assembly/test.ts CHANGED
@@ -1,7 +1,4 @@
1
- import { bs } from "../lib/as-bs";
2
- import { serializeString_SIMD } from "./serialize/simd/string";
3
- import { serializeString_SWAR } from "./serialize/swar/string";
1
+ import { JSON } from ".";
2
+ import { expect } from "./__tests__/lib";
4
3
 
5
- serializeString_SWAR("a\"cd");
6
- // serializeString_SIMD("a\0b\"\nd");
7
- console.log(bs.out<string>());
4
+ expect(JSON.stringify(JSON.parse<string>(JSON.stringify("abcdYZ12345890sdfw\"vie91kfESDFOK12i9i12dsf./?")))).toBe('"abcdYZ12345890sdfw\\"vie91kfESDFOK12i9i12dsf./?"')
@@ -1,4 +1,5 @@
1
- import { bench } from "./lib/bench.js";
1
+ import { dumpToFile } from "./lib/bench.js";
2
+ import { bench, blackbox } from "./lib/bench.js";
2
3
 
3
4
  const v1 = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
4
5
  const v2 = '"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"';
@@ -6,22 +7,19 @@ const v2 = '"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"';
6
7
  bench(
7
8
  "Serialize Alphabet",
8
9
  () => {
9
- blackbox(JSON.stringify(blackbox(v1)));
10
+ blackbox(JSON.stringify(v1));
10
11
  },
11
12
  64_000_00,
12
13
  v1.length << 1,
13
14
  );
15
+ dumpToFile("abc", "serialize")
14
16
 
15
17
  bench(
16
18
  "Deserialize Alphabet",
17
19
  () => {
18
- blackbox(JSON.parse(blackbox(v2)));
20
+ blackbox(JSON.parse(v2));
19
21
  },
20
22
  64_000_00,
21
23
  v2.length << 1,
22
24
  );
23
-
24
- function blackbox<T>(value: T): T {
25
- (globalThis as any).__blackhole = value;
26
- return globalThis.__blackhole;
27
- }
25
+ dumpToFile("abc", "deserialize")