Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[AssemblyScript] Added basic AssemblyScript support #6408

Closed
wants to merge 22 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
f25a3d6
[Assembly Script] Add basic Assembly Script support
LucasSwitz Jan 19, 2021
61c3c89
[AssemblyScript] Created basic standalone AssemlbyScript generator
LucasSwitz Jan 21, 2021
68f3a3b
Merge branch 'master' into assembly_script_support
LucasSwitz Jan 21, 2021
ddd08c9
[AssemblyScript] added AssemblyScript source to build
LucasSwitz Jan 21, 2021
8801f84
Merge branch 'assembly_script_support' of https://github.com/LucasSwi…
LucasSwitz Jan 21, 2021
df9b280
[AssemlbyScript] Added AssemblyScript generator to Cmake and labeler
LucasSwitz Jan 21, 2021
ff78ada
[AssemblyScript] Removed unused imports from GenEnum.
LucasSwitz Jan 26, 2021
ca4864a
Merge branch 'master' into assembly_script_support
LucasSwitz Jan 26, 2021
45b3cf3
[AssemblyScript] Aligned with new FieldDef
LucasSwitz Jan 26, 2021
9009f14
Merge branch 'master' into assembly_script_support
LucasSwitz Feb 12, 2021
f259c0c
Merge branch 'master' into assembly_script_support
LucasSwitz Mar 24, 2021
fbc284e
Removed unused GenPrefixedImport logic
LucasSwitz Mar 24, 2021
8e5a436
Removed unused GenPrefixedImport logic
LucasSwitz Mar 24, 2021
90382ac
Merge branch 'assembly_script_support' of https://github.com/LucasSwi…
LucasSwitz Mar 24, 2021
a2766d7
Merge branch 'master' into assembly_script_support
LucasSwitz May 13, 2021
8721423
Update BUILD.bazel
LucasSwitz May 13, 2021
22e3322
Replace Long types with i64 / u64
LucasSwitz May 27, 2021
45fea2d
Merge branch 'assembly_script_support' of https://github.com/LucasSwi…
LucasSwitz May 27, 2021
c071b69
Replace Long types with i64 / u64
LucasSwitz May 27, 2021
63bdba5
Merge branch 'master' into assembly_script_support
LucasSwitz May 27, 2021
50a7279
Ran clang formatter
LucasSwitz May 27, 2021
d5fc36d
Fixed readInt64 type
LucasSwitz May 27, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
671 changes: 671 additions & 0 deletions as/builder.ts

Large diffs are not rendered by default.

365 changes: 365 additions & 0 deletions as/byte-buffer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,365 @@
import { FILE_IDENTIFIER_LENGTH, SIZEOF_INT } from './constants';
import { Long } from './long';
LucasSwitz marked this conversation as resolved.
Show resolved Hide resolved
import { int32, isLittleEndian, float32, float64 } from './utils';
import { Offset, Table, IGeneratedObject } from './types';

