json-as 1.0.0-alpha.2 → 1.0.0-alpha.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.
Files changed (46) hide show
  1. package/.prettierignore +6 -0
  2. package/.prettierrc.json +0 -1
  3. package/CHANGELOG +23 -1
  4. package/README.md +33 -21
  5. package/as-test.config.json +1 -1
  6. package/asconfig.json +1 -29
  7. package/assembly/__tests__/array.spec.ts +67 -0
  8. package/assembly/__tests__/bool.spec.ts +4 -12
  9. package/assembly/__tests__/box.spec.ts +37 -0
  10. package/assembly/__tests__/date.spec.ts +38 -0
  11. package/assembly/__tests__/float.spec.ts +11 -21
  12. package/assembly/__tests__/integer.spec.ts +7 -9
  13. package/assembly/__tests__/null.spec.ts +12 -0
  14. package/assembly/__tests__/obj.spec.ts +137 -3
  15. package/assembly/__tests__/simd/string.spec.ts +21 -21
  16. package/assembly/__tests__/string.spec.ts +6 -4
  17. package/assembly/__tests__/test.spec.ts +120 -191
  18. package/assembly/deserialize/simple/bool.ts +5 -8
  19. package/assembly/deserialize/simple/date.ts +2 -2
  20. package/assembly/deserialize/simple/map.ts +1 -1
  21. package/assembly/deserialize/simple/object.ts +3 -1
  22. package/assembly/deserialize/simple/string.ts +4 -3
  23. package/assembly/globals/tables.ts +74 -416
  24. package/assembly/index.ts +48 -25
  25. package/assembly/serialize/simd/string.ts +11 -11
  26. package/assembly/serialize/simple/array.ts +5 -4
  27. package/assembly/serialize/simple/bool.ts +2 -2
  28. package/assembly/serialize/simple/date.ts +1 -1
  29. package/assembly/serialize/simple/integer.ts +6 -1
  30. package/assembly/serialize/simple/map.ts +6 -6
  31. package/assembly/serialize/simple/string.ts +3 -3
  32. package/assembly/test.ts +30 -15
  33. package/assembly/util/bytes.ts +1 -1
  34. package/assembly/util/snp.ts +2 -2
  35. package/modules/as-bs/assembly/index.ts +73 -92
  36. package/modules/test/assembly/index.ts +22 -0
  37. package/package.json +6 -10
  38. package/run-tests.sh +15 -0
  39. package/transform/lib/builder.js +1340 -1262
  40. package/transform/lib/index.js +582 -512
  41. package/transform/lib/index.js.map +1 -1
  42. package/transform/lib/linker.js +12 -10
  43. package/transform/lib/types.js +19 -19
  44. package/transform/lib/util.js +34 -34
  45. package/transform/lib/visitor.js +529 -526
  46. package/transform/src/index.ts +22 -16
