Skip to content

Commit

Permalink
properly predict size
Browse files Browse the repository at this point in the history
  • Loading branch information
JairusSW committed Jan 30, 2025
1 parent fab14f0 commit 467f039
Show file tree
Hide file tree
Showing 18 changed files with 60 additions and 86 deletions.
16 changes: 8 additions & 8 deletions assembly/__tests__/test.spec.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
// import { JSON } from "json-as";
// import { describe, expect, run } from "as-test/assembly";
// import { DerivedObject, Null, ObjWithStrangeKey, ObjectWithFloat, OmitIf, Player, Vec3 } from "./types";
import { JSON } from "../";
import { describe, expect } from "../../modules/test/assembly/index";
import { DerivedObject, Null, ObjWithStrangeKey, ObjectWithFloat, OmitIf, Player, Vec3 } from "./types";

// describe("Should serialize class inheritance", () => {
// const obj = new DerivedObject("1", "2");
describe("Should serialize class inheritance", () => {
const obj = new DerivedObject("1", "2");

// expect(JSON.stringify(obj)).toBe('{"a":"1","b":"2"}');
// });
expect(JSON.stringify(obj)).toBe('{"a":"1","b":"2"}');
});

// describe("Should serialize nulls", () => {
// expect(JSON.stringify<Null>(null)).toBe("null");
Expand Down Expand Up @@ -117,7 +117,7 @@
// const jsonStr = '{"a":"1","b":"2"}';
// const obj = JSON.parse<DerivedObject>(jsonStr);

// expect(obj instanceof DerivedObject).toBe(true);
// expect((obj instanceof DerivedObject).toString()).toBe("true");
// expect(obj.a).toBe("1");
// expect(obj.b).toBe("2");
// });
Expand Down
12 changes: 0 additions & 12 deletions assembly/__tests__/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,28 @@ export class ObjWithString {
s!: string;
}


@json
export class ObjWithStrangeKey<T> {

@alias('a\\\t"\x02b`c')
data!: T;
}


@json
export class ObjectWithStringArray {
sa!: string[];
}


@json
export class ObjectWithFloat {
f!: f64;
}


@json
export class ObjectWithFloatArray {
fa!: f64[];
}


@json
export class BaseObject {
a: string;
Expand All @@ -39,7 +34,6 @@ export class BaseObject {
}
}


@json
export class DerivedObject extends BaseObject {
b: string;
Expand All @@ -49,7 +43,6 @@ export class DerivedObject extends BaseObject {
}
}


