json-as 1.0.4 → 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/CHANGELOG.md +10 -1
  2. package/README.md +26 -8
  3. package/SECURITY.md +2 -1
  4. package/assembly/__benches__/large.bench.ts +3 -0
  5. package/assembly/__benches__/vec3.bench.ts +3 -0
  6. package/assembly/__tests__/arbitrary.spec.ts +3 -3
  7. package/assembly/__tests__/array.spec.ts +5 -8
  8. package/assembly/__tests__/box.spec.ts +10 -20
  9. package/assembly/__tests__/custom.spec.ts +5 -6
  10. package/assembly/__tests__/date.spec.ts +4 -6
  11. package/assembly/__tests__/float.spec.ts +3 -3
  12. package/assembly/__tests__/map.spec.ts +1 -1
  13. package/assembly/__tests__/raw.spec.ts +3 -3
  14. package/assembly/__tests__/struct.spec.ts +24 -14
  15. package/assembly/deserialize/simd/string.ts +1 -2
  16. package/assembly/deserialize/simple/array/struct.ts +2 -3
  17. package/assembly/deserialize/simple/array.ts +1 -1
  18. package/assembly/deserialize/simple/bool.ts +1 -1
  19. package/assembly/deserialize/simple/map.ts +3 -4
  20. package/assembly/deserialize/simple/object.ts +2 -3
  21. package/assembly/deserialize/simple/raw.ts +1 -1
  22. package/assembly/deserialize/simple/struct.ts +2 -3
  23. package/assembly/index.ts +23 -7
  24. package/assembly/serialize/simd/string.ts +1 -0
  25. package/assembly/serialize/simple/integer.ts +1 -1
  26. package/assembly/serialize/simple/object.ts +7 -6
  27. package/assembly/test.ts +23 -24
  28. package/bench.js +2 -4
  29. package/index.ts +1 -1
  30. package/lib/as-bs.ts +4 -13
  31. package/package.json +5 -3
  32. package/run-tests.sh +1 -1
  33. package/transform/lib/index.js +58 -55
  34. package/transform/lib/index.js.map +1 -1
  35. package/transform/src/index.ts +72 -131
package/assembly/index.ts CHANGED
@@ -4,6 +4,7 @@ import { bs } from "../lib/as-bs";
4
4
  import { serializeString } from "./serialize/simple/string";
5
5
  import { serializeArray } from "./serialize/simple/array";
6
6
  import { serializeMap } from "./serialize/simple/map";
7
+ import { serializeDate } from "./serialize/simple/date";
7
8
  import { deserializeBoolean } from "./deserialize/simple/bool";
8
9
  import { deserializeArray } from "./deserialize/simple/array";
9
10
  import { deserializeFloat } from "./deserialize/simple/float";
@@ -28,6 +29,8 @@ import { serializeObject } from "./serialize/simple/object";
28
29
  import { deserializeObject } from "./deserialize/simple/object";
29
30
  import { serializeRaw } from "./serialize/simple/raw";
30
31
  import { deserializeRaw } from "./deserialize/simple/raw";
32
+ import { isSpace } from "util/string";
33
+ import { deserializeString_SIMD } from "./deserialize/simd/string";
31
34
 
