json-as 1.2.6 → 1.3.1

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 (135) hide show
  1. package/CHANGELOG.md +417 -0
  2. package/README.md +135 -36
  3. package/assembly/custom/util.ts +24 -70
  4. package/assembly/deserialize/float.ts +181 -0
  5. package/assembly/deserialize/helpers/uint.ts +12 -0
  6. package/assembly/deserialize/index/arbitrary.ts +25 -0
  7. package/assembly/deserialize/index/array.ts +61 -0
  8. package/assembly/deserialize/index/bool.ts +1 -0
  9. package/assembly/deserialize/index/date.ts +1 -0
  10. package/assembly/deserialize/index/float.ts +1 -0
  11. package/assembly/deserialize/index/integer.ts +1 -0
  12. package/assembly/deserialize/index/map.ts +1 -0
  13. package/assembly/deserialize/index/object.ts +1 -0
  14. package/assembly/deserialize/index/raw.ts +1 -0
  15. package/assembly/deserialize/index/set.ts +1 -0
  16. package/assembly/deserialize/index/staticarray.ts +1 -0
  17. package/assembly/deserialize/index/string.ts +15 -0
  18. package/assembly/deserialize/index/struct.ts +1 -0
  19. package/assembly/deserialize/index/typedarray.ts +15 -0
  20. package/assembly/deserialize/index/unsigned.ts +1 -0
  21. package/assembly/deserialize/index.ts +14 -0
  22. package/assembly/deserialize/integer.ts +42 -0
  23. package/assembly/deserialize/simd/array/integer.ts +307 -0
  24. package/assembly/deserialize/simd/string.ts +130 -11
  25. package/assembly/deserialize/simple/arbitrary.ts +5 -12
  26. package/assembly/deserialize/simple/array/arbitrary.ts +12 -36
  27. package/assembly/deserialize/simple/array/array.ts +2 -8
  28. package/assembly/deserialize/simple/array/bool.ts +2 -8
  29. package/assembly/deserialize/simple/array/box.ts +2 -8
  30. package/assembly/deserialize/simple/array/float.ts +2 -8
  31. package/assembly/deserialize/simple/array/integer.ts +2 -8
  32. package/assembly/deserialize/simple/array/map.ts +6 -26
  33. package/assembly/deserialize/simple/array/object.ts +6 -26
  34. package/assembly/deserialize/simple/array/raw.ts +18 -61
  35. package/assembly/deserialize/simple/array/string.ts +5 -10
  36. package/assembly/deserialize/simple/array/struct.ts +6 -26
  37. package/assembly/deserialize/simple/array.ts +2 -5
  38. package/assembly/deserialize/simple/bool.ts +2 -6
  39. package/assembly/deserialize/simple/map.ts +29 -102
  40. package/assembly/deserialize/simple/object.ts +24 -81
  41. package/assembly/deserialize/simple/raw.ts +1 -4
  42. package/assembly/deserialize/simple/set.ts +11 -37
  43. package/assembly/deserialize/simple/staticarray/array.ts +1 -1
  44. package/assembly/deserialize/simple/staticarray/bool.ts +1 -1
  45. package/assembly/deserialize/simple/staticarray/float.ts +1 -1
  46. package/assembly/deserialize/simple/staticarray/integer.ts +1 -1
  47. package/assembly/deserialize/simple/staticarray/string.ts +7 -14
  48. package/assembly/deserialize/simple/staticarray/struct.ts +1 -1
  49. package/assembly/deserialize/simple/staticarray.ts +57 -21
  50. package/assembly/deserialize/simple/string.ts +90 -10
  51. package/assembly/deserialize/simple/struct.ts +25 -121
  52. package/assembly/deserialize/simple/typedarray.ts +94 -0
  53. package/assembly/deserialize/swar/array/arbitrary.ts +8 -0
  54. package/assembly/deserialize/swar/array/array.ts +39 -0
  55. package/assembly/deserialize/swar/array/bool.ts +47 -0
  56. package/assembly/deserialize/swar/array/box.ts +8 -0
  57. package/assembly/deserialize/swar/array/float.ts +39 -0
  58. package/assembly/deserialize/swar/array/integer.ts +461 -0
  59. package/assembly/deserialize/swar/array/map.ts +7 -0
  60. package/assembly/deserialize/swar/array/object.ts +44 -0
  61. package/assembly/deserialize/swar/array/raw.ts +8 -0
  62. package/assembly/deserialize/swar/array/shared.ts +96 -0
  63. package/assembly/deserialize/swar/array/string.ts +39 -0
  64. package/assembly/deserialize/swar/array/struct.ts +44 -0
  65. package/assembly/deserialize/swar/array.ts +49 -0
  66. package/assembly/deserialize/swar/string.ts +648 -15
  67. package/assembly/deserialize/unsigned.ts +75 -0
  68. package/assembly/index.d.ts +1 -3
  69. package/assembly/index.ts +316 -374
  70. package/assembly/serialize/index/arbitrary.ts +75 -0
  71. package/assembly/serialize/index/array.ts +1 -0
  72. package/assembly/serialize/index/bool.ts +1 -0
  73. package/assembly/serialize/index/date.ts +1 -0
  74. package/assembly/serialize/index/float.ts +1 -0
  75. package/assembly/serialize/index/integer.ts +1 -0
  76. package/assembly/serialize/index/map.ts +1 -0
  77. package/assembly/serialize/index/object.ts +46 -0
  78. package/assembly/serialize/index/raw.ts +1 -0
  79. package/assembly/serialize/index/set.ts +1 -0
  80. package/assembly/serialize/index/staticarray.ts +1 -0
  81. package/assembly/serialize/index/string.ts +15 -0
  82. package/assembly/serialize/index/struct.ts +1 -0
  83. package/assembly/serialize/index/typedarray.ts +66 -0
  84. package/assembly/serialize/index.ts +13 -0
  85. package/assembly/serialize/simd/string.ts +4 -13
  86. package/assembly/serialize/simple/arbitrary.ts +6 -0
  87. package/assembly/serialize/simple/raw.ts +1 -5
  88. package/assembly/serialize/simple/string.ts +3 -11
  89. package/assembly/serialize/simple/typedarray.ts +63 -0
  90. package/assembly/serialize/swar/string.ts +6 -21
  91. package/assembly/util/concat.ts +1 -5
  92. package/assembly/util/index.ts +1 -0
  93. package/assembly/util/masks.ts +12 -18
  94. package/assembly/util/memory.ts +0 -0
  95. package/assembly/util/snp.ts +1 -4
  96. package/assembly/util/stringScan.ts +24 -0
  97. package/assembly/util/swar.ts +50 -6
  98. package/lib/as-bs.ts +137 -127
  99. package/package.json +26 -5
  100. package/transform/lib/builder.d.ts.map +1 -1
  101. package/transform/lib/builder.js +5 -13
  102. package/transform/lib/builder.js.map +1 -1
  103. package/transform/lib/index.d.ts +1 -0
  104. package/transform/lib/index.d.ts.map +1 -1
  105. package/transform/lib/index.js +672 -757
  106. package/transform/lib/index.js.map +1 -1
  107. package/transform/lib/linkers/alias.d.ts.map +1 -1
  108. package/transform/lib/linkers/alias.js.map +1 -1
  109. package/transform/lib/linkers/custom.d.ts.map +1 -1
  110. package/transform/lib/linkers/custom.js +8 -9
  111. package/transform/lib/linkers/custom.js.map +1 -1
  112. package/transform/lib/linkers/imports.d.ts.map +1 -1
  113. package/transform/lib/linkers/imports.js.map +1 -1
  114. package/transform/lib/types.d.ts +6 -0
  115. package/transform/lib/types.d.ts.map +1 -1
  116. package/transform/lib/types.js +83 -21
  117. package/transform/lib/types.js.map +1 -1
  118. package/transform/lib/util.d.ts.map +1 -1
  119. package/transform/lib/util.js +1 -1
  120. package/transform/lib/util.js.map +1 -1
  121. package/transform/lib/visitor.d.ts.map +1 -1
  122. package/transform/lib/visitor.js +1 -2
  123. package/transform/lib/visitor.js.map +1 -1
  124. package/.prettierrc +0 -3
  125. package/ARCHITECTURE.md +0 -320
  126. package/CONTRIBUTING.md +0 -238
  127. package/TODO +0 -1
  128. package/assembly/deserialize/simple/float.ts +0 -11
  129. package/assembly/deserialize/simple/integer.ts +0 -9
  130. package/assembly/test.ts +0 -30
  131. package/eslint.config.js +0 -60
  132. package/lib/tsconfig.json +0 -8
  133. package/tools/assemblyscript-eslint-local.js +0 -29
  134. package/tools/assemblyscript-eslint.js +0 -29
  135. package/transform/tsconfig.json +0 -35