@@ -18,7 +18,7 @@ export function serializeString_SIMD(src: string): void {
18
18
  const srcSize = changetype<OBJECT>(changetype<usize>(src) - TOTAL_OVERHEAD).rtSize;
19
19
  let srcStart = changetype<usize>(src);
20
20
  const srcEnd = srcStart + srcSize;
21
- bs.ensureSize(srcSize + 4);
21
+ bs.proposeSize(srcSize + 4);
22
22
  const srcEnd16 = srcEnd - 15;
23
23
 
24
24
  store<u8>(changetype<usize>(bs.offset), 34); /* " */
@@ -45,13 +45,13 @@ export function serializeString_SIMD(src: string): void {
45
45
  mask &= mask - 1;
46
46
 
47
47
  if ((escaped & 0xffff) != BACK_SLASH) {
48
- bs.ensureSize(10);
48
+ bs.growSize(10);
49
49
  store<u64>(dst_offset, 13511005048209500);
50
50
  store<u32>(dst_offset, escaped, 8);
51
51
  v128.store(dst_offset, v128.load(src_offset, 2), 12);
52
52
  bs.offset += 10;
53
53
  } else {
54
- bs.ensureSize(2);
54
+ bs.growSize(2);
55
55
  store<u32>(dst_offset, escaped);
56
56
  v128.store(dst_offset, v128.load(src_offset, 2), 4);
57
57
  bs.offset += 2;
@@ -84,7 +84,7 @@ export function serializeString_SIMD(src: string): void {
84
84
  mask &= mask - 1;
85
85
 
86
86
  if ((escaped & 0xffff) != BACK_SLASH) {
87
- bs.ensureSize(10);
87
+ bs.growSize(10);
88
88
  store<u64>(dst_offset, 13511005048209500);
89
89
  store<u32>(dst_offset, escaped, 8);
90
90
  while (lane_index < 6) {
@@ -93,7 +93,7 @@ export function serializeString_SIMD(src: string): void {
93
93
  }
94
94
  bs.offset += 10;
95
95
  } else {
96
- bs.ensureSize(2);
96
+ bs.growSize(2);
97
97
  store<u32>(dst_offset, escaped);
98
98
 
99
99
  while (lane_index < 6) {
@@ -116,12 +116,12 @@ export function serializeString_SIMD(src: string): void {
116
116
  const escaped = load<u32>(SERIALIZE_ESCAPE_TABLE + (codeA << 2));
117
117
 
118
118
  if ((escaped & 0xffff) != BACK_SLASH) {
119
- bs.ensureSize(10);
119
+ bs.growSize(10);
120
120
  store<u64>(bs.offset, 13511005048209500);
121
121
  store<u32>(bs.offset, escaped, 8);
122
122
  bs.offset += 12;
123
123
  } else {
124
- bs.ensureSize(2);
124
+ bs.growSize(2);
125
125
  store<u32>(bs.offset, escaped);
126
126
  bs.offset += 4;
127
127
  }
@@ -134,12 +134,12 @@ export function serializeString_SIMD(src: string): void {
134
134
  const escaped = load<u32>(SERIALIZE_ESCAPE_TABLE + (codeB << 2));
135
135
 
136
136
  if ((escaped & 0xffff) != BACK_SLASH) {
137
- bs.ensureSize(10);
137
+ bs.growSize(10);
138
138
  store<u64>(bs.offset, 13511005048209500);
139
139
  store<u32>(bs.offset, escaped, 8);
140
140
  bs.offset += 12;
141
141
  } else {
142
- bs.ensureSize(2);
142
+ bs.growSize(2);
143
143
  store<u32>(bs.offset, escaped);
144
144
  bs.offset += 4;
145
145
  }
@@ -156,12 +156,12 @@ export function serializeString_SIMD(src: string): void {
156
156
  const escaped = load<u32>(SERIALIZE_ESCAPE_TABLE + (code << 2));
157
157
 
158
158
  if ((escaped & 0xffff) != BACK_SLASH) {
159
- bs.ensureSize(10);
159
+ bs.growSize(10);
160
160
  store<u64>(bs.offset, 13511005048209500);
161
161
  store<u32>(bs.offset, escaped, 8);
162
162
  bs.offset += 12;
163
163
  } else {
164
- bs.ensureSize(2);
164
+ bs.growSize(2);
165
165
  store<u32>(bs.offset, escaped);
166
166
  bs.offset += 4;
167
167
  }
@@ -3,15 +3,16 @@ import { COMMA, BRACKET_RIGHT, BRACKET_LEFT } from "../../custom/chars";
3
3
  import { JSON } from "../..";
4
4
 
5
5
  export function serializeArray<T extends any[]>(src: T): void {
6
+ bs.proposeSize(4);
6
7
  const end = src.length - 1;
7
8
  let i = 0;
8
9
  if (end == -1) {
9
- bs.ensureSize(4);
10
10
  store<u32>(bs.offset, 6094939);
11
11
  bs.offset += 4;
12
12
  return;
13
13
  }
14
- bs.ensureSize(end << 3);
14
+ // {} = 4
15
+ // xi, = n << 1
15
16
 
16
17
  store<u16>(bs.offset, BRACKET_LEFT);
17
18
  bs.offset += 2;
@@ -19,14 +20,14 @@ export function serializeArray<T extends any[]>(src: T): void {
19
20
  while (i < end) {
20
21
  const block = unchecked(src[i++]);
21
22
  JSON.__serialize<valueof<T>>(block);
22
- bs.ensureSize(2);
23
+ bs.growSize(2);
23
24
  store<u16>(bs.offset, COMMA);
24
25
  bs.offset += 2;
25
26
  }
26
27
 
27
28
  const lastBlock = unchecked(src[end]);
28
29
  JSON.__serialize<valueof<T>>(lastBlock);
29
- bs.ensureSize(2);
30
+ bs.growSize(2);
30
31
  store<u16>(bs.offset, BRACKET_RIGHT);
31
32
  bs.offset += 2;
32
33
  }
@@ -7,11 +7,11 @@ import { bs } from "../../../modules/as-bs";
7
7
  */
8
8
  export function serializeBool(data: bool): void {
9
9
  if (data == true) {
10
- bs.ensureSize(8);
10
+ bs.proposeSize(8);
11
11
  store<u64>(bs.offset, 28429475166421108);
12
12
  bs.offset += 8;
13
13
  } else {
14
- bs.ensureSize(10);
14
+ bs.proposeSize(10);
15
15
  store<u64>(bs.offset, 32370086184550502);
16
16
  store<u64>(bs.offset, 101, 8);
17
17
  bs.offset += 10;
@@ -5,7 +5,7 @@ import { bytes } from "../../util/bytes";
5
5
  export function serializeDate(src: Date): void {
6
6
  const data = src.toISOString();
7
7
  const dataSize = bytes(data);
8
- bs.ensureSize(dataSize + 4);
8
+ bs.proposeSize(dataSize + 4);
9
9
  store<u16>(bs.offset, QUOTE);
10
10
  memory.copy(bs.offset + 2, changetype<usize>(data), dataSize);
11
11
  store<u16>(bs.offset + dataSize, QUOTE, 2);
@@ -3,5 +3,10 @@ import { bs } from "../../../modules/as-bs";
3
3
 
4
4
  export function serializeInteger<T extends number>(data: T): void {
5
5
  bs.ensureSize(sizeof<T>() << 3);
6
- bs.offset += itoa_buffered(bs.offset, data) << 1;
6
+ const bytesWritten = itoa_buffered(bs.offset, data) << 1;
7
+ bs.offset += bytesWritten;
8
+ bs.growSize(bytesWritten);
7
9
  }
10
+
11
+ // 32 {"x":,"y":,"z"}
12
+ // 18 3.41.28.3
@@ -7,7 +7,7 @@ export function serializeMap<T extends Map<any, any>>(src: T): void {
7
7
  const srcEnd = srcSize - 1;
8
8
 
9
9
  if (srcSize == 0) {
10
- bs.ensureSize(4);
10
+ bs.proposeSize(4);
11
11
  store<u32>(bs.offset, 8192123);
12
12
  bs.offset += 4;
13
13
  return;
@@ -16,28 +16,28 @@ export function serializeMap<T extends Map<any, any>>(src: T): void {
16
16
  let keys = src.keys();
17
17
  let values = src.values();
18
18
 
19
- bs.ensureSize(srcSize << 3); // This needs to be predicted better
19
+ bs.proposeSize(srcSize << 3); // This needs to be predicted better
20
20
 
21
21
  store<u16>(bs.offset, BRACE_LEFT);
22
22
  bs.offset += 2;
23
23
 
24
24
  for (let i = 0; i < srcEnd; i++) {
25
25
  JSON.__serialize(unchecked(keys[i]));
26
- bs.ensureSize(2);
26
+ bs.growSize(2);
27
27
  store<u16>(bs.offset, COLON);
28
28
  bs.offset += 2;
29
29
  JSON.__serialize(unchecked(values[i]));
30
- bs.ensureSize(2);
30
+ bs.growSize(2);
31
31
  store<u16>(bs.offset, COMMA);
32
32
  bs.offset += 2;
33
33
  }
34
34
 
35
35
  JSON.__serialize(unchecked(keys[srcEnd]));
36
- bs.ensureSize(2);
36
+ bs.growSize(2);
37
37
  store<u16>(bs.offset, COLON);
38
38
  bs.offset += 2;
39
39
  JSON.__serialize(unchecked(values[srcEnd]));
40
- bs.ensureSize(2);
40
+ bs.growSize(2);
41
41
  store<u16>(bs.offset, BRACE_RIGHT);
42
42
  bs.offset += 2;
43
43
  }
@@ -11,7 +11,7 @@ import { SERIALIZE_ESCAPE_TABLE } from "../../globals/tables";
11
11
  */
12
12
  export function serializeString(src: string): void {
13
13
  const srcSize = bytes(src);
14
- bs.ensureSize(srcSize + 4);
14
+ bs.proposeSize(srcSize + 4);
15
15
  let srcPtr = changetype<usize>(src);
16
16
  const srcEnd = srcPtr + srcSize;
17
17
 
@@ -27,12 +27,12 @@ export function serializeString(src: string): void {
27
27
  bs.offset += remBytes;
28
28
  const escaped = load<u32>(SERIALIZE_ESCAPE_TABLE + (code << 2));
29
29
  if ((escaped & 0xffff) != BACK_SLASH) {
30
- bs.ensureSize(10);
30
+ bs.growSize(10);
31
31
  store<u64>(bs.offset, 13511005048209500, 0);
32
32
  store<u32>(bs.offset, escaped, 8);
33
33
  bs.offset += 12;
34
34
  } else {
35
- bs.ensureSize(2);
35
+ bs.growSize(2);
36
36
  store<u32>(bs.offset, escaped, 0);
37
37
  bs.offset += 4;
38
38
  }
package/assembly/test.ts CHANGED
@@ -1,25 +1,30 @@
1
1
  import { JSON } from ".";
2
+ import { bytes } from "./util";
2
3
 
3
- // @json or @serializable work here
4
4
  @json
5
- class Vec3 {
6
- x: f64 = 0.0;
7
- y: f64 = 0.0;
8
- z: f64 = 0.0;
5
+ class Obj {
6
+ public a: string = "hello";
7
+ public b: string = "world";
8
+ public c: string = "\"\t\f\u0000\u0001";
9
9
  }
10
10
 
11
+ @json
12
+ class Vec3 {
13
+ x: f32 = 0.0;
14
+ y: f32 = 0.0;
15
+ z: f32 = 0.0;
16
+ }
11
17
 
12
18
  @json
13
19
  class Player {
14
-
15
20
  @alias("first name")
16
21
  firstName!: string;
17
22
  lastName!: string;
18
23
  lastActive!: i32[];
19
24
  // Drop in a code block, function, or expression that evaluates to a boolean
20
- @omitif((self: Player): boolean => self.age <= 18)
25
+ @omitif((age) => age < 18)
26
+ @omitif('this.age <= 0')
21
27
  age!: i32;
22
-
23
28
  @omitnull()
24
29
  pos!: Vec3 | null;
25
30
  isVerified!: boolean;
@@ -28,17 +33,27 @@ class Player {
28
33
  const player: Player = {
29
34
  firstName: "Jairus",
30
35
  lastName: "Tanaka",
31
- lastActive: [1, 20, 2025],
36
+ lastActive: [2, 7, 2025],
32
37
  age: 18,
33
38
  pos: {
34
39
  x: 3.4,
35
40
  y: 1.2,
36
- z: 8.3,
41
+ z: 8.3
37
42
  },
38
- isVerified: true,
43
+ isVerified: true
39
44
  };
40
45
 
41
- const stringified = JSON.stringify<Player>(player);
42
- console.log("Serialized: " + stringified);
43
- // const parsed = JSON.parse<Player>('{"pos":{"x":3.4,"y":1.2,"z":8.3},"first name":"Jairus","lastName":"Tanaka","lastActive":[1,20,2025],"age":18,"isVerified":true}');
44
- console.log("Deserialized: " + JSON.stringify<Player>(JSON.parse<Player>('{"pos":{"x":3.4,"y":1.2,"z":8.3},"first name":"Jairus","lastName":"Tanaka","lastActive":[1,20,2025],"age":18,"isVerified":true}')));
46
+ 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");
47
+ // console.log("Bytes " + bytes(a1).toString());
48
+ console.log("a1: " + a1);
49
+
50
+ const obj = new Obj();
51
+ const a2 = JSON.stringify(obj);
52
+ // console.log("Bytes " + bytes(a2).toString());
53
+ console.log("a2: " + a2);
54
+
55
+ const a3 = JSON.stringify(player);
56
+ // console.log("Bytes " + bytes(a3).toString());
57
+ console.log("a3: " + a3);
58
+
59
+ JSON.Memory.shrink();
@@ -7,6 +7,6 @@ import { OBJECT, TOTAL_OVERHEAD } from "rt/common";
7
7
  } else if (isManaged<T>() || isReference<T>()) {
8
8
  return changetype<OBJECT>(changetype<usize>(o) - TOTAL_OVERHEAD).rtSize;
9
9
  } else {
10
- ERROR("Cannot convert type " + nameof<T>() + " to bytes!");
10
+ throw new Error("Cannot convert type " + nameof<T>() + " to bytes!");
11
11
  }
12
12
  }
@@ -7,7 +7,7 @@ import { POW_TEN_TABLE_32, POW_TEN_TABLE_64 } from "../globals/tables";
7
7
  import { atoi } from "./atoi";
8
8
 
9
9
  // @ts-ignore: Decorator valid here
10
- @inline function snp<T extends number>(srcStart: usize, srcEnd: usize): T {
10
+ @inline export function snp<T extends number>(srcStart: usize, srcEnd: usize): T {
11
11
  // @ts-ignore: type
12
12
  let val: T = 0;
13
13
  let char = load<u16>(srcStart) - 48;
@@ -46,7 +46,7 @@ import { atoi } from "./atoi";
46
46
  char = load<u16>(srcStart);
47
47
  if (char == 45) {
48
48
  // @ts-ignore: type
49
- return val / pow10(atoi(srcStart + 2, srcEnd));
49
+ return val / pow10(atoi<u8>(srcStart + 2, srcEnd));
50
50
  } else {
51
51
  // @ts-ignore: type
52
52
  return val * pow10(atoi(srcStart, srcEnd));
@@ -1,61 +1,81 @@
1
1
  import { OBJECT, TOTAL_OVERHEAD } from "rt/common";
2
2
 
3
- let maxOffset: usize = __new(0, idof<ArrayBuffer>());
4
-
5
3
  /**
6
4
  * Central buffer namespace for managing memory operations.
7
5
  */
8
6
  export namespace bs {
9
- /** Current buffer pointer. */
10
- export let buffer: usize = maxOffset;
7
+ /** Current buffer pointer. */ // @ts-ignore
8
+ export let buffer: ArrayBuffer = new ArrayBuffer(32);//__new(32, idof<ArrayBuffer>());
11
9
 
12
10
  /** Current offset within the buffer. */
13
- export let offset: usize = maxOffset;
11
+ export let offset: usize = changetype<usize>(buffer);
14
12
 
15
13
  /** Byte length of the buffer. */
16
- export let byteLength: usize = 0;
14
+ let bufferSize: usize = 32;
15
+
16
+ /** Proposed size of output */
17
+ export let stackSize: usize = 0;
17
18
 
18
19
  /**
19
- * Sets the buffer to a given data object and initializes related properties.
20
- * @param data - The data object to set as the buffer.
20
+ * Proposes that the buffer size is should be greater than or equal to the proposed size.
21
+ * If necessary, reallocates the buffer to the exact new size.
22
+ * @param size - The size to propose.
21
23
  */
22
- // @ts-ignore: Decorator valid here
23
- @inline export function setBuffer<T>(data: T): void {
24
- buffer = changetype<usize>(data);
25
- offset = changetype<usize>(data);
26
- byteLength = bytes(data);
27
- maxOffset = byteLength + buffer;
24
+ // @ts-ignore: decorator
25
+ @inline export function ensureSize(size: u32): void {
26
+ // console.log("Ensure " + (stackSize).toString() + " -> " + (stackSize + size).toString() + " (" + size.toString() + ") " + (((stackSize + size) > bufferSize) ? "+" : ""));
27
+ if (offset + size > bufferSize + changetype<usize>(buffer)) {
28
+ const deltaBytes = nextPowerOf2(size + 64);
29
+ bufferSize += deltaBytes;
30
+ // @ts-ignore: exists
31
+ const newPtr = changetype<ArrayBuffer>(__renew(
32
+ changetype<usize>(buffer),
33
+ bufferSize
34
+ ));
35
+ offset = offset + changetype<usize>(newPtr) - changetype<usize>(buffer);
36
+ buffer = newPtr;
37
+ }
28
38
  }
29
39
 
30
40
  /**
31
- * Ensures the buffer has sufficient capacity for a given size.
32
- * If necessary, reallocates the buffer to accommodate the new size.
33
- * @param size - The size to ensure capacity for.
41
+ * Proposes that the buffer size is should be greater than or equal to the proposed size.
42
+ * If necessary, reallocates the buffer to the exact new size.
43
+ * @param size - The size to propose.
34
44
  */
35
- // @ts-ignore: Decorator valid here
36
- @inline export function ensureCapacity(size: u32): void {
37
- const newSize: usize = offset + size;
38
- if (newSize > byteLength) {
39
- const newPtr = __renew(buffer, (byteLength = nextPowerOf2(newSize - buffer)));
40
- offset = offset - buffer + newPtr;
41
- maxOffset = newPtr + byteLength;
45
+ // @ts-ignore: decorator
46
+ @inline export function proposeSize(size: u32): void {
47
+ // console.log("Propose " + (stackSize).toString() + " -> " + (stackSize + size).toString() + " (" + size.toString() + ") " + (((stackSize + size) > bufferSize) ? "+" : ""));
48
+ if ((stackSize += size) > bufferSize) {
49
+ const deltaBytes = nextPowerOf2(size);
50
+ bufferSize += deltaBytes;
51
+ // @ts-ignore: exists
52
+ const newPtr = changetype<ArrayBuffer>(__renew(
53
+ changetype<usize>(buffer),
54
+ bufferSize
55
+ ));
56
+ offset = offset + changetype<usize>(newPtr) - changetype<usize>(buffer);
42
57
  buffer = newPtr;
43
58
  }
44
59
  }
45
60
 
46
61
  /**
47
- * Ensures the buffer size is sufficient for a given size.
62
+ * Increases the proposed size by nextPowerOf2(n + 64) if necessary.
48
63
  * If necessary, reallocates the buffer to the exact new size.
49
- * @param size - The size to ensure.
64
+ * @param size - The size to grow by.
50
65
  */
51
- // @ts-ignore: Decorator valid here
52
- @inline export function ensureSize(size: u32): void {
53
- const newSize: usize = offset + size;
54
- if (newSize > maxOffset) {
55
- byteLength += size;
56
- const newPtr = __renew(buffer, byteLength);
57
- offset = offset - buffer + newPtr;
58
- maxOffset = newPtr + byteLength;
66
+ // @ts-ignore: decorator
67
+ @inline export function growSize(size: u32): void {
68
+ // console.log("Grow " + (stackSize).toString() + " -> " + (stackSize + size).toString() + " (" + size.toString() + ") " + (((stackSize + size) > bufferSize) ? "+" : ""));
69
+ if ((stackSize += size) > bufferSize) {
70
+ const deltaBytes = nextPowerOf2(size + 64);
71
+ bufferSize += deltaBytes;
72
+ // @ts-ignore
73
+ const newPtr = changetype<ArrayBuffer>(__renew(
74
+ changetype<usize>(buffer),
75
+ bufferSize
76
+ ));
77
+ // if (buffer != newPtr) console.log(" Old: " + changetype<usize>(buffer).toString() + "\n New: " + changetype<usize>(newPtr).toString());
78
+ offset = offset + changetype<usize>(newPtr) - changetype<usize>(buffer);
59
79
  buffer = newPtr;
60
80
  }
61
81
  }
@@ -66,68 +86,27 @@ export namespace bs {
66
86
  */
67
87
  // @ts-ignore: Decorator valid here
68
88
  @inline export function resize(newSize: u32): void {
89
+ // @ts-ignore: exists
69
90
  const newPtr = __renew(buffer, newSize);
70
- byteLength = newSize;
91
+ bufferSize = newSize;
71
92
  buffer = newPtr;
72
- offset = buffer + newSize;
73
- maxOffset = buffer + byteLength;
74
- }
75
-
76
- /**
77
- * Gets the remaining space available in the buffer.
78
- * @returns The number of bytes remaining.
79
- */
80
- // @ts-ignore: Decorator valid here
81
- @inline export function getRemainingSize(): usize {
82
- return maxOffset - offset;
83
- }
84
-
85
- /**
86
- * Clears data from a specified offset onward.
87
- * @param fromOffset - The starting offset to clear from.
88
- */
89
- // @ts-ignore: Decorator valid here
90
- @inline export function clearFromOffset(fromOffset: usize): void {
91
- if (fromOffset < offset) {
92
- memory.fill(fromOffset, 0, offset - fromOffset);
93
- offset = fromOffset;
94
- }
95
- }
96
-
97
- /**
98
- * Shrinks the buffer to fit the current offset.
99
- */
100
- // @ts-ignore: Decorator valid here
101
- @inline export function shrink(): void {
102
- byteLength = offset - buffer;
103
- buffer = __renew(buffer, byteLength);
104
- maxOffset = byteLength + buffer;
105
- }
106
-
107
- /**
108
- * Shrinks the buffer and resets the offset, returning the buffer as a specified type.
109
- * @returns The buffer cast to the specified type.
110
- */
111
- // @ts-ignore: Decorator valid here
112
- @inline export function shrinkTo<T>(): T {
113
- shrink();
114
- offset = buffer;
115
- return changetype<T>(buffer);
93
+ offset = newPtr + newSize;
94
+ stackSize = newPtr;
116
95
  }
117
96
 
118
97
  /**
119
98
  * Copies the buffer's content to a new object of a specified type.
120
- * Optionally shrinks the buffer after copying.
121
- * @param s - Whether to shrink the buffer after copying.
122
99
  * @returns The new object containing the buffer's content.
123
100
  */
124
101
  // @ts-ignore: Decorator valid here
125
- @inline export function out<T>(s: bool = false): T {
126
- const len = offset - buffer;
102
+ @inline export function out<T>(): T {
103
+ const len = offset - changetype<usize>(buffer);
104
+ // @ts-ignore: exists
127
105
  const _out = __new(len, idof<T>());
128
- memory.copy(_out, buffer, len);
129
- if (s) shrink();
130
- offset = buffer;
106
+ memory.copy(_out, changetype<usize>(buffer), len);
107
+
108
+ offset = changetype<usize>(buffer);
109
+ stackSize = 0;
131
110
  return changetype<T>(_out);
132
111
  }
133
112
 
@@ -139,12 +118,14 @@ export namespace bs {
139
118
  * @returns The destination pointer cast to the specified type.
140
119
  */
141
120
  // @ts-ignore: Decorator valid here
142
- @inline export function outTo<T>(dst: usize, s: bool = false): T {
143
- const len = offset - buffer;
121
+ @inline export function outTo<T>(dst: usize): T {
122
+ const len = offset - changetype<usize>(buffer);
123
+ // @ts-ignore: exists
144
124
  if (len != changetype<OBJECT>(dst - TOTAL_OVERHEAD).rtSize) __renew(len, idof<T>());
145
- memory.copy(dst, buffer, len);
146
- if (s) shrink();
147
- offset = buffer;
125
+ memory.copy(dst, changetype<usize>(buffer), len);
126
+
127
+ offset = changetype<usize>(buffer);
128
+ stackSize = 0;
148
129
  return changetype<T>(dst);
149
130
  }
150
131
  }
@@ -161,6 +142,6 @@ export namespace bs {
161
142
  } else if (isManaged<T>() || isReference<T>()) {
162
143
  return changetype<OBJECT>(changetype<usize>(o) - TOTAL_OVERHEAD).rtSize;
163
144
  } else {
164
- ERROR("Cannot convert type " + nameof<T>() + " to bytes!");
145
+ throw new Error("Cannot convert type " + nameof<T>() + " to bytes!");
165
146
  }
166
147
  }
@@ -0,0 +1,22 @@
1
+ export function describe(description: string, routine: () => void): void {
2
+ routine();
3
+ }
4
+
5
+ export function expect(left: string): Expectation {
6
+ return new Expectation(left);
7
+ }
8
+
9
+ class Expectation {
10
+ public left: string;
11
+
12
+ constructor(left: string) {
13
+ this.left = left;
14
+ }
15
+ toBe(right: string): void {
16
+ if (this.left != right) {
17
+ console.log(" (expected) -> " + right);
18
+ console.log(" (received) -> " + this.left);
19
+ process.exit(1);
20
+ }
21
+ }
22
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "json-as",
3
- "version": "1.0.0-alpha.2",
3
+ "version": "1.0.0-alpha.4",
4
4
  "author": "Jairus Tanaka",
5
5
  "repository": {
6
6
  "type": "git",
@@ -8,17 +8,13 @@
8
8
  },
9
9
  "main": "transform/lib/index.js",
10
10
  "devDependencies": {
11
- "as-bs": "./modules/as-bs/",
12
11
  "@assemblyscript/wasi-shim": "^0.1.0",
13
- "@types/node": "latest",
14
- "as-bench": "^0.0.0-alpha",
12
+ "@types/node": "^22.13.1",
15
13
  "as-console": "^7.0.0",
16
- "as-test": "^0.3.5",
17
- "assemblyscript": "^0.27.31",
14
+ "assemblyscript": "^0.27.34",
18
15
  "assemblyscript-prettier": "^3.0.1",
19
- "prettier": "^3.4.2",
20
- "typescript": "latest",
21
- "visitor-as": "^0.11.4"
16
+ "prettier": "^3.5.0",
17
+ "typescript": "^5.7.3"
22
18
  },
23
19
  "bugs": {
24
20
  "url": "https://github.com/JairusSW/as-json/issues"
@@ -55,7 +51,7 @@
55
51
  "@JairusSW:registry": "https://npm.pkg.github.com"
56
52
  },
57
53
  "scripts": {
58
- "test": "rm -rf ./build/ && ast test",
54
+ "test": "bash ./run-tests.sh",
59
55
  "build:bench": "rm -rf ./build/ && asc assembly/__benches__/misc.bench.ts -o ./build/bench.wasm --textFile ./build/bench.wat --transform ./transform --optimizeLevel 3 --shrinkLevel 0 --converge --noAssert --uncheckedBehavior always --runtime incremental --enable simd --enable bulk-memory",
60
56
  "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",
61
57
  "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",
package/run-tests.sh ADDED
@@ -0,0 +1,15 @@
1
+ #!/bin/bash
2
+
3
+ mkdir -p ./build
4
+
5
+ for file in ./assembly/__tests__/*.spec.ts; do
6
+ filename=$(basename -- "$file")
7
+ output="./build/${filename%.ts}.wasm"
8
+
9
+ asc "$file" --transform ./transform -o "$output" || { echo "Tests failed"; exit 1; }
10
+
11
+ echo " -> $filename"
12
+ wasmtime "$output" || { echo "Tests failed"; exit 1; }
13
+ done
14
+
15
+ echo "All tests passed"