json-as 1.0.7 → 1.0.9
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 +15 -0
- package/README.md +18 -2
- package/asconfig.json +1 -2
- package/assembly/__benches__/abc.bench.ts +5 -5
- package/assembly/__benches__/large.bench.ts +5 -51
- package/assembly/{custom → __benches__/lib}/bench.ts +4 -0
- package/assembly/__benches__/medium.bench.ts +3 -3
- package/assembly/__benches__/small.bench.ts +1 -1
- package/assembly/__benches__/vec3.bench.ts +3 -49
- package/assembly/__tests__/custom.spec.ts +4 -3
- package/assembly/__tests__/hierarchy.spec.ts +55 -0
- package/assembly/__tests__/lib/index.ts +1 -0
- package/assembly/custom/util.ts +0 -4
- package/assembly/deserialize/simple/array/box.ts +45 -0
- package/assembly/deserialize/simple/array/object.ts +28 -0
- package/assembly/deserialize/simple/array.ts +8 -0
- package/assembly/index.ts +39 -41
- package/assembly/serialize/simd/string.ts +12 -12
- package/assembly/test.ts +46 -133
- package/assembly/util/idofd.ts +6 -0
- package/bench/abc.bench.ts +1 -1
- package/bench/large.bench.ts +3 -3
- package/bench/lib/bench.ts +12 -0
- package/bench/medium.bench.ts +1 -1
- package/bench/runners/assemblyscript.js +28 -0
- package/bench/small.bench.ts +1 -1
- package/bench/tsconfig.json +12 -0
- package/bench/vec3.bench.ts +1 -1
- package/package.json +3 -4
- package/run-bench.as.sh +44 -18
- package/run-bench.js.sh +32 -6
- package/run-tests.sh +1 -1
- package/transform/lib/index.js +381 -122
- package/transform/lib/index.js.map +1 -1
- package/transform/lib/types.js +1 -0
- package/transform/lib/types.js.map +1 -1
- package/transform/src/index.ts +430 -117
- package/transform/src/types.ts +1 -0
- package/assembly/__benches__/lib/index.ts +0 -26
- package/assembly/custom/memory.ts +0 -25
- package/assembly/custom/sink.ts +0 -231
- package/assembly/custom/types.ts +0 -5
package/assembly/index.ts
CHANGED
|
@@ -15,7 +15,6 @@ import { deserializeInteger } from "./deserialize/simple/integer";
|
|
|
15
15
|
import { deserializeString } from "./deserialize/simple/string";
|
|
16
16
|
import { serializeArbitrary } from "./serialize/simple/arbitrary";
|
|
17
17
|
|
|
18
|
-
import { Sink } from "./custom/sink";
|
|
19
18
|
import { NULL_WORD, QUOTE } from "./custom/chars";
|
|
20
19
|
import { dtoa_buffered, itoa_buffered } from "util/number";
|
|
21
20
|
import { serializeBool } from "./serialize/simple/bool";
|
|
@@ -29,8 +28,6 @@ import { serializeObject } from "./serialize/simple/object";
|
|
|
29
28
|
import { deserializeObject } from "./deserialize/simple/object";
|
|
30
29
|
import { serializeRaw } from "./serialize/simple/raw";
|
|
31
30
|
import { deserializeRaw } from "./deserialize/simple/raw";
|
|
32
|
-
import { isSpace } from "util/string";
|
|
33
|
-
import { deserializeString_SIMD } from "./deserialize/simd/string";
|
|
34
31
|
|
|
35
32
|
/**
|
|
36
33
|
* Offset of the 'storage' property in the JSON.Value class.
|
|
@@ -116,12 +113,11 @@ export namespace JSON {
|
|
|
116
113
|
// bs.setBuffer(oldBuf);
|
|
117
114
|
// return changetype<string>(newBuf);
|
|
118
115
|
// }
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
//
|
|
122
|
-
|
|
123
|
-
//
|
|
124
|
-
inline.always(data.__SERIALIZE_CUSTOM());
|
|
116
|
+
// if (ASC_FEATURE_SIMD) {
|
|
117
|
+
// serializeString_SIMD(data as string);
|
|
118
|
+
// } else {
|
|
119
|
+
serializeString(data as string);
|
|
120
|
+
// }
|
|
125
121
|
return bs.out<string>();
|
|
126
122
|
// @ts-ignore: Supplied by transform
|
|
127
123
|
} else if (isDefined(data.__SERIALIZE)) {
|
|
@@ -145,7 +141,7 @@ export namespace JSON {
|
|
|
145
141
|
inline.always(serializeMap(changetype<nonnull<T>>(data)));
|
|
146
142
|
return bs.out<string>();
|
|
147
143
|
} else if (data instanceof JSON.Raw) {
|
|
148
|
-
|
|
144
|
+
serializeRaw(data);
|
|
149
145
|
return bs.out<string>();
|
|
150
146
|
} else if (data instanceof JSON.Value) {
|
|
151
147
|
inline.always(serializeArbitrary(data));
|
|
@@ -196,19 +192,12 @@ export namespace JSON {
|
|
|
196
192
|
} else {
|
|
197
193
|
let type: nonnull<T> = changetype<nonnull<T>>(0);
|
|
198
194
|
// @ts-ignore: Defined by transform
|
|
199
|
-
if (isDefined(type.
|
|
200
|
-
const out = changetype<nonnull<T>>(
|
|
195
|
+
if (isDefined(type.__DESERIALIZE)) {
|
|
196
|
+
const out = changetype<nonnull<T>>(__new(offsetof<nonnull<T>>(), idof<nonnull<T>>()));
|
|
201
197
|
// @ts-ignore: Defined by transform
|
|
202
198
|
if (isDefined(type.__INITIALIZE)) out.__INITIALIZE();
|
|
203
199
|
// @ts-ignore
|
|
204
|
-
return out.
|
|
205
|
-
// @ts-ignore: Defined by transform
|
|
206
|
-
} else if (isDefined(type.__DESERIALIZE)) {
|
|
207
|
-
const out = __new(offsetof<nonnull<T>>(), idof<nonnull<T>>());
|
|
208
|
-
// @ts-ignore: Defined by transform
|
|
209
|
-
if (isDefined(type.__INITIALIZE)) changetype<nonnull<T>>(out).__INITIALIZE();
|
|
210
|
-
// @ts-ignore
|
|
211
|
-
return inline.always(deserializeStruct<nonnull<T>>(dataPtr, dataPtr + dataSize, out));
|
|
200
|
+
return out.__DESERIALIZE(dataPtr, dataPtr + dataSize, out);
|
|
212
201
|
} else if (type instanceof Map) {
|
|
213
202
|
// @ts-ignore
|
|
214
203
|
return inline.always(deserializeMap<nonnull<T>>(dataPtr, dataPtr + dataSize, 0));
|
|
@@ -404,18 +393,16 @@ export namespace JSON {
|
|
|
404
393
|
case JSON.Types.Array: {
|
|
405
394
|
const arr = this.get<JSON.Value[]>();
|
|
406
395
|
if (!arr.length) return "[]";
|
|
407
|
-
|
|
396
|
+
let out = "[";
|
|
408
397
|
const end = arr.length - 1;
|
|
409
398
|
for (let i = 0; i < end; i++) {
|
|
410
399
|
const element = unchecked(arr[i]);
|
|
411
|
-
out
|
|
412
|
-
out.write(",");
|
|
400
|
+
out += element.toString() + ",";
|
|
413
401
|
}
|
|
414
402
|
|
|
415
403
|
const element = unchecked(arr[end]);
|
|
416
|
-
out
|
|
404
|
+
out += element.toString() + "]";
|
|
417
405
|
|
|
418
|
-
out.write("]");
|
|
419
406
|
return out.toString();
|
|
420
407
|
}
|
|
421
408
|
case JSON.Types.Object: {
|
|
@@ -556,22 +543,22 @@ export namespace JSON {
|
|
|
556
543
|
// @ts-ignore: Supplied by transform
|
|
557
544
|
} else if (isDefined(src.__SERIALIZE)) {
|
|
558
545
|
// @ts-ignore
|
|
559
|
-
|
|
546
|
+
serializeStruct(changetype<nonnull<T>>(src));
|
|
560
547
|
} else if (src instanceof Date) {
|
|
561
548
|
// @ts-ignore
|
|
562
549
|
inline.always(serializeDate(changetype<nonnull<T>>(src)));
|
|
563
550
|
} else if (src instanceof Array) {
|
|
564
551
|
// @ts-ignore
|
|
565
|
-
|
|
552
|
+
serializeArray(changetype<nonnull<T>>(src));
|
|
566
553
|
} else if (src instanceof Map) {
|
|
567
554
|
// @ts-ignore
|
|
568
|
-
|
|
555
|
+
serializeMap(changetype<nonnull<T>>(src));
|
|
569
556
|
} else if (src instanceof JSON.Raw) {
|
|
570
557
|
serializeRaw(src);
|
|
571
558
|
} else if (src instanceof JSON.Value) {
|
|
572
|
-
|
|
559
|
+
serializeArbitrary(src);
|
|
573
560
|
} else if (src instanceof JSON.Obj) {
|
|
574
|
-
|
|
561
|
+
serializeObject(src);
|
|
575
562
|
} else if (src instanceof JSON.Box) {
|
|
576
563
|
__serialize(src.value);
|
|
577
564
|
} else {
|
|
@@ -596,22 +583,17 @@ export namespace JSON {
|
|
|
596
583
|
return null;
|
|
597
584
|
} else if (isArray<T>()) {
|
|
598
585
|
// @ts-ignore: type
|
|
599
|
-
return
|
|
586
|
+
return deserializeArray<T>(srcStart, srcEnd, dst);
|
|
600
587
|
} else {
|
|
601
588
|
let type: nonnull<T> = changetype<nonnull<T>>(0);
|
|
602
589
|
// @ts-ignore: Defined by transform
|
|
603
|
-
if (isDefined(type.
|
|
604
|
-
const out = __new(offsetof<nonnull<T>>(), idof<nonnull<T>>())
|
|
590
|
+
if (isDefined(type.__DESERIALIZE)) {
|
|
591
|
+
const out = changetype<nonnull<T>>(dst || __new(offsetof<nonnull<T>>(), idof<nonnull<T>>()))
|
|
605
592
|
// @ts-ignore: Defined by transform
|
|
606
|
-
|
|
607
|
-
// @ts-ignore
|
|
608
|
-
return changetype<nonnull<T>>(out).__DESERIALIZE_CUSTOM(ptrToStr(srcStart, srcEnd));
|
|
609
|
-
// @ts-ignore: Defined by transform
|
|
610
|
-
} else if (isDefined(type.__DESERIALIZE)) {
|
|
611
|
-
return inline.always(deserializeStruct<T>(srcStart, srcEnd, dst));
|
|
593
|
+
return out.__DESERIALIZE(srcStart, srcEnd, out);
|
|
612
594
|
} else if (type instanceof Map) {
|
|
613
595
|
// @ts-ignore: type
|
|
614
|
-
return
|
|
596
|
+
return deserializeMap<T>(srcStart, srcEnd, dst);
|
|
615
597
|
} else if (type instanceof Date) {
|
|
616
598
|
// @ts-ignore: type
|
|
617
599
|
return deserializeDate(srcStart, srcEnd);
|
|
@@ -620,7 +602,10 @@ export namespace JSON {
|
|
|
620
602
|
return deserializeRaw(srcStart, srcEnd);
|
|
621
603
|
} else if (type instanceof JSON.Value) {
|
|
622
604
|
// @ts-ignore: type
|
|
623
|
-
return
|
|
605
|
+
return deserializeArbitrary(srcStart, srcEnd, 0);
|
|
606
|
+
} else if (type instanceof JSON.Obj) {
|
|
607
|
+
// @ts-ignore: type
|
|
608
|
+
return deserializeObject(srcStart, srcEnd, 0);
|
|
624
609
|
} else if (type instanceof JSON.Box) {
|
|
625
610
|
// @ts-ignore: type
|
|
626
611
|
return new JSON.Box(deserializeBox(srcStart, srcEnd, dst, changetype<nonnull<T>>(0).value));
|
|
@@ -628,6 +613,19 @@ export namespace JSON {
|
|
|
628
613
|
}
|
|
629
614
|
throw new Error(`Could not deserialize data '${ptrToStr(srcStart, srcEnd).slice(0, 100)}' to type. Make sure to add the correct decorators to classes.`);
|
|
630
615
|
}
|
|
616
|
+
namespace Util {
|
|
617
|
+
// @ts-ignore: decorator
|
|
618
|
+
@inline export function isSpace(code: u16): boolean {
|
|
619
|
+
return code == 0x20 || code - 9 <= 4;
|
|
620
|
+
}
|
|
621
|
+
// @ts-ignore: decorator
|
|
622
|
+
@inline export function ptrToStr(start: usize, end: usize): string {
|
|
623
|
+
const size = end - start;
|
|
624
|
+
const out = __new(size, idof<string>());
|
|
625
|
+
memory.copy(out, start, size);
|
|
626
|
+
return changetype<string>(out);
|
|
627
|
+
}
|
|
628
|
+
}
|
|
631
629
|
}
|
|
632
630
|
|
|
633
631
|
// @ts-ignore: decorator
|
|
@@ -1,13 +1,7 @@
|
|
|
1
1
|
import { bs } from "../../../lib/as-bs";
|
|
2
2
|
import { BACK_SLASH } from "../../custom/chars";
|
|
3
3
|
import { SERIALIZE_ESCAPE_TABLE } from "../../globals/tables";
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
const SPLAT_34 = i16x8.splat(34); /* " */
|
|
7
|
-
const SPLAT_92 = i16x8.splat(92); /* \ */
|
|
8
|
-
|
|
9
|
-
const SPLAT_32 = i16x8.splat(32); /* [ESC] */
|
|
10
|
-
const SPLAT_0 = i16x8.splat(0); /* 0 */
|
|
4
|
+
import { bytes } from "../../util";
|
|
11
5
|
|
|
12
6
|
/**
|
|
13
7
|
* Serializes strings into their JSON counterparts using SIMD operations
|
|
@@ -15,16 +9,23 @@ const SPLAT_0 = i16x8.splat(0); /* 0 */
|
|
|
15
9
|
* @param srcEnd pointer to end serialization at
|
|
16
10
|
*/
|
|
17
11
|
export function serializeString_SIMD(src: string): void {
|
|
18
|
-
const
|
|
12
|
+
const SPLAT_34 = i16x8.splat(34); /* " */
|
|
13
|
+
const SPLAT_92 = i16x8.splat(92); /* \ */
|
|
14
|
+
|
|
15
|
+
const SPLAT_32 = i16x8.splat(32); /* [ESC] */
|
|
16
|
+
const SPLAT_0 = i16x8.splat(0); /* 0 */
|
|
17
|
+
|
|
18
|
+
const srcSize = bytes(src);
|
|
19
19
|
let srcStart = changetype<usize>(src);
|
|
20
20
|
const srcEnd = srcStart + srcSize;
|
|
21
|
+
const srcEnd16 = srcEnd - 16;
|
|
22
|
+
|
|
21
23
|
bs.proposeSize(srcSize + 4);
|
|
22
|
-
const srcEnd16 = srcEnd - 15;
|
|
23
24
|
|
|
24
25
|
store<u8>(changetype<usize>(bs.offset), 34); /* " */
|
|
25
26
|
bs.offset += 2;
|
|
26
27
|
|
|
27
|
-
while (srcStart
|
|
28
|
+
while (srcStart <= srcEnd16) {
|
|
28
29
|
const block = v128.load(srcStart);
|
|
29
30
|
v128.store(bs.offset, block);
|
|
30
31
|
|
|
@@ -62,8 +63,7 @@ export function serializeString_SIMD(src: string): void {
|
|
|
62
63
|
bs.offset += 16;
|
|
63
64
|
}
|
|
64
65
|
|
|
65
|
-
|
|
66
|
-
|
|
66
|
+
const rem = srcEnd - srcStart;
|
|
67
67
|
if (rem & 8) {
|
|
68
68
|
const block = v128.load64_zero(srcStart);
|
|
69
69
|
v128.store64_lane(bs.offset, block, 0);
|
package/assembly/test.ts
CHANGED
|
@@ -1,153 +1,66 @@
|
|
|
1
1
|
import { JSON } from ".";
|
|
2
2
|
import { bytes } from "./util";
|
|
3
|
-
|
|
4
|
-
|
|
5
3
|
@json
|
|
6
|
-
class
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
public c: string = '"\t\f\u0000\u0001';
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
@json
|
|
14
|
-
class Vec3 {
|
|
15
|
-
x: f32 = 0.0;
|
|
16
|
-
y: f32 = 0.0;
|
|
17
|
-
z: f32 = 0.0;
|
|
18
|
-
}
|
|
4
|
+
class GenericEnum<T> {
|
|
5
|
+
private tag: string = ""
|
|
6
|
+
private value: T | null = null
|
|
19
7
|
|
|
8
|
+
constructor() {
|
|
9
|
+
this.tag = ""
|
|
10
|
+
this.value = null
|
|
11
|
+
}
|
|
20
12
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
// Drop in a code block, function, or expression that evaluates to a boolean
|
|
28
|
-
@omitif((self: Player) => self.age < 18)
|
|
29
|
-
age!: i32;
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
@omitnull()
|
|
33
|
-
pos!: Vec3 | null;
|
|
34
|
-
isVerified!: boolean;
|
|
35
|
-
}
|
|
36
|
-
|
|
13
|
+
static create<T>(tag: string, value: T): GenericEnum<T> {
|
|
14
|
+
const item = new GenericEnum<T>()
|
|
15
|
+
item.tag = tag
|
|
16
|
+
item.value = value
|
|
17
|
+
return item
|
|
18
|
+
}
|
|
37
19
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
x: f64 = 0.0;
|
|
41
|
-
y: f64 = 0.0;
|
|
42
|
-
constructor(x: f64, y: f64) {
|
|
43
|
-
this.x = x;
|
|
44
|
-
this.y = y;
|
|
20
|
+
getTag(): string {
|
|
21
|
+
return this.tag
|
|
45
22
|
}
|
|
46
23
|
|
|
24
|
+
getValue(): T | null {
|
|
25
|
+
return this.value
|
|
26
|
+
}
|
|
47
27
|
|
|
48
28
|
@serializer
|
|
49
|
-
|
|
50
|
-
|
|
29
|
+
serialize(self: GenericEnum<T>): string {
|
|
30
|
+
const tagJson = JSON.stringify(self.tag)
|
|
31
|
+
const valueJson = JSON.stringify(self.value)
|
|
32
|
+
return `{"tag":${tagJson},"value":${valueJson}}`
|
|
51
33
|
}
|
|
52
34
|
|
|
53
|
-
|
|
54
35
|
@deserializer
|
|
55
|
-
|
|
56
|
-
const
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
const c = data.indexOf(",");
|
|
60
|
-
const x = data.slice(1, c);
|
|
61
|
-
const y = data.slice(c + 1, data.length - 1);
|
|
36
|
+
deserialize(data: string): GenericEnum<T> {
|
|
37
|
+
const parsed = JSON.parse<Map<string, JSON.Raw>>(data);
|
|
38
|
+
const result = new GenericEnum<T>();
|
|
62
39
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
}
|
|
40
|
+
if (parsed.has("tag")) {
|
|
41
|
+
result.tag = JSON.parse<string>(parsed.get("tag").data);
|
|
42
|
+
}
|
|
66
43
|
|
|
44
|
+
if (parsed.has("value")) {
|
|
45
|
+
result.value = JSON.parse<T>(parsed.get("value").data);
|
|
46
|
+
}
|
|
67
47
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
obj: T = instantiate<T>();
|
|
48
|
+
return result;
|
|
49
|
+
}
|
|
71
50
|
}
|
|
72
51
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
52
|
+
export function test(): void {
|
|
53
|
+
const myEnum = GenericEnum.create<string>("test_tag", "test_value");
|
|
54
|
+
// Serialize it
|
|
55
|
+
const serialized = JSON.stringify<GenericEnum<string>>(myEnum);
|
|
56
|
+
console.log("=== Serialized ===");
|
|
57
|
+
console.log(serialized);
|
|
58
|
+
console.log("=== Attempting to deserialize (this will crash) ===");
|
|
59
|
+
|
|
60
|
+
// This line crashes
|
|
61
|
+
const parsed = JSON.parse<GenericEnum<string>>(serialized);
|
|
62
|
+
console.log("=== Deserialized ===");
|
|
63
|
+
console.log(JSON.stringify(parsed))
|
|
77
64
|
}
|
|
78
65
|
|
|
79
|
-
|
|
80
|
-
firstName: "Jairus",
|
|
81
|
-
lastName: "Tanaka",
|
|
82
|
-
lastActive: [2, 7, 2025],
|
|
83
|
-
age: 18,
|
|
84
|
-
pos: {
|
|
85
|
-
x: 3.4,
|
|
86
|
-
y: 1.2,
|
|
87
|
-
z: 8.3,
|
|
88
|
-
},
|
|
89
|
-
isVerified: true,
|
|
90
|
-
};
|
|
91
|
-
|
|
92
|
-
const a1 = JSON.stringify("\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\u0008\u0009\u000a\u000b\u000c\u000d\u000e\u000f\u000f\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f");
|
|
93
|
-
// console.log("Bytes " + bytes(a1).toString());
|
|
94
|
-
console.log("a1: " + a1);
|
|
95
|
-
|
|
96
|
-
const obj = new Obj();
|
|
97
|
-
const a2 = JSON.stringify(obj);
|
|
98
|
-
// console.log("Bytes " + bytes(a2).toString());
|
|
99
|
-
console.log("a2: " + a2);
|
|
100
|
-
|
|
101
|
-
const a3 = JSON.stringify(player);
|
|
102
|
-
// console.log("Bytes " + bytes(a3).toString());
|
|
103
|
-
console.log("a3: " + a3);
|
|
104
|
-
|
|
105
|
-
const a4 = new JSON.Obj();
|
|
106
|
-
|
|
107
|
-
a4.set("x", 1.5);
|
|
108
|
-
a4.set("y", 5.4);
|
|
109
|
-
a4.set("z", 9.8);
|
|
110
|
-
a4.set("obj", obj);
|
|
111
|
-
a4.set<boolean>("bool", false);
|
|
112
|
-
|
|
113
|
-
console.log("a4: " + JSON.stringify(a4));
|
|
114
|
-
|
|
115
|
-
const a5 = JSON.parse<JSON.Obj>('{"foo":"bar"}');
|
|
116
|
-
|
|
117
|
-
console.log("a5: " + JSON.stringify(a5));
|
|
118
|
-
|
|
119
|
-
const a6 = JSON.parse<JSON.Obj>('{"x":1.5,"y":5.4,"z":9.8,"obj":{"foo":"bar"}}');
|
|
120
|
-
|
|
121
|
-
console.log("a6: " + JSON.stringify(a6));
|
|
122
|
-
|
|
123
|
-
const a7 = JSON.parse<JSON.Value[]>('["string",true,3.14,{"x":1.0,"y":2.0,"z":3.0},[1,2,3,true]]');
|
|
124
|
-
|
|
125
|
-
console.log("a7: " + JSON.stringify(a7));
|
|
126
|
-
|
|
127
|
-
const a8 = JSON.stringify(["hello", JSON.stringify("world"), "working?"]);
|
|
128
|
-
|
|
129
|
-
console.log("a8: " + a8);
|
|
130
|
-
|
|
131
|
-
const a9 = JSON.stringify<JSON.Raw>(JSON.Raw.from('"hello world"'));
|
|
132
|
-
|
|
133
|
-
console.log("a9: " + a9);
|
|
134
|
-
|
|
135
|
-
const m10 = new Map<string, JSON.Raw>();
|
|
136
|
-
m10.set("hello", new JSON.Raw('"world"'));
|
|
137
|
-
m10.set("pos", new JSON.Raw('{"x":1.0,"y":2.0,"z":3.0}'));
|
|
138
|
-
|
|
139
|
-
const a10 = JSON.stringify(m10);
|
|
140
|
-
|
|
141
|
-
console.log("a10: " + a10);
|
|
142
|
-
|
|
143
|
-
const a11 = JSON.parse<JSON.Obj>(' { "x" : 3.4 , "y" : 1.2 , "z" : 8.3 } ');
|
|
144
|
-
|
|
145
|
-
console.log("a11: " + JSON.stringify(a11));
|
|
146
|
-
|
|
147
|
-
const a12 = JSON.parse<InnerObj<ObjWithBracketString>>('{"obj":{"data":"hello} world"}}');
|
|
148
|
-
|
|
149
|
-
console.log("a12: " + JSON.stringify(a12));
|
|
150
|
-
|
|
151
|
-
const a13 = JSON.stringify<JSON.Obj>(new JSON.Obj());
|
|
152
|
-
|
|
153
|
-
console.log("a13: " + a13);
|
|
66
|
+
test();
|
package/bench/abc.bench.ts
CHANGED
package/bench/large.bench.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { bench } from "./lib/bench";
|
|
1
|
+
import { bench } from "./lib/bench.js";
|
|
2
2
|
|
|
3
3
|
class Vec3 {
|
|
4
4
|
public x!: number;
|
|
@@ -110,7 +110,7 @@ const v1: LargeJSON = {
|
|
|
110
110
|
const v2 = `{"id":2,"name":"Medium Object","age":18,"email":"me@jairus.dev","street":"I don't want to say my street","city":"I don't want to say this either","state":"It really depends","zip":"I forget what it is","tags":["me","dogs","mountains","bar","foo"],"theme":"Hyper Term Black","notifications":true,"language":"en-US","movement":[{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3}]}`;
|
|
111
111
|
|
|
112
112
|
bench(
|
|
113
|
-
"Serialize
|
|
113
|
+
"Serialize Large Object",
|
|
114
114
|
() => {
|
|
115
115
|
JSON.stringify(v1);
|
|
116
116
|
},
|
|
@@ -118,7 +118,7 @@ bench(
|
|
|
118
118
|
);
|
|
119
119
|
|
|
120
120
|
bench(
|
|
121
|
-
"Deserialize
|
|
121
|
+
"Deserialize Large Object",
|
|
122
122
|
() => {
|
|
123
123
|
JSON.parse(v2);
|
|
124
124
|
},
|
package/bench/lib/bench.ts
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
|
+
if (typeof console === "undefined") {
|
|
2
|
+
console = {
|
|
3
|
+
log: print,
|
|
4
|
+
error: print,
|
|
5
|
+
warn: print,
|
|
6
|
+
};
|
|
7
|
+
}
|
|
8
|
+
|
|
1
9
|
export function bench(description: string, routine: () => void, ops: number = 1_000_000): void {
|
|
2
10
|
console.log(" - Benchmarking " + description);
|
|
11
|
+
let warmup = ops / 10;
|
|
12
|
+
while (--warmup) {
|
|
13
|
+
routine();
|
|
14
|
+
}
|
|
3
15
|
const start = Date.now();
|
|
4
16
|
let count = ops;
|
|
5
17
|
while (count !== 0) {
|
package/bench/medium.bench.ts
CHANGED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
const bytes = readbuffer("./build/" + arguments[0]);
|
|
2
|
+
const module = new WebAssembly.Module(bytes);
|
|
3
|
+
let memory = null;
|
|
4
|
+
const { exports } = new WebAssembly.Instance(module, {
|
|
5
|
+
env: {
|
|
6
|
+
abort: (msg, file, line) => {
|
|
7
|
+
console.log("abort: " + __liftString(msg) + " in " + __liftString(file) + ":" + __liftString(line));
|
|
8
|
+
},
|
|
9
|
+
"console.log": (ptr) => {
|
|
10
|
+
console.log(__liftString(ptr));
|
|
11
|
+
},
|
|
12
|
+
"Date.now": () => Date.now(),
|
|
13
|
+
},
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
memory = exports.memory;
|
|
17
|
+
|
|
18
|
+
function __liftString(pointer) {
|
|
19
|
+
if (!pointer) return null;
|
|
20
|
+
const end = (pointer + new Uint32Array(memory.buffer)[(pointer - 4) >>> 2]) >>> 1,
|
|
21
|
+
memoryU16 = new Uint16Array(memory.buffer);
|
|
22
|
+
let start = pointer >>> 1,
|
|
23
|
+
string = "";
|
|
24
|
+
while (end - start > 1024) string += String.fromCharCode(...memoryU16.subarray(start, (start += 1024)));
|
|
25
|
+
return string + String.fromCharCode(...memoryU16.subarray(start, end));
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
exports.start();
|
package/bench/small.bench.ts
CHANGED
package/bench/vec3.bench.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "json-as",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.9",
|
|
4
4
|
"author": "Jairus Tanaka",
|
|
5
5
|
"description": "The only JSON library you'll need for AssemblyScript. SIMD enabled",
|
|
6
6
|
"types": "assembly/index.ts",
|
|
@@ -18,9 +18,8 @@
|
|
|
18
18
|
"test": "bash ./run-tests.sh",
|
|
19
19
|
"bench:as": "bash ./run-bench.as.sh",
|
|
20
20
|
"bench:js": "bash ./run-bench.js.sh",
|
|
21
|
-
"build:
|
|
22
|
-
"build:test": "rm -rf ./build/ && JSON_DEBUG=true asc assembly/test.ts --transform ./transform -o ./build/test.wasm --textFile ./build/test.wat --optimizeLevel 3 --shrinkLevel 0",
|
|
23
|
-
"build:test:simd": "rm -rf ./build/ && JSON_DEBUG=true asc assembly/test.ts --transform ./transform -o ./build/test.wasm --textFile ./build/test.wat --optimizeLevel 3 --shrinkLevel 0 --enable simd",
|
|
21
|
+
"build:test": "rm -rf ./build/ && JSON_DEBUG=true asc assembly/test.ts --transform ./transform -o ./build/test.wasm --textFile ./build/test.wat --debug --config ./node_modules/@assemblyscript/wasi-shim/asconfig.json",
|
|
22
|
+
"build:test:simd": "rm -rf ./build/ && JSON_DEBUG=true asc assembly/test.ts --transform ./transform -o ./build/test.wasm --textFile ./build/test.wat --optimizeLevel 3 --shrinkLevel 0 --enable simd --config ./node_modules/@assemblyscript/wasi-shim/asconfig.json",
|
|
24
23
|
"test:wasmtime": "wasmtime ./build/test.wasm",
|
|
25
24
|
"test:wasmer": "wasmer ./build/test.wasm",
|
|
26
25
|
"build:transform": "tsc -p ./transform",
|
package/run-bench.as.sh
CHANGED
|
@@ -1,27 +1,53 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
|
+
RUNTIMES=${RUNTIMES:-"minimal stub"}
|
|
3
|
+
ENGINES=${ENGINES:-"liftoff ignition sparkplug turbofan llvm"}
|
|
4
|
+
for file in ./assembly/__benches__/vec3.bench.ts; do
|
|
5
|
+
filename=$(basename -- "$file")
|
|
6
|
+
output_wasi=
|
|
7
|
+
for runtime in $RUNTIMES; do
|
|
8
|
+
output="./build/${filename%.ts}.${runtime}.wasm"
|
|
2
9
|
|
|
3
|
-
|
|
10
|
+
npx asc "$file" --transform ./transform -o "${output}.1" -O3 --converge --noAssert --uncheckedBehavior always --runtime $runtime --enable simd --enable bulk-memory --exportStart start || {
|
|
11
|
+
echo "Build failed"
|
|
12
|
+
exit 1
|
|
13
|
+
}
|
|
4
14
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
output="./build/${filename%.ts}.wasm"
|
|
15
|
+
wasm-opt -all -O4 "${output}.1" -o "$output"
|
|
16
|
+
rm "${output}.1"
|
|
8
17
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
18
|
+
npx asc "$file" --transform ./transform -o "${output}.2" -O3 --converge --noAssert --uncheckedBehavior always --runtime $runtime --enable simd --enable bulk-memory --config ./node_modules/@assemblyscript/wasi-shim/asconfig.json || {
|
|
19
|
+
echo "Build failed"
|
|
20
|
+
exit 1
|
|
21
|
+
}
|
|
12
22
|
|
|
13
|
-
|
|
23
|
+
wasm-opt -all -O4 "${output}.2" -o "${output%.wasm}.wasi.wasm"
|
|
24
|
+
rm "${output}.2"
|
|
14
25
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
elif [ "$build_time" -ge 1000 ]; then
|
|
18
|
-
formatted_time="$(bc <<< "scale=2; $build_time/1000")s"
|
|
19
|
-
else
|
|
20
|
-
formatted_time="${build_time}ms"
|
|
21
|
-
fi
|
|
26
|
+
for engine in $ENGINES; do
|
|
27
|
+
echo -e "$filename (asc/$runtime/$engine)\n"
|
|
22
28
|
|
|
23
|
-
|
|
24
|
-
|
|
29
|
+
arg="${filename%.ts}.${runtime}.wasm"
|
|
30
|
+
if [[ "$engine" == "ignition" ]]; then
|
|
31
|
+
v8 --no-opt --module ./bench/runners/assemblyscript.js -- $arg
|
|
32
|
+
fi
|
|
33
|
+
|
|
34
|
+
if [[ "$engine" == "liftoff" ]]; then
|
|
35
|
+
v8 --liftoff-only --no-opt --module ./bench/runners/assemblyscript.js -- $arg
|
|
36
|
+
fi
|
|
37
|
+
|
|
38
|
+
if [[ "$engine" == "sparkplug" ]]; then
|
|
39
|
+
v8 --sparkplug --always-sparkplug --no-opt --module ./bench/runners/assemblyscript.js -- $arg
|
|
40
|
+
fi
|
|
41
|
+
|
|
42
|
+
if [[ "$engine" == "turbofan" ]]; then
|
|
43
|
+
v8 --no-liftoff --no-wasm-tier-up --module ./bench/runners/assemblyscript.js -- $arg
|
|
44
|
+
fi
|
|
45
|
+
|
|
46
|
+
if [[ "$engine" == "llvm" ]]; then
|
|
47
|
+
wasmer run "${output%.wasm}.wasi.wasm" --llvm --enable-simd --enable-bulk-memory --enable-relaxed-simd --enable-pass-params-opt
|
|
48
|
+
fi
|
|
49
|
+
done
|
|
50
|
+
done
|
|
25
51
|
done
|
|
26
52
|
|
|
27
|
-
echo "Finished benchmarks
|
|
53
|
+
echo "Finished benchmarks"
|