@@ -0,0 +1,75 @@
1
+ import { JSON } from "../..";
2
+ import { bs } from "../../../lib/as-bs";
3
+ import { serializeArray } from "./array";
4
+ import { serializeBool } from "./bool";
5
+ import { serializeFloat } from "./float";
6
+ import { serializeInteger } from "./integer";
7
+ import { serializeMap } from "./map";
8
+ import { serializeObject } from "./object";
9
+ import { serializeString } from "./string";
10
+ import { serializeDynamic } from "./typedarray";
11
+
12
+ export function serializeArbitrary(src: JSON.Value): void {
13
+ switch (src.type) {
14
+ case JSON.Types.Null:
15
+ bs.proposeSize(8);
16
+ store<u64>(bs.offset, 30399761348886638);
17
+ bs.offset += 8;
18
+ break;
19
+ case JSON.Types.U8:
20
+ serializeInteger<u8>(src.get<u8>());
21
+ break;
22
+ case JSON.Types.U16:
23
+ serializeInteger<u16>(src.get<u16>());
24
+ break;
25
+ case JSON.Types.U32:
26
+ serializeInteger<u32>(src.get<u32>());
27
+ break;
28
+ case JSON.Types.U64:
29
+ serializeInteger<u64>(src.get<u64>());
30
+ break;
31
+ case JSON.Types.I8:
32
+ serializeInteger<i8>(src.get<i8>());
33
+ break;
34
+ case JSON.Types.I16:
35
+ serializeInteger<i16>(src.get<i16>());
36
+ break;
37
+ case JSON.Types.I32:
38
+ serializeInteger<i32>(src.get<i32>());
39
+ break;
40
+ case JSON.Types.I64:
41
+ serializeInteger<i64>(src.get<i64>());
42
+ break;
43
+ case JSON.Types.F32:
44
+ serializeFloat<f32>(src.get<f32>());
45
+ break;
46
+ case JSON.Types.F64:
47
+ serializeFloat<f64>(src.get<f64>());
48
+ break;
49
+ case JSON.Types.String:
50
+ serializeString(src.get<string>());
51
+ break;
52
+ case JSON.Types.Bool:
53
+ serializeBool(src.get<bool>());
54
+ break;
55
+ case JSON.Types.Array:
56
+ serializeArray(src.get<JSON.Value[]>());
57
+ break;
58
+ case JSON.Types.Object:
59
+ serializeObject(src.get<JSON.Obj>());
60
+ break;
61
+ case JSON.Types.Map:
62
+ serializeMap(src.get<Map<string, JSON.Value>>());
63
+ break;
64
+ case JSON.Types.TypedArray:
65
+ case JSON.Types.ArrayBuffer:
66
+ serializeDynamic(src.type, src.get<usize>());
67
+ break;
68
+ default: {
69
+ const fn = JSON.Value.METHODS.get(src.type - JSON.Types.Struct);
70
+ const ptr = src.get<usize>();
71
+ call_indirect<void>(fn, 0, ptr);
72
+ break;
73
+ }
74
+ }
75
+ }
@@ -0,0 +1 @@
1
+ export { serializeArray } from "../simple/array";
@@ -0,0 +1 @@
1
+ export { serializeBool } from "../simple/bool";
@@ -0,0 +1 @@
1
+ export { serializeDate } from "../simple/date";
@@ -0,0 +1 @@
1
+ export { serializeFloat } from "../simple/float";
@@ -0,0 +1 @@
1
+ export { serializeInteger } from "../simple/integer";
@@ -0,0 +1 @@
1
+ export { serializeMap } from "../simple/map";
@@ -0,0 +1,46 @@
1
+ import { bs } from "../../../lib/as-bs";
2
+ import { JSON } from "../..";
3
+ import { BRACE_LEFT, BRACE_RIGHT, COLON, COMMA } from "../../custom/chars";
4
+ import { serializeArbitrary } from "./arbitrary";
5
+ import { serializeString } from "./string";
6
+
7
+ export function serializeObject(src: JSON.Obj): void {
8
+ const srcSize = src.size;
9
+ const srcEnd = srcSize - 1;
10
+
11
+ if (srcSize == 0) {
12
+ bs.proposeSize(4);
13
+ store<u32>(bs.offset, 8192123);
14
+ bs.offset += 4;
15
+ return;
16
+ }
17
+
18
+ const keys = src.keys();
19
+ const values = src.values();
20
+
21
+ bs.growSize(2);
22
+ store<u16>(bs.offset, BRACE_LEFT);
23
+ bs.offset += 2;
24
+
25
+ for (let i = 0; i < srcEnd; i++) {
26
+ serializeString(unchecked(keys[i]));
27
+ bs.growSize(2);
28
+ store<u16>(bs.offset, COLON);
29
+ bs.offset += 2;
30
+
31
+ serializeArbitrary(unchecked(values[i]));
32
+ bs.growSize(2);
33
+ store<u16>(bs.offset, COMMA);
34
+ bs.offset += 2;
35
+ }
36
+
37
+ serializeString(unchecked(keys[srcEnd]));
38
+ bs.growSize(2);
39
+ store<u16>(bs.offset, COLON);
40
+ bs.offset += 2;
41
+ serializeArbitrary(unchecked(values[srcEnd]));
42
+
43
+ bs.growSize(2);
44
+ store<u16>(bs.offset, BRACE_RIGHT);
45
+ bs.offset += 2;
46
+ }
@@ -0,0 +1 @@
1
+ export { serializeRaw } from "../simple/raw";
@@ -0,0 +1 @@
1
+ export { serializeSet } from "../simple/set";
@@ -0,0 +1 @@
1
+ export { serializeStaticArray } from "../simple/staticarray";
@@ -0,0 +1,15 @@
1
+ import { JSONMode } from "../..";
2
+ import { serializeString as serializeString_NAIVE } from "../simple/string";
3
+ import { serializeString_SIMD } from "../simd/string";
4
+ import { serializeString_SWAR } from "../swar/string";
5
+
6
+
7
+ @inline export function serializeString(src: string): void {
8
+ if (JSON_MODE == JSONMode.SIMD) {
9
+ serializeString_SIMD(src);
10
+ } else if (JSON_MODE == JSONMode.NAIVE) {
11
+ serializeString_NAIVE(src);
12
+ } else {
13
+ serializeString_SWAR(src);
14
+ }
15
+ }
@@ -0,0 +1 @@
1
+ export { serializeStruct } from "../simple/struct";
@@ -0,0 +1,66 @@
1
+ import { OBJECT, TOTAL_OVERHEAD } from "rt/common";
2
+ import { JSON } from "../..";
3
+ export { serializeArrayBufferUnsafe, serializeTypedArray } from "../simple/typedarray";
4
+ import { serializeArrayBufferUnsafe, serializeTypedArray } from "../simple/typedarray";
5
+
6
+
7
+ @inline export function serializeDynamic(type: u16, data: usize): void {
8
+ if (type == JSON.Types.ArrayBuffer) {
9
+ serializeArrayBufferUnsafe(data, changetype<OBJECT>(data - TOTAL_OVERHEAD).rtSize);
10
+ } else if (type == JSON.Types.TypedArray) {
11
+ const id = changetype<OBJECT>(data - TOTAL_OVERHEAD).rtId;
12
+ if (id == idof<Int8Array>()) {
13
+ serializeTypedArray<Int8Array>(changetype<Int8Array>(data));
14
+ } else if (id == idof<Uint8Array>()) {
15
+ serializeTypedArray<Uint8Array>(changetype<Uint8Array>(data));
16
+ } else if (id == idof<Uint8ClampedArray>()) {
17
+ serializeTypedArray<Uint8ClampedArray>(changetype<Uint8ClampedArray>(data));
18
+ } else if (id == idof<Int16Array>()) {
19
+ serializeTypedArray<Int16Array>(changetype<Int16Array>(data));
20
+ } else if (id == idof<Uint16Array>()) {
21
+ serializeTypedArray<Uint16Array>(changetype<Uint16Array>(data));
22
+ } else if (id == idof<Int32Array>()) {
23
+ serializeTypedArray<Int32Array>(changetype<Int32Array>(data));
24
+ } else if (id == idof<Uint32Array>()) {
25
+ serializeTypedArray<Uint32Array>(changetype<Uint32Array>(data));
26
+ } else if (id == idof<Int64Array>()) {
27
+ serializeTypedArray<Int64Array>(changetype<Int64Array>(data));
28
+ } else if (id == idof<Uint64Array>()) {
29
+ serializeTypedArray<Uint64Array>(changetype<Uint64Array>(data));
30
+ } else if (id == idof<Float32Array>()) {
31
+ serializeTypedArray<Float32Array>(changetype<Float32Array>(data));
32
+ } else if (id == idof<Float64Array>()) {
33
+ serializeTypedArray<Float64Array>(changetype<Float64Array>(data));
34
+ } else if (changetype<Int8Array>(data) instanceof Int8Array) {
35
+ serializeTypedArray<Int8Array>(changetype<Int8Array>(data));
36
+ } else if (changetype<Uint8Array>(data) instanceof Uint8Array) {
37
+ serializeTypedArray<Uint8Array>(changetype<Uint8Array>(data));
38
+ } else if (changetype<Uint8ClampedArray>(data) instanceof Uint8ClampedArray) {
39
+ serializeTypedArray<Uint8ClampedArray>(changetype<Uint8ClampedArray>(data));
40
+ } else if (changetype<Int16Array>(data) instanceof Int16Array) {
41
+ serializeTypedArray<Int16Array>(changetype<Int16Array>(data));
42
+ } else if (changetype<Uint16Array>(data) instanceof Uint16Array) {
43
+ serializeTypedArray<Uint16Array>(changetype<Uint16Array>(data));
44
+ } else if (changetype<Int32Array>(data) instanceof Int32Array) {
45
+ serializeTypedArray<Int32Array>(changetype<Int32Array>(data));
46
+ } else if (changetype<Uint32Array>(data) instanceof Uint32Array) {
47
+ serializeTypedArray<Uint32Array>(changetype<Uint32Array>(data));
48
+ } else if (changetype<Int64Array>(data) instanceof Int64Array) {
49
+ serializeTypedArray<Int64Array>(changetype<Int64Array>(data));
50
+ } else if (changetype<Uint64Array>(data) instanceof Uint64Array) {
51
+ serializeTypedArray<Uint64Array>(changetype<Uint64Array>(data));
52
+ } else if (changetype<Float32Array>(data) instanceof Float32Array) {
53
+ serializeTypedArray<Float32Array>(changetype<Float32Array>(data));
54
+ } else if (changetype<Float64Array>(data) instanceof Float64Array) {
55
+ serializeTypedArray<Float64Array>(changetype<Float64Array>(data));
56
+ } else {
57
+ throw new Error("Unsupported typed array in JSON.Value");
58
+ }
59
+ }
60
+ }
61
+
62
+
63
+ @inline export function serializeArrayBuffer(data: ArrayBuffer): void {
64
+ const dataStart = changetype<usize>(data);
65
+ serializeArrayBufferUnsafe(dataStart, changetype<OBJECT>(dataStart - TOTAL_OVERHEAD).rtSize);
66
+ }
@@ -0,0 +1,13 @@
1
+ export * from "./index/arbitrary";
2
+ export * from "./index/array";
3
+ export * from "./index/bool";
4
+ export * from "./index/date";
5
+ export * from "./index/float";
6
+ export * from "./index/integer";
7
+ export * from "./index/map";
8
+ export * from "./index/object";
9
+ export * from "./index/raw";
10
+ export * from "./index/set";
11
+ export * from "./index/staticarray";
12
+ export * from "./index/string";
13
+ export * from "./index/struct";
@@ -2,6 +2,7 @@ import { OBJECT, TOTAL_OVERHEAD } from "rt/common";
2
2
  import { bs, sc } from "../../../lib/as-bs";