export class ByteBuffer {
private position_: i32 = 0;

/**
* Create a new ByteBuffer with a given array of bytes (`Uint8Array`)
*/
constructor(private bytes_: Uint8Array) {}

/**
* Create and allocate a new ByteBuffer with a given size.
*/
static allocate(byte_size: i32): ByteBuffer {
return new ByteBuffer(new Uint8Array(byte_size));
}

clear(): void {
this.position_ = 0;
}

/**
* Get the underlying `Uint8Array`.
*/
bytes(): Uint8Array {
return this.bytes_;
}

/**
* Get the buffer's position.
*/
position(): i32 {
return this.position_;
}

/**
* Set the buffer's position.
*/
setPosition(position: i32): void {
this.position_ = position;
}

/**
* Get the buffer's capacity.
*/
capacity(): i32 {
return this.bytes_.length;
}

readInt8(offset: i32): i32 {
return (i32(this.readUint8(offset)) << 24) >> 24;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Manual sign extension is unnecessary when you cast to u8 -> i32 via as i32

Suggested change
return (i32(this.readUint8(offset)) << 24) >> 24;
return this.readUint8(offset) as i32;

}

readUint8(offset: i32): i32 {
return this.bytes_[offset];
}

readInt16(offset: i32): i32 {
return (i32(this.readUint16(offset)) << 16) >> 16;
LucasSwitz marked this conversation as resolved.
Show resolved Hide resolved
}

readUint16(offset: i32): i32 {
return i32(this.bytes_[offset]) | (i32(this.bytes_[offset + 1]) << 8);
}

readInt32(offset: i32): i32 {
return (
i32(this.bytes_[offset]) |
(i32(this.bytes_[offset + 1]) << 8) |
(i32(this.bytes_[offset + 2]) << 16) |
(i32(this.bytes_[offset + 3]) << 24)
);
}

readUint32(offset: i32): i32 {
return this.readInt32(offset) >>> 0;
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
readUint32(offset: i32): i32 {
return this.readInt32(offset) >>> 0;
}
readUint32(offset: i32): u32 {
return this.readInt32(offset);
}


readInt64(offset: i32): Long {
return new Long(this.readInt32(offset), this.readInt32(offset + 4));
}

readUint64(offset: i32): Long {
return new Long(this.readUint32(offset), this.readUint32(offset + 4));
}

readFloat32(offset: i32): f32 {
int32[0] = this.readInt32(offset);
return float32[0];
}

readFloat64(offset: i32): f64 {
int32[isLittleEndian ? 0 : 1] = this.readInt32(offset);
int32[isLittleEndian ? 1 : 0] = this.readInt32(offset + 4);
return float64[0];
}

writeInt8(offset: i32, value: i32): void {
this.bytes_[offset] = value;
}

writeUint8(offset: i32, value: i32): void {
this.bytes_[offset] = value;
}

writeInt16(offset: i32, value: i32): void {
this.bytes_[offset] = value;
this.bytes_[offset + 1] = value >> 8;
}

writeUint16(offset: i32, value: i32): void {
this.bytes_[offset] = value;
this.bytes_[offset + 1] = value >> 8;
}

writeInt32(offset: i32, value: i32): void {
this.bytes_[offset] = value;
this.bytes_[offset + 1] = value >> 8;
this.bytes_[offset + 2] = value >> 16;
this.bytes_[offset + 3] = value >> 24;
}

writeUint32(offset: i32, value: i32): void {
this.bytes_[offset] = value;
this.bytes_[offset + 1] = value >> 8;
this.bytes_[offset + 2] = value >> 16;
this.bytes_[offset + 3] = value >> 24;
}

writeInt64(offset: i32, value: Long): void {
this.writeInt32(offset, value.low);
this.writeInt32(offset + 4, value.high);
}

writeUint64(offset: i32, value: Long): void {
this.writeUint32(offset, value.low);
this.writeUint32(offset + 4, value.high);
}

writeFloat32(offset: i32, value: f32): void {
float32[0] = value;
this.writeInt32(offset, int32[0]);
}

writeFloat64(offset: i32, value: f64): void {
float64[0] = value;
this.writeInt32(offset, int32[isLittleEndian ? 0 : 1]);
this.writeInt32(offset + 4, int32[isLittleEndian ? 1 : 0]);
}

/**
* Return the file identifier. Behavior is undefined for FlatBuffers whose
* schema does not include a file_identifier (likely points at padding or the
* start of a the root vtable).
*/
getBufferIdentifier(): string {
if (
this.bytes_.length <
this.position_ + SIZEOF_INT + FILE_IDENTIFIER_LENGTH
) {
throw new Error(
'FlatBuffers: ByteBuffer is too short to contain an identifier.'
);
}
let result = '';
for (let i = 0; i < FILE_IDENTIFIER_LENGTH; i++) {
result += String.fromCharCode(
this.readInt8(this.position_ + SIZEOF_INT + i)
);
}
return result;
}

/**
* Look up a field in the vtable, return an offset into the object, or 0 if the
* field is not present.
*/
__offset(bb_pos: i32, vtable_offset: i32): Offset {
const vtable = bb_pos - this.readInt32(bb_pos);
return vtable_offset < this.readInt16(vtable)
? this.readInt16(vtable + vtable_offset)
: 0;
}

/**
* Initialize any Table-derived type to point to the union at the given offset.
*/
__union(t: Table, offset: i32): Table {
t.bb_pos = offset + this.readInt32(offset);
t.bb = this;
return t;
}

/**
* Create a JavaScript string from UTF-8 data stored inside the FlatBuffer.
* This allocates a new string and converts to wide chars upon each access.
*
* To avoid the conversion to UTF-16, pass Encoding.UTF8_BYTES as
* the "optionalEncoding" argument. This is useful for avoiding conversion to
* and from UTF-16 when the data will just be packaged back up in another
* FlatBuffer later on.
*
* @param offset
* @param opt_encoding Defaults to UTF16_STRING
*/
__string(offset: i32): string {
offset += this.readInt32(offset);

const length = this.readInt32(offset);
let result = '';
let i = 0;

offset += SIZEOF_INT;

while (i < length) {
let codePoint: i32;

// Decode UTF-8
const a = this.readUint8(offset + i++);
if (a < 0xc0) {
codePoint = a;
} else {
const b = this.readUint8(offset + i++);
if (a < 0xe0) {
codePoint = ((a & 0x1f) << 6) | (b & 0x3f);
} else {
const c = this.readUint8(offset + i++);
if (a < 0xf0) {
codePoint = ((a & 0x0f) << 12) | ((b & 0x3f) << 6) | (c & 0x3f);
} else {
const d = this.readUint8(offset + i++);
codePoint =
((a & 0x07) << 18) |
((b & 0x3f) << 12) |
((c & 0x3f) << 6) |
(d & 0x3f);
}
}
}

// Encode UTF-16
if (codePoint < 0x10000) {
result += String.fromCharCode(codePoint);
} else {
codePoint -= 0x10000;
result += String.fromCharCode(
(codePoint >> 10) + 0xd800,
(codePoint & ((1 << 10) - 1)) + 0xdc00
);
}
}

return result;
}

/**
* Handle unions that can contain string as its member, if a Table-derived type then initialize it,
* if a string then return a new one
*
* WARNING: strings are immutable in JS so we can't change the string that the user gave us, this
* makes the behaviour of __union_with_string different compared to __union
*/
__union_with_string(offset: i32): string {
return this.__string(offset) as string;
}

__union_with_table(o: Table, offset: i32): Table {
return this.__union(o, offset);
}

/**
* Retrieve the relative offset stored at "offset"
*/
__indirect(offset: Offset): Offset {
return offset + this.readInt32(offset);
}

/**
* Get the start of data of a vector whose offset is stored at "offset" in this object.
*/
__vector(offset: Offset): Offset {
return offset + this.readInt32(offset) + SIZEOF_INT; // data starts after the length
}

/**
* Get the length of a vector whose offset is stored at "offset" in this object.
*/
__vector_len(offset: Offset): Offset {
return this.readInt32(offset + this.readInt32(offset));
}

__has_identifier(ident: string): boolean {
if (ident.length != FILE_IDENTIFIER_LENGTH) {
throw new Error(
'FlatBuffers: file identifier must be length ' + FILE_IDENTIFIER_LENGTH
);
}
for (let i = 0; i < FILE_IDENTIFIER_LENGTH; i++) {
if (
ident.charCodeAt(i) != this.readInt8(this.position() + SIZEOF_INT + i)
) {
return false;
}
}
return true;
}

/**
* A helper function to avoid generated code depending on this file directly.
*/
createLong(low: i32, high: i32): Long {
return Long.create(low, high);
}

/**
* A helper function for generating list for obj api
*/
createScalarList(
listAccessor: (i: i32) => unknown,
listLength: i32
): unknown[] {
const ret: unknown[] = [];
for (let i = 0; i < listLength; ++i) {
if (listAccessor(i) !== null) {
ret.push(listAccessor(i));
}
}

return ret;
}

/**
* This function is here only to get around typescript type system
*/
createStringList(
listAccessor: (i: i32) => unknown,
listLength: i32
): unknown[] {
return this.createScalarList(listAccessor, listLength);
}

/**
* A helper function for generating list for obj api
* @param listAccessor function that accepts an index and return data at that index
* @param listLength listLength
* @param res result list
*/
createObjList(
listAccessor: (i: i32) => IGeneratedObject,
listLength: i32
): IGeneratedObject[] {
const ret: IGeneratedObject[] = [];
for (let i = 0; i < listLength; ++i) {
const val = listAccessor(i);
if (val !== null) {
ret.push(val.unpack());
}
}

return ret;
}
}
4 changes: 4 additions & 0 deletions as/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export const SIZEOF_SHORT = 2;
export const SIZEOF_INT = 4;
export const FILE_IDENTIFIER_LENGTH = 4;
export const SIZE_PREFIX_LENGTH = 4;
4 changes: 4 additions & 0 deletions as/encoding.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export enum Encoding {
UTF8_BYTES = 1,
UTF16_STRING = 2,
}
Loading