json-as 1.2.1 → 1.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +31 -1
- package/assembly/deserialize/simd/string.ts +62 -63
- package/assembly/deserialize/simple/arbitrary.ts +4 -4
- package/assembly/deserialize/simple/array/arbitrary.ts +1 -1
- package/assembly/index.d.ts +9 -0
- package/assembly/index.ts +211 -112
- package/assembly/serialize/simd/string.ts +16 -3
- package/assembly/serialize/simple/arbitrary.ts +16 -2
- package/assembly/serialize/swar/string.ts +41 -15
- package/assembly/test.ts +38 -0
- package/lib/as-bs.ts +113 -22
- package/package.json +4 -3
- package/transform/lib/index.js +34 -1
- package/transform/lib/index.js.map +1 -1
- package/.github/FUNDING.yml +0 -1
- package/.github/dependabot.yml +0 -11
- package/.github/workflows/benchmark.yml +0 -72
- package/.github/workflows/release-package.yml +0 -47
- package/.github/workflows/tests.yml +0 -25
- package/.prettierignore +0 -9
- package/.prettierrc.json +0 -7
- package/.trunk/configs/.markdownlint.yaml +0 -2
- package/.trunk/configs/.shellcheckrc +0 -7
- package/.trunk/configs/.yamllint.yaml +0 -7
- package/.trunk/trunk.yaml +0 -37
- package/CHANGELOG.md +0 -334
- package/SECURITY.md +0 -32
- package/asconfig.json +0 -7
- package/assembly/__benches__/abc.bench.ts +0 -28
- package/assembly/__benches__/large.bench.ts +0 -238
- package/assembly/__benches__/lib/bench.ts +0 -85
- package/assembly/__benches__/medium.bench.ts +0 -128
- package/assembly/__benches__/small.bench.ts +0 -46
- package/assembly/__benches__/throughput.ts +0 -172
- package/assembly/__benches__/vec3.bench.ts +0 -37
- package/assembly/__tests__/arbitrary.spec.ts +0 -35
- package/assembly/__tests__/array.spec.ts +0 -145
- package/assembly/__tests__/bool.spec.ts +0 -12
- package/assembly/__tests__/box.spec.ts +0 -27
- package/assembly/__tests__/custom.spec.ts +0 -56
- package/assembly/__tests__/date.spec.ts +0 -36
- package/assembly/__tests__/enum.spec.ts +0 -35
- package/assembly/__tests__/float.spec.ts +0 -42
- package/assembly/__tests__/generics.spec.ts +0 -49
- package/assembly/__tests__/hierarchy.spec.ts +0 -61
- package/assembly/__tests__/integer.spec.ts +0 -26
- package/assembly/__tests__/lib/index.ts +0 -41
- package/assembly/__tests__/map.spec.ts +0 -7
- package/assembly/__tests__/namespace.spec.ts +0 -63
- package/assembly/__tests__/null.spec.ts +0 -12
- package/assembly/__tests__/raw.spec.ts +0 -23
- package/assembly/__tests__/resolving.spec.ts +0 -55
- package/assembly/__tests__/staticarray.spec.ts +0 -12
- package/assembly/__tests__/string.spec.ts +0 -30
- package/assembly/__tests__/struct.spec.ts +0 -163
- package/assembly/__tests__/test.spec.ts +0 -3
- package/assembly/__tests__/types.spec.ts +0 -27
- package/assembly/__tests__/types.ts +0 -98
- package/assembly/test.tmp.ts +0 -133
- package/bench/abc.bench.ts +0 -25
- package/bench/large.bench.ts +0 -127
- package/bench/lib/bench.d.ts +0 -27
- package/bench/lib/bench.js +0 -53
- package/bench/lib/chart.ts +0 -217
- package/bench/medium.bench.ts +0 -68
- package/bench/runners/assemblyscript.js +0 -34
- package/bench/small.bench.ts +0 -34
- package/bench/throughput.ts +0 -87
- package/bench/tsconfig.json +0 -13
- package/bench/vec3.bench.ts +0 -30
- package/bench.ts +0 -18
- package/ci/bench/lib/bench.ts +0 -42
- package/ci/bench/runners/assemblyscript.js +0 -29
- package/ci/run-bench.as.sh +0 -63
- package/publish.sh +0 -78
- package/run-bench.as.sh +0 -60
- package/run-bench.js.sh +0 -36
- package/run-tests.sh +0 -51
- package/scripts/build-chart01.ts +0 -38
- package/scripts/build-chart02.ts +0 -38
- package/scripts/build-chart03.ts +0 -139
- package/scripts/build-chart05.ts +0 -47
- package/scripts/generate-as-class.ts +0 -50
- package/scripts/lib/bench-utils.ts +0 -308
- package/transform/src/builder.ts +0 -1375
- package/transform/src/index.ts +0 -1486
- package/transform/src/linkers/alias.ts +0 -58
- package/transform/src/linkers/custom.ts +0 -32
- package/transform/src/linkers/imports.ts +0 -22
- package/transform/src/types.ts +0 -300
- package/transform/src/util.ts +0 -128
- package/transform/src/visitor.ts +0 -530
package/assembly/index.ts
CHANGED
|
@@ -31,8 +31,8 @@ import { serializeString_SIMD } from "./serialize/simd/string";
|
|
|
31
31
|
import { serializeString_SWAR } from "./serialize/swar/string";
|
|
32
32
|
import { deserializeString_SWAR } from "./deserialize/swar/string";
|
|
33
33
|
import { deserializeString } from "./deserialize/simple/string";
|
|
34
|
+
import { serializeString } from "./serialize/simple/string";
|
|
34
35
|
// import { deserializeString_SIMD } from "./deserialize/simd/string";
|
|
35
|
-
|
|
36
36
|
/**
|
|
37
37
|
* Offset of the 'storage' property in the JSON.Value class.
|
|
38
38
|
*/
|
|
@@ -106,21 +106,12 @@ export namespace JSON {
|
|
|
106
106
|
return NULL_WORD;
|
|
107
107
|
// @ts-ignore
|
|
108
108
|
} else if (isString<nonnull<T>>()) {
|
|
109
|
-
|
|
110
|
-
// out = changetype<string>(__renew(changetype<usize>(out), bytes(data) + 4));
|
|
111
|
-
// // const oldSize = bs.byteLength;
|
|
112
|
-
// const oldBuf = bs.buffer;
|
|
113
|
-
// const newSize = bytes(data) + 4;
|
|
114
|
-
// const newBuf = __new(newSize, idof<string>());
|
|
115
|
-
// bs.setBuffer(newBuf);
|
|
116
|
-
// serializeString_SWAR(changetype<string>(data));
|
|
117
|
-
// bs.setBuffer(oldBuf);
|
|
118
|
-
// return changetype<string>(newBuf);
|
|
119
|
-
// }
|
|
120
|
-
if (ASC_FEATURE_SIMD) {
|
|
109
|
+
if (JSON_MODE === JSONMode.SIMD) {
|
|
121
110
|
serializeString_SIMD(data as string);
|
|
122
|
-
} else {
|
|
111
|
+
} else if (JSON_MODE === JSONMode.SWAR) {
|
|
123
112
|
serializeString_SWAR(data as string);
|
|
113
|
+
} else {
|
|
114
|
+
serializeString(data as string);
|
|
124
115
|
}
|
|
125
116
|
return bs.out<string>();
|
|
126
117
|
// @ts-ignore: Supplied by transform
|
|
@@ -187,7 +178,7 @@ export namespace JSON {
|
|
|
187
178
|
// // @ts-ignore
|
|
188
179
|
// return changetype<string>(deserializeString_SIMD(dataPtr, dataPtr + dataSize, __new(dataSize - 4, idof<string>())));
|
|
189
180
|
// } else {
|
|
190
|
-
|
|
181
|
+
|
|
191
182
|
// @ts-ignore
|
|
192
183
|
return deserializeString(dataPtr, dataPtr + dataSize, 0);
|
|
193
184
|
// }
|
|
@@ -232,19 +223,31 @@ export namespace JSON {
|
|
|
232
223
|
* Enum representing the different types supported by JSON.
|
|
233
224
|
*/
|
|
234
225
|
export enum Types {
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
226
|
+
StructNull = -12,
|
|
227
|
+
ArrayNull = -11,
|
|
228
|
+
ObjectNull = -10,
|
|
229
|
+
StringNull = -9,
|
|
230
|
+
BoolNull = -8,
|
|
231
|
+
F64Null = -7,
|
|
232
|
+
F32Null = -6,
|
|
233
|
+
U64Null = -5,
|
|
234
|
+
U32Null = -4,
|
|
235
|
+
U16Null = -3,
|
|
236
|
+
U8Null = -2,
|
|
237
|
+
RawNull = -1, // unused
|
|
238
|
+
Null = 0,
|
|
239
|
+
Raw = 1,
|
|
240
|
+
U8 = 2,
|
|
241
|
+
U16 = 3,
|
|
242
|
+
U32 = 4,
|
|
243
|
+
U64 = 5,
|
|
244
|
+
F32 = 6,
|
|
245
|
+
F64 = 7,
|
|
243
246
|
Bool = 8,
|
|
244
247
|
String = 9,
|
|
245
248
|
Object = 10,
|
|
246
|
-
Array =
|
|
247
|
-
Struct =
|
|
249
|
+
Array = 11,
|
|
250
|
+
Struct = 12,
|
|
248
251
|
}
|
|
249
252
|
|
|
250
253
|
export class Raw {
|
|
@@ -271,6 +274,7 @@ export namespace JSON {
|
|
|
271
274
|
static METHODS: Map<u32, u32> = new Map<u32, u32>();
|
|
272
275
|
public type: i32;
|
|
273
276
|
|
|
277
|
+
public isNull: bool;
|
|
274
278
|
private storage: u64;
|
|
275
279
|
|
|
276
280
|
private constructor() {
|
|
@@ -298,63 +302,125 @@ export namespace JSON {
|
|
|
298
302
|
out.set<T>(value);
|
|
299
303
|
return out;
|
|
300
304
|
}
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
* @param value - The value to be set.
|
|
305
|
-
*/
|
|
306
|
-
@inline set<T>(value: T): void {
|
|
307
|
-
if (isBoolean<T>()) {
|
|
308
|
-
this.type = JSON.Types.Bool;
|
|
305
|
+
@inline private setPrimitive<T>(value: T): void {
|
|
306
|
+
if (isBoolean(value)) {
|
|
307
|
+
this.type = JSON.Types.BoolNull;
|
|
309
308
|
store<T>(changetype<usize>(this), value, STORAGE);
|
|
310
|
-
} else if (isInteger<T>() && !isSigned<T>() && changetype<usize>(value) == 0 && nameof<T>() == "usize") {
|
|
311
|
-
this.type = JSON.Types.Null;
|
|
312
|
-
store<usize>(changetype<usize>(this), 0, STORAGE);
|
|
313
309
|
} else if (value instanceof u8 || value instanceof i8) {
|
|
314
|
-
this.type = JSON.Types.
|
|
310
|
+
this.type = JSON.Types.U8Null;
|
|
315
311
|
store<T>(changetype<usize>(this), value, STORAGE);
|
|
316
312
|
} else if (value instanceof u16 || value instanceof i16) {
|
|
317
313
|
this.type = JSON.Types.U16;
|
|
318
314
|
store<T>(changetype<usize>(this), value, STORAGE);
|
|
319
315
|
} else if (value instanceof u32 || value instanceof i32) {
|
|
320
|
-
this.type = JSON.Types.
|
|
316
|
+
this.type = JSON.Types.U32Null;
|
|
321
317
|
store<T>(changetype<usize>(this), value, STORAGE);
|
|
322
318
|
} else if (value instanceof u64 || value instanceof i64) {
|
|
323
|
-
this.type = JSON.Types.
|
|
319
|
+
this.type = JSON.Types.U64Null;
|
|
324
320
|
store<T>(changetype<usize>(this), value, STORAGE);
|
|
325
321
|
} else if (value instanceof f32) {
|
|
326
|
-
this.type = JSON.Types.
|
|
322
|
+
this.type = JSON.Types.F32Null;
|
|
327
323
|
store<T>(changetype<usize>(this), value, STORAGE);
|
|
328
324
|
} else if (value instanceof f64) {
|
|
329
|
-
this.type = JSON.Types.
|
|
330
|
-
store<T>(changetype<usize>(this), value, STORAGE);
|
|
331
|
-
} else if (isString<T>()) {
|
|
332
|
-
this.type = JSON.Types.String;
|
|
333
|
-
store<T>(changetype<usize>(this), value, STORAGE);
|
|
334
|
-
} else if (value instanceof JSON.Raw) {
|
|
335
|
-
this.type = JSON.Types.Raw;
|
|
325
|
+
this.type = JSON.Types.F64Null;
|
|
336
326
|
store<T>(changetype<usize>(this), value, STORAGE);
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
/**
|
|
330
|
+
* Sets the value of the JSON.Value instance.
|
|
331
|
+
* @param value - The value to be set.
|
|
332
|
+
*/
|
|
333
|
+
@inline set<T>(value: T): void {
|
|
334
|
+
if (isNullable<T>()) {
|
|
335
|
+
this.isNull = changetype<usize>(value) === 0;
|
|
336
|
+
if (value instanceof JSON.Box) {
|
|
337
|
+
return this.setPrimitive(value.value);
|
|
338
|
+
} else if (isBoolean<T>()) {
|
|
339
|
+
this.type = JSON.Types.BoolNull;
|
|
340
|
+
store<T>(changetype<usize>(this), value, STORAGE);
|
|
341
|
+
} else if (isString<T>()) {
|
|
342
|
+
this.type = JSON.Types.StringNull;
|
|
343
|
+
store<T>(changetype<usize>(this), value, STORAGE);
|
|
344
|
+
} else if (value instanceof JSON.Raw) {
|
|
345
|
+
this.type = JSON.Types.RawNull;
|
|
346
|
+
store<T>(changetype<usize>(this), value, STORAGE);
|
|
347
|
+
} else if (value instanceof Map) {
|
|
348
|
+
if (idof<T>() !== idof<Map<string, JSON.Value>>()) {
|
|
349
|
+
abort("Maps must be of type Map<string, JSON.Value>!");
|
|
350
|
+
}
|
|
351
|
+
this.type = JSON.Types.StructNull;
|
|
352
|
+
store<T>(changetype<usize>(this), value, STORAGE);
|
|
353
|
+
// @ts-ignore: supplied by transform
|
|
354
|
+
} else if (isDefined(value.__SERIALIZE) && isManaged<T>(value)) {
|
|
355
|
+
this.type = idof<T>() + JSON.Types.StructNull;
|
|
356
|
+
// @ts-ignore
|
|
357
|
+
if (!JSON.Value.METHODS.has(idof<T>())) JSON.Value.METHODS.set(idof<T>(), value.__SERIALIZE.index);
|
|
358
|
+
// @ts-ignore
|
|
359
|
+
store<usize>(changetype<usize>(this), changetype<usize>(value), STORAGE);
|
|
360
|
+
} else if (value instanceof JSON.Obj) {
|
|
361
|
+
this.type = JSON.Types.ObjectNull;
|
|
362
|
+
store<T>(changetype<usize>(this), value, STORAGE);
|
|
363
|
+
// @ts-ignore
|
|
364
|
+
} else if (isArray<T>() && idof<valueof<T>>() == idof<JSON.Value>()) {
|
|
365
|
+
// @ts-ignore: T satisfies constraints of any[]
|
|
366
|
+
this.type = JSON.Types.ArrayNull;
|
|
367
|
+
store<T>(changetype<usize>(this), value, STORAGE);
|
|
368
|
+
}
|
|
369
|
+
} else {
|
|
370
|
+
if (value instanceof JSON.Box) {
|
|
371
|
+
return this.set(value.value);
|
|
372
|
+
} else if (isBoolean<T>()) {
|
|
373
|
+
this.type = JSON.Types.Bool;
|
|
374
|
+
store<T>(changetype<usize>(this), value, STORAGE);
|
|
375
|
+
} else if (isInteger<T>() && !isSigned<T>() && changetype<usize>(value) == 0 && nameof<T>() == "usize") {
|
|
376
|
+
this.type = JSON.Types.Null;
|
|
377
|
+
store<usize>(changetype<usize>(this), 0, STORAGE);
|
|
378
|
+
} else if (value instanceof u8 || value instanceof i8) {
|
|
379
|
+
this.type = JSON.Types.U8;
|
|
380
|
+
store<T>(changetype<usize>(this), value, STORAGE);
|
|
381
|
+
} else if (value instanceof u16 || value instanceof i16) {
|
|
382
|
+
this.type = JSON.Types.U16;
|
|
383
|
+
store<T>(changetype<usize>(this), value, STORAGE);
|
|
384
|
+
} else if (value instanceof u32 || value instanceof i32) {
|
|
385
|
+
this.type = JSON.Types.U32;
|
|
386
|
+
store<T>(changetype<usize>(this), value, STORAGE);
|
|
387
|
+
} else if (value instanceof u64 || value instanceof i64) {
|
|
388
|
+
this.type = JSON.Types.U64;
|
|
389
|
+
store<T>(changetype<usize>(this), value, STORAGE);
|
|
390
|
+
} else if (value instanceof f32) {
|
|
391
|
+
this.type = JSON.Types.F32;
|
|
392
|
+
store<T>(changetype<usize>(this), value, STORAGE);
|
|
393
|
+
} else if (value instanceof f64) {
|
|
394
|
+
this.type = JSON.Types.F64;
|
|
395
|
+
store<T>(changetype<usize>(this), value, STORAGE);
|
|
396
|
+
} else if (isString<T>()) {
|
|
397
|
+
this.type = JSON.Types.String;
|
|
398
|
+
store<T>(changetype<usize>(this), value, STORAGE);
|
|
399
|
+
} else if (value instanceof JSON.Raw) {
|
|
400
|
+
this.type = JSON.Types.Raw;
|
|
401
|
+
store<T>(changetype<usize>(this), value, STORAGE);
|
|
402
|
+
} else if (value instanceof Map) {
|
|
403
|
+
if (idof<T>() !== idof<Map<string, JSON.Value>>()) {
|
|
404
|
+
abort("Maps must be of type Map<string, JSON.Value>!");
|
|
405
|
+
}
|
|
406
|
+
this.type = JSON.Types.Struct;
|
|
407
|
+
store<T>(changetype<usize>(this), value, STORAGE);
|
|
408
|
+
// @ts-ignore: supplied by transform
|
|
409
|
+
} else if (isDefined(value.__SERIALIZE) && isManaged<T>(value)) {
|
|
410
|
+
this.type = idof<T>() + JSON.Types.Struct;
|
|
411
|
+
// @ts-ignore
|
|
412
|
+
if (!JSON.Value.METHODS.has(idof<T>())) JSON.Value.METHODS.set(idof<T>(), value.__SERIALIZE.index);
|
|
413
|
+
// @ts-ignore
|
|
414
|
+
store<usize>(changetype<usize>(this), changetype<usize>(value), STORAGE);
|
|
415
|
+
} else if (value instanceof JSON.Obj) {
|
|
416
|
+
this.type = JSON.Types.Object;
|
|
417
|
+
store<T>(changetype<usize>(this), value, STORAGE);
|
|
418
|
+
// @ts-ignore
|
|
419
|
+
} else if (isArray<T>() && idof<valueof<T>>() == idof<JSON.Value>()) {
|
|
420
|
+
// @ts-ignore: T satisfies constraints of any[]
|
|
421
|
+
this.type = JSON.Types.Array;
|
|
422
|
+
store<T>(changetype<usize>(this), value, STORAGE);
|
|
340
423
|
}
|
|
341
|
-
this.type = JSON.Types.Struct;
|
|
342
|
-
store<T>(changetype<usize>(this), value, STORAGE);
|
|
343
|
-
// @ts-ignore: supplied by transform
|
|
344
|
-
} else if (isDefined(value.__SERIALIZE) && isManaged<T>(value)) {
|
|
345
|
-
this.type = idof<T>() + JSON.Types.Struct;
|
|
346
|
-
// @ts-ignore
|
|
347
|
-
if (!JSON.Value.METHODS.has(idof<T>())) JSON.Value.METHODS.set(idof<T>(), value.__SERIALIZE.index);
|
|
348
|
-
// @ts-ignore
|
|
349
|
-
store<usize>(changetype<usize>(this), changetype<usize>(value), STORAGE);
|
|
350
|
-
} else if (value instanceof JSON.Obj) {
|
|
351
|
-
this.type = JSON.Types.Object;
|
|
352
|
-
store<T>(changetype<usize>(this), value, STORAGE);
|
|
353
|
-
// @ts-ignore
|
|
354
|
-
} else if (isArray<T>() && idof<valueof<T>>() == idof<JSON.Value>()) {
|
|
355
|
-
// @ts-ignore: T satisfies constraints of any[]
|
|
356
|
-
this.type = JSON.Types.Array;
|
|
357
|
-
store<T>(changetype<usize>(this), value, STORAGE);
|
|
358
424
|
}
|
|
359
425
|
}
|
|
360
426
|
|
|
@@ -375,12 +441,29 @@ export namespace JSON {
|
|
|
375
441
|
return load<T>(changetype<usize>(this), STORAGE);
|
|
376
442
|
}
|
|
377
443
|
|
|
444
|
+
/**
|
|
445
|
+
* Gets the value of the JSON.Value instance as a Box<T>.
|
|
446
|
+
* Alias for .get<T>()
|
|
447
|
+
* @returns The encapsulated value.
|
|
448
|
+
*/
|
|
449
|
+
@inline asBox<T>(): Box<T> | null {
|
|
450
|
+
if (this.isNull) return null;
|
|
451
|
+
return changetype<Box<T>>(JSON.Box.fromValue<T>(this));
|
|
452
|
+
}
|
|
453
|
+
|
|
378
454
|
/**
|
|
379
455
|
* Converts the JSON.Value to a string representation.
|
|
380
456
|
* @returns The string representation of the JSON.Value.
|
|
381
457
|
*/
|
|
382
458
|
toString(): string {
|
|
459
|
+
if (this.type < JSON.Types.Null) {
|
|
460
|
+
if (this.isNull) return "null";
|
|
461
|
+
else this.type = ~this.type + 1;
|
|
462
|
+
}
|
|
463
|
+
|
|
383
464
|
switch (this.type) {
|
|
465
|
+
case JSON.Types.Null:
|
|
466
|
+
return "null";
|
|
384
467
|
case JSON.Types.U8:
|
|
385
468
|
return this.get<u8>().toString();
|
|
386
469
|
case JSON.Types.U16:
|
|
@@ -439,7 +522,7 @@ export namespace JSON {
|
|
|
439
522
|
// @ts-ignore: type
|
|
440
523
|
storage: Map<string, JSON.Value> = new Map<string, JSON.Value>();
|
|
441
524
|
|
|
442
|
-
constructor() {}
|
|
525
|
+
constructor() { }
|
|
443
526
|
|
|
444
527
|
// @ts-ignore: decorator
|
|
445
528
|
@inline get size(): i32 {
|
|
@@ -509,6 +592,24 @@ export namespace JSON {
|
|
|
509
592
|
this.value = value;
|
|
510
593
|
return this;
|
|
511
594
|
}
|
|
595
|
+
/**
|
|
596
|
+
* Creates a Box<T> | null from a JSON.Value
|
|
597
|
+
* This means that it can create a nullable primitive from a JSON.Value
|
|
598
|
+
* ```js
|
|
599
|
+
* const value = JSON.parse<i32>("null"); // -> Box<i32> | null
|
|
600
|
+
* const boxed = JSON.Box.fromValue<i32>(value); // -> Box<i32> | null
|
|
601
|
+
* // null
|
|
602
|
+
* ```
|
|
603
|
+
* @param from T
|
|
604
|
+
* @returns Box<T> | null
|
|
605
|
+
*/
|
|
606
|
+
@inline static fromValue<T>(value: JSON.Value): Box<T> | null {
|
|
607
|
+
if (!(value instanceof JSON.Value)) throw new Error("value must be of type JSON.Value");
|
|
608
|
+
if (value.isNull) return null;
|
|
609
|
+
const v = value.type === JSON.Types.F64 ?value.get<f64>() : value.get<T>();
|
|
610
|
+
// @ts-ignore
|
|
611
|
+
return new Box(isInteger<T>() || isFloat<T>() ? <T>(v) : v);
|
|
612
|
+
}
|
|
512
613
|
/**
|
|
513
614
|
* Creates a reference to a primitive type
|
|
514
615
|
* This means that it can create a nullable primitive
|
|
@@ -533,58 +634,60 @@ export namespace JSON {
|
|
|
533
634
|
/**
|
|
534
635
|
* Serializes JSON data but writes directly to the buffer.
|
|
535
636
|
* Should only be used if you know what you are doing.
|
|
536
|
-
* @param
|
|
637
|
+
* @param data - T
|
|
537
638
|
* @returns void
|
|
538
639
|
*/
|
|
539
|
-
export function __serialize<T>(
|
|
640
|
+
export function __serialize<T>(data: T): void {
|
|
540
641
|
if (isBoolean<T>()) {
|
|
541
|
-
serializeBool(
|
|
542
|
-
} else if (isInteger<T>() && nameof<T>() == "usize" &&
|
|
642
|
+
serializeBool(data as bool);
|
|
643
|
+
} else if (isInteger<T>() && nameof<T>() == "usize" && data == 0) {
|
|
543
644
|
bs.proposeSize(8);
|
|
544
645
|
store<u64>(bs.offset, 30399761348886638);
|
|
545
646
|
bs.offset += 8;
|
|
546
647
|
} else if (isInteger<T>()) {
|
|
547
648
|
// @ts-ignore
|
|
548
|
-
serializeInteger<T>(
|
|
549
|
-
} else if (isFloat<T>(
|
|
649
|
+
serializeInteger<T>(data);
|
|
650
|
+
} else if (isFloat<T>(data)) {
|
|
550
651
|
// @ts-ignore
|
|
551
|
-
serializeFloat<T>(
|
|
652
|
+
serializeFloat<T>(data);
|
|
552
653
|
// @ts-ignore: Function is generated by transform
|
|
553
|
-
} else if (isNullable<T>() && changetype<usize>(
|
|
654
|
+
} else if (isNullable<T>() && changetype<usize>(data) == <usize>0) {
|
|
554
655
|
bs.proposeSize(8);
|
|
555
656
|
store<u64>(bs.offset, 30399761348886638);
|
|
556
657
|
bs.offset += 8;
|
|
557
658
|
} else if (isString<nonnull<T>>()) {
|
|
558
|
-
if (
|
|
559
|
-
serializeString_SIMD(
|
|
659
|
+
if (JSON_MODE === JSONMode.SIMD) {
|
|
660
|
+
serializeString_SIMD(data as string);
|
|
661
|
+
} else if (JSON_MODE === JSONMode.SWAR) {
|
|
662
|
+
serializeString_SWAR(data as string);
|
|
560
663
|
} else {
|
|
561
|
-
|
|
664
|
+
serializeString(data as string);
|
|
562
665
|
}
|
|
563
666
|
// @ts-ignore: Supplied by transform
|
|
564
|
-
} else if (isDefined(
|
|
667
|
+
} else if (isDefined(data.__SERIALIZE_CUSTOM)) {
|
|
565
668
|
// @ts-ignore
|
|
566
|
-
return
|
|
669
|
+
return data.__SERIALIZE_CUSTOM();
|
|
567
670
|
// @ts-ignore: Supplied by transform
|
|
568
|
-
} else if (isDefined(
|
|
671
|
+
} else if (isDefined(data.__SERIALIZE)) {
|
|
569
672
|
// @ts-ignore
|
|
570
|
-
serializeStruct(changetype<nonnull<T>>(
|
|
571
|
-
} else if (
|
|
673
|
+
serializeStruct(changetype<nonnull<T>>(data));
|
|
674
|
+
} else if (data instanceof Date) {
|
|
572
675
|
// @ts-ignore
|
|
573
|
-
inline.always(serializeDate(changetype<nonnull<T>>(
|
|
574
|
-
} else if (
|
|
676
|
+
inline.always(serializeDate(changetype<nonnull<T>>(data)));
|
|
677
|
+
} else if (data instanceof Array || data instanceof StaticArray) {
|
|
575
678
|
// @ts-ignore
|
|
576
|
-
serializeArray(changetype<nonnull<T>>(
|
|
577
|
-
} else if (
|
|
679
|
+
serializeArray(changetype<nonnull<T>>(data));
|
|
680
|
+
} else if (data instanceof Map) {
|
|
578
681
|
// @ts-ignore
|
|
579
|
-
serializeMap(changetype<nonnull<T>>(
|
|
580
|
-
} else if (
|
|
581
|
-
serializeRaw(
|
|
582
|
-
} else if (
|
|
583
|
-
serializeArbitrary(
|
|
584
|
-
} else if (
|
|
585
|
-
serializeObject(
|
|
586
|
-
} else if (
|
|
587
|
-
__serialize(
|
|
682
|
+
serializeMap(changetype<nonnull<T>>(data));
|
|
683
|
+
} else if (data instanceof JSON.Raw) {
|
|
684
|
+
serializeRaw(data);
|
|
685
|
+
} else if (data instanceof JSON.Value) {
|
|
686
|
+
serializeArbitrary(data);
|
|
687
|
+
} else if (data instanceof JSON.Obj) {
|
|
688
|
+
serializeObject(data);
|
|
689
|
+
} else if (data instanceof JSON.Box) {
|
|
690
|
+
__serialize(data.value);
|
|
588
691
|
} else {
|
|
589
692
|
throw new Error(`Could not serialize provided data. Make sure to add the correct decorators to classes.`);
|
|
590
693
|
}
|
|
@@ -608,7 +711,7 @@ export namespace JSON {
|
|
|
608
711
|
return deserializeFloat<T>(srcStart, srcEnd);
|
|
609
712
|
} else if (isString<T>()) {
|
|
610
713
|
if (srcEnd - srcStart < 4) throw new Error("Cannot parse data as string because it was formatted incorrectly!");
|
|
611
|
-
|
|
714
|
+
|
|
612
715
|
// @ts-ignore: type
|
|
613
716
|
return deserializeString(srcStart, srcEnd, dst);
|
|
614
717
|
} else if (isNullable<T>() && srcEnd - srcStart == 8 && load<u64>(srcStart) == 30399761348886638) {
|
|
@@ -721,22 +824,12 @@ export namespace JSON {
|
|
|
721
824
|
return NULL_WORD;
|
|
722
825
|
// @ts-ignore
|
|
723
826
|
} else if (isString<nonnull<T>>()) {
|
|
724
|
-
|
|
725
|
-
// out = changetype<string>(__renew(changetype<usize>(out), bytes(data) + 4));
|
|
726
|
-
// // const oldSize = bs.byteLength;
|
|
727
|
-
// const oldBuf = bs.buffer;
|
|
728
|
-
// const newSize = bytes(data) + 4;
|
|
729
|
-
// const newBuf = __new(newSize, idof<string>());
|
|
730
|
-
// bs.setBuffer(newBuf);
|
|
731
|
-
// serializeString_SWAR(changetype<string>(data));
|
|
732
|
-
// bs.setBuffer(oldBuf);
|
|
733
|
-
// return changetype<string>(newBuf);
|
|
734
|
-
// }
|
|
735
|
-
if (ASC_FEATURE_SIMD) {
|
|
827
|
+
if (JSON_MODE === JSONMode.SIMD) {
|
|
736
828
|
serializeString_SIMD(data as string);
|
|
737
|
-
} else {
|
|
738
|
-
bs.saveState();
|
|
829
|
+
} else if (JSON_MODE === JSONMode.SWAR) {
|
|
739
830
|
serializeString_SWAR(data as string);
|
|
831
|
+
} else {
|
|
832
|
+
serializeString(data as string);
|
|
740
833
|
}
|
|
741
834
|
return bs.cpyOut<string>();
|
|
742
835
|
// @ts-ignore: Supplied by transform
|
|
@@ -784,6 +877,12 @@ export namespace JSON {
|
|
|
784
877
|
}
|
|
785
878
|
}
|
|
786
879
|
|
|
880
|
+
export enum JSONMode {
|
|
881
|
+
SWAR = 0,
|
|
882
|
+
SIMD = 1,
|
|
883
|
+
NAIVE = 2
|
|
884
|
+
}
|
|
885
|
+
|
|
787
886
|
// @ts-ignore: decorator
|
|
788
887
|
@inline function parseBox<T>(data: string, ty: T): T {
|
|
789
888
|
return JSON.parse<T>(data);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { bs } from "../../../lib/as-bs";
|
|
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
4
|
import { bytes } from "../../util";
|
|
@@ -7,6 +7,18 @@ import { bytes } from "../../util";
|
|
|
7
7
|
* Serializes strings into their JSON counterparts using SIMD operations
|
|
8
8
|
*/
|
|
9
9
|
export function serializeString_SIMD(src: string): void {
|
|
10
|
+
let srcStart = changetype<usize>(src);
|
|
11
|
+
if (isDefined(JSON_CACHE)) {
|
|
12
|
+
// check cache
|
|
13
|
+
const e = unchecked(sc.entries[(srcStart >> 4) & sc.CACHE_MASK]);
|
|
14
|
+
if (e.key == srcStart) {
|
|
15
|
+
// bs.offset += e.len;
|
|
16
|
+
// bs.stackSize += e.len;
|
|
17
|
+
bs.cacheOutput = e.ptr;
|
|
18
|
+
bs.cacheOutputLen = e.len;
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
10
22
|
const U00_MARKER = 13511005048209500;
|
|
11
23
|
const SPLAT_34 = i16x8.splat(34); /* " */
|
|
12
24
|
const SPLAT_92 = i16x8.splat(92); /* \ */
|
|
@@ -14,7 +26,6 @@ export function serializeString_SIMD(src: string): void {
|
|
|
14
26
|
const SPLAT_32 = i16x8.splat(32); /* [ESC] */
|
|
15
27
|
|
|
16
28
|
const srcSize = bytes(src);
|
|
17
|
-
let srcStart = changetype<usize>(src);
|
|
18
29
|
const srcEnd = srcStart + srcSize;
|
|
19
30
|
const srcEnd16 = srcEnd - 16;
|
|
20
31
|
|
|
@@ -36,7 +47,7 @@ export function serializeString_SIMD(src: string): void {
|
|
|
36
47
|
let mask = i16x8.bitmask(sieve);
|
|
37
48
|
|
|
38
49
|
while (mask != 0) {
|
|
39
|
-
const lane_index = ctz(mask) << 1;
|
|
50
|
+
const lane_index = ctz(mask) << 1; // 0 2 4 6 8 10 12 14
|
|
40
51
|
// console.log("lane: " + (lane_index >= 8 ? (lane_index - 8).toString():lane_index.toString()));
|
|
41
52
|
const src_offset = srcStart + lane_index;
|
|
42
53
|
const code = load<u16>(src_offset) << 2;
|
|
@@ -85,4 +96,6 @@ export function serializeString_SIMD(src: string): void {
|
|
|
85
96
|
|
|
86
97
|
store<u8>(bs.offset, 34); /* " */
|
|
87
98
|
bs.offset += 2;
|
|
99
|
+
|
|
100
|
+
if (isDefined(JSON_CACHE)) sc.insertCached(changetype<usize>(src), srcStart, srcSize);
|
|
88
101
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { JSON } from "../..";
|
|
2
|
-
import {
|
|
2
|
+
import { bs } from "../../../lib/as-bs";
|
|
3
3
|
import { serializeArray } from "./array";
|
|
4
4
|
import { serializeBool } from "./bool";
|
|
5
5
|
import { serializeFloat } from "./float";
|
|
@@ -8,7 +8,21 @@ import { serializeObject } from "./object";
|
|
|
8
8
|
import { serializeString } from "./string";
|
|
9
9
|
|
|
10
10
|
export function serializeArbitrary(src: JSON.Value): void {
|
|
11
|
+
if (src.type < JSON.Types.Null) {
|
|
12
|
+
if (src.isNull) {
|
|
13
|
+
bs.proposeSize(8);
|
|
14
|
+
store<u64>(bs.offset, 30399761348886638);
|
|
15
|
+
bs.offset += 8;
|
|
16
|
+
return;
|
|
17
|
+
} else src.type = ~src.type + 1;
|
|
18
|
+
}
|
|
19
|
+
|
|
11
20
|
switch (src.type) {
|
|
21
|
+
case JSON.Types.Null:
|
|
22
|
+
bs.proposeSize(8);
|
|
23
|
+
store<u64>(bs.offset, 30399761348886638);
|
|
24
|
+
bs.offset += 8;
|
|
25
|
+
break;
|
|
12
26
|
case JSON.Types.U8:
|
|
13
27
|
serializeInteger<u8>(src.get<u8>());
|
|
14
28
|
break;
|
|
@@ -28,7 +42,7 @@ export function serializeArbitrary(src: JSON.Value): void {
|
|
|
28
42
|
serializeFloat<f64>(src.get<f64>());
|
|
29
43
|
break;
|
|
30
44
|
case JSON.Types.String:
|
|
31
|
-
|
|
45
|
+
serializeString(src.get<string>());
|
|
32
46
|
break;
|
|
33
47
|
case JSON.Types.Bool:
|
|
34
48
|
serializeBool(src.get<bool>());
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { bs } from "../../../lib/as-bs";
|
|
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 {
|
|
4
|
+
import { OBJECT, TOTAL_OVERHEAD } from "rt/common";
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
// @ts-ignore: decorator allowed
|
|
@@ -22,8 +22,21 @@ import { bytes } from "../../util/bytes";
|
|
|
22
22
|
@lazy const U00_MARKER = 13511005048209500;
|
|
23
23
|
|
|
24
24
|
export function serializeString_SWAR(src: string): void {
|
|
25
|
-
const srcSize = bytes(src);
|
|
26
25
|
let srcStart = changetype<usize>(src);
|
|
26
|
+
|
|
27
|
+
if (isDefined(JSON_CACHE)) {
|
|
28
|
+
// check cache
|
|
29
|
+
const e = unchecked(sc.entries[(srcStart >> 4) & sc.CACHE_MASK]);
|
|
30
|
+
if (e.key == srcStart) {
|
|
31
|
+
// bs.offset += e.len;
|
|
32
|
+
// bs.stackSize += e.len;
|
|
33
|
+
bs.cacheOutput = e.ptr;
|
|
34
|
+
bs.cacheOutputLen = e.len;
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const srcSize = changetype<OBJECT>(srcStart - TOTAL_OVERHEAD).rtSize
|
|
27
40
|
const srcEnd = srcStart + srcSize;
|
|
28
41
|
const srcEnd8 = srcEnd - 8;
|
|
29
42
|
|
|
@@ -68,7 +81,7 @@ export function serializeString_SWAR(src: string): void {
|
|
|
68
81
|
bs.offset += 8;
|
|
69
82
|
}
|
|
70
83
|
|
|
71
|
-
while (srcStart <= srcEnd - 2) {
|
|
84
|
+
while (srcStart <= srcEnd - 2) {
|
|
72
85
|
const code = load<u16>(srcStart);
|
|
73
86
|
if (code == 92 || code == 34 || code < 32) {
|
|
74
87
|
const escaped = load<u32>(SERIALIZE_ESCAPE_TABLE + (code << 2));
|
|
@@ -91,19 +104,32 @@ while (srcStart <= srcEnd - 2) {
|
|
|
91
104
|
|
|
92
105
|
store<u16>(bs.offset, 34); // "
|
|
93
106
|
bs.offset += 2;
|
|
107
|
+
|
|
108
|
+
if (isDefined(JSON_CACHE)) sc.insertCached(changetype<usize>(src), srcStart, srcSize);
|
|
94
109
|
}
|
|
95
110
|
|
|
96
111
|
// @ts-ignore: decorators allowed
|
|
97
112
|
@inline function v64x4_should_escape(x: u64): u64 {
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
const
|
|
101
|
-
|
|
102
|
-
const
|
|
103
|
-
const
|
|
104
|
-
const
|
|
105
|
-
|
|
106
|
-
const
|
|
107
|
-
|
|
108
|
-
|
|
113
|
+
// console.log("input: " + mask_to_string(x));
|
|
114
|
+
const hi = x & 0xff00_ff00_ff00_ff00;
|
|
115
|
+
const lo = x & 0x00ff_00ff_00ff_00ff;
|
|
116
|
+
x &= 0x00ff_00ff_00ff_00ff;
|
|
117
|
+
// const is_cp = hi & 0x8080_8080_8080_8080;
|
|
118
|
+
const is_ascii = 0x0080_0080_0080_0080 & ~x; // lane remains 0x80 if ascii
|
|
119
|
+
const lt32 = (x - 0x0020_0020_0020_0020);
|
|
120
|
+
const sub34 = x ^ 0x0022_0022_0022_0022;
|
|
121
|
+
const eq34 = (sub34 - 0x0001_0001_0001_0001);
|
|
122
|
+
const sub92 = x ^ 0x005C_005C_005C_005C;
|
|
123
|
+
const eq92 = (sub92 - 0x0001_0001_0001_0001);
|
|
124
|
+
// console.log("low: " + mask_to_string(lo));
|
|
125
|
+
// console.log("high: " + mask_to_string(hi));
|
|
126
|
+
// console.log("is_cp: " + mask_to_string(is_cp));
|
|
127
|
+
// console.log("is_ascii: " + mask_to_string(is_ascii));
|
|
128
|
+
// console.log("lt32: " + mask_to_string(lt32));
|
|
129
|
+
// console.log("sub34: " + mask_to_string(sub34));
|
|
130
|
+
// console.log("eq34: " + mask_to_string(eq34));
|
|
131
|
+
// console.log("eq92: " + mask_to_string(eq92));
|
|
132
|
+
// console.log("pre: " + mask_to_string((lt32 | eq34 | eq92)));
|
|
133
|
+
// console.log("out: " + mask_to_string((lt32 | eq34 | eq92) & is_ascii));
|
|
134
|
+
return ((lt32 | eq34 | eq92)& is_ascii);
|
|
109
135
|
}
|
package/assembly/test.ts
CHANGED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { JSON } from ".";
|
|
2
|
+
|
|
3
|
+
@json
|
|
4
|
+
class Vec3 {
|
|
5
|
+
x!: f32;
|
|
6
|
+
y!: f32;
|
|
7
|
+
z!: f32;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const vec: Vec3 = {
|
|
11
|
+
x: 1.0,
|
|
12
|
+
y: 2.0,
|
|
13
|
+
z: 3.0
|
|
14
|
+
}
|
|
15
|
+
const str: JSON.Value[] = [
|
|
16
|
+
JSON.Value.from<string>("foo"),
|
|
17
|
+
JSON.Value.from("bar"),
|
|
18
|
+
JSON.Value.from(1),
|
|
19
|
+
JSON.Value.from(2),
|
|
20
|
+
JSON.Value.from(true),
|
|
21
|
+
JSON.Value.from<JSON.Box<i32> | null>(null),
|
|
22
|
+
JSON.Value.from(vec),
|
|
23
|
+
JSON.Value.from<Vec3 | null>(null),
|
|
24
|
+
JSON.Value.from<JSON.Box<i32> | null>(JSON.Box.from(123)),
|
|
25
|
+
JSON.Value.from<JSON.Box<i32> | null>(null),
|
|
26
|
+
];
|
|
27
|
+
const box = JSON.Box.from<i32>(123);
|
|
28
|
+
const value = JSON.Value.from<JSON.Box<i32> | null>(box);
|
|
29
|
+
const reboxed = JSON.Box.fromValue<i32>(value); // Box<i32> | null
|
|
30
|
+
console.log(reboxed !== null ? reboxed!.toString() : "null");
|
|
31
|
+
|
|
32
|
+
// console.log(str[9]!.asBox<i32>()?.toString());
|
|
33
|
+
// console.log(str.toString())
|
|
34
|
+
const serialized = JSON.stringify(str);
|
|
35
|
+
console.log("Serialized: " + serialized);
|
|
36
|
+
|
|
37
|
+
const deserialized = JSON.parse<JSON.Value[]>(serialized);
|
|
38
|
+
console.log("Deserialized: " + JSON.stringify(deserialized).toString());
|