@json
export class Map4 {
a: string;
Expand All @@ -58,7 +51,6 @@ export class Map4 {
d: string;
}


@json
export class Vec3 {
x: f64;
Expand All @@ -68,7 +60,6 @@ export class Vec3 {
static shouldIgnore: string = "should not be serialized";
}


@json
export class Player {
firstName: string;
Expand All @@ -82,17 +73,14 @@ export class Player {
export class Nullable {}
export type Null = Nullable | null;


@json
export class OmitIf {
x: i32 = 1;


@omitif("this.y == -1")
y: i32 = -1;
z: i32 = 1;


@omitnull()
foo: string | null = null;
}
2 changes: 1 addition & 1 deletion assembly/deserialize/simple/bool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ export function deserializeBoolean(srcStart: usize, srcEnd: usize): boolean {
const firstChar = load<u16>(srcStart);
if (firstChar == CHAR_T && load<u64>(srcStart) == 28429475166421108) return true;
else if (firstChar == CHAR_F && load<u64>(srcSize, 2) == 28429466576093281) return false;
return false; //ERROR(`Expected to find boolean, but found "${data.slice(0, 100)}" instead!`);
return false; //throw new Error(`Expected to find boolean, but found "${data.slice(0, 100)}" instead!`);
}
2 changes: 1 addition & 1 deletion assembly/deserialize/simple/map.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { isSpace } from "../../util";
export function deserializeMap<T extends Map<any, any>>(srcStart: usize, srcEnd: usize, dst: usize): T {
const out = changetype<T>(dst || __new(offsetof<T>(), idof<T>()));
// @ts-ignore: type
if (!isString<indexof<T>>() && !isInteger<indexof<T>>() && !isFloat<indexof<T>>()) ERROR("Map key must also be a valid JSON key!");
if (!isString<indexof<T>>() && !isInteger<indexof<T>>() && !isFloat<indexof<T>>()) throw new Error("Map key must also be a valid JSON key!");

const srcPtr = srcStart;
let key: string | null = null;
Expand Down
12 changes: 6 additions & 6 deletions assembly/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ export namespace JSON {
// @ts-ignore: Supplied by transform
} else if (isDefined(data.__SERIALIZE) && isDefined(data.__ALLOCATE)) {
// @ts-ignore
data.__ALLOCATE();
// data.__ALLOCATE();
// @ts-ignore
data.__SERIALIZE(changetype<usize>(data));
return bs.out<string>();
Expand All @@ -135,7 +135,7 @@ export namespace JSON {
} else if (data instanceof JSON.Box) {
return JSON.stringify(data.value);
} else {
ERROR(`Could not serialize data of type ${nameof<T>()}. Make sure to add the correct decorators to classes.`);
throw new Error(`Could not serialize data of type ${nameof<T>()}. Make sure to add the correct decorators to classes.`);
}
}

Expand Down Expand Up @@ -184,7 +184,7 @@ export namespace JSON {
// @ts-ignore
return new JSON.Box(JSON.parse<indexof<T>>(data));
} else {
ERROR(`Could not deserialize data ${data} to type ${nameof<T>()}. Make sure to add the correct decorators to classes.`);
throw new Error(`Could not deserialize data ${data} to type ${nameof<T>()}. Make sure to add the correct decorators to classes.`);
}
}

Expand Down Expand Up @@ -359,7 +359,7 @@ export namespace JSON {
if (isBoolean<T>()) {
serializeBool(src as bool);
} else if (isInteger<T>() && nameof<T>() == "usize" && src == 0) {
bs.ensureSize(8);
bs.proposeSize(8);
store<u64>(bs.offset, 30399761348886638);
bs.offset += 8;
} else if (isInteger<T>()) {
Expand All @@ -370,7 +370,7 @@ export namespace JSON {
serializeFloat<T>(src);
// @ts-ignore: Function is generated by transform
} else if (isNullable<T>() && changetype<usize>(src) == <usize>0) {
bs.ensureSize(8);
bs.proposeSize(8);
store<u64>(bs.offset, 30399761348886638);
bs.offset += 8;
} else if (isString<nonnull<T>>()) {
Expand All @@ -393,7 +393,7 @@ export namespace JSON {
} else if (src instanceof JSON.Box) {
__serialize(src.value);
} else {
ERROR(`Could not serialize provided data. Make sure to add the correct decorators to classes.`);
throw new Error(`Could not serialize provided data. Make sure to add the correct decorators to classes.`);
}
}
export function __deserialize<T>(srcStart: usize, srcEnd: usize, dst: usize = 0): T {
Expand Down
8 changes: 4 additions & 4 deletions assembly/serialize/simple/array.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,27 @@ export function serializeArray<T extends any[]>(src: T): void {
const end = src.length - 1;
let i = 0;
if (end == -1) {
bs.ensureSize(4);
bs.proposeSize(4);
store<u32>(bs.offset, 6094939);
bs.offset += 4;
return;
}
bs.ensureSize(end << 3);
bs.proposeSize(end << 3);

store<u16>(bs.offset, BRACKET_LEFT);
bs.offset += 2;

while (i < end) {
const block = unchecked(src[i++]);
JSON.__serialize<valueof<T>>(block);
bs.addSize(2);
bs.growSize(2);
store<u16>(bs.offset, COMMA);
bs.offset += 2;
}

const lastBlock = unchecked(src[end]);
JSON.__serialize<valueof<T>>(lastBlock);
bs.ensureSize(2);
bs.proposeSize(2);
store<u16>(bs.offset, BRACKET_RIGHT);
bs.offset += 2;
}
4 changes: 2 additions & 2 deletions assembly/serialize/simple/bool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ import { bs } from "../../../modules/as-bs";
*/
export function serializeBool(data: bool): void {
if (data == true) {
bs.ensureSize(8);
bs.proposeSize(8);
store<u64>(bs.offset, 28429475166421108);
bs.offset += 8;
} else {
bs.ensureSize(10);
bs.proposeSize(10);
store<u64>(bs.offset, 32370086184550502);
store<u64>(bs.offset, 101, 8);
bs.offset += 10;
Expand Down
2 changes: 1 addition & 1 deletion assembly/serialize/simple/date.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { bytes } from "../../util/bytes";
export function serializeDate(src: Date): void {
const data = src.toISOString();
const dataSize = bytes(data);
bs.ensureSize(dataSize + 4);
bs.proposeSize(dataSize + 4);
store<u16>(bs.offset, QUOTE);
memory.copy(bs.offset + 2, changetype<usize>(data), dataSize);
store<u16>(bs.offset + dataSize, QUOTE, 2);
Expand Down
2 changes: 1 addition & 1 deletion assembly/serialize/simple/float.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ import { dtoa_buffered } from "util/number";
import { bs } from "../../../modules/as-bs";

export function serializeFloat<T extends number>(data: T): void {
bs.ensureSize(64);
bs.proposeSize(64);
bs.offset += dtoa_buffered(bs.offset, data) << 1;
}
2 changes: 1 addition & 1 deletion assembly/serialize/simple/integer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ import { itoa_buffered } from "util/number";
import { bs } from "../../../modules/as-bs";

export function serializeInteger<T extends number>(data: T): void {
bs.ensureSize(sizeof<T>() << 3);
bs.proposeSize(sizeof<T>() << 3);
bs.offset += itoa_buffered(bs.offset, data) << 1;
}
12 changes: 6 additions & 6 deletions assembly/serialize/simple/map.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export function serializeMap<T extends Map<any, any>>(src: T): void {
const srcEnd = srcSize - 1;

if (srcSize == 0) {
bs.ensureSize(4);
bs.proposeSize(4);
store<u32>(bs.offset, 8192123);
bs.offset += 4;
return;
Expand All @@ -16,28 +16,28 @@ export function serializeMap<T extends Map<any, any>>(src: T): void {
let keys = src.keys();
let values = src.values();

bs.ensureSize(srcSize << 3); // This needs to be predicted better
bs.proposeSize(srcSize << 3); // This needs to be predicted better

store<u16>(bs.offset, BRACE_LEFT);
bs.offset += 2;

for (let i = 0; i < srcEnd; i++) {
JSON.__serialize(unchecked(keys[i]));
bs.addSize(2);
bs.growSize(2);
store<u16>(bs.offset, COLON);
bs.offset += 2;
JSON.__serialize(unchecked(values[i]));
bs.addSize(2);
bs.growSize(2);
store<u16>(bs.offset, COMMA);
bs.offset += 2;
}

JSON.__serialize(unchecked(keys[srcEnd]));
bs.addSize(2);
bs.growSize(2);
store<u16>(bs.offset, COLON);
bs.offset += 2;
JSON.__serialize(unchecked(values[srcEnd]));
bs.addSize(2);
bs.growSize(2);
store<u16>(bs.offset, BRACE_RIGHT);
bs.offset += 2;
}
7 changes: 3 additions & 4 deletions assembly/serialize/simple/string.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { bytes } from "../../util/bytes";
import { bs } from "../../../modules/as-bs";
import { BACK_SLASH, QUOTE } from "../../custom/chars";
import { SERIALIZE_ESCAPE_TABLE } from "../../globals/tables";
import { ptrToStr } from "../../util/ptrToStr";

/**
* Serializes valid strings into their JSON counterpart
Expand All @@ -12,7 +11,7 @@ import { ptrToStr } from "../../util/ptrToStr";
*/
export function serializeString(src: string): void {
const srcSize = bytes(src);
bs.ensureSize(srcSize + 4);
bs.proposeSize(srcSize + 4);
let srcPtr = changetype<usize>(src);
const srcEnd = srcPtr + srcSize;

Expand All @@ -28,12 +27,12 @@ export function serializeString(src: string): void {
bs.offset += remBytes;
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, 0);
store<u32>(bs.offset, escaped, 8);
bs.offset += 12;
} else {
bs.addSize(2);
bs.growSize(2);
store<u32>(bs.offset, escaped, 0);
bs.offset += 4;
}
Expand Down
15 changes: 9 additions & 6 deletions assembly/test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { JSON } from "../";
import { JSON } from ".";
import { bs } from "../modules/as-bs/assembly";
import { serializeString } from "./serialize/simple/string";
import { bytes } from "./util";

assert(JSON.stringify<bool>(true) == "true", `JSON.stringify<bool>(true) == 'true'`);
assert(JSON.stringify<bool>(false) == "false", `JSON.stringify<bool>(false) == 'false'`);

assert(JSON.parse<bool>("true") == true, `JSON.parse<bool>(\"false\") == 'false'`);
assert(JSON.parse<bool>("false") == false, `JSON.parse<bool>(\"false\") == 'false'`);
serializeString("hello world");
console.log("\n-------------------------\nWritten: " + (bs.realSize - bs.buffer).toString())
const serialized = bs.out<string>();
console.log("Data: " + serialized);
console.log("Bytes: " + bytes(serialized).toString());
2 changes: 1 addition & 1 deletion assembly/util/bytes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ import { OBJECT, TOTAL_OVERHEAD } from "rt/common";
} else if (isManaged<T>() || isReference<T>()) {
return changetype<OBJECT>(changetype<usize>(o) - TOTAL_OVERHEAD).rtSize;
} else {
ERROR("Cannot convert type " + nameof<T>() + " to bytes!");
throw new Error("Cannot convert type " + nameof<T>() + " to bytes!");
}
}
Loading

0 comments on commit 467f039

Please sign in to comment.