32
35
  /**
33
36
  * Offset of the 'storage' property in the JSON.Value class.
@@ -179,8 +182,14 @@ export namespace JSON {
179
182
  // @ts-ignore
180
183
  return null;
181
184
  } else if (isString<T>()) {
185
+ if (dataSize < 4) throw new Error("Cannot parse data as string because it was formatted incorrectly!");
186
+ // if (ASC_FEATURE_SIMD) {
187
+ // // @ts-ignore
188
+ // return changetype<string>(deserializeString_SIMD(dataPtr, dataPtr + dataSize, __new(dataSize - 4, idof<string>())));
189
+ // } else {
182
190
  // @ts-ignore
183
191
  return deserializeString(dataPtr, dataPtr + dataSize, __new(dataSize - 4, idof<string>()));
192
+ // }
184
193
  } else if (isArray<T>()) {
185
194
  // @ts-ignore
186
195
  return inline.always(deserializeArray<nonnull<T>>(dataPtr, dataPtr + dataSize, changetype<usize>(instantiate<T>())));
@@ -210,6 +219,7 @@ export namespace JSON {
210
219
  // @ts-ignore: type
211
220
  return deserializeRaw(dataPtr, dataPtr + dataSize);
212
221
  } else if (type instanceof JSON.Value) {
222
+ // should cut out whitespace here
213
223
  // @ts-ignore
214
224
  return inline.always(deserializeArbitrary(dataPtr, dataPtr + dataSize, 0));
215
225
  } else if (type instanceof JSON.Obj) {
@@ -478,7 +488,6 @@ export namespace JSON {
478
488
  const out = changetype<JSON.Obj>(__new(offsetof<JSON.Obj>(), idof<JSON.Obj>()));
479
489
 
480
490
  if (value instanceof Map) {
481
-
482
491
  }
483
492
  return out;
484
493
  }
@@ -579,14 +588,15 @@ export namespace JSON {
579
588
  } else if (isFloat<T>()) {
580
589
  return deserializeFloat<T>(srcStart, srcEnd);
581
590
  } else if (isString<T>()) {
591
+ if (srcEnd - srcStart < 4) throw new Error("Cannot parse data as string because it was formatted incorrectly!");
582
592
  // @ts-ignore: type
583
593
  return deserializeString(srcStart, srcEnd, dst);
584
- } else if (isArray<T>()) {
585
- // @ts-ignore: type
586
- return inline.always(deserializeArray<T>(srcStart, srcEnd, dst));
587
594
  } else if (isNullable<T>() && srcEnd - srcStart == 8 && load<u64>(srcStart) == 30399761348886638) {
588
595
  // @ts-ignore
589
596
  return null;
597
+ } else if (isArray<T>()) {
598
+ // @ts-ignore: type
599
+ return inline.always(deserializeArray<T>(srcStart, srcEnd, dst));
590
600
  } else {
591
601
  let type: nonnull<T> = changetype<nonnull<T>>(0);
592
602
  // @ts-ignore: Defined by transform
@@ -630,9 +640,15 @@ export namespace JSON {
630
640
  }
631
641
 
632
642
  // @ts-ignore: inline
633
- @inline export function toRaw(data: string): JSON.Raw { return new JSON.Raw(data) }
643
+ @inline export function toRaw(data: string): JSON.Raw {
644
+ return new JSON.Raw(data);
645
+ }
634
646
  // @ts-ignore: inline
635
- @inline export function fromRaw(data: JSON.Raw): string { return data.data }
647
+ @inline export function fromRaw(data: JSON.Raw): string {
648
+ return data.data;
649
+ }
636
650
 
637
651
  // @ts-ignore: inline
638
- @inline export function toBox<T>(data: T): JSON.Box<T> { return new JSON.Box<T>(data) }
652
+ @inline export function toBox<T>(data: T): JSON.Box<T> {
653
+ return new JSON.Box<T>(data);
654
+ }
@@ -1,3 +1,4 @@
1
+ import { bs } from "../../../lib/as-bs";
1
2
  import { BACK_SLASH } from "../../custom/chars";
2
3
  import { SERIALIZE_ESCAPE_TABLE } from "../../globals/tables";
3
4
  import { OBJECT, TOTAL_OVERHEAD } from "rt/common";
@@ -10,4 +10,4 @@ import { itoa_buffered } from "util/number";
10
10
  }
11
11
 
12
12
  // 32 {"x":,"y":,"z"}
13
- // 18 3.41.28.3
13
+ // 18 3.41.28.3
@@ -5,13 +5,14 @@ import { bytes } from "../../util";
5
5
 
6
6
  export function serializeObject(data: JSON.Obj): void {
7
7
  if (!data.size) {
8
- store<u32>(bs.offset, 0);
8
+ bs.proposeSize(4);
9
+ store<u32>(bs.offset, 8192123);
9
10
  bs.offset += 4;
10
11
  return;
11
12
  }
12
13
 
13
- // This grabs `JSON.Obj.stackSize` which is private
14
- bs.ensureSize(load<u32>(changetype<usize>(data), offsetof<JSON.Obj>("stackSize")) - 2);
14
+
15
+ bs.proposeSize(load<u32>(changetype<usize>(data), offsetof<JSON.Obj>("stackSize")) - 2);
15
16
  const keys = data.keys();
16
17
  const values = data.values();
17
18
 
@@ -25,7 +26,7 @@ export function serializeObject(data: JSON.Obj): void {
25
26
  const keySize = bytes(firstKey);
26
27
  store<u16>(bs.offset, QUOTE);
27
28
  memory.copy(bs.offset + 2, changetype<usize>(firstKey), keySize);
28
- store<u32>(bs.offset += keySize + 2, 3801122); // ":
29
+ store<u32>((bs.offset += keySize + 2), 3801122); // ":
29
30
  bs.offset += 4;
30
31
  JSON.__serialize(unchecked(values[0]));
31
32
 
@@ -34,11 +35,11 @@ export function serializeObject(data: JSON.Obj): void {
34
35
  const keySize = bytes(key);
35
36
  store<u32>(bs.offset, 2228268); // ,"
36
37
  memory.copy(bs.offset + 4, changetype<usize>(key), keySize);
37
- store<u32>(bs.offset += keySize + 4, 3801122); // ":
38
+ store<u32>((bs.offset += keySize + 4), 3801122); // ":
38
39
  bs.offset += 4;
39
40
  JSON.__serialize(unchecked(values[i]));
40
41
  }
41
42
 
42
43
  store<u16>(bs.offset, BRACE_RIGHT);
43
44
  bs.offset += 2;
44
- }
45
+ }
package/assembly/test.ts CHANGED
@@ -5,9 +5,10 @@ import { bytes } from "./util";
5
5
  class Obj {
6
6
  public a: string = "hello";
7
7
  public b: string = "world";
8
- public c: string = "\"\t\f\u0000\u0001";
8
+ public c: string = '"\t\f\u0000\u0001';
9
9
  }
10
10
 
11
+
11
12
  @json
12
13
  class Vec3 {
13
14
  x: f32 = 0.0;
@@ -15,8 +16,10 @@ class Vec3 {
15
16
  z: f32 = 0.0;
16
17
  }
17
18
 
19
+
18
20
  @json
19
21
  class Player {
22
+
20
23
  @alias("first name")
21
24
  firstName!: string;
22
25
  lastName!: string;
@@ -24,11 +27,13 @@ class Player {
24
27
  // Drop in a code block, function, or expression that evaluates to a boolean
25
28
  @omitif((self: Player) => self.age < 18)
26
29
  age!: i32;
30
+
27
31
  @omitnull()
28
32
  pos!: Vec3 | null;
29
33
  isVerified!: boolean;
30
34
  }
31
35
 
36
+
32
37
  @json
33
38
  class Point {
34
39
  x: f64 = 0.0;
@@ -37,10 +42,12 @@ class Point {
37
42
  this.x = x;
38
43
  this.y = y;
39
44
  }
45
+
40
46
  @serializer
41
47
  serializer(self: Point): string {
42
48
  return `(${self.x},${self.y})`;
43
49
  }
50
+
44
51
  @deserializer
45
52
  deserializer(data: string): Point | null {
46
53
  const dataSize = bytes(data);
@@ -50,18 +57,17 @@ class Point {
50
57
  const x = data.slice(1, c);
51
58
  const y = data.slice(c + 1, data.length - 1);
52
59
 
53
- return new Point(
54
- f64.parse(x),
55
- f64.parse(y)
56
- );
60
+ return new Point(f64.parse(x), f64.parse(y));
57
61
  }
58
62
  }
59
63
 
64
+
60
65
  @json
61
66
  class InnerObj<T> {
62
- obj: T = instantiate<T>()
67
+ obj: T = instantiate<T>();
63
68
  }
64
69
 
70
+
65
71
  @json
66
72
  class ObjWithBracketString {
67
73
  data: string = "";
@@ -75,9 +81,9 @@ const player: Player = {
75
81
  pos: {
76
82
  x: 3.4,
77
83
  y: 1.2,
78
- z: 8.3
84
+ z: 8.3,
79
85
  },
80
- isVerified: true
86
+ isVerified: true,
81
87
  };
82
88
 
83
89
  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");
@@ -98,7 +104,7 @@ const a4 = new JSON.Obj();
98
104
  a4.set("x", 1.5);
99
105
  a4.set("y", 5.4);
100
106
  a4.set("z", 9.8);
101
- a4.set("obj", obj)
107
+ a4.set("obj", obj);
102
108
  a4.set<boolean>("bool", false);
103
109
 
104
110
  console.log("a4: " + JSON.stringify(a4));
@@ -115,37 +121,30 @@ const a7 = JSON.parse<JSON.Value[]>('["string",true,3.14,{"x":1.0,"y":2.0,"z":3.
115
121
 
116
122
  console.log("a7: " + JSON.stringify(a7));
117
123
 
118
- const a8 = JSON.stringify(["hello", JSON.stringify("world"),"working?"]);
124
+ const a8 = JSON.stringify(["hello", JSON.stringify("world"), "working?"]);
119
125
 
120
126
  console.log("a8: " + a8);
121
127
 
122
- const a9 = JSON.stringify<JSON.Raw>(JSON.Raw.from("\"hello world\""));
128
+ const a9 = JSON.stringify<JSON.Raw>(JSON.Raw.from('"hello world"'));
123
129
 
124
130
  console.log("a9: " + a9);
125
131
 
126
132
  const m10 = new Map<string, JSON.Raw>();
127
- m10.set("hello", new JSON.Raw("\"world\""));
128
- m10.set("pos", new JSON.Raw("{\"x\":1.0,\"y\":2.0,\"z\":3.0}"));
133
+ m10.set("hello", new JSON.Raw('"world"'));
134
+ m10.set("pos", new JSON.Raw('{"x":1.0,"y":2.0,"z":3.0}'));
129
135
 
130
136
  const a10 = JSON.stringify(m10);
131
137
 
132
138
  console.log("a10: " + a10);
133
139
 
134
- const a11 = JSON.parse<Vec3>(' { "x" : 3.4 , "y" : 1.2 , "z" : 8.3 } ');
140
+ const a11 = JSON.parse<JSON.Obj>(' { "x" : 3.4 , "y" : 1.2 , "z" : 8.3 } ');
135
141
 
136
142
  console.log("a11: " + JSON.stringify(a11));
137
143
 
138
144
  const a12 = JSON.parse<InnerObj<ObjWithBracketString>>('{"obj":{"data":"hello} world"}}');
139
145
 
140
- console.log("a12: " + JSON.stringify(a12))
141
-
146
+ console.log("a12: " + JSON.stringify(a12));
142
147
 
143
- @json
144
- class NullableObj {
145
- bar: Bar | null = null;
146
- }
148
+ const a13 = JSON.stringify<JSON.Obj>(new JSON.Obj());
147
149
 
148
- @json
149
- class Bar {
150
- value: string = "";
151
- }
150
+ console.log("a13: " + a13);
package/bench.js CHANGED
@@ -34,9 +34,7 @@ const vec = {
34
34
  let data;
35
35
 
36
36
  const bench = new Bench({ time: 1000 })
37
- .add("serialize vec3", () =>
38
- data = JSON.stringify(vec)
39
- )
37
+ .add("serialize vec3", () => (data = JSON.stringify(vec)))
40
38
  .add("deserialize vec3", () => {
41
39
  data = JSON.parse('{"x":3,"y":1,"z":8}');
42
40
  })
@@ -44,7 +42,7 @@ const bench = new Bench({ time: 1000 })
44
42
  data = JSON.stringify("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789~`!@#$%^&*()-_=+{[}]|\\:;\"'?/>.<,'\"}");
45
43
  })
46
44
  .add("deserialize alphabet string", () => {
47
- data = JSON.parse('"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789~`!@#$%^&*()-_=+{[}]|\\\\:;\\"\'?/>.<,\'\\"}"')
45
+ data = JSON.parse('"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789~`!@#$%^&*()-_=+{[}]|\\\\:;\\"\'?/>.<,\'\\"}"');
48
46
  }) /*
49
47
  .add("parse float", () => {
50
48
  data = JSON.parse("1.2345")
package/index.ts CHANGED
@@ -1 +1 @@
1
- export { JSON } from "./assembly/index";
1
+ export { JSON } from "./assembly/index";
package/lib/as-bs.ts CHANGED
@@ -5,7 +5,7 @@ import { OBJECT, TOTAL_OVERHEAD } from "rt/common";
5
5
  */
