json-as 1.3.9 → 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.
- package/CHANGELOG.md +60 -19
- package/README.md +120 -21
- package/assembly/custom/chars.ts +39 -78
- package/assembly/deserialize/index/arbitrary.ts +28 -10
- package/assembly/deserialize/index/float.ts +2 -4
- package/assembly/deserialize/index/integer.ts +2 -4
- package/assembly/deserialize/index/object.ts +6 -1
- package/assembly/deserialize/index/string.ts +2 -7
- package/assembly/deserialize/index/unsigned.ts +2 -4
- package/assembly/deserialize/naive/array/arbitrary.ts +3 -136
- package/assembly/deserialize/naive/array/array.ts +30 -1
- package/assembly/deserialize/naive/array/integer.ts +2 -7
- package/assembly/deserialize/naive/array/map.ts +10 -14
- package/assembly/deserialize/naive/array/object.ts +10 -14
- package/assembly/deserialize/naive/array/struct.ts +19 -1
- package/assembly/deserialize/naive/bool.ts +1 -5
- package/assembly/deserialize/naive/date.ts +1 -2
- package/assembly/deserialize/naive/float.ts +4 -11
- package/assembly/deserialize/naive/integer.ts +2 -4
- package/assembly/deserialize/naive/map.ts +42 -205
- package/assembly/deserialize/naive/object.ts +291 -174
- package/assembly/deserialize/naive/raw.ts +1 -5
- package/assembly/deserialize/naive/set.ts +3 -6
- package/assembly/deserialize/naive/staticarray.ts +2 -4
- package/assembly/deserialize/naive/string.ts +68 -24
- package/assembly/deserialize/naive/typedarray.ts +1 -2
- package/assembly/deserialize/naive/unsigned.ts +2 -4
- package/assembly/deserialize/simd/array/integer.ts +5 -13
- package/assembly/deserialize/simd/float.ts +5 -12
- package/assembly/deserialize/simd/integer.ts +6 -15
- package/assembly/deserialize/simd/string.ts +21 -43
- package/assembly/deserialize/swar/array/arbitrary.ts +1 -2
- package/assembly/deserialize/swar/array/array.ts +2 -4
- package/assembly/deserialize/swar/array/bool.ts +2 -4
- package/assembly/deserialize/swar/array/box.ts +1 -2
- package/assembly/deserialize/swar/array/float.ts +8 -21
- package/assembly/deserialize/swar/array/generic.ts +2 -4
- package/assembly/deserialize/swar/array/integer.ts +13 -27
- package/assembly/deserialize/swar/array/map.ts +1 -2
- package/assembly/deserialize/swar/array/object.ts +2 -4
- package/assembly/deserialize/swar/array/raw.ts +1 -2
- package/assembly/deserialize/swar/array/shared.ts +9 -21
- package/assembly/deserialize/swar/array/string.ts +4 -10
- package/assembly/deserialize/swar/array/struct.ts +3 -9
- package/assembly/deserialize/swar/array.ts +1 -3
- package/assembly/deserialize/swar/float.ts +7 -17
- package/assembly/deserialize/swar/integer.ts +6 -15
- package/assembly/deserialize/swar/string.ts +40 -54
- package/assembly/deserialize/swar/typedarray.ts +4 -4
- package/assembly/index.d.ts +259 -21
- package/assembly/index.ts +1704 -266
- package/assembly/serialize/index/arbitrary.ts +70 -4
- package/assembly/serialize/index/jsonarray.ts +51 -0
- package/assembly/serialize/index/object.ts +39 -14
- package/assembly/serialize/index/string.ts +1 -2
- package/assembly/serialize/index/typedarray.ts +1 -2
- package/assembly/serialize/index.ts +1 -0
- package/assembly/serialize/naive/array.ts +23 -34
- package/assembly/serialize/naive/bool.ts +0 -1
- package/assembly/serialize/naive/float.ts +16 -25
- package/assembly/serialize/naive/integer.ts +1 -5
- package/assembly/serialize/naive/raw.ts +1 -2
- package/assembly/serialize/naive/set.ts +0 -4
- package/assembly/serialize/naive/staticarray.ts +0 -5
- package/assembly/serialize/naive/string.ts +11 -7
- package/assembly/serialize/naive/typedarray.ts +0 -6
- package/assembly/serialize/simd/string.ts +1 -3
- package/assembly/serialize/swar/string.ts +2 -4
- package/assembly/util/atoi-fast.ts +4 -14
- package/assembly/util/atoi.ts +1 -2
- package/assembly/util/bytes.ts +1 -2
- package/assembly/util/idofd.ts +1 -2
- package/assembly/util/isSpace.ts +1 -2
- package/assembly/util/itoa-fast.ts +9 -15
- package/assembly/util/nextPowerOf2.ts +1 -2
- package/assembly/util/parsefloat-fast.ts +4 -7
- package/assembly/util/ptrToStr.ts +1 -2
- package/assembly/util/scanValueEnd.ts +1 -2
- package/assembly/util/scanValueEndSimd.ts +198 -0
- package/assembly/util/scanValueEndSwar.ts +184 -0
- package/assembly/util/scientific.ts +8 -14
- package/assembly/util/simd-int.ts +4 -8
- package/assembly/util/snp.ts +2 -7
- package/assembly/util/stringScan.ts +2 -4
- package/assembly/util/swar-int.ts +8 -16
- package/assembly/util/swar.ts +2 -4
- package/lib/as-bs.ts +57 -42
- package/package.json +27 -10
- package/transform/lib/builder.d.ts +0 -1
- package/transform/lib/builder.js +0 -1
- package/transform/lib/index.d.ts +0 -1
- package/transform/lib/index.js +617 -326
- package/transform/lib/linkers/alias.d.ts +0 -1
- package/transform/lib/linkers/alias.js +0 -1
- package/transform/lib/linkers/custom.d.ts +0 -1
- package/transform/lib/linkers/custom.js +0 -1
- package/transform/lib/linkers/imports.d.ts +0 -1
- package/transform/lib/linkers/imports.js +0 -1
- package/transform/lib/types.d.ts +4 -2
- package/transform/lib/types.js +5 -1
- package/transform/lib/util.d.ts +0 -1
- package/transform/lib/util.js +0 -1
- package/transform/lib/visitor.d.ts +0 -1
- package/transform/lib/visitor.js +0 -1
- package/assembly/util/dragonbox-cache.ts +0 -445
- package/assembly/util/dragonbox.ts +0 -660
- package/transform/lib/builder.d.ts.map +0 -1
- package/transform/lib/builder.js.map +0 -1
- package/transform/lib/index.d.ts.map +0 -1
- package/transform/lib/index.js.map +0 -1
- package/transform/lib/linkers/alias.d.ts.map +0 -1
- package/transform/lib/linkers/alias.js.map +0 -1
- package/transform/lib/linkers/custom.d.ts.map +0 -1
- package/transform/lib/linkers/custom.js.map +0 -1
- package/transform/lib/linkers/imports.d.ts.map +0 -1
- package/transform/lib/linkers/imports.js.map +0 -1
- package/transform/lib/types.d.ts.map +0 -1
- package/transform/lib/types.js.map +0 -1
- package/transform/lib/util.d.ts.map +0 -1
- package/transform/lib/util.js.map +0 -1
- package/transform/lib/visitor.d.ts.map +0 -1
- package/transform/lib/visitor.js.map +0 -1
|
@@ -82,8 +82,7 @@
|
|
|
82
82
|
* @param srcStart Pointer to 16 source bytes (8 UTF-16 chars).
|
|
83
83
|
* @returns The parsed 8-digit value, or `U32.MAX_VALUE` on invalid input.
|
|
84
84
|
*/
|
|
85
|
-
|
|
86
|
-
@inline export function parse8Digits_SIMD(srcStart: usize): u32 {
|
|
85
|
+
export function parse8Digits_SIMD(srcStart: usize): u32 {
|
|
87
86
|
const block = load<v128>(srcStart);
|
|
88
87
|
const digits = i16x8.sub(block, SPLAT_30);
|
|
89
88
|
if (v128.any_true(i16x8.gt_u(digits, SPLAT_09))) return U32.MAX_VALUE;
|
|
@@ -104,8 +103,7 @@
|
|
|
104
103
|
* @param srcStart Pointer to 16 source bytes (8 UTF-16 chars).
|
|
105
104
|
* @returns The parsed 8-digit value.
|
|
106
105
|
*/
|
|
107
|
-
|
|
108
|
-
@inline export function parse8Digits_SIMD_Unsafe(srcStart: usize): u32 {
|
|
106
|
+
export function parse8Digits_SIMD_Unsafe(srcStart: usize): u32 {
|
|
109
107
|
const block = load<v128>(srcStart);
|
|
110
108
|
const digits = i16x8.sub(block, SPLAT_30);
|
|
111
109
|
const packed = i8x16.narrow_i16x8_u(digits, ZERO_I16X8);
|
|
@@ -132,8 +130,7 @@
|
|
|
132
130
|
* @param srcStart Pointer to 32 source bytes (16 UTF-16 chars).
|
|
133
131
|
* @returns The parsed 16-digit value, or `U64.MAX_VALUE` on invalid input.
|
|
134
132
|
*/
|
|
135
|
-
|
|
136
|
-
@inline export function parse16Digits_SIMD(srcStart: usize): u64 {
|
|
133
|
+
export function parse16Digits_SIMD(srcStart: usize): u64 {
|
|
137
134
|
const block0 = load<v128>(srcStart);
|
|
138
135
|
const block1 = load<v128>(srcStart, 16);
|
|
139
136
|
|
|
@@ -168,8 +165,7 @@
|
|
|
168
165
|
* @param srcStart Pointer to 32 source bytes (16 UTF-16 chars).
|
|
169
166
|
* @returns The parsed 16-digit value.
|
|
170
167
|
*/
|
|
171
|
-
|
|
172
|
-
@inline export function parse16Digits_SIMD_Unsafe(srcStart: usize): u64 {
|
|
168
|
+
export function parse16Digits_SIMD_Unsafe(srcStart: usize): u64 {
|
|
173
169
|
const block0 = load<v128>(srcStart);
|
|
174
170
|
const block1 = load<v128>(srcStart, 16);
|
|
175
171
|
const digits0 = i16x8.sub(block0, SPLAT_30);
|
package/assembly/util/snp.ts
CHANGED
|
@@ -6,11 +6,7 @@
|
|
|
6
6
|
import { POW_TEN_TABLE_32, POW_TEN_TABLE_64 } from "../globals/tables";
|
|
7
7
|
import { atoi } from "./atoi";
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
@inline export function snp<T extends number>(
|
|
11
|
-
srcStart: usize,
|
|
12
|
-
srcEnd: usize,
|
|
13
|
-
): T {
|
|
9
|
+
export function snp<T extends number>(srcStart: usize, srcEnd: usize): T {
|
|
14
10
|
// @ts-ignore: type
|
|
15
11
|
let val: T = 0;
|
|
16
12
|
let char = load<u16>(srcStart) - 48;
|
|
@@ -62,8 +58,7 @@ import { atoi } from "./atoi";
|
|
|
62
58
|
}
|
|
63
59
|
}
|
|
64
60
|
|
|
65
|
-
|
|
66
|
-
@inline function pow10<T extends number>(x: u16): T {
|
|
61
|
+
function pow10<T extends number>(x: u16): T {
|
|
67
62
|
if (sizeof<T>() == 8) {
|
|
68
63
|
return <T>load<u64>(POW_TEN_TABLE_64 + x);
|
|
69
64
|
} else {
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { BACK_SLASH, QUOTE } from "../custom/chars";
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
@inline export function isUnescapedQuote(ptr: usize): bool {
|
|
3
|
+
export function isUnescapedQuote(ptr: usize): bool {
|
|
5
4
|
if (load<u16>(ptr) != QUOTE) return false;
|
|
6
5
|
|
|
7
6
|
let escaped = false;
|
|
@@ -13,8 +12,7 @@ import { BACK_SLASH, QUOTE } from "../custom/chars";
|
|
|
13
12
|
return !escaped;
|
|
14
13
|
}
|
|
15
14
|
|
|
16
|
-
|
|
17
|
-
@inline export function scanStringEnd(ptr: usize, end: usize): usize {
|
|
15
|
+
export function scanStringEnd(ptr: usize, end: usize): usize {
|
|
18
16
|
ptr += 2;
|
|
19
17
|
while (ptr < end) {
|
|
20
18
|
if (load<u16>(ptr) == QUOTE && isUnescapedQuote(ptr)) return ptr;
|
|
@@ -26,8 +26,7 @@ const FINAL_4_MAGIC: u64 = 0x0000_0064_0000_0001;
|
|
|
26
26
|
* @param block Four UTF-16 code units packed into a `u64`.
|
|
27
27
|
* @returns The parsed 4-digit value, or `U32.MAX_VALUE` on invalid input.
|
|
28
28
|
*/
|
|
29
|
-
|
|
30
|
-
@inline export function parse4Digits_Baseline(block: u64): u32 {
|
|
29
|
+
export function parse4Digits_Baseline(block: u64): u32 {
|
|
31
30
|
const digits = (block & LANE_LO_4) - ZERO_4;
|
|
32
31
|
if (((digits | (digits + RANGE_ADD_4)) & RANGE_MASK_4) != 0) {
|
|
33
32
|
return U32.MAX_VALUE;
|
|
@@ -58,8 +57,7 @@ const FINAL_4_MAGIC: u64 = 0x0000_0064_0000_0001;
|
|
|
58
57
|
* @param block Four UTF-16 code units packed into a `u64`.
|
|
59
58
|
* @returns The parsed 4-digit value, or `U32.MAX_VALUE` on invalid input.
|
|
60
59
|
*/
|
|
61
|
-
|
|
62
|
-
@inline export function parse4Digits_PairMul(block: u64): u32 {
|
|
60
|
+
export function parse4Digits_PairMul(block: u64): u32 {
|
|
63
61
|
const digits = block - ZERO_4;
|
|
64
62
|
if (((digits | (digits + RANGE_ADD_4)) & RANGE_MASK_4) != 0) {
|
|
65
63
|
return U32.MAX_VALUE;
|
|
@@ -76,8 +74,7 @@ const FINAL_4_MAGIC: u64 = 0x0000_0064_0000_0001;
|
|
|
76
74
|
* @param block Four UTF-16 code units packed into a `u64`.
|
|
77
75
|
* @returns The parsed 4-digit value.
|
|
78
76
|
*/
|
|
79
|
-
|
|
80
|
-
@inline export function parse4Digits_PairMul_Unsafe(block: u64): u32 {
|
|
77
|
+
export function parse4Digits_PairMul_Unsafe(block: u64): u32 {
|
|
81
78
|
const digits = block - ZERO_4;
|
|
82
79
|
const pairs = (digits * 10 + (digits >> 16)) & U32_LO_PAIR;
|
|
83
80
|
return <u32>((pairs * FINAL_4_MAGIC) >> 32);
|
|
@@ -97,8 +94,7 @@ const FINAL_4_MAGIC: u64 = 0x0000_0064_0000_0001;
|
|
|
97
94
|
* @param hi The second `u64`, four UTF-16 code units.
|
|
98
95
|
* @returns The parsed 8-digit value, or `U32.MAX_VALUE` on invalid input.
|
|
99
96
|
*/
|
|
100
|
-
|
|
101
|
-
@inline export function parse8Digits_PairMul(lo: u64, hi: u64): u32 {
|
|
97
|
+
export function parse8Digits_PairMul(lo: u64, hi: u64): u32 {
|
|
102
98
|
const loDigits = lo - ZERO_4;
|
|
103
99
|
const hiDigits = hi - ZERO_4;
|
|
104
100
|
const bad =
|
|
@@ -124,8 +120,7 @@ const FINAL_4_MAGIC: u64 = 0x0000_0064_0000_0001;
|
|
|
124
120
|
* @param hi The second `u64`, four UTF-16 code units.
|
|
125
121
|
* @returns The parsed 8-digit value.
|
|
126
122
|
*/
|
|
127
|
-
|
|
128
|
-
@inline export function parse8Digits_PairMul_Unsafe(lo: u64, hi: u64): u32 {
|
|
123
|
+
export function parse8Digits_PairMul_Unsafe(lo: u64, hi: u64): u32 {
|
|
129
124
|
const loDigits = lo - ZERO_4;
|
|
130
125
|
const hiDigits = hi - ZERO_4;
|
|
131
126
|
const loPairs = (loDigits * 10 + (loDigits >> 16)) & U32_LO_PAIR;
|
|
@@ -150,8 +145,7 @@ const FINAL_4_MAGIC: u64 = 0x0000_0064_0000_0001;
|
|
|
150
145
|
* @param block Four UTF-16 code units packed into a `u64`.
|
|
151
146
|
* @returns A mask with non-digit lanes flagged in their high bit, or 0.
|
|
152
147
|
*/
|
|
153
|
-
|
|
154
|
-
@inline export function nonDigitMask4(block: u64): u64 {
|
|
148
|
+
export function nonDigitMask4(block: u64): u64 {
|
|
155
149
|
const digits = (block & LANE_LO_4) - ZERO_4;
|
|
156
150
|
return (digits | (digits + RANGE_ADD_4)) & RANGE_MASK_4;
|
|
157
151
|
}
|
|
@@ -174,8 +168,7 @@ const FINAL_4_MAGIC: u64 = 0x0000_0064_0000_0001;
|
|
|
174
168
|
* @param srcStart Pointer to the start of 32 source bytes (16 UTF-16 chars).
|
|
175
169
|
* @returns The parsed 16-digit value, or `U64.MAX_VALUE` on invalid input.
|
|
176
170
|
*/
|
|
177
|
-
|
|
178
|
-
@inline export function parse16Digits_SWAR(srcStart: usize): u64 {
|
|
171
|
+
export function parse16Digits_SWAR(srcStart: usize): u64 {
|
|
179
172
|
const b0 = load<u64>(srcStart);
|
|
180
173
|
const b1 = load<u64>(srcStart, 8);
|
|
181
174
|
const b2 = load<u64>(srcStart, 16);
|
|
@@ -220,8 +213,7 @@ const FINAL_4_MAGIC: u64 = 0x0000_0064_0000_0001;
|
|
|
220
213
|
* @param srcStart Pointer to the start of 32 source bytes (16 UTF-16 chars).
|
|
221
214
|
* @returns The parsed 16-digit value.
|
|
222
215
|
*/
|
|
223
|
-
|
|
224
|
-
@inline export function parse16Digits_SWAR_Unsafe(srcStart: usize): u64 {
|
|
216
|
+
export function parse16Digits_SWAR_Unsafe(srcStart: usize): u64 {
|
|
225
217
|
const b0 = load<u64>(srcStart);
|
|
226
218
|
const b1 = load<u64>(srcStart, 8);
|
|
227
219
|
const b2 = load<u64>(srcStart, 16);
|
package/assembly/util/swar.ts
CHANGED
|
@@ -18,8 +18,7 @@
|
|
|
18
18
|
* @param block Packed UTF-16 ASCII hex digits.
|
|
19
19
|
* @returns The decoded 16-bit value.
|
|
20
20
|
*/
|
|
21
|
-
|
|
22
|
-
@inline export function hex4_to_u16_swar(block: u64): u16 {
|
|
21
|
+
export function hex4_to_u16_swar(block: u64): u16 {
|
|
23
22
|
// (c & 0xF) + 9 * (c >> 6)
|
|
24
23
|
block = (block & 0x0f000f000f000f) + ((block >> 6) & 0x03000300030003) * 9;
|
|
25
24
|
|
|
@@ -51,8 +50,7 @@
|
|
|
51
50
|
* @param code The 16-bit value to encode.
|
|
52
51
|
* @returns Four packed UTF-16 ASCII hex digits.
|
|
53
52
|
*/
|
|
54
|
-
|
|
55
|
-
@inline export function u16_to_hex4_swar(code: u16): u64 {
|
|
53
|
+
export function u16_to_hex4_swar(code: u16): u64 {
|
|
56
54
|
let block =
|
|
57
55
|
(<u64>((code >> 12) & 0xf)) |
|
|
58
56
|
((<u64>((code >> 8) & 0xf)) << 16) |
|
package/lib/as-bs.ts
CHANGED
|
@@ -40,15 +40,13 @@ export namespace bs {
|
|
|
40
40
|
* Using bit shifts for efficiency: alpha = 1/8, so (1 - alpha) = 7/8
|
|
41
41
|
* @param newSize - The new size to incorporate into the average
|
|
42
42
|
*/
|
|
43
|
-
|
|
44
|
-
@inline function updateTypicalSize(newSize: usize): void {
|
|
43
|
+
function updateTypicalSize(newSize: usize): void {
|
|
45
44
|
// EMA: typicalSize = (newSize >> 3) + typicalSize - (typicalSize >> 3)
|
|
46
45
|
// Simplified: typicalSize += (newSize - typicalSize) >> 3
|
|
47
46
|
typicalSize += (newSize - typicalSize) >> EMA_ALPHA_SHIFT;
|
|
48
47
|
}
|
|
49
48
|
|
|
50
|
-
|
|
51
|
-
@inline function renewBuffer(newSize: usize): void {
|
|
49
|
+
function renewBuffer(newSize: usize): void {
|
|
52
50
|
const oldPtr = buffer;
|
|
53
51
|
const relOffset = offset - oldPtr;
|
|
54
52
|
const newPtr = heap.realloc(oldPtr, newSize);
|
|
@@ -57,8 +55,7 @@ export namespace bs {
|
|
|
57
55
|
bufferSize = newSize;
|
|
58
56
|
}
|
|
59
57
|
|
|
60
|
-
|
|
61
|
-
@inline function reserve(requiredSize: usize, extra: usize): void {
|
|
58
|
+
function reserve(requiredSize: usize, extra: usize): void {
|
|
62
59
|
if (requiredSize <= bufferSize) return;
|
|
63
60
|
// Grow aggressively (2x) to minimize realloc frequency in hot serialization paths.
|
|
64
61
|
let next = bufferSize << 1;
|
|
@@ -67,8 +64,7 @@ export namespace bs {
|
|
|
67
64
|
renewBuffer(next);
|
|
68
65
|
}
|
|
69
66
|
|
|
70
|
-
|
|
71
|
-
@inline function finalizeDynamicOutput(len: usize): void {
|
|
67
|
+
function finalizeDynamicOutput(len: usize): void {
|
|
72
68
|
counter += 1;
|
|
73
69
|
updateTypicalSize(len);
|
|
74
70
|
if ((counter & SHRINK_EVERY_N_MASK) == 0 && bufferSize > typicalSize << 2) {
|
|
@@ -83,8 +79,7 @@ export namespace bs {
|
|
|
83
79
|
/**
|
|
84
80
|
* Stores the state of the buffer, allowing further changes to be reset
|
|
85
81
|
*/
|
|
86
|
-
|
|
87
|
-
@inline export function saveState(): void {
|
|
82
|
+
export function saveState(): void {
|
|
88
83
|
pauseOffsets.push(offset - buffer);
|
|
89
84
|
pauseStackSizes.push(stackSize);
|
|
90
85
|
}
|
|
@@ -93,8 +88,7 @@ export namespace bs {
|
|
|
93
88
|
* Resets the buffer to the state it was in when `pause()` was called.
|
|
94
89
|
* This allows for changes made after the pause to be discarded.
|
|
95
90
|
*/
|
|
96
|
-
|
|
97
|
-
@inline export function loadState(): void {
|
|
91
|
+
export function loadState(): void {
|
|
98
92
|
const length = pauseOffsets.length;
|
|
99
93
|
if (length == 0) return;
|
|
100
94
|
const index = length - 1;
|
|
@@ -109,8 +103,7 @@ export namespace bs {
|
|
|
109
103
|
* serialize/deserialize op mid-flight: a partial run can leave `offset`
|
|
110
104
|
* advanced and the pause stacks non-empty, which would corrupt the next op.
|
|
111
105
|
*/
|
|
112
|
-
|
|
113
|
-
@inline export function reset(): void {
|
|
106
|
+
export function reset(): void {
|
|
114
107
|
offset = buffer;
|
|
115
108
|
stackSize = 0;
|
|
116
109
|
pauseOffsets.length = 0;
|
|
@@ -122,8 +115,7 @@ export namespace bs {
|
|
|
122
115
|
* If necessary, reallocates the buffer to the exact new size.
|
|
123
116
|
* @param size - The size to propose.
|
|
124
117
|
*/
|
|
125
|
-
|
|
126
|
-
@inline export function ensureSize(size: u32): void {
|
|
118
|
+
export function ensureSize(size: u32): void {
|
|
127
119
|
reserve(offset - buffer + usize(size), MIN_BUFFER_SIZE);
|
|
128
120
|
}
|
|
129
121
|
|
|
@@ -132,8 +124,7 @@ export namespace bs {
|
|
|
132
124
|
* If necessary, reallocates the buffer to the exact new size.
|
|
133
125
|
* @param size - The size to propose.w
|
|
134
126
|
*/
|
|
135
|
-
|
|
136
|
-
@inline export function proposeSize(size: u32): void {
|
|
127
|
+
export function proposeSize(size: u32): void {
|
|
137
128
|
stackSize += size;
|
|
138
129
|
reserve(stackSize, 0);
|
|
139
130
|
}
|
|
@@ -143,8 +134,7 @@ export namespace bs {
|
|
|
143
134
|
* If necessary, reallocates the buffer to the exact new size.
|
|
144
135
|
* @param size - The size to grow by.
|
|
145
136
|
*/
|
|
146
|
-
|
|
147
|
-
@inline export function growSize(size: u32): void {
|
|
137
|
+
export function growSize(size: u32): void {
|
|
148
138
|
stackSize += size;
|
|
149
139
|
reserve(stackSize, MIN_BUFFER_SIZE);
|
|
150
140
|
}
|
|
@@ -153,8 +143,7 @@ export namespace bs {
|
|
|
153
143
|
* Resizes the buffer to the specified size.
|
|
154
144
|
* @param newSize - The new buffer size.
|
|
155
145
|
*/
|
|
156
|
-
|
|
157
|
-
@inline export function resize(newSize: u32): void {
|
|
146
|
+
export function resize(newSize: u32): void {
|
|
158
147
|
const oldPtr = buffer;
|
|
159
148
|
const relOffset = offset - oldPtr;
|
|
160
149
|
const newPtr = heap.realloc(buffer, newSize);
|
|
@@ -168,8 +157,7 @@ export namespace bs {
|
|
|
168
157
|
* finalization. Keeps enough capacity for the recent typical output size while
|
|
169
158
|
* releasing clearly excess memory.
|
|
170
159
|
*/
|
|
171
|
-
|
|
172
|
-
@inline export function shrink(): void {
|
|
160
|
+
export function shrink(): void {
|
|
173
161
|
let next = typicalSize << 1;
|
|
174
162
|
if (next < MIN_BUFFER_SIZE) next = MIN_BUFFER_SIZE;
|
|
175
163
|
if (bufferSize > next) {
|
|
@@ -184,8 +172,7 @@ export namespace bs {
|
|
|
184
172
|
* Copies the buffer's content to a new object of a specified type. Does not shrink the buffer.
|
|
185
173
|
* @returns The new object containing the buffer's content.
|
|
186
174
|
*/
|
|
187
|
-
|
|
188
|
-
@inline export function cpyOut<T>(): T {
|
|
175
|
+
export function cpyOut<T>(): T {
|
|
189
176
|
if (pauseOffsets.length == 0) {
|
|
190
177
|
const len = offset - buffer;
|
|
191
178
|
// @ts-expect-error: __new is a runtime builtin
|
|
@@ -214,8 +201,7 @@ export namespace bs {
|
|
|
214
201
|
* Note: this restores only `offset`. Deserialization paths do not currently depend on
|
|
215
202
|
* `stackSize`, which is tracked for serialization growth heuristics.
|
|
216
203
|
*/
|
|
217
|
-
|
|
218
|
-
@inline export function sliceOut<T>(start: usize): T {
|
|
204
|
+
export function sliceOut<T>(start: usize): T {
|
|
219
205
|
const sliceStart = buffer + start;
|
|
220
206
|
const len = offset - sliceStart;
|
|
221
207
|
// @ts-expect-error: __new is a runtime builtin
|
|
@@ -229,8 +215,7 @@ export namespace bs {
|
|
|
229
215
|
* Copies the slice starting at a caller-provided relative buffer offset into a string field
|
|
230
216
|
* and restores `offset` back to that slice start.
|
|
231
217
|
*/
|
|
232
|
-
|
|
233
|
-
@inline export function toField(start: usize, dstFieldPtr: usize): void {
|
|
218
|
+
export function toField(start: usize, dstFieldPtr: usize): void {
|
|
234
219
|
const sliceStart = buffer + start;
|
|
235
220
|
const byteLength = <u32>(offset - sliceStart);
|
|
236
221
|
if (byteLength == 0) {
|
|
@@ -265,8 +250,7 @@ export namespace bs {
|
|
|
265
250
|
* adaptive buffer management - shrinks buffer when consistently oversized.
|
|
266
251
|
* @returns The new object containing the buffer's content.
|
|
267
252
|
*/
|
|
268
|
-
|
|
269
|
-
@inline export function out<T>(): T {
|
|
253
|
+
export function out<T>(): T {
|
|
270
254
|
let out: usize;
|
|
271
255
|
if (cacheOutput === 0) {
|
|
272
256
|
const len = offset - buffer;
|
|
@@ -287,6 +271,42 @@ export namespace bs {
|
|
|
287
271
|
}
|
|
288
272
|
return changetype<T>(out);
|
|
289
273
|
}
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* Like `out<T>()`, but writes the finished bytes into the existing object
|
|
277
|
+
* `target`, reusing its allocation: an in-place overwrite when the size
|
|
278
|
+
* already matches, `__renew` when it differs. Falls back to a fresh
|
|
279
|
+
* `out<T>()` when `target` is null or a static (`< __heap_base`), so callers
|
|
280
|
+
* can pass an empty/uninitialized target on the first call. Mirrors the reuse
|
|
281
|
+
* policy of `toField`, but for the top-level return value.
|
|
282
|
+
*/
|
|
283
|
+
export function outTo<T>(target: usize): T {
|
|
284
|
+
if (target < __heap_base) return out<T>();
|
|
285
|
+
let len: usize;
|
|
286
|
+
let src: usize;
|
|
287
|
+
if (cacheOutput === 0) {
|
|
288
|
+
len = offset - buffer;
|
|
289
|
+
src = buffer;
|
|
290
|
+
} else {
|
|
291
|
+
len = cacheOutputLen;
|
|
292
|
+
src = cacheOutput;
|
|
293
|
+
}
|
|
294
|
+
let dst = target;
|
|
295
|
+
if (changetype<OBJECT>(target - TOTAL_OVERHEAD).rtSize != <u32>len) {
|
|
296
|
+
// @ts-expect-error: __renew is a runtime builtin
|
|
297
|
+
dst = __renew(target, len);
|
|
298
|
+
}
|
|
299
|
+
memory.copy(dst, src, len);
|
|
300
|
+
if (cacheOutput === 0) {
|
|
301
|
+
finalizeDynamicOutput(len);
|
|
302
|
+
} else {
|
|
303
|
+
cacheOutput = 0;
|
|
304
|
+
cacheOutputLen = 0;
|
|
305
|
+
offset = buffer;
|
|
306
|
+
stackSize = 0;
|
|
307
|
+
}
|
|
308
|
+
return changetype<T>(dst);
|
|
309
|
+
}
|
|
290
310
|
}
|
|
291
311
|
|
|
292
312
|
/**
|
|
@@ -334,12 +354,9 @@ export namespace bs {
|
|
|
334
354
|
* avoiding re-serialization of previously seen strings.
|
|
335
355
|
*/
|
|
336
356
|
export namespace sc {
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
@inline export const ENTRY_PTR = offsetof<sc.Entry>("ptr");
|
|
341
|
-
// @ts-expect-error: @inline is a valid decorator
|
|
342
|
-
@inline export const ENTRY_LEN = offsetof<sc.Entry>("len");
|
|
357
|
+
export const ENTRY_KEY = offsetof<sc.Entry>("key");
|
|
358
|
+
export const ENTRY_PTR = offsetof<sc.Entry>("ptr");
|
|
359
|
+
export const ENTRY_LEN = offsetof<sc.Entry>("len");
|
|
343
360
|
|
|
344
361
|
// @ts-expect-error: JSON_CACHE may not be defined. If so, it will default to false.
|
|
345
362
|
export const CACHE_ENABLED: bool = isDefined(JSON_CACHE) ? JSON_CACHE : false;
|
|
@@ -388,8 +405,7 @@ export namespace sc {
|
|
|
388
405
|
* Uses pointer address shifted right by 4 bits (aligned to 16-byte boundaries)
|
|
389
406
|
* masked to fit within cache size.
|
|
390
407
|
*/
|
|
391
|
-
|
|
392
|
-
@inline
|
|
408
|
+
|
|
393
409
|
export function indexFor(ptr: usize): usize {
|
|
394
410
|
return (ptr >> 4) & CACHE_MASK;
|
|
395
411
|
}
|
|
@@ -400,8 +416,7 @@ export namespace sc {
|
|
|
400
416
|
* @param key - The string pointer to look up
|
|
401
417
|
* @returns true if cache hit, false if cache miss
|
|
402
418
|
*/
|
|
403
|
-
|
|
404
|
-
@inline
|
|
419
|
+
|
|
405
420
|
export function tryEmitCached(key: usize): bool {
|
|
406
421
|
const e = unchecked(entries[indexFor(key)]);
|
|
407
422
|
if (e.key == key) {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "json-as",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"author": "Jairus Tanaka",
|
|
3
|
+
"version": "1.5.0",
|
|
4
|
+
"author": "Jairus Tanaka <me@jairus.dev>",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "git+https://github.com/JairusSW/json-as.git"
|
|
@@ -11,22 +11,25 @@
|
|
|
11
11
|
"devDependencies": {
|
|
12
12
|
"@assemblyscript/wasi-shim": "^0.1.0",
|
|
13
13
|
"@eslint/js": "^10.0.1",
|
|
14
|
-
"@types/node": "^25.9.
|
|
14
|
+
"@types/node": "^25.9.2",
|
|
15
15
|
"as-heap-analyzer": "^1.2.0",
|
|
16
|
-
"as-test": "^1.
|
|
17
|
-
"assemblyscript": "^0.28.
|
|
16
|
+
"as-test": "^1.6.0",
|
|
17
|
+
"assemblyscript": "^0.28.18",
|
|
18
|
+
"assemblyscript-json": "^1.1.0",
|
|
18
19
|
"assemblyscript-prettier": "^3.0.4",
|
|
19
20
|
"chartjs-node-canvas": "^5.0.0",
|
|
20
21
|
"chartjs-plugin-datalabels": "^2.2.0",
|
|
21
|
-
"eslint": "^10.4.
|
|
22
|
+
"eslint": "^10.4.1",
|
|
23
|
+
"fast-json-parse": "^1.0.3",
|
|
24
|
+
"fast-json-stringify": "^6.4.0",
|
|
22
25
|
"husky": "^9.1.7",
|
|
23
|
-
"json-as": "
|
|
26
|
+
"json-as": "file:./",
|
|
24
27
|
"prettier": "3.8.3",
|
|
25
28
|
"serve": "^14.2.6",
|
|
26
29
|
"tinybench": "^6.0.2",
|
|
27
|
-
"try-as": "^1.1.
|
|
30
|
+
"try-as": "^1.1.4",
|
|
28
31
|
"typescript": "^6.0.3",
|
|
29
|
-
"typescript-eslint": "^8.60.
|
|
32
|
+
"typescript-eslint": "^8.60.1"
|
|
30
33
|
},
|
|
31
34
|
"bugs": {
|
|
32
35
|
"url": "https://github.com/JairusSW/json-as/issues"
|
|
@@ -95,6 +98,7 @@
|
|
|
95
98
|
"test:ci": "ast test --parallel --clean --enable try-as",
|
|
96
99
|
"test:coverage": "ast test --enable coverage --enable try-as",
|
|
97
100
|
"bench": "bash -c 'bash ./scripts/run-bench.as.sh \"$@\" && { arg=\"${1:-}\"; if [ -z \"$arg\" ] || [ \"${arg#custom/}\" = \"$arg\" ]; then bash ./scripts/run-bench.js.sh \"$@\"; fi; } && bash ./scripts/build-charts.sh' --",
|
|
101
|
+
"bench:all": "bash ./scripts/bench-all.sh",
|
|
98
102
|
"bench:as": "bash ./scripts/run-bench.as.sh",
|
|
99
103
|
"bench:js": "bash ./scripts/run-bench.js.sh",
|
|
100
104
|
"charts": "bun run charts:build && bun run charts:serve",
|
|
@@ -107,6 +111,16 @@
|
|
|
107
111
|
"test:wasmtime": "wasmtime ./build/test.wasm",
|
|
108
112
|
"test:wasmer": "wasmer ./build/test.wasm",
|
|
109
113
|
"build:transform": "tsc -p ./transform",
|
|
114
|
+
"build:playground": "npm run build:transform && JSON_DEBUG=0 JSON_WRITE=assembly/playground.ts asc assembly/playground.ts --transform ./transform -o ./build/playground.wasm --textFile ./build/playground.wat --enable simd --config ./node_modules/@assemblyscript/wasi-shim/asconfig.json",
|
|
115
|
+
"build:pg": "npm run build:playground",
|
|
116
|
+
"run:playground": "wasmtime ./build/playground.wasm",
|
|
117
|
+
"run:pg": "npm run run:playground",
|
|
118
|
+
"playground": "npm run build:playground && npm run run:playground",
|
|
119
|
+
"build:playground:tmp": "asc assembly/playground.tmp.ts -o ./build/playground.tmp.wasm --textFile ./build/playground.tmp.wat -O3 --noAssert --uncheckedBehavior always --runtime incremental --enable bulk-memory --enable simd --use JSON_MODE=1 --exportStart start --exportRuntime",
|
|
120
|
+
"playground:tmp": "npm run build:playground:tmp && v8 --no-liftoff --module ./bench/runners/assemblyscript.js -- playground.tmp.wasm",
|
|
121
|
+
"pg:tmp": "npm run playground:tmp",
|
|
122
|
+
"play": "npm run playground",
|
|
123
|
+
"pg": "npm run playground",
|
|
110
124
|
"bench:wasmer": "wasmer ./build/bench.wasm --llvm",
|
|
111
125
|
"format": "prettier -w .",
|
|
112
126
|
"lint": "eslint . --no-warn-ignored",
|
|
@@ -122,5 +136,8 @@
|
|
|
122
136
|
"prepare": "husky"
|
|
123
137
|
},
|
|
124
138
|
"type": "module",
|
|
125
|
-
"types": "assembly/index.ts"
|
|
139
|
+
"types": "assembly/index.ts",
|
|
140
|
+
"dependencies": {
|
|
141
|
+
"xjb-as": "^0.1.0"
|
|
142
|
+
}
|
|
126
143
|
}
|
package/transform/lib/builder.js
CHANGED
package/transform/lib/index.d.ts
CHANGED