Rename lib prefix to '~lib' (parens aren't valid); Add built-in alignof<T>; Prepare for ArrayBufferView

This commit is contained in:
dcodeIO
2018-04-02 19:05:26 +02:00
parent 3b50720603
commit 06198a3723
51 changed files with 2286 additions and 2209 deletions

15
std/assembly.d.ts vendored
View File

@ -223,8 +223,10 @@ declare const NaN: f32 | f64;
declare const Infinity: f32 | f64;
/** Heap base offset. */
declare const HEAP_BASE: usize;
/** Determines the byte size of the specified core or class type. Compiles to a constant. */
/** Determines the byte size of the specified underlying core type. Compiles to a constant. */
declare function sizeof<T>(): usize;
/** Determines the alignment (log2) of the specified underlying core type. Compiles to a constant. */
declare function alignof<T>(): usize;
/** Determines the offset of the specified field within the given class type. Returns the class type's end offset if field name has been omitted. Compiles to a constant. */
declare function offsetof<T>(fieldName?: string): usize;
/** Changes the type of any value of `usize` kind to another one of `usize` kind. Useful for casting class instances to their pointer values and vice-versa. Beware that this is unsafe.*/
@ -270,6 +272,17 @@ declare class ArrayBuffer {
slice(begin?: i32, end?: i32): ArrayBuffer;
}
/** Interface for a typed view on an array buffer. */
declare interface ArrayBufferView<T> {
[key: number]: T;
/** The {@link ArrayBuffer} referenced by this view. */
readonly buffer: ArrayBuffer;
/** The offset in bytes from the start of the referenced {@link ArrayBuffer}. */
readonly byteOffset: i32;
/** The length in bytes from the start of the referenced {@link ArrayBuffer}. */
readonly byteLength: i32;
}
/** Class representing a sequence of values of type `T`. */
declare class Array<T> {
[key: number]: T;

View File

@ -3,7 +3,7 @@ const HEADER_SIZE: usize = sizeof<i32>();
@sealed
export class ArrayBuffer {
readonly byteLength: i32;
readonly byteLength: i32; // capped to [0, 0x7fffffff]
constructor(length: i32) {
if (<u32>length > 0x7fffffff) throw new RangeError("Invalid array buffer length");
@ -19,21 +19,20 @@ export class ArrayBuffer {
if (end < 0) end = max(len + end, 0);
else end = min(end, len);
var newLen = max(end - begin, 0);
if (newLen) {
let buffer = allocate_memory(HEADER_SIZE + <usize>newLen);
store<i32>(buffer, newLen);
move_memory(buffer + HEADER_SIZE, changetype<usize>(this) + HEADER_SIZE + begin, newLen);
return changetype<ArrayBuffer>(buffer);
} else if (ArrayBuffer.EMPTY) {
return ArrayBuffer.EMPTY;
} else {
let buffer = allocate_memory(HEADER_SIZE);
store<i32>(buffer, 0);
ArrayBuffer.EMPTY = changetype<ArrayBuffer>(buffer);
return changetype<ArrayBuffer>(buffer);
}
var buffer = allocate_memory(HEADER_SIZE + <usize>newLen);
store<i32>(buffer, newLen);
move_memory(buffer + HEADER_SIZE, changetype<usize>(this) + HEADER_SIZE + begin, newLen);
return changetype<ArrayBuffer>(buffer);
}
/** @internal */
static EMPTY: ArrayBuffer | null = null;
// TODO: built-in isView?
// TODO: built-in transfer?
}
/** @internal */
export declare interface ArrayBufferView<T> {
readonly buffer: ArrayBuffer;
readonly byteOffset: i32;
readonly byteLength: i32;
readonly length: i32;
}

View File

@ -52,6 +52,8 @@ export declare function store<T>(offset: usize, value: void, constantOffset?: us
export declare function sizeof<T>(): usize; // | u32 / u64
export declare function alignof<T>(): usize; // | u32 / u64
export declare function offsetof<T>(fieldName?: string): usize; // | u32 / u64
export declare function select<T>(ifTrue: T, ifFalse: T, condition: bool): T;

View File

@ -1,30 +1,19 @@
class TypedArray<T> {
/** @internal */
abstract class TypedArray<T> /* implements ArrayBufferView<T> */ {
readonly buffer: ArrayBuffer;
readonly byteOffset: i32;
readonly byteLength: i32;
get length(): i32 { return this.byteLength / sizeof<T>(); }
get length(): i32 { return this.byteLength >> alignof<T>(); }
constructor(length: i32) {
var byteLength = length * sizeof<T>();
const maxLength = <u32>0x7fffffff >> alignof<T>();
if (<u32>length > maxLength) throw new RangeError("Invalid typed array length");
var byteLength = length << alignof<T>();
this.buffer = new ArrayBuffer(byteLength);
this.byteOffset = 0;
this.byteLength = byteLength;
}
@operator("[]")
private __get(index: i32): T {
var offset = this.byteOffset;
assert(<u32>index < <u32>this.byteLength / sizeof<T>());
return load<T>(changetype<usize>(this.buffer) + (offset + index) * sizeof<T>(), 4);
}
@operator("[]=")
private __set(index: i32, value: T): void {
var offset = this.byteOffset;
assert(<u32>index < <u32>(this.byteLength / sizeof<T>()));
store<T>(changetype<usize>(this.buffer) + (offset + index) * sizeof<T>(), value, 4);
}
}
// export class Int8Array extends TypedArray<i8> {