6
6
  export namespace bs {
7
7
  /** Current buffer pointer. */ // @ts-ignore
8
- export let buffer: ArrayBuffer = new ArrayBuffer(32);//__new(32, idof<ArrayBuffer>());
8
+ export let buffer: ArrayBuffer = new ArrayBuffer(32); //__new(32, idof<ArrayBuffer>());
9
9
 
10
10
  /** Current offset within the buffer. */
11
11
  export let offset: usize = changetype<usize>(buffer);
@@ -28,10 +28,7 @@ export namespace bs {
28
28
  const deltaBytes = nextPowerOf2(size + 64);
29
29
  bufferSize += deltaBytes;
30
30
  // @ts-ignore: exists
31
- const newPtr = changetype<ArrayBuffer>(__renew(
32
- changetype<usize>(buffer),
33
- bufferSize
34
- ));
31
+ const newPtr = changetype<ArrayBuffer>(__renew(changetype<usize>(buffer), bufferSize));
35
32
  offset = offset + changetype<usize>(newPtr) - changetype<usize>(buffer);
36
33
  buffer = newPtr;
37
34
  }
@@ -49,10 +46,7 @@ export namespace bs {
49
46
  const deltaBytes = nextPowerOf2(size);
50
47
  bufferSize += deltaBytes;
51
48
  // @ts-ignore: exists
52
- const newPtr = changetype<ArrayBuffer>(__renew(
53
- changetype<usize>(buffer),
54
- bufferSize
55
- ));
49
+ const newPtr = changetype<ArrayBuffer>(__renew(changetype<usize>(buffer), bufferSize));
56
50
  offset = offset + changetype<usize>(newPtr) - changetype<usize>(buffer);
57
51
  buffer = newPtr;
58
52
  }
@@ -70,10 +64,7 @@ export namespace bs {
70
64
  const deltaBytes = nextPowerOf2(size + 64);
71
65
  bufferSize += deltaBytes;
72
66
  // @ts-ignore
73
- const newPtr = changetype<ArrayBuffer>(__renew(
74
- changetype<usize>(buffer),
75
- bufferSize
76
- ));
67
+ const newPtr = changetype<ArrayBuffer>(__renew(changetype<usize>(buffer), bufferSize));
77
68
  // if (buffer != newPtr) console.log(" Old: " + changetype<usize>(buffer).toString() + "\n New: " + changetype<usize>(newPtr).toString());
78
69
  offset = offset + changetype<usize>(newPtr) - changetype<usize>(buffer);
79
70
  buffer = newPtr;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "json-as",
3
- "version": "1.0.4",
3
+ "version": "1.0.5",
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",
@@ -44,7 +44,9 @@
44
44
  "lekiano",
45
45
  "Florian Guitton",
46
46
  "Matt Johnson-Pint",
47
- "Tomáš Hromada"
47
+ "Tomáš Hromada",
48
+ "Loredana Cirstea",
49
+ "Accipiter Nisus"
48
50
  ],
49
51
  "keywords": [
50
52
  "assemblyscript",
@@ -65,4 +67,4 @@
65
67
  "@JairusSW:registry": "https://npm.pkg.github.com"
66
68
  },
67
69
  "type": "module"
68
- }
70
+ }
package/run-tests.sh CHANGED
@@ -7,7 +7,7 @@ for file in ./assembly/__tests__/*.spec.ts; do
7
7
  output="./build/${filename%.ts}.wasm"
8
8
 
9
9
  start_time=$(date +%s%3N)
10
- npx asc "$file" --transform ./transform -o "$output" || { echo "Tests failed"; exit 1; }
10
+ npx asc "$file" --transform ./transform -o "$output" --enable simd || { echo "Tests failed"; exit 1; }
11
11
  end_time=$(date +%s%3N)
12
12
 
13
13
  build_time=$((end_time - start_time))
@@ -1,19 +1,22 @@
1
1
  import { Node } from "assemblyscript/dist/assemblyscript.js";
2
2
  import { Transform } from "assemblyscript/dist/transform.js";
3
3
  import { Visitor } from "./visitor.js";
4
- import { SimpleParser, toString } from "./util.js";
4
+ import { isStdlib, SimpleParser, toString } from "./util.js";
5
5
  import * as path from "path";
6
6
  import { fileURLToPath } from "url";
7
7
  import { Property, PropertyFlags, Schema } from "./types.js";
8
8
  import { getClasses, getImportedClass } from "./linker.js";
9
9
  let indent = " ";
10
10
  class JSONTransform extends Visitor {
11
+ program;
12
+ baseDir;
11
13
  parser;
12
14
  schemas = [];
13
15
  schema;
14
16
  sources = new Set();
15
17
  imports = [];
16
18
  topStatements = [];
19
+ simdStatements = [];
17
20
  visitClassDeclaration(node) {
18
21
  if (!node.decorators?.length)
19
22
  return;
@@ -29,8 +32,8 @@ class JSONTransform extends Visitor {
29
32
  if (process.env["JSON_DEBUG"])
30
33
  console.log("Created schema: " + this.schema.name + " in file " + node.range.source.normalizedPath);
31
34
  const members = [...node.members.filter((v) => v.kind === 54 && v.flags !== 32 && v.flags !== 512 && v.flags !== 1024 && !v.decorators?.some((decorator) => decorator.name.text === "omit"))];
32
- const serializers = [...(node.members.filter((v) => v.kind === 58 && v.decorators && v.decorators.some((e) => e.name.text.toLowerCase() === "serializer")))];
33
- const deserializers = [...(node.members.filter((v) => v.kind === 58 && v.decorators && v.decorators.some((e) => e.name.text.toLowerCase() === "deserializer")))];
35
+ const serializers = [...node.members.filter((v) => v.kind === 58 && v.decorators && v.decorators.some((e) => e.name.text.toLowerCase() === "serializer"))];
36
+ const deserializers = [...node.members.filter((v) => v.kind === 58 && v.decorators && v.decorators.some((e) => e.name.text.toLowerCase() === "deserializer"))];
34
37
  if (serializers.length > 1)
35
38
  throwError("Multiple serializers detected for class " + node.name.text + " but schemas can only have one serializer!", serializers[1].range);
36
39
  if (deserializers.length > 1)
@@ -51,7 +54,7 @@ class JSONTransform extends Visitor {
51
54
  let SERIALIZER = "";
52
55
  SERIALIZER += " __SERIALIZE_CUSTOM(ptr: usize): void {\n";
53
56
  SERIALIZER += " const data = this." + serializer.name.text + "(changetype<" + this.schema.name + ">(ptr));\n";
54
- SERIALIZER += " if (isNullable(data) && changetype<usize>(data) == <usize>0) throw new Error(\"Could not serialize data using custom serializer!\");\n";
57
+ SERIALIZER += ' if (isNullable(data) && changetype<usize>(data) == <usize>0) throw new Error("Could not serialize data using custom serializer!");\n';
55
58
  SERIALIZER += " const dataSize = data.length << 1;\n";
56
59
  SERIALIZER += " memory.copy(bs.offset, changetype<usize>(data), dataSize);\n";
57
60
  SERIALIZER += " bs.offset += dataSize;\n";
@@ -78,7 +81,7 @@ class JSONTransform extends Visitor {
78
81
  let DESERIALIZER = "";
79
82
  DESERIALIZER += " __DESERIALIZE_CUSTOM(data: string): " + this.schema.name + " {\n";
80
83
  DESERIALIZER += " const d = this." + deserializer.name.text + "(data)";
81
- DESERIALIZER += " if (isNullable(d) && changetype<usize>(d) == <usize>0) throw new Error(\"Could not deserialize data using custom deserializer!\");\n";
84
+ DESERIALIZER += ' if (isNullable(d) && changetype<usize>(d) == <usize>0) throw new Error("Could not deserialize data using custom deserializer!");\n';
82
85
  DESERIALIZER += " return d;\n";
83
86
  DESERIALIZER += " }\n";
84
87
  if (process.env["JSON_DEBUG"])
@@ -217,12 +220,13 @@ class JSONTransform extends Visitor {
217
220
  else if (member.type == "string" || member.type == "String") {
218
221
  INITIALIZE += ` this.${member.name} = "";\n`;
219
222
  }
223
+ const SIMD_ENABLED = this.program.options.hasFeature(16);
220
224
  if (!isRegular && !member.flags.has(PropertyFlags.OmitIf) && !member.flags.has(PropertyFlags.OmitNull))
221
225
  isRegular = true;
222
226
  if (isRegular && isPure) {
223
227
  const keyPart = (isFirst ? "{" : ",") + aliasName + ":";
224
228
  this.schema.byteSize += keyPart.length << 1;
225
- SERIALIZE += this.getStores(keyPart)
229
+ SERIALIZE += this.getStores(keyPart, SIMD_ENABLED)
226
230
  .map((v) => indent + v + "\n")
227
231
  .join("");
228
232
  SERIALIZE += indent + `JSON.__serialize<${member.type}>(load<${member.type}>(ptr, offsetof<this>(${JSON.stringify(realName)})));\n`;
@@ -232,7 +236,7 @@ class JSONTransform extends Visitor {
232
236
  else if (isRegular && !isPure) {
233
237
  const keyPart = (isFirst ? "" : ",") + aliasName + ":";
234
238
  this.schema.byteSize += keyPart.length << 1;
235
- SERIALIZE += this.getStores(keyPart)
239
+ SERIALIZE += this.getStores(keyPart, SIMD_ENABLED)
236
240
  .map((v) => indent + v + "\n")
237
241
  .join("");
238
242
  SERIALIZE += indent + `JSON.__serialize<${member.type}>(load<${member.type}>(ptr, offsetof<this>(${JSON.stringify(realName)})));\n`;
@@ -245,7 +249,7 @@ class JSONTransform extends Visitor {
245
249
  indentInc();
246
250
  const keyPart = aliasName + ":";
247
251
  this.schema.byteSize += keyPart.length << 1;
248
- SERIALIZE += this.getStores(keyPart)
252
+ SERIALIZE += this.getStores(keyPart, SIMD_ENABLED)
249
253
  .map((v) => indent + v + "\n")
250
254
  .join("");
251
255
  SERIALIZE += indent + `JSON.__serialize<${member.type}>(load<${member.type}>(ptr, offsetof<this>(${JSON.stringify(realName)})));\n`;
@@ -269,7 +273,7 @@ class JSONTransform extends Visitor {
269
273
  SERIALIZE += indent + `if (${toString(member.flags.get(PropertyFlags.OmitIf))}) {\n`;
270
274
  }
271
275
  indentInc();
272
- SERIALIZE += this.getStores(aliasName + ":")
276
+ SERIALIZE += this.getStores(aliasName + ":", SIMD_ENABLED)
273
277
  .map((v) => indent + v + "\n")
274
278
  .join("");
275
279
  SERIALIZE += indent + `JSON.__serialize<${member.type}>(load<${member.type}>(ptr, offsetof<this>(${JSON.stringify(realName)})));\n`;
@@ -317,7 +321,9 @@ class JSONTransform extends Visitor {
317
321
  for (let i = 0; i < memberGroup.length; i++) {
318
322
  const member = memberGroup[i];
319
323
  const memberName = member.alias || member.name;
320
- const dst = this.schemas.find(v => v.name == member.type) ? "ptr + offsetof<this>(\"" + member.name + "\") + 12" : "0";
324
+ const dst = this.schemas.find(v => v.name == member.type)
325
+ ? "load<usize>(ptr + offsetof<this>(\"" + member.name + "\"))"
326
+ : "0";
321
327
  if (memberLen == 2) {
322
328
  DESERIALIZE += `${indent} case ${memberName.charCodeAt(0)}: { // ${memberName}\n`;
323
329
  DESERIALIZE += `${indent} store<${member.type}>(ptr, JSON.__deserialize<${member.type}>(valStart, valEnd, ${dst}), offsetof<this>(${JSON.stringify(member.name)}));\n`;
@@ -416,19 +422,17 @@ class JSONTransform extends Visitor {
416
422
  }
417
423
  addRequiredImports(node) {
418
424
  const filePath = fileURLToPath(import.meta.url);
419
- const baseDir = path.resolve(filePath, '..', '..', '..');
420
- const nodePath = path.resolve(process.cwd(), node.range.source.normalizedPath);
425
+ const baseDir = path.resolve(filePath, "..", "..", "..");
426
+ const nodePath = path.resolve(this.baseDir, node.range.source.normalizedPath);
421
427
  const bsImport = this.imports.find((i) => i.declarations?.find((d) => d.foreignName.text == "bs" || d.name.text == "bs"));
422
428
  const jsonImport = this.imports.find((i) => i.declarations?.find((d) => d.foreignName.text == "JSON" || d.name.text == "JSON"));
423
- let bsPath = path.posix.join(...(path.relative(path.dirname(nodePath), path.join(baseDir, "lib", "as-bs")).split(path.sep))).replace(/^.*node_modules\/json-as/, "json-as");
424
- let jsonPath = path.posix.join(...(path.relative(path.dirname(nodePath), path.join(baseDir, "assembly", "index.ts")).split(path.sep))).replace(/^.*node_modules\/json-as/, "json-as");
429
+ let bsPath = path.posix.join(...path.relative(path.dirname(nodePath), path.join(baseDir, "lib", "as-bs")).split(path.sep)).replace(/^.*node_modules\/json-as/, "json-as");
430
+ let jsonPath = path.posix.join(...path.relative(path.dirname(nodePath), path.join(baseDir, "assembly", "index.ts")).split(path.sep)).replace(/^.*node_modules\/json-as/, "json-as");
425
431
  if (!bsImport) {
426
432
  if (node.normalizedPath.startsWith("~")) {
427
433
  bsPath = "json-as/lib/as-bs";
428
434
  }
429
- const replaceNode = Node.createImportStatement([
430
- Node.createImportDeclaration(Node.createIdentifierExpression("bs", node.range, false), null, node.range)
431
- ], Node.createStringLiteralExpression(bsPath, node.range), node.range);
435
+ const replaceNode = Node.createImportStatement([Node.createImportDeclaration(Node.createIdentifierExpression("bs", node.range, false), null, node.range)], Node.createStringLiteralExpression(bsPath, node.range), node.range);
432
436
  this.topStatements.push(replaceNode);
433
437
  if (process.env["JSON_DEBUG"])
434
438
  console.log("Added as-bs import: " + toString(replaceNode) + "\n");
@@ -437,9 +441,7 @@ class JSONTransform extends Visitor {
437
441
  if (node.normalizedPath.startsWith("~")) {
438
442
  jsonPath = "json-as/assembly/index.ts";
439
443
  }
440
- const replaceNode = Node.createImportStatement([
441
- Node.createImportDeclaration(Node.createIdentifierExpression("JSON", node.range, false), null, node.range)
442
- ], Node.createStringLiteralExpression(jsonPath, node.range), node.range);
444
+ const replaceNode = Node.createImportStatement([Node.createImportDeclaration(Node.createIdentifierExpression("JSON", node.range, false), null, node.range)], Node.createStringLiteralExpression(jsonPath, node.range), node.range);
443
445
  this.topStatements.push(replaceNode);
444
446
  if (process.env["JSON_DEBUG"])
445
447
  console.log("Added json-as import: " + toString(replaceNode) + "\n");
@@ -450,6 +452,14 @@ class JSONTransform extends Visitor {
450
452
  const sizes = strToNum(data, simd);
451
453
  let offset = 0;
452
454
  for (const [size, num] of sizes) {
455
+ if (size == "v128" && simd) {
456
+ let index = this.simdStatements.findIndex((v) => v.includes(num));
457
+ let name = "SIMD_" + (index == -1 ? this.simdStatements.length : index);
458
+ if (index && !this.simdStatements.includes(`const ${name} = ${num};`))
459
+ this.simdStatements.push(`const ${name} = ${num};`);
460
+ out.push("store<v128>(bs.offset, " + name + ", " + offset + "); // " + data.slice(offset >> 1, (offset >> 1) + 8));
461
+ offset += 16;
462
+ }
453
463
  if (size == "u64") {
454
464
  out.push("store<u64>(bs.offset, " + num + ", " + offset + "); // " + data.slice(offset >> 1, (offset >> 1) + 4));
455
465
  offset += 8;
@@ -467,36 +477,8 @@ class JSONTransform extends Visitor {
467
477
  return out;
468
478
  }
469
479
  isValidType(type, node) {
470
- const validTypes = [
471
- "string",
472
- "u8",
473
- "i8",
474
- "u16",
475
- "i16",
476
- "u32",
477
- "i32",
478
- "u64",
479
- "i64",
480
- "f32",
481
- "f64",
482
- "bool",
483
- "boolean",
484
- "Date",
485
- "JSON.Value",
486
- "JSON.Obj",
487
- "JSON.Raw",
488
- "Value",
489
- "Obj",
490
- "Raw",
491
- ...this.schemas.map((v) => v.name)
492
- ];
493
- const baseTypes = [
494
- "Array",
495
- "Map",
496
- "Set",
497
- "JSON.Box",
498
- "Box"
499
- ];
480
+ const validTypes = ["string", "u8", "i8", "u16", "i16", "u32", "i32", "u64", "i64", "f32", "f64", "bool", "boolean", "Date", "JSON.Value", "JSON.Obj", "JSON.Raw", "Value", "Obj", "Raw", ...this.schemas.map((v) => v.name)];
481
+ const baseTypes = ["Array", "Map", "Set", "JSON.Box", "Box"];
500
482
  if (node && node.isGeneric && node.typeParameters)
501
483
  validTypes.push(...node.typeParameters.map((v) => v.name.text));
502
484
  if (type.endsWith("| null")) {
@@ -514,19 +496,35 @@ class JSONTransform extends Visitor {
514
496
  export default class Transformer extends Transform {
515
497
  afterParse(parser) {
516
498
  const transformer = new JSONTransform();
517
- const sources = parser.sources.sort((_a, _b) => {
518
- const a = _a.internalPath;
519
- const b = _b.internalPath;
520
- if (a[0] == "~" && b[0] !== "~") {
499
+ const sources = parser.sources
500
+ .filter((source) => {
501
+ const p = source.internalPath;
502
+ if (p.startsWith("~lib/rt") || p.startsWith("~lib/performance") || p.startsWith("~lib/wasi_") || p.startsWith("~lib/shared/")) {
503
+ return false;
504
+ }
505
+ return !isStdlib(source);
506
+ })
507
+ .sort((a, b) => {
508
+ if (a.sourceKind >= 2 && b.sourceKind <= 1) {
521
509
  return -1;
522
510
  }
523
- else if (a[0] !== "~" && b[0] == "~") {
511
+ else if (a.sourceKind <= 1 && b.sourceKind >= 2) {
512
+ return 1;
513
+ }
514
+ else {
515
+ return 0;
516
+ }
517
+ })
518
+ .sort((a, b) => {
519
+ if (a.sourceKind === 1) {
524
520
  return 1;
525
521
  }
526
522
  else {
527
523
  return 0;
528
524
  }
529
525
  });
526
+ transformer.baseDir = path.join(process.cwd(), this.baseDir);
527
+ transformer.program = this.program;
530
528
  transformer.parser = parser;
531
529
  for (const source of sources) {
532
530
  transformer.imports = [];
@@ -536,6 +534,11 @@ export default class Transformer extends Transform {
536
534
  source.statements.unshift(...transformer.topStatements);
537
535
  transformer.topStatements = [];
538
536
  }
537
+ if (transformer.simdStatements.length) {
538
+ for (const simd of transformer.simdStatements)
539
+ source.statements.unshift(SimpleParser.parseTopLevelStatement(simd));
540
+ }
541
+ transformer.simdStatements = [];
539
542
  }
540
543
  const schemas = transformer.schemas;
541
544
  for (const schema of schemas) {