assemblyscript/std/assembly/fixedarray.ts

48 lines
1.7 KiB
TypeScript
Raw Normal View History

2019-03-20 17:12:33 +01:00
import { ALLOCATE, REGISTER, MAX_BYTELENGTH, HEADER, HEADER_SIZE, LINK, UNLINK } from "./runtime";
2019-03-19 15:43:05 +01:00
// NOTE: DO NOT USE YET!
// TODO: FixedArray<T,S> with S being the static size, i.e. `new FixedArray<i32,10>`.
// Then hard-wire this special type to the compiler and do static length checks instead :)
export class FixedArray<T> {
[key: number]: T;
constructor(length: i32) {
if (<u32>length > <u32>MAX_BYTELENGTH >>> alignof<T>()) throw new RangeError("Invalid length");
var outSize = <usize>length << alignof<T>();
var out = ALLOCATE(outSize);
memory.fill(out, 0, outSize);
return REGISTER<FixedArray<T>>(out);
}
get length(): i32 {
return changetype<HEADER>(changetype<usize>(this) - HEADER_SIZE).payloadSize >>> alignof<T>();
}
@operator("[]") private __get(index: i32): T {
if (<u32>index >= <u32>this.length) throw new RangeError("Offset out of bounds");
2019-03-20 17:12:33 +01:00
return this.__unchecked_get(index);
2019-03-19 15:43:05 +01:00
}
@operator("[]=") private __set(index: i32, value: T): void {
if (<u32>index >= <u32>this.length) throw new RangeError("Offset out of bounds");
2019-03-20 17:12:33 +01:00
return this.__unchecked_set(index, value);
2019-03-19 15:43:05 +01:00
}
@operator("{}") private __unchecked_get(index: i32): T {
return load<T>(changetype<usize>(this) + (<usize>index << alignof<T>()));
}
@operator("{}=") private __unchecked_set(index: i32, value: T): void {
2019-03-20 17:12:33 +01:00
if (isManaged<T>()) {
let offset = changetype<usize>(this) + (<usize>index << alignof<T>());
let oldValue = load<T>(offset);
store<T>(offset, LINK<T,this>(value, this));
UNLINK<T,this>(oldValue, this); // order is important
} else {
store<T>(changetype<usize>(this) + (<usize>index << alignof<T>()), value);
}
2019-03-19 15:43:05 +01:00
}
}