Skip to content

Commit

Permalink
fix: splice in bs.proposeSize()
Browse files Browse the repository at this point in the history
  • Loading branch information
JairusSW committed Feb 6, 2025
1 parent abe509c commit 8efff46
Show file tree
Hide file tree
Showing 8 changed files with 134 additions and 53 deletions.
37 changes: 25 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,17 @@
</pre>
</h5>

## Contents
- [About](#about)
- [Installation](#installation)
- [Usage](#usage)
- [Examples](#examples)
- [Performance](#performance)
- [License](#license)
- [Contact](#contact)

## About

## Installation

```bash
Expand Down Expand Up @@ -40,7 +51,6 @@ If you'd like to see the code that the transform generates, run with `JSON_DEBUG
```js
import { JSON } from "json-as";

// @json or @serializable work here
@json
class Vec3 {
x: f32 = 0.0;
Expand Down Expand Up @@ -76,11 +86,15 @@ const player: Player = {
isVerified: true
};

const stringified = JSON.stringify<Player>(player);

const serialized = JSON.stringify<Player>(player);
const parsed = JSON.parse<Player>(stringified);

console.log("Serialized: " + stringified);
console.log("Parsed: " + parsed);
```

## Examples

Classes can even have inheritance. Here's a nasty example

```js
Expand Down Expand Up @@ -124,16 +138,15 @@ You can also add it to your `asconfig.json`

If you use this project in your codebase, consider dropping a [star](https://github.com/JairusSW/as-json). I would really appreciate it!

## Notes

If you want a feature, drop an issue (and again, maybe a star). I'll likely add it in less than 7 days.
## 📃 License

## Contact
This project is distributed under an open source license. You can view the full license using the following link: [License](./LICENSE)

- [Email](mailto:[email protected])
- [GitHub](https://github.com/JairusSW)
- [Discord](discord.com/users/600700584038760448)
## 📫 Contact

## Issues
Please send all issues to [GitHub Issues](https://github.com/JairusSW/as-json/issues) and to converse, please send me an email at [[email protected]](mailto:[email protected])

Please submit an issue to https://github.com/JairusSW/as-json/issues if you find anything wrong with this library
- **Email:** Send me inquiries, questions, or requests at [[email protected]](mailto:[email protected])
- **GitHub:** Visit the official GitHub repository [Here](https://github.com/JairusSW/as-json)
- **Website:** Visit my official website at [jairus.dev](https://jairus.dev/)
- **Discord:** Converse with me on [My Discord](discord.com/users/600700584038760448) or on the [AssemblyScript Discord Server](https://discord.gg/assemblyscript/)
22 changes: 11 additions & 11 deletions assembly/serialize/simd/string.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export function serializeString_SIMD(src: string): void {
const srcSize = changetype<OBJECT>(changetype<usize>(src) - TOTAL_OVERHEAD).rtSize;
let srcStart = changetype<usize>(src);
const srcEnd = srcStart + srcSize;
bs.ensureSize(srcSize + 4);
bs.proposeSize(srcSize + 4);
const srcEnd16 = srcEnd - 15;

store<u8>(changetype<usize>(bs.offset), 34); /* " */
Expand All @@ -45,13 +45,13 @@ export function serializeString_SIMD(src: string): void {
mask &= mask - 1;

if ((escaped & 0xffff) != BACK_SLASH) {
bs.addSize(10);
bs.growSize(10);
store<u64>(dst_offset, 13511005048209500);
store<u32>(dst_offset, escaped, 8);
v128.store(dst_offset, v128.load(src_offset, 2), 12);
bs.offset += 10;
} else {
bs.addSize(2);
bs.growSize(2);
store<u32>(dst_offset, escaped);
v128.store(dst_offset, v128.load(src_offset, 2), 4);
bs.offset += 2;
Expand Down Expand Up @@ -84,7 +84,7 @@ export function serializeString_SIMD(src: string): void {
mask &= mask - 1;

if ((escaped & 0xffff) != BACK_SLASH) {
bs.addSize(10);
bs.growSize(10);
store<u64>(dst_offset, 13511005048209500);
store<u32>(dst_offset, escaped, 8);
while (lane_index < 6) {
Expand All @@ -93,7 +93,7 @@ export function serializeString_SIMD(src: string): void {
}
bs.offset += 10;
} else {
bs.addSize(2);
bs.growSize(2);
store<u32>(dst_offset, escaped);

while (lane_index < 6) {
Expand All @@ -116,12 +116,12 @@ export function serializeString_SIMD(src: string): void {
const escaped = load<u32>(SERIALIZE_ESCAPE_TABLE + (codeA << 2));

if ((escaped & 0xffff) != BACK_SLASH) {
bs.addSize(10);
bs.growSize(10);
store<u64>(bs.offset, 13511005048209500);
store<u32>(bs.offset, escaped, 8);
bs.offset += 12;
} else {
bs.addSize(2);
bs.growSize(2);
store<u32>(bs.offset, escaped);
bs.offset += 4;
}
Expand All @@ -134,12 +134,12 @@ export function serializeString_SIMD(src: string): void {
const escaped = load<u32>(SERIALIZE_ESCAPE_TABLE + (codeB << 2));

if ((escaped & 0xffff) != BACK_SLASH) {
bs.addSize(10);
bs.growSize(10);
store<u64>(bs.offset, 13511005048209500);
store<u32>(bs.offset, escaped, 8);
bs.offset += 12;
} else {
bs.addSize(2);
bs.growSize(2);
store<u32>(bs.offset, escaped);
bs.offset += 4;
}
Expand All @@ -156,12 +156,12 @@ export function serializeString_SIMD(src: string): void {
const escaped = load<u32>(SERIALIZE_ESCAPE_TABLE + (code << 2));

if ((escaped & 0xffff) != BACK_SLASH) {
bs.addSize(10);
bs.growSize(10);
store<u64>(bs.offset, 13511005048209500);
store<u32>(bs.offset, escaped, 8);
bs.offset += 12;
} else {
bs.addSize(2);
bs.growSize(2);
store<u32>(bs.offset, escaped);
bs.offset += 4;
}
Expand Down
7 changes: 4 additions & 3 deletions assembly/serialize/simple/array.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,16 @@ import { COMMA, BRACKET_RIGHT, BRACKET_LEFT } from "../../custom/chars";
import { JSON } from "../..";

export function serializeArray<T extends any[]>(src: T): void {
bs.proposeSize(4);
const end = src.length - 1;
let i = 0;
if (end == -1) {
bs.proposeSize(4);
store<u32>(bs.offset, 6094939);
bs.offset += 4;
return;
}
bs.proposeSize(end << 3);
// {} = 4
// xi, = n << 1

store<u16>(bs.offset, BRACKET_LEFT);
bs.offset += 2;
Expand All @@ -26,7 +27,7 @@ export function serializeArray<T extends any[]>(src: T): void {

const lastBlock = unchecked(src[end]);
JSON.__serialize<valueof<T>>(lastBlock);
bs.proposeSize(2);
bs.growSize(2);
store<u16>(bs.offset, BRACKET_RIGHT);
bs.offset += 2;
}
6 changes: 4 additions & 2 deletions assembly/serialize/simple/integer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { itoa_buffered } from "util/number";
import { bs } from "../../../modules/as-bs";

export function serializeInteger<T extends number>(data: T): void {
bs.proposeSize(sizeof<T>() << 3);
bs.offset += itoa_buffered(bs.offset, data) << 1;
bs.ensureSize(sizeof<T>() << 3);
const bytesWritten = itoa_buffered(bs.offset, data) << 1;
bs.offset += bytesWritten;
bs.realSize += bytesWritten;
}
43 changes: 40 additions & 3 deletions assembly/test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,42 @@
import { bs } from "../modules/as-bs/assembly";
import { JSON } from "./";
import { describe, expect } from "../modules/test/assembly";
@json
class Vec3 {
x: f32 = 0.0;
y: f32 = 0.0;
z: f32 = 0.0;
}

console.log(JSON.stringify(JSON.parse<string>('"\\u0000\\u0001\\u0002\\u0003\\u0004\\u0005\\u0006\\u0007\\b\\t\\n\\u000b\\f\\r\\u000e\\u000f\\u000f\\u0011\\u0012\\u0013\\u0014\\u0015\\u0016\\u0017\\u0018\\u0019\\u001a\\u001b\\u001c\\u001d\\u001e\\u001f"')));
console.log('"\\u0000\\u0001\\u0002\\u0003\\u0004\\u0005\\u0006\\u0007\\b\\t\\n\\u000b\\f\\r\\u000e\\u000f\\u000f\\u0011\\u0012\\u0013\\u0014\\u0015\\u0016\\u0017\\u0018\\u0019\\u001a\\u001b\\u001c\\u001d\\u001e\\u001f"');
@json
class Player {
@alias("first name")
firstName: string = "";
lastName: string = "";
lastActive: i32[] = [];
// // Drop in a code block, function, or expression that evaluates to a boolean
// // @omitif((self) => self.age < 18)
// // @omitif('this.age <= 0')
// age: i32 = 0;
// // @omitnull()
// pos: Vec3 | null = new Vec3();
// isVerified: boolean = false;
}

const player: Player = {
firstName: "Emmet",
lastName: "West",
lastActive: [8, 27, 2022],
// age: 23,
// pos: {
// x: 3.4,
// y: 1.2,
// z: 8.3
// },
// isVerified: true
};

// bs.proposeSize(1024);
const serialized = JSON.stringify<Player>(player);
console.log("Serialized: " + serialized);
// const parsed = JSON.parse<Player>(serialized);
// console.log("Parsed: " + JSON.stringify(parsed));
68 changes: 48 additions & 20 deletions modules/as-bs/assembly/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,42 +11,70 @@ export namespace bs {
export let offset: usize = buffer;

/** Byte length of the buffer. */
export let byteLength: usize = 32;
let bufferEnd: usize = buffer + 32;

/** Proposed size of output */
export let realSize: usize = offset;
export let realSize: usize = buffer;

/**
* Byte length of the buffer
* @returns usize
*/
// @ts-ignore: decorator
@inline export function byteLength(): usize {
return bufferEnd - buffer;
}
/**
* Proposes that the buffer size is should be greater than or equal to the proposed size.
* If necessary, reallocates the buffer to the exact new size.
* @param size - The size to propose.
*/
// @ts-ignore: Decorator valid here
// @ts-ignore: decorator
@inline export function ensureSize(size: u32): void {
if (offset + size > bufferEnd) {
bufferEnd += nextPowerOf2(size + 32);
// @ts-ignore: exists
const newPtr = __renew(buffer, bufferEnd - buffer);
// I don't know if this is even needed. I'll need to take a look at the runtime
// offset = offset - buffer + newPtr;
// buffer = newPtr;
}
console.log("Ensure " + (realSize - buffer).toString() + " " + size.toString());
}
/**
* Proposes that the buffer size is should be greater than or equal to the proposed size.
* If necessary, reallocates the buffer to the exact new size.
* @param size - The size to propose.
*/
// @ts-ignore: decorator
@inline export function proposeSize(size: u32): void {
if ((realSize = size) > byteLength) {
byteLength = nextPowerOf2(size);
// @ts-ignore
const newPtr = __renew(buffer, byteLength);
offset = offset - buffer + newPtr;
buffer = newPtr;
realSize = offset + size;
if (realSize > bufferEnd) {
bufferEnd += nextPowerOf2(size);
// @ts-ignore: exists
const newPtr = __renew(buffer, bufferEnd - buffer);
// I don't know if this is even needed. I'll need to take a look at the runtime
// offset = offset - buffer + newPtr;
// buffer = newPtr;
}
console.log("Propose " + (realSize - buffer).toString() + " " + size.toString());
}

/**
* Increases the proposed size by nextPowerOf2(n + 8) if necessary.
* If necessary, reallocates the buffer to the exact new size.
* @param size - The size to grow by.
*/
// @ts-ignore: Decorator valid here
// @ts-ignore: decorator
@inline export function growSize(size: u32): void {
realSize += size;
if (realSize > byteLength) {
byteLength += nextPowerOf2(size + 8);
if ((realSize += size) > bufferEnd) {
bufferEnd += nextPowerOf2(size + 32);
// @ts-ignore
const newPtr = __renew(buffer, byteLength);
offset = offset - buffer + newPtr;
buffer = newPtr;
const newPtr = __renew(buffer, bufferEnd);
// offset = offset - buffer + newPtr;
// buffer = newPtr;
}
console.log("Grow " + (realSize - buffer).toString() + " " + size.toString());
}

/**
Expand All @@ -55,9 +83,9 @@ export namespace bs {
*/
// @ts-ignore: Decorator valid here
@inline export function resize(newSize: u32): void {
// @ts-ignore
// @ts-ignore: exists
const newPtr = __renew(buffer, newSize);
byteLength = newSize;
bufferEnd = newSize;
buffer = newPtr;
offset = newPtr + newSize;
realSize = newPtr;
Expand All @@ -70,7 +98,7 @@ export namespace bs {
// @ts-ignore: Decorator valid here
@inline export function out<T>(): T {
const len = offset - buffer;
// @ts-ignore
// @ts-ignore: exists
const _out = __new(len, idof<T>());
memory.copy(_out, buffer, len);

Expand All @@ -89,7 +117,7 @@ export namespace bs {
// @ts-ignore: Decorator valid here
@inline export function outTo<T>(dst: usize): T {
const len = offset - buffer;
// @ts-ignore
// @ts-ignore: exists
if (len != changetype<OBJECT>(dst - TOTAL_OVERHEAD).rtSize) __renew(len, idof<T>());
memory.copy(dst, buffer, len);

Expand Down
2 changes: 1 addition & 1 deletion transform/lib/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion transform/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ class JSONTransform extends Visitor {
SERIALIZE += indent + "bs.offset += 2;\n";
SERIALIZE += "}";

SERIALIZE = indent + "bs.proposeSize(" + this.schema.byteSize + ");\n" + SERIALIZE;
SERIALIZE = SERIALIZE.slice(0, 32) + indent + "bs.proposeSize(" + this.schema.byteSize + ");\n" + SERIALIZE.slice(32);

INITIALIZE += " return this;\n";
INITIALIZE += "}";
Expand Down

0 comments on commit 8efff46

Please sign in to comment.