3
3
  import { BACK_SLASH } from "../../custom/chars";
4
4
  import { SERIALIZE_ESCAPE_TABLE } from "../../globals/tables";
5
+ import { u16_to_hex4_swar } from "../../util/swar";
5
6
  // @ts-expect-error: @lazy is a valid decorator
6
7
  @lazy const U00_MARKER = 13511005048209500;
7
8
  // @ts-expect-error: @lazy is a valid decorator
@@ -118,7 +119,7 @@ export function serializeString_SIMD(src: string): void {
118
119
  // unpaired high/low surrogate
119
120
  const dstIdx = bs.offset + laneIdx - 1;
120
121
  store<u32>(dstIdx, U_MARKER); // \u
121
- store<u64>(dstIdx, load<u64>(changetype<usize>(code.toString(16))), 4);
122
+ store<u64>(dstIdx, u16_to_hex4_swar(code), 4);
122
123
  // memory.copy(dstIdx + 12, srcIdx + 1, 15 - laneIdx);
123
124
  store<v128>(dstIdx, load<v128>(srcIdx, 1), 12);
124
125
  bs.offset += 10;
@@ -174,23 +175,13 @@ export function serializeString_SIMD(src: string): void {
174
175
  store<u16>(bs.offset, 34); // "
175
176
  bs.offset += 2;
176
177
 
177
- if (isDefined(JSON_CACHE))
178
- sc.insertCached(changetype<usize>(src), srcStart, srcSize);
178
+ if (isDefined(JSON_CACHE)) sc.insertCached(changetype<usize>(src), srcStart, srcSize);
179
179
  }
180
180
 
181
181
  // @ts-expect-error: @inline is a valid decorator
182
182
  @inline function write_u_escape(code: u16): void {
183
183
  bs.growSize(10);
184
184
  store<u32>(bs.offset, U_MARKER); // "\u"
185
- // write hex digits (lowercase, matches tests)
186
- store<u16>(bs.offset + 4, hexNibble((code >> 12) & 0xf));
187
- store<u16>(bs.offset + 6, hexNibble((code >> 8) & 0xf));
188
- store<u16>(bs.offset + 8, hexNibble((code >> 4) & 0xf));
189
- store<u16>(bs.offset + 10, hexNibble(code & 0xf));
185
+ store<u64>(bs.offset, u16_to_hex4_swar(code), 4);
190
186
  bs.offset += 12;
191
187
  }
192
-
193
- // @ts-expect-error: @inline is a valid decorator
194
- @inline function hexNibble(n: u16): u16 {
195
- return n < 10 ? 48 + n : 87 + n;
196
- }
@@ -7,6 +7,7 @@ import { serializeInteger } from "./integer";
7
7
  import { serializeMap } from "./map";
8
8
  import { serializeObject } from "./object";
9
9
  import { serializeString } from "./string";
10
+ import { serializeDynamic } from "../index/typedarray";
10
11
 
11
12
  export function serializeArbitrary(src: JSON.Value): void {
12
13
  switch (src.type) {
@@ -63,6 +64,11 @@ export function serializeArbitrary(src: JSON.Value): void {
63
64
  serializeMap(src.get<Map<string, JSON.Value>>());
64
65
  break;
65
66
  }
67
+ case JSON.Types.TypedArray:
68
+ case JSON.Types.ArrayBuffer: {
69
+ serializeDynamic(src.type, src.get<usize>());
70
+ break;
71
+ }
66
72
  default: {
67
73
  const fn = JSON.Value.METHODS.get(src.type - JSON.Types.Struct);
68
74
  const ptr = src.get<usize>();
@@ -11,10 +11,6 @@ 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(
15
- changetype<usize>(bs.offset),
16
- changetype<usize>(data.data),
17
- dataSize,
18
- );
14
+ memory.copy(changetype<usize>(bs.offset), changetype<usize>(data.data), dataSize);
19
15
  bs.offset += dataSize;
20
16
  }
@@ -3,6 +3,7 @@ import { _intTo16 } from "../../custom/util";
3
3
  import { bytes } from "../../util/bytes";
4
4
  import { BACK_SLASH, QUOTE } from "../../custom/chars";
5
5
  import { SERIALIZE_ESCAPE_TABLE } from "../../globals/tables";
6
+ import { u16_to_hex4_swar } from "../../util/swar";
6
7
  import { serializeStruct } from "./struct";
7
8
 
8
9
  // @ts-ignore: decorator allowed
@@ -68,7 +69,7 @@ import { serializeStruct } from "./struct";
68
69
  // unpaired high/low surrogate
69
70
  bs.growSize(10);
70
71
  store<u32>(bs.offset, U_MARKER); // \u
71
- store<u64>(bs.offset, load<u64>(changetype<usize>(code.toString(16))), 4);
72
+ store<u64>(bs.offset, u16_to_hex4_swar(code), 4);
72
73
  bs.offset += 12;
73
74
  lastPtr = srcPtr;
74
75
  continue;
@@ -84,15 +85,6 @@ import { serializeStruct } from "./struct";
84
85
  @inline function write_u_escape(code: u16): void {
85
86
  bs.growSize(10);
86
87
  store<u32>(bs.offset, U_MARKER); // "\u"
87
- // write hex digits (lowercase, matches tests)
88
- store<u16>(bs.offset + 4, hexNibble((code >> 12) & 0xf));
89
- store<u16>(bs.offset + 6, hexNibble((code >> 8) & 0xf));
90
- store<u16>(bs.offset + 8, hexNibble((code >> 4) & 0xf));
91
- store<u16>(bs.offset + 10, hexNibble(code & 0xf));
88
+ store<u64>(bs.offset, u16_to_hex4_swar(code), 4);
92
89
  bs.offset += 12;
93
90
  }
94
-
95
- // @ts-ignore: inline
96
- @inline function hexNibble(n: u16): u16 {
97
- return n < 10 ? 48 + n : 87 + n;
98
- }
@@ -0,0 +1,63 @@
1
+ import { bs } from "../../../lib/as-bs";
2
+ import { BRACKET_LEFT, BRACKET_RIGHT, COMMA } from "../../custom/chars";
3
+ import { serializeFloat } from "./float";
4
+ import { serializeInteger } from "./integer";
5
+
6
+
7
+ @inline
8
+ function serializeTypedArrayElement<T extends ArrayLike<number>>(src: T, index: i32): void {
9
+ if (isFloat<valueof<T>>()) {
10
+ serializeFloat<valueof<T>>(unchecked(src[index]));
11
+ } else {
12
+ serializeInteger<valueof<T>>(unchecked(src[index]));
13
+ }
14
+ }
15
+
16
+ export function serializeTypedArray<T extends ArrayLike<number>>(src: T): void {
17
+ bs.proposeSize(4);
18
+ const end = src.length - 1;
19
+ if (end == -1) {
20
+ store<u32>(bs.offset, 6094939);
21
+ bs.offset += 4;
22
+ return;
23
+ }
24
+
25
+ store<u16>(bs.offset, BRACKET_LEFT);
26
+ bs.offset += 2;
27
+
28
+ for (let i = 0; i < end; i++) {
29
+ serializeTypedArrayElement(src, i);
30
+ bs.growSize(2);
31
+ store<u16>(bs.offset, COMMA);
32
+ bs.offset += 2;
33
+ }
34
+
35
+ serializeTypedArrayElement(src, end);
36
+ store<u16>(bs.offset, BRACKET_RIGHT);
37
+ bs.offset += 2;
38
+ }
39
+
40
+ export function serializeArrayBufferUnsafe(srcStart: usize, byteLength: i32): void {
41
+ const end = byteLength - 1;
42
+
43
+ bs.proposeSize(4);
44
+ if (end == -1) {
45
+ store<u32>(bs.offset, 6094939);
46
+ bs.offset += 4;
47
+ return;
48
+ }
49
+
50
+ store<u16>(bs.offset, BRACKET_LEFT);
51
+ bs.offset += 2;
52
+
53
+ for (let i = 0; i < end; i++) {
54
+ serializeInteger<u8>(load<u8>(srcStart + <usize>i));
55
+ bs.growSize(2);
56
+ store<u16>(bs.offset, COMMA);
57
+ bs.offset += 2;
58
+ }
59
+
60
+ serializeInteger<u8>(load<u8>(srcStart + <usize>end));
61
+ store<u16>(bs.offset, BRACKET_RIGHT);
62
+ bs.offset += 2;
63
+ }
@@ -1,6 +1,7 @@
1
1
  import { bs, sc } from "../../../lib/as-bs";
2
2
  import { BACK_SLASH } from "../../custom/chars";
3
3
  import { SERIALIZE_ESCAPE_TABLE } from "../../globals/tables";
4
+ import { u16_to_hex4_swar } from "../../util/swar";
4
5
  import { OBJECT, TOTAL_OVERHEAD } from "rt/common";
5
6
 
6
7
  // @ts-expect-error: @lazy is a valid decorator
@@ -89,7 +90,7 @@ export function serializeString_SWAR(src: string): void {
89
90
  // unpaired high/low surrogate
90
91
  const dstIdx = bs.offset + laneIdx - 1;
91
92
  store<u32>(dstIdx, U_MARKER); // \u
92
- store<u64>(dstIdx, load<u64>(changetype<usize>(code.toString(16))), 4);
93
+ store<u64>(dstIdx, u16_to_hex4_swar(code), 4);
93
94
  store<u64>(dstIdx, load<u64>(srcIdx, 1), 12);
94
95
  bs.offset += 10;
95
96
  } while (mask !== 0);
@@ -145,38 +146,22 @@ export function serializeString_SWAR(src: string): void {
145
146
  store<u16>(bs.offset, 34); // "
146
147
  bs.offset += 2;
147
148
 
148
- if (isDefined(JSON_CACHE))
149
- sc.insertCached(changetype<usize>(src), srcStart, srcSize);
149
+ if (isDefined(JSON_CACHE)) sc.insertCached(changetype<usize>(src), srcStart, srcSize);
150
150
  }
151
151
 
152
152
  // @ts-expect-error: @inline is a valid decorator
153
153
  @inline function write_u_escape(code: u16): void {
154
154
  bs.growSize(10);
155
155
  store<u32>(bs.offset, U_MARKER); // "\u"
156
- // write hex digits (lowercase, matches tests)
157
- store<u16>(bs.offset + 4, hexNibble((code >> 12) & 0xf));
158
- store<u16>(bs.offset + 6, hexNibble((code >> 8) & 0xf));
159
- store<u16>(bs.offset + 8, hexNibble((code >> 4) & 0xf));
160
- store<u16>(bs.offset + 10, hexNibble(code & 0xf));
156
+ store<u64>(bs.offset, u16_to_hex4_swar(code), 4);
161
157
  bs.offset += 12;
162
158
  }
163
159
 
164
- // @ts-expect-error: @inline is a valid decorator
165
- @inline function hexNibble(n: u16): u16 {
166
- return n < 10 ? 48 + n : 87 + n;
167
- }
168
-
169
160
  // @ts-expect-error: @inline is a valid decorator
170
161
  @inline export function detect_escapable_u64_swar_safe(block: u64): u64 {
171
162
  const lo = block & 0x00ff_00ff_00ff_00ff;
172
- const ascii_mask =
173
- ((lo - 0x0020_0020_0020_0020) |
174
- ((lo ^ 0x0022_0022_0022_0022) - 0x0001_0001_0001_0001) |
175
- ((lo ^ 0x005c_005c_005c_005c) - 0x0001_0001_0001_0001)) &
176
- (0x0080_0080_0080_0080 & ~lo);
177
- const hi_mask =
178
- ((block - 0x0100_0100_0100_0100) & ~block & 0x8000_8000_8000_8000) ^
179
- 0x8000_8000_8000_8000;
163
+ const ascii_mask = ((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);
164
+ const hi_mask = ((block - 0x0100_0100_0100_0100) & ~block & 0x8000_8000_8000_8000) ^ 0x8000_8000_8000_8000;
180
165
  return (ascii_mask & (~hi_mask >> 8)) | hi_mask;
181
166
  }
182
167
 
@@ -4,10 +4,6 @@ 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(
8
- changetype<usize>(left) + leftSize,
9
- changetype<usize>(right),
10
- rightSize,
11
- );
7
+ memory.copy(changetype<usize>(left) + leftSize, changetype<usize>(right), rightSize);
12
8
  return changetype<string>(jointPtr);
13
9
  }
@@ -3,3 +3,4 @@ export * from "./atoi";
3
3
  export * from "./concat";
4
4
  export * from "./bytes";
5
5
  export * from "./nextPowerOf2";
6
+ export * from "./stringScan";
@@ -11,27 +11,21 @@ export function mask_to_string(mask: u64): string {
11
11
  return result;
12
12
  }
13
13
 
14
+ export function block_to_string(block: u64): string {
15
+ let result = " ";
16
+ const buf = changetype<usize>(new ArrayBuffer(8));
17
+ store<u64>(buf, block);
18
+ result += String.fromCharCode(load<u16>(buf, 6)) + " ";
19
+ result += String.fromCharCode(load<u16>(buf, 4)) + " ";
20
+ result += String.fromCharCode(load<u16>(buf, 2)) + " ";
21
+ result += String.fromCharCode(load<u16>(buf, 0)) + " ";
22
+ return result;
23
+ }
24
+
14
25
  export function mask_to_string_v128(vec: v128): string {
15
26
  let result = "0x";
16
27
 
17
- const lanes: i8[] = [
18
- i8x16.extract_lane_s(vec, 0),
19
- i8x16.extract_lane_s(vec, 1),
20
- i8x16.extract_lane_s(vec, 2),
21
- i8x16.extract_lane_s(vec, 3),
22
- i8x16.extract_lane_s(vec, 4),
23
- i8x16.extract_lane_s(vec, 5),
24
- i8x16.extract_lane_s(vec, 6),
25
- i8x16.extract_lane_s(vec, 7),
26
- i8x16.extract_lane_s(vec, 8),
27
- i8x16.extract_lane_s(vec, 9),
28
- i8x16.extract_lane_s(vec, 10),
29
- i8x16.extract_lane_s(vec, 11),
30
- i8x16.extract_lane_s(vec, 12),
31
- i8x16.extract_lane_s(vec, 13),
32
- i8x16.extract_lane_s(vec, 14),
33
- i8x16.extract_lane_s(vec, 15),
34
- ];
28
+ const lanes: i8[] = [i8x16.extract_lane_s(vec, 0), i8x16.extract_lane_s(vec, 1), i8x16.extract_lane_s(vec, 2), i8x16.extract_lane_s(vec, 3), i8x16.extract_lane_s(vec, 4), i8x16.extract_lane_s(vec, 5), i8x16.extract_lane_s(vec, 6), i8x16.extract_lane_s(vec, 7), i8x16.extract_lane_s(vec, 8), i8x16.extract_lane_s(vec, 9), i8x16.extract_lane_s(vec, 10), i8x16.extract_lane_s(vec, 11), i8x16.extract_lane_s(vec, 12), i8x16.extract_lane_s(vec, 13), i8x16.extract_lane_s(vec, 14), i8x16.extract_lane_s(vec, 15)];
35
29
 
36
30
  for (let i = 15; i >= 0; i--) {
37
31
  const byte = lanes[i];
File without changes
@@ -7,10 +7,7 @@ import { POW_TEN_TABLE_32, POW_TEN_TABLE_64 } from "../globals/tables";
7
7
  import { atoi } from "./atoi";
8
8
 
9
9
  // @ts-ignore: Decorator valid here
10
- @inline export function snp<T extends number>(
11
- srcStart: usize,
12
- srcEnd: usize,
13
- ): T {
10
+ @inline export function snp<T extends number>(srcStart: usize, srcEnd: usize): T {
14
11
  // @ts-ignore: type
15
12
  let val: T = 0;
16
13
  let char = load<u16>(srcStart) - 48;
@@ -0,0 +1,24 @@
1
+ import { BACK_SLASH, QUOTE } from "../custom/chars";
2
+
3
+ // @ts-ignore
4
+ @inline export function isUnescapedQuote(ptr: usize): bool {
5
+ if (load<u16>(ptr) != QUOTE) return false;
6
+
7
+ let escaped = false;
8
+ while (ptr >= 2 && load<u16>(ptr - 2) == BACK_SLASH) {
9
+ escaped = !escaped;
10
+ ptr -= 2;
11
+ }
12
+
13
+ return !escaped;
14
+ }
15
+
16
+ // @ts-ignore
17
+ @inline export function scanStringEnd(ptr: usize, end: usize): usize {
18
+ ptr += 2;
19
+ while (ptr < end) {
20
+ if (load<u16>(ptr) == QUOTE && isUnescapedQuote(ptr)) return ptr;
21
+ ptr += 2;
22
+ }
23
+ return end;
24
+ }
@@ -1,12 +1,56 @@
1
+ /**
2
+ * Decode four lowercase ASCII hex digits packed into UTF-16 lanes into one `u16`.
3
+ *
4
+ * The input is a `u64` whose four 16-bit lanes each contain one ASCII hex code
5
+ * unit in the low byte:
6
+ *
7
+ * - lane 0: most-significant hex digit
8
+ * - lane 1: next hex digit
9
+ * - lane 2: next hex digit
10
+ * - lane 3: least-significant hex digit
11
+ *
12
+ * For example, `0x0034_0033_0032_0031` represents the UTF-16 string `"1234"`
13
+ * and decodes to `0x1234`.
14
+ *
15
+ * This helper assumes the digits are already valid lowercase hexadecimal
16
+ * characters in the ranges `0-9` or `a-f`.
17
+ *
18
+ * @param block Packed UTF-16 ASCII hex digits.
19
+ * @returns The decoded 16-bit value.
20
+ */
1
21
  // @ts-expect-error: @inline is a valid decorator
2
22
  @inline export function hex4_to_u16_swar(block: u64): u16 {
3
23
  // (c & 0xF) + 9 * (c >> 6)
4
24
  block = (block & 0x0f000f000f000f) + ((block >> 6) & 0x03000300030003) * 9;
5
25
 
6
- return <u16>(
7
- (((block >> 0) << 12) |
8
- ((block >> 16) << 8) |
9
- ((block >> 32) << 4) |
10
- (block >> 48))
11
- );
26
+ return <u16>(((block >> 0) << 12) | ((block >> 16) << 8) | ((block >> 32) << 4) | (block >> 48));
27
+ }
28
+
29
+ /**
30
+ * Encode one `u16` into four lowercase ASCII hex digits packed into UTF-16 lanes.
31
+ *
32
+ * The returned `u64` is laid out so it can be written directly as four UTF-16
33
+ * code units:
34
+ *
35
+ * - lane 0: most-significant hex digit
36
+ * - lane 1: next hex digit
37
+ * - lane 2: next hex digit
38
+ * - lane 3: least-significant hex digit
39
+ *
40
+ * Each lane stores the ASCII character in the low byte and zero in the high
41
+ * byte. For example, `0x1234` becomes `0x0034_0033_0032_0031`, which
42
+ * represents the UTF-16 string `"1234"`.
43
+ *
44
+ * This helper is the inverse of {@link hex4_to_u16_swar}.
45
+ *
46
+ * @param code The 16-bit value to encode.
47
+ * @returns Four packed UTF-16 ASCII hex digits.
48
+ */
49
+ // @ts-expect-error: @inline is a valid decorator
50
+ @inline export function u16_to_hex4_swar(code: u16): u64 {
51
+ let block = (<u64>((code >> 12) & 0xf)) | ((<u64>((code >> 8) & 0xf)) << 16) | ((<u64>((code >> 4) & 0xf)) << 32) | ((<u64>(code & 0xf)) << 48);
52
+
53
+ const alphaMask = ((block + 0x0006_0006_0006_0006) >> 4) & 0x0001_0001_0001_0001;
54
+ block += 0x0030_0030_0030_0030 + alphaMask * 39;
55
+ return block;
12
56
  }