json-as 1.3.2 → 1.3.4
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 +5 -0
- package/README.md +3 -2
- package/assembly/deserialize/simd/string.ts +20 -0
- package/assembly/deserialize/simple/map.ts +2 -0
- package/assembly/deserialize/simple/staticarray.ts +1 -0
- package/assembly/deserialize/simple/struct.ts +3 -1
- package/assembly/deserialize/swar/array/bool.ts +1 -0
- package/assembly/deserialize/swar/array/generic.ts +2 -1
- package/assembly/deserialize/swar/array/integer.ts +1 -0
- package/assembly/deserialize/swar/array/object.ts +1 -0
- package/assembly/deserialize/swar/array/shared.ts +18 -3
- package/assembly/deserialize/swar/array/string.ts +1 -0
- package/assembly/deserialize/swar/array/struct.ts +1 -0
- package/assembly/deserialize/swar/array.ts +1 -0
- package/assembly/deserialize/swar/string.ts +21 -2
- package/assembly/index.d.ts +1 -0
- package/assembly/index.ts +27 -22
- package/assembly/serialize/simd/string.ts +43 -16
- package/assembly/serialize/simple/array.ts +48 -6
- package/assembly/serialize/simple/bool.ts +12 -0
- package/assembly/serialize/simple/float.ts +16 -0
- package/assembly/serialize/simple/integer.ts +6 -0
- package/assembly/serialize/simple/set.ts +59 -5
- package/assembly/serialize/simple/staticarray.ts +57 -3
- package/assembly/serialize/simple/typedarray.ts +29 -9
- package/assembly/serialize/swar/string.ts +165 -18
- package/assembly/tsconfig.json +2 -2
- package/assembly/util/dragonbox-cache.ts +2 -1320
- package/assembly/util/dragonbox.ts +63 -35
- package/lib/as-bs.ts +26 -18
- package/package.json +11 -10
- package/transform/lib/index.d.ts.map +1 -1
- package/transform/lib/index.js +288 -73
- package/transform/lib/index.js.map +1 -1
|
@@ -14,43 +14,51 @@ let _dbMulIsInteger: bool = false;
|
|
|
14
14
|
let _dbParity: bool = false;
|
|
15
15
|
let _dbRemovedExponent: i32 = 0;
|
|
16
16
|
|
|
17
|
+
|
|
17
18
|
@inline
|
|
18
19
|
function rotr32(n: u32, r: i32): u32 {
|
|
19
20
|
const s = r & 31;
|
|
20
21
|
return (n >>> s) | (n << ((32 - s) & 31));
|
|
21
22
|
}
|
|
22
23
|
|
|
24
|
+
|
|
23
25
|
@inline
|
|
24
26
|
function rotr64(n: u64, r: i32): u64 {
|
|
25
27
|
const s = r & 63;
|
|
26
28
|
return (n >>> s) | (n << ((64 - s) & 63));
|
|
27
29
|
}
|
|
28
30
|
|
|
31
|
+
|
|
29
32
|
@inline
|
|
30
33
|
function floor_log10_pow2(e: i32): i32 {
|
|
31
34
|
return (e * 315653) >> 20;
|
|
32
35
|
}
|
|
33
36
|
|
|
37
|
+
|
|
34
38
|
@inline
|
|
35
39
|
function floor_log2_pow10(e: i32): i32 {
|
|
36
40
|
return (e * 1741647) >> 19;
|
|
37
41
|
}
|
|
38
42
|
|
|
43
|
+
|
|
39
44
|
@inline
|
|
40
45
|
function floor_log10_pow2_minus_log10_4_over_3(e: i32): i32 {
|
|
41
46
|
return (e * 631305 - 261663) >> 21;
|
|
42
47
|
}
|
|
43
48
|
|
|
49
|
+
|
|
44
50
|
@inline
|
|
45
51
|
function floor_log5_pow2(e: i32): i32 {
|
|
46
52
|
return (e * 225799) >> 19;
|
|
47
53
|
}
|
|
48
54
|
|
|
55
|
+
|
|
49
56
|
@inline
|
|
50
57
|
function floor_log5_pow2_minus_log5_3(e: i32): i32 {
|
|
51
58
|
return (e * 451597 - 715764) >> 20;
|
|
52
59
|
}
|
|
53
60
|
|
|
61
|
+
|
|
54
62
|
@inline
|
|
55
63
|
function umul128_upper64(x: u64, y: u64): u64 {
|
|
56
64
|
const a = <u32>(x >>> 32);
|
|
@@ -65,6 +73,7 @@ function umul128_upper64(x: u64, y: u64): u64 {
|
|
|
65
73
|
return ac + (intermediate >>> 32) + (ad >>> 32) + (bc >>> 32);
|
|
66
74
|
}
|
|
67
75
|
|
|
76
|
+
|
|
68
77
|
@inline
|
|
69
78
|
function umul96_upper64(x: u32, y: u64): u64 {
|
|
70
79
|
const yh = <u32>(y >>> 32);
|
|
@@ -74,6 +83,7 @@ function umul96_upper64(x: u32, y: u64): u64 {
|
|
|
74
83
|
return xyh + (xyl >>> 32);
|
|
75
84
|
}
|
|
76
85
|
|
|
86
|
+
|
|
77
87
|
@inline
|
|
78
88
|
function computeMul32(u: u32, cache: u64): void {
|
|
79
89
|
const r = umul96_upper64(u, cache);
|
|
@@ -81,28 +91,33 @@ function computeMul32(u: u32, cache: u64): void {
|
|
|
81
91
|
_dbMulIsInteger = <u32>r == 0;
|
|
82
92
|
}
|
|
83
93
|
|
|
94
|
+
|
|
84
95
|
@inline
|
|
85
96
|
function computeMulParity32(twoF: u32, cache: u64, beta: i32): void {
|
|
86
97
|
const r = <u64>twoF * cache;
|
|
87
98
|
_dbParity = ((r >>> (64 - beta)) & 1) != 0;
|
|
88
|
-
_dbMulIsInteger =
|
|
99
|
+
_dbMulIsInteger = <u32>(r >>> (32 - beta)) == 0;
|
|
89
100
|
}
|
|
90
101
|
|
|
102
|
+
|
|
91
103
|
@inline
|
|
92
104
|
function computeLeftEndpointShorter32(cache: u64, beta: i32): u32 {
|
|
93
105
|
return <u32>((cache - (cache >>> 25)) >>> (40 - beta));
|
|
94
106
|
}
|
|
95
107
|
|
|
108
|
+
|
|
96
109
|
@inline
|
|
97
110
|
function computeRightEndpointShorter32(cache: u64, beta: i32): u32 {
|
|
98
111
|
return <u32>((cache + (cache >>> 24)) >>> (40 - beta));
|
|
99
112
|
}
|
|
100
113
|
|
|
114
|
+
|
|
101
115
|
@inline
|
|
102
116
|
function computeRoundUpShorter32(cache: u64, beta: i32): u32 {
|
|
103
117
|
return (<u32>(cache >>> (39 - beta)) + 1) >>> 1;
|
|
104
118
|
}
|
|
105
119
|
|
|
120
|
+
|
|
106
121
|
@inline
|
|
107
122
|
function removeTrailingZeros32(significand: u32): u32 {
|
|
108
123
|
let exponent = 0;
|
|
@@ -126,22 +141,26 @@ function removeTrailingZeros32(significand: u32): u32 {
|
|
|
126
141
|
return significand;
|
|
127
142
|
}
|
|
128
143
|
|
|
144
|
+
|
|
129
145
|
@inline
|
|
130
146
|
function divideByPow10_32_1(n: u32): u32 {
|
|
131
147
|
return <u32>((<u64>n * 429496730) >>> 32);
|
|
132
148
|
}
|
|
133
149
|
|
|
150
|
+
|
|
134
151
|
@inline
|
|
135
152
|
function divideByPow10_32_2(n: u32): u32 {
|
|
136
153
|
return <u32>((<u64>n * 1374389535) >>> 37);
|
|
137
154
|
}
|
|
138
155
|
|
|
156
|
+
|
|
139
157
|
@inline
|
|
140
158
|
function checkDivisibilityAndDivideByPow10_32_1(n: u32): u64 {
|
|
141
159
|
const prod = <u32>(n * 6554);
|
|
142
|
-
return (<u64>(prod >>> 16) << 32) | ((
|
|
160
|
+
return ((<u64>(prod >>> 16)) << 32) | ((prod & 0xffff) < 6554 ? 1 : 0);
|
|
143
161
|
}
|
|
144
162
|
|
|
163
|
+
|
|
145
164
|
@inline
|
|
146
165
|
function computeMul64(u: u64, cacheHigh: u64, cacheLow: u64): void {
|
|
147
166
|
const high = umul128_upper64(u, cacheHigh);
|
|
@@ -167,6 +186,7 @@ function computeMul64(u: u64, cacheHigh: u64, cacheLow: u64): void {
|
|
|
167
186
|
_dbMulIsInteger = rLow == 0;
|
|
168
187
|
}
|
|
169
188
|
|
|
189
|
+
|
|
170
190
|
@inline
|
|
171
191
|
function computeMulParity64(twoF: u64, cacheHigh: u64, cacheLow: u64, beta: i32): void {
|
|
172
192
|
const high = twoF * cacheHigh;
|
|
@@ -185,24 +205,28 @@ function computeMulParity64(twoF: u64, cacheHigh: u64, cacheLow: u64, beta: i32)
|
|
|
185
205
|
|
|
186
206
|
const rHigh = high + lowHigh;
|
|
187
207
|
_dbParity = ((rHigh >>> (64 - beta)) & 1) != 0;
|
|
188
|
-
_dbMulIsInteger = (((
|
|
208
|
+
_dbMulIsInteger = (((rHigh << beta) & 0xffffffffffffffff) | (lowLow >>> (64 - beta))) == 0;
|
|
189
209
|
}
|
|
190
210
|
|
|
211
|
+
|
|
191
212
|
@inline
|
|
192
213
|
function computeLeftEndpointShorter64(cacheHigh: u64, beta: i32): u64 {
|
|
193
214
|
return (cacheHigh - (cacheHigh >>> 54)) >>> (11 - beta);
|
|
194
215
|
}
|
|
195
216
|
|
|
217
|
+
|
|
196
218
|
@inline
|
|
197
219
|
function computeRightEndpointShorter64(cacheHigh: u64, beta: i32): u64 {
|
|
198
220
|
return (cacheHigh + (cacheHigh >>> 53)) >>> (11 - beta);
|
|
199
221
|
}
|
|
200
222
|
|
|
223
|
+
|
|
201
224
|
@inline
|
|
202
225
|
function computeRoundUpShorter64(cacheHigh: u64, beta: i32): u64 {
|
|
203
226
|
return ((cacheHigh >>> (10 - beta)) + 1) >>> 1;
|
|
204
227
|
}
|
|
205
228
|
|
|
229
|
+
|
|
206
230
|
@inline
|
|
207
231
|
function removeTrailingZeros64(significand: u64): u64 {
|
|
208
232
|
let exponent = 0;
|
|
@@ -231,22 +255,26 @@ function removeTrailingZeros64(significand: u64): u64 {
|
|
|
231
255
|
return significand;
|
|
232
256
|
}
|
|
233
257
|
|
|
258
|
+
|
|
234
259
|
@inline
|
|
235
260
|
function divideByPow10_64_1(n: u64): u64 {
|
|
236
261
|
return umul128_upper64(n, 1844674407370955162);
|
|
237
262
|
}
|
|
238
263
|
|
|
264
|
+
|
|
239
265
|
@inline
|
|
240
266
|
function divideByPow10_64_3(n: u64): u64 {
|
|
241
267
|
return umul128_upper64(n, 4722366482869645214) >>> 8;
|
|
242
268
|
}
|
|
243
269
|
|
|
270
|
+
|
|
244
271
|
@inline
|
|
245
272
|
function checkDivisibilityAndDivideByPow10_64_2(n: u64): u64 {
|
|
246
273
|
const prod = <u32>(n * 656);
|
|
247
|
-
return (<u64>(prod >>> 16) << 32) | ((
|
|
274
|
+
return ((<u64>(prod >>> 16)) << 32) | ((prod & 0xffff) < 656 ? 1 : 0);
|
|
248
275
|
}
|
|
249
276
|
|
|
277
|
+
|
|
250
278
|
@inline
|
|
251
279
|
function genExponent(buffer: usize, k: i32): i32 {
|
|
252
280
|
let negative = k < 0;
|
|
@@ -262,7 +290,7 @@ function prettify(buffer: usize, length: i32, k: i32): i32 {
|
|
|
262
290
|
if (fast >= 0) return fast;
|
|
263
291
|
|
|
264
292
|
if (!k) {
|
|
265
|
-
const tail = buffer + (<usize>length << 1);
|
|
293
|
+
const tail = buffer + ((<usize>length) << 1);
|
|
266
294
|
store<u16>(tail, CHAR_DOT);
|
|
267
295
|
store<u16>(tail, CHAR_0, 2);
|
|
268
296
|
return length + 2;
|
|
@@ -270,29 +298,29 @@ function prettify(buffer: usize, length: i32, k: i32): i32 {
|
|
|
270
298
|
|
|
271
299
|
const kk = length + k;
|
|
272
300
|
if (length <= kk && kk <= 21) {
|
|
273
|
-
for (let i = length; i < kk; ++i) store<u16>(buffer + (<usize>i << 1), CHAR_0);
|
|
274
|
-
const tail = buffer + (<usize>kk << 1);
|
|
301
|
+
for (let i = length; i < kk; ++i) store<u16>(buffer + ((<usize>i) << 1), CHAR_0);
|
|
302
|
+
const tail = buffer + ((<usize>kk) << 1);
|
|
275
303
|
store<u16>(tail, CHAR_DOT);
|
|
276
304
|
store<u16>(tail, CHAR_0, 2);
|
|
277
305
|
return kk + 2;
|
|
278
306
|
} else if (kk > 0 && kk <= 21) {
|
|
279
|
-
const ptr = buffer + (<usize>kk << 1);
|
|
280
|
-
memory.copy(ptr + 2, ptr, <usize
|
|
281
|
-
store<u16>(buffer + (<usize>kk << 1), CHAR_DOT);
|
|
307
|
+
const ptr = buffer + ((<usize>kk) << 1);
|
|
308
|
+
memory.copy(ptr + 2, ptr, (<usize>-k) << 1);
|
|
309
|
+
store<u16>(buffer + ((<usize>kk) << 1), CHAR_DOT);
|
|
282
310
|
return length + 1;
|
|
283
311
|
} else if (-6 < kk && kk <= 0) {
|
|
284
312
|
const offset = 2 - kk;
|
|
285
|
-
memory.copy(buffer + (<usize>offset << 1), buffer, <usize>length << 1);
|
|
313
|
+
memory.copy(buffer + ((<usize>offset) << 1), buffer, (<usize>length) << 1);
|
|
286
314
|
store<u16>(buffer, CHAR_0);
|
|
287
315
|
store<u16>(buffer, CHAR_DOT, 2);
|
|
288
|
-
for (let i = 2; i < offset; ++i) store<u16>(buffer + (<usize>i << 1), CHAR_0);
|
|
316
|
+
for (let i = 2; i < offset; ++i) store<u16>(buffer + ((<usize>i) << 1), CHAR_0);
|
|
289
317
|
return length + offset;
|
|
290
318
|
} else if (length == 1) {
|
|
291
319
|
store<u16>(buffer, CHAR_E, 2);
|
|
292
320
|
length = genExponent(buffer + 4, kk - 1);
|
|
293
321
|
return length + 2;
|
|
294
322
|
} else {
|
|
295
|
-
const len = <usize>length << 1;
|
|
323
|
+
const len = (<usize>length) << 1;
|
|
296
324
|
memory.copy(buffer + 4, buffer + 2, len - 2);
|
|
297
325
|
store<u16>(buffer, CHAR_DOT, 2);
|
|
298
326
|
store<u16>(buffer + len, CHAR_E, 2);
|
|
@@ -303,7 +331,7 @@ function prettify(buffer: usize, length: i32, k: i32): i32 {
|
|
|
303
331
|
|
|
304
332
|
function prettifyFast(buffer: usize, length: i32, k: i32): i32 {
|
|
305
333
|
if (k == 0) {
|
|
306
|
-
const tail = buffer + (<usize>length << 1);
|
|
334
|
+
const tail = buffer + ((<usize>length) << 1);
|
|
307
335
|
store<u16>(tail, CHAR_DOT);
|
|
308
336
|
store<u16>(tail, CHAR_0, 2);
|
|
309
337
|
return length + 2;
|
|
@@ -312,24 +340,24 @@ function prettifyFast(buffer: usize, length: i32, k: i32): i32 {
|
|
|
312
340
|
const kk = length + k;
|
|
313
341
|
if (length <= kk && kk <= 21) {
|
|
314
342
|
for (let i = length; i < kk; ++i) {
|
|
315
|
-
store<u16>(buffer + (<usize>i << 1), CHAR_0);
|
|
343
|
+
store<u16>(buffer + ((<usize>i) << 1), CHAR_0);
|
|
316
344
|
}
|
|
317
|
-
const tail = buffer + (<usize>kk << 1);
|
|
345
|
+
const tail = buffer + ((<usize>kk) << 1);
|
|
318
346
|
store<u16>(tail, CHAR_DOT);
|
|
319
347
|
store<u16>(tail, CHAR_0, 2);
|
|
320
348
|
return kk + 2;
|
|
321
349
|
} else if (kk > 0 && kk <= 21) {
|
|
322
|
-
const ptr = buffer + (<usize>kk << 1);
|
|
323
|
-
memory.copy(ptr + 2, ptr, <usize>(length - kk) << 1);
|
|
324
|
-
store<u16>(buffer + (<usize>kk << 1), CHAR_DOT);
|
|
350
|
+
const ptr = buffer + ((<usize>kk) << 1);
|
|
351
|
+
memory.copy(ptr + 2, ptr, (<usize>(length - kk)) << 1);
|
|
352
|
+
store<u16>(buffer + ((<usize>kk) << 1), CHAR_DOT);
|
|
325
353
|
return length + 1;
|
|
326
354
|
} else if (-6 < kk && kk <= 0) {
|
|
327
355
|
const offset = 2 - kk;
|
|
328
|
-
memory.copy(buffer + (<usize>offset << 1), buffer, <usize>length << 1);
|
|
356
|
+
memory.copy(buffer + ((<usize>offset) << 1), buffer, (<usize>length) << 1);
|
|
329
357
|
store<u16>(buffer, CHAR_0);
|
|
330
358
|
store<u16>(buffer, CHAR_DOT, 2);
|
|
331
359
|
for (let i = 2; i < offset; ++i) {
|
|
332
|
-
store<u16>(buffer + (<usize>i << 1), CHAR_0);
|
|
360
|
+
store<u16>(buffer + ((<usize>i) << 1), CHAR_0);
|
|
333
361
|
}
|
|
334
362
|
return length + offset;
|
|
335
363
|
}
|
|
@@ -346,7 +374,7 @@ function dragonboxToDecimalF32(binarySignificand: u32, binaryExponent: i32): u32
|
|
|
346
374
|
if (twoFc == 0) {
|
|
347
375
|
const minusK = floor_log10_pow2_minus_log10_4_over_3(binaryExponent);
|
|
348
376
|
const beta = binaryExponent + floor_log2_pow10(-minusK);
|
|
349
|
-
const cache = load<u64>(DRAGONBOX_F32_CACHE + (<usize>(31 - minusK) << 3));
|
|
377
|
+
const cache = load<u64>(DRAGONBOX_F32_CACHE + ((<usize>(31 - minusK)) << 3));
|
|
350
378
|
let xi = computeLeftEndpointShorter32(cache, beta);
|
|
351
379
|
const zi = computeRightEndpointShorter32(cache, beta);
|
|
352
380
|
if (!(binaryExponent >= 2 && binaryExponent <= 3)) ++xi;
|
|
@@ -370,7 +398,7 @@ function dragonboxToDecimalF32(binarySignificand: u32, binaryExponent: i32): u32
|
|
|
370
398
|
}
|
|
371
399
|
|
|
372
400
|
const minusK = floor_log10_pow2(binaryExponent) - 1;
|
|
373
|
-
const cache = load<u64>(DRAGONBOX_F32_CACHE + (<usize>(31 - minusK) << 3));
|
|
401
|
+
const cache = load<u64>(DRAGONBOX_F32_CACHE + ((<usize>(31 - minusK)) << 3));
|
|
374
402
|
const beta = binaryExponent + floor_log2_pow10(-minusK);
|
|
375
403
|
const deltai = <u32>(cache >>> (63 - beta));
|
|
376
404
|
|
|
@@ -432,7 +460,7 @@ function dragonboxToDecimalF64(binarySignificand: u64, binaryExponent: i32): u64
|
|
|
432
460
|
if (twoFc == 0) {
|
|
433
461
|
const minusK = floor_log10_pow2_minus_log10_4_over_3(binaryExponent);
|
|
434
462
|
const beta = binaryExponent + floor_log2_pow10(-minusK);
|
|
435
|
-
const idx = <usize>(292 - minusK) << 4;
|
|
463
|
+
const idx = (<usize>(292 - minusK)) << 4;
|
|
436
464
|
const cacheHigh = load<u64>(DRAGONBOX_F64_CACHE + idx);
|
|
437
465
|
const cacheLow = load<u64>(DRAGONBOX_F64_CACHE + idx + 8);
|
|
438
466
|
let xi = computeLeftEndpointShorter64(cacheHigh, beta);
|
|
@@ -458,7 +486,7 @@ function dragonboxToDecimalF64(binarySignificand: u64, binaryExponent: i32): u64
|
|
|
458
486
|
}
|
|
459
487
|
|
|
460
488
|
const minusK = floor_log10_pow2(binaryExponent) - 2;
|
|
461
|
-
const idx = <usize>(292 - minusK) << 4;
|
|
489
|
+
const idx = (<usize>(292 - minusK)) << 4;
|
|
462
490
|
const cacheHigh = load<u64>(DRAGONBOX_F64_CACHE + idx);
|
|
463
491
|
const cacheLow = load<u64>(DRAGONBOX_F64_CACHE + idx + 8);
|
|
464
492
|
const beta = binaryExponent + floor_log2_pow10(-minusK);
|
|
@@ -520,9 +548,9 @@ function dragonboxCoreF32(buffer: usize, value: f32): u32 {
|
|
|
520
548
|
value = -value;
|
|
521
549
|
store<u16>(buffer, CHAR_MINUS);
|
|
522
550
|
}
|
|
523
|
-
const digits = dragonboxToDecimalF32(reinterpret<u32>(value) &
|
|
524
|
-
let len = itoa_buffered<u32>(buffer + (<usize>sign << 1), digits);
|
|
525
|
-
return <u32>(prettify(buffer + (<usize>sign << 1), len, _dbK) + sign);
|
|
551
|
+
const digits = dragonboxToDecimalF32(reinterpret<u32>(value) & 0x7fffff, (reinterpret<u32>(value) >>> 23) & 0xff);
|
|
552
|
+
let len = itoa_buffered<u32>(buffer + ((<usize>sign) << 1), digits);
|
|
553
|
+
return <u32>(prettify(buffer + ((<usize>sign) << 1), len, _dbK) + sign);
|
|
526
554
|
}
|
|
527
555
|
|
|
528
556
|
function dragonboxCoreF64(buffer: usize, value: f64): u32 {
|
|
@@ -533,9 +561,9 @@ function dragonboxCoreF64(buffer: usize, value: f64): u32 {
|
|
|
533
561
|
store<u16>(buffer, CHAR_MINUS);
|
|
534
562
|
}
|
|
535
563
|
const bits = reinterpret<u64>(value);
|
|
536
|
-
const digits = dragonboxToDecimalF64(bits &
|
|
537
|
-
let len = itoa_buffered<u64>(buffer + (<usize>sign << 1), digits);
|
|
538
|
-
return <u32>(prettify(buffer + (<usize>sign << 1), len, _dbK) + sign);
|
|
564
|
+
const digits = dragonboxToDecimalF64(bits & 0x000fffffffffffff, <i32>((bits >>> 52) & 0x7ff));
|
|
565
|
+
let len = itoa_buffered<u64>(buffer + ((<usize>sign) << 1), digits);
|
|
566
|
+
return <u32>(prettify(buffer + ((<usize>sign) << 1), len, _dbK) + sign);
|
|
539
567
|
}
|
|
540
568
|
|
|
541
569
|
export function dragonbox_f32_buffered(buffer: usize, value: f32): u32 {
|
|
@@ -557,8 +585,8 @@ export function dragonbox_f32_buffered(buffer: usize, value: f32): u32 {
|
|
|
557
585
|
store<u16>(buffer, CHAR_MINUS);
|
|
558
586
|
buffer += 2;
|
|
559
587
|
}
|
|
560
|
-
store<u64>(buffer,
|
|
561
|
-
store<u64>(buffer + 8,
|
|
588
|
+
store<u64>(buffer, 0x690066006e0049);
|
|
589
|
+
store<u64>(buffer + 8, 0x7900740069006e);
|
|
562
590
|
return 8 + (sign ? 1 : 0);
|
|
563
591
|
}
|
|
564
592
|
return dragonboxCoreF32(buffer, value);
|
|
@@ -583,8 +611,8 @@ export function dragonbox_f64_buffered(buffer: usize, value: f64): u32 {
|
|
|
583
611
|
store<u16>(buffer, CHAR_MINUS);
|
|
584
612
|
buffer += 2;
|
|
585
613
|
}
|
|
586
|
-
store<u64>(buffer,
|
|
587
|
-
store<u64>(buffer + 8,
|
|
614
|
+
store<u64>(buffer, 0x690066006e0049);
|
|
615
|
+
store<u64>(buffer + 8, 0x7900740069006e);
|
|
588
616
|
return 8 + (sign ? 1 : 0);
|
|
589
617
|
}
|
|
590
618
|
return dragonboxCoreF64(buffer, value);
|
package/lib/as-bs.ts
CHANGED
|
@@ -190,7 +190,6 @@ export namespace bs {
|
|
|
190
190
|
}
|
|
191
191
|
}
|
|
192
192
|
|
|
193
|
-
|
|
194
193
|
/**
|
|
195
194
|
* Copies the slice starting at a caller-provided relative buffer offset and restores
|
|
196
195
|
* `offset` back to that slice start.
|
|
@@ -287,18 +286,21 @@ export namespace bs {
|
|
|
287
286
|
*
|
|
288
287
|
* Enable caching by setting the `JSON_CACHE` environment variable:
|
|
289
288
|
* ```bash
|
|
290
|
-
* JSON_CACHE=
|
|
289
|
+
* JSON_CACHE=true npx asc your-file.ts --transform json-as/transform
|
|
291
290
|
* ```
|
|
292
291
|
*
|
|
293
|
-
*
|
|
292
|
+
* You can also configure cache size directly:
|
|
293
|
+
* - `JSON_CACHE=<int>` => bytes
|
|
294
|
+
* - `JSON_CACHE=<int>kb|mb|gb` => kilobits/megabits/gigabits
|
|
295
|
+
* - `JSON_CACHE=<int>KB|MB|GB` => kilobytes/megabytes/gigabytes
|
|
294
296
|
*
|
|
295
|
-
*
|
|
297
|
+
* ## Memory Configuration
|
|
296
298
|
*
|
|
297
|
-
*
|
|
298
|
-
*
|
|
299
|
-
* Memory usage: ~49KB (4096 * 12 bytes per entry)
|
|
299
|
+
* The cache uses a size budget from `JSON_CACHE` (or defaults to 1MB when
|
|
300
|
+
* enabled with `true/on/yes`):
|
|
300
301
|
*
|
|
301
|
-
* - **
|
|
302
|
+
* - **CACHE_SIZE**: Number of direct-mapped cache slots. Derived from budget.
|
|
303
|
+
* - **ARENA_SIZE**: Circular buffer for storing cached serialized strings.
|
|
302
304
|
* When full, wraps around and overwrites oldest entries. Larger values retain
|
|
303
305
|
* more cached data but consume more memory.
|
|
304
306
|
*
|
|
@@ -325,16 +327,20 @@ export namespace sc {
|
|
|
325
327
|
// @ts-expect-error: @inline is a valid decorator
|
|
326
328
|
@inline export const ENTRY_LEN = offsetof<sc.Entry>("len");
|
|
327
329
|
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
export const CACHE_MASK = CACHE_SIZE - 1;
|
|
333
|
-
|
|
334
|
-
/** Size of the circular arena buffer for cached strings (1MB) */
|
|
335
|
-
export const ARENA_SIZE = 1 << 20;
|
|
330
|
+
// @ts-expect-error: JSON_CACHE may not be defined. If so, it will default to false.
|
|
331
|
+
export const CACHE_ENABLED: bool = isDefined(JSON_CACHE) ? JSON_CACHE : false;
|
|
332
|
+
// @ts-expect-error: JSON_CACHE_SIZE may not be defined. If so, it will default to 1MB.
|
|
333
|
+
export const CACHE_BYTES: usize = isDefined(JSON_CACHE_SIZE) ? <usize>JSON_CACHE_SIZE : (1 << 20);
|
|
336
334
|
/** Minimum serialized length to cache - smaller outputs aren't worth caching */
|
|
337
335
|
export const MIN_CACHE_LEN: usize = 128;
|
|
336
|
+
/** Size of the circular arena buffer for cached strings */
|
|
337
|
+
export const ARENA_SIZE: usize = CACHE_BYTES >= MIN_CACHE_LEN ? CACHE_BYTES : MIN_CACHE_LEN;
|
|
338
|
+
|
|
339
|
+
/** Number of cache slots (power of 2 for efficient masking). Set to 0 when caching disabled. */
|
|
340
|
+
const CACHE_SIZE_BASE: i32 = CACHE_ENABLED ? i32((ARENA_SIZE >> 10) >= 1 ? (ARENA_SIZE >> 10) : 1) : 0;
|
|
341
|
+
export const CACHE_SIZE: usize = CACHE_ENABLED ? <usize>(1 << (32 - clz<i32>(CACHE_SIZE_BASE - 1))) : 0;
|
|
342
|
+
/** Bitmask for fast modulo operation on cache index */
|
|
343
|
+
export const CACHE_MASK: usize = CACHE_SIZE > 0 ? CACHE_SIZE - 1 : 0;
|
|
338
344
|
|
|
339
345
|
/** Cache entry structure - stores pointer to string, cached output location, and length */
|
|
340
346
|
@unmanaged
|
|
@@ -348,9 +354,9 @@ export namespace sc {
|
|
|
348
354
|
}
|
|
349
355
|
|
|
350
356
|
/** Static array of cache entries */
|
|
351
|
-
export const entries = new StaticArray<sc.Entry>(CACHE_SIZE);
|
|
357
|
+
export const entries = new StaticArray<sc.Entry>(i32(CACHE_SIZE));
|
|
352
358
|
/** Circular buffer arena for storing cached serialized strings */
|
|
353
|
-
export const arena = new ArrayBuffer(ARENA_SIZE);
|
|
359
|
+
export const arena = new ArrayBuffer(i32(ARENA_SIZE));
|
|
354
360
|
/** Current write position in the arena */
|
|
355
361
|
export let arenaPtr: usize = changetype<usize>(arena);
|
|
356
362
|
/** End boundary of the arena */
|
|
@@ -394,7 +400,9 @@ export namespace sc {
|
|
|
394
400
|
* @param len - Length of serialized output
|
|
395
401
|
*/
|
|
396
402
|
export function insertCached(str: usize, start: usize, len: usize): void {
|
|
403
|
+
if (!CACHE_ENABLED || ARENA_SIZE == 0) return;
|
|
397
404
|
if (len < MIN_CACHE_LEN) return;
|
|
405
|
+
if (len > ARENA_SIZE) return;
|
|
398
406
|
if (arenaPtr + len > arenaEnd) {
|
|
399
407
|
// Wrap around to beginning of arena (circular buffer)
|
|
400
408
|
arenaPtr = changetype<usize>(arena);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "json-as",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.4",
|
|
4
4
|
"author": "Jairus Tanaka",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -10,19 +10,19 @@
|
|
|
10
10
|
"main": "transform/lib/index.js",
|
|
11
11
|
"devDependencies": {
|
|
12
12
|
"@assemblyscript/wasi-shim": "^0.1.0",
|
|
13
|
-
"@eslint/js": "^
|
|
14
|
-
"@types/node": "^25.0
|
|
15
|
-
"as-test": "^1.0.
|
|
16
|
-
"assemblyscript": "^0.28.
|
|
17
|
-
"assemblyscript-prettier": "^3.0.
|
|
13
|
+
"@eslint/js": "^10.0.1",
|
|
14
|
+
"@types/node": "^25.6.0",
|
|
15
|
+
"as-test": "^1.0.7",
|
|
16
|
+
"assemblyscript": "^0.28.14",
|
|
17
|
+
"assemblyscript-prettier": "^3.0.4",
|
|
18
18
|
"chartjs-node-canvas": "^5.0.0",
|
|
19
19
|
"chartjs-plugin-datalabels": "^2.2.0",
|
|
20
|
-
"eslint": "^10.
|
|
21
|
-
"prettier": "3.8.
|
|
20
|
+
"eslint": "^10.2.0",
|
|
21
|
+
"prettier": "3.8.3",
|
|
22
22
|
"serve": "^14.2.6",
|
|
23
23
|
"tinybench": "^6.0.0",
|
|
24
|
-
"typescript": "^
|
|
25
|
-
"typescript-eslint": "^8.
|
|
24
|
+
"typescript": "^6.0.2",
|
|
25
|
+
"typescript-eslint": "^8.58.2"
|
|
26
26
|
},
|
|
27
27
|
"bugs": {
|
|
28
28
|
"url": "https://github.com/JairusSW/json-as/issues"
|
|
@@ -91,6 +91,7 @@
|
|
|
91
91
|
"bench": "npm run bench:as && npm run bench:js && npm run charts:build",
|
|
92
92
|
"bench:as": "bash ./scripts/run-bench.as.sh",
|
|
93
93
|
"bench:js": "bash ./scripts/run-bench.js.sh",
|
|
94
|
+
"charts": "bun run charts:build && bun run charts:serve",
|
|
94
95
|
"charts:build": "bash ./scripts/build-charts.sh",
|
|
95
96
|
"charts:publish": "bash ./scripts/publish-benchmarks.sh",
|
|
96
97
|
"charts:serve": "serve ./build/charts/",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAA4G,eAAe,EAA8G,MAAM,EAAE,OAAO,EAAS,MAAM,EAA6C,MAAM,uCAAuC,CAAC;AAC3X,OAAO,EAAE,SAAS,EAAE,MAAM,kCAAkC,CAAC;AAK7D,OAAO,EAA2B,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AAE7E,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAA4G,eAAe,EAA8G,MAAM,EAAE,OAAO,EAAS,MAAM,EAA6C,MAAM,uCAAuC,CAAC;AAC3X,OAAO,EAAE,SAAS,EAAE,MAAM,kCAAkC,CAAC;AAK7D,OAAO,EAA2B,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AAE7E,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAuJvC,qBAAa,aAAc,SAAQ,OAAO;IACxC,MAAM,CAAC,EAAE,EAAE,aAAa,CAAuB;IAExC,OAAO,EAAG,OAAO,CAAC;IAClB,OAAO,EAAG,MAAM,CAAC;IACjB,MAAM,EAAG,MAAM,CAAC;IAChB,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAA+B;IAC7D,MAAM,EAAG,MAAM,CAAC;IAChB,OAAO,EAAE,SAAS,CAAmB;IACrC,OAAO,EAAE,eAAe,EAAE,CAAM;IAChC,cAAc,EAAE,MAAM,EAAE,CAAM;IAE9B,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,CAAqB;IAEvD,OAAO,CAAC,4BAA4B;IA6CpC,wBAAwB,CAAC,IAAI,EAAE,gBAAgB,GAAG,IAAI;IAYtD,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,cAAoB,GAAG,MAAM;IAsC3E,qBAAqB,CAAC,IAAI,EAAE,gBAAgB,GAAG,IAAI;IAuiDnD,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAItC,oBAAoB,CAAC,IAAI,EAAE,gBAAgB,GAAG,IAAI;IA4ClD,oBAAoB,CAAC,IAAI,EAAE,eAAe,GAAG,IAAI;IAIjD,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAI/B,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IA+J9B,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,OAAe,GAAG,MAAM,EAAE;IA0BxD,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,gBAAgB,GAAG,OAAO;CAc3D;AA4BD,MAAM,CAAC,OAAO,OAAO,WAAY,SAAQ,SAAS;IAChD,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAyBvD,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;CAwDjC;AA+MD,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAO9C"}
|