Skip to content

Commit de6450d

Browse files
committed
Gate and streamline generated deserialize paths
1 parent c403c75 commit de6450d

8 files changed

Lines changed: 47 additions & 38 deletions

File tree

ARCHITECTURE.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,9 @@ The transform (`transform/src/`) is an AssemblyScript compiler plugin that runs
5858
- Decorator metadata (@alias, @omit, @omitnull, @omitif)
5959
- Inheritance relationships
6060
- Type dependencies
61-
3. **Code Generation**: Generates two methods for each class:
61+
3. **Code Generation**: Generates methods for each class:
6262
- `__SERIALIZE(ptr: usize): void` - Writes JSON to the buffer
63-
- `__DESERIALIZE<T>(srcStart, srcEnd, out): T` - Parses JSON into object
63+
- `__DESERIALIZE<T>(srcStart, srcEnd, out): usize` - Parses JSON into `out` and returns the advanced source pointer
6464

6565
### Key Files
6666

@@ -91,9 +91,10 @@ __SERIALIZE(ptr: usize): void {
9191
bs.offset += 2;
9292
}
9393

94-
__DESERIALIZE<T>(srcStart: usize, srcEnd: usize, out: T): T {
94+
__DESERIALIZE<T>(srcStart: usize, srcEnd: usize, out: T): usize {
9595
// Key matching and value parsing logic
9696
// Uses switch statements on key length for efficiency
97+
return srcStart;
9798
}
9899
```
99100

@@ -286,12 +287,14 @@ For `@json` decorated classes, the generated `__DESERIALIZE` method:
286287
4. Compares key bytes directly (often as `u32` or `u64` for short keys)
287288
5. Deserializes value to appropriate type
288289
6. Stores in output object at correct offset
290+
7. Returns the updated source pointer after the parsed value
289291

290292
## Environment Variables
291293

292294
| Variable | Default | Description |
293295
|----------|---------|-------------|
294296
| `JSON_MODE` | SWAR | Optimization mode: NAIVE, SWAR, SIMD |
297+
| `JSON_USE_FAST_PATH` | 0 | When set to `1`, emit the fast struct `__DESERIALIZE` body and helper; otherwise emit only the slow path |
295298
| `JSON_DEBUG` | 0 | Debug level 0-3 (prints generated code) |
296299
| `JSON_WRITE` | "" | Comma-separated files to output after transform |
297300
| `JSON_CACHE` | 0 | Enable string caching (set to 1) |

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
## UNRELEASED
44

55
- compat: add compatability between json-as and try-as by ignoring methods prefixed by __try
6+
- feat: gate generated fast struct deserialization behind `JSON_USE_FAST_PATH=1`
7+
- refactor: make generated struct `__DESERIALIZE` methods return the advanced source pointer
68

79
## 2026-02-18 - 1.2.6
810

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,8 @@ Here's a short list:
433433

434434
**JSON_MODE** (default: SWAR) - Selects which mode should be used. Can be `NAIVE,SWAR,SIMD`. Note that `--enable simd` may be required.
435435

436+
**JSON_USE_FAST_PATH** (default: 0) - When set to `1`, the transform emits the fast `__DESERIALIZE` implementation for generated structs. When unset or `0`, it emits only the slow path.
437+
436438
**JSON_WRITE** (default: "") - Select a series of files to output after transform and optimization passes have completed for easy inspection. Usage: `JSON_WRITE=.path-to-file-a.ts,./path-to-file-b.ts`
437439

438440
### Running benchmarks locally

assembly/index.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,8 @@ export namespace JSON {
215215
// @ts-expect-error: Defined by transform
216216
if (isDefined(type.__INITIALIZE)) out.__INITIALIZE();
217217
// @ts-expect-error
218-
return out.__DESERIALIZE(dataPtr, dataPtr + dataSize, out);
218+
out.__DESERIALIZE(dataPtr, dataPtr + dataSize, out);
219+
return out;
219220
} else if (type instanceof Map) {
220221
// @ts-expect-error
221222
return inline.always(deserializeMap<nonnull<T>>(dataPtr, dataPtr + dataSize, 0));
@@ -818,7 +819,8 @@ export namespace JSON {
818819
// @ts-expect-error: Defined by transform
819820
if (isDefined(type.__INITIALIZE)) out.__INITIALIZE();
820821
// @ts-expect-error: Defined by transform
821-
return out.__DESERIALIZE(srcStart, srcEnd, out);
822+
out.__DESERIALIZE(srcStart, srcEnd, out);
823+
return out;
822824
} else if (type instanceof Map) {
823825
// @ts-expect-error: type
824826
return deserializeMap<T>(srcStart, srcEnd, dst);

transform/lib/index.d.ts.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

transform/lib/index.js

Lines changed: 15 additions & 16 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

transform/lib/index.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)