This commit is contained in:
dcode
2019-03-17 12:25:54 +01:00
parent f21b339563
commit edb2299f13
52 changed files with 16800 additions and 18592 deletions

View File

@ -15,8 +15,8 @@ function ensureLength(array: ArrayBufferView, length: i32, alignLog2: u32): void
if (newData !== changetype<usize>(oldData)) {
array.data = changetype<ArrayBuffer>(newData); // links
array.dataStart = newData;
array.dataLength = newByteLength;
}
array.dataLength = newByteLength;
}
}
@ -183,7 +183,7 @@ export class Array<T> extends ArrayBufferView {
pop(): T {
var length = this.length_;
if (length < 1) throw new RangeError("Array is empty");
var element = load<T>(this.dataStart + (<usize>--length << alignof<T>()));
var element = load<T>(this.dataStart + (<usize>(--length) << alignof<T>()));
this.length_ = length;
return element;
}
@ -265,7 +265,7 @@ export class Array<T> extends ArrayBufferView {
}
unshift(element: T): i32 {
var newLength = this.length_;
var newLength = this.length_ + 1;
ensureLength(changetype<ArrayBufferView>(this), newLength, alignof<T>());
var base = this.dataStart;
memory.copy(
@ -327,14 +327,17 @@ export class Array<T> extends ArrayBufferView {
}
reverse(): Array<T> {
var front = this.dataStart;
var back = this.dataStart + this.dataLength - sizeof<T>();
while (front < back) {
let temp = load<T>(front);
store<T>(front, load<T>(back));
store<T>(back, temp);
front += sizeof<T>();
back -= sizeof<T>();
var length = this.length_;
if (length) {
let front = this.dataStart;
let back = this.dataStart + (<usize>(length - 1) << alignof<T>());
while (front < back) {
let temp = load<T>(front);
store<T>(front, load<T>(back));
store<T>(back, temp);
front += sizeof<T>();
back -= sizeof<T>();
}
}
return this;
}
@ -507,15 +510,16 @@ export class Array<T> extends ArrayBufferView {
var sepLen = separator.length;
var estLen = 0;
var value: string | null;
for (let i = 0, len = lastIndex + 1; i < len; ++i) {
estLen += load<string>(dataStart + (<usize>i << alignof<T>())).length;
value = load<string>(dataStart + (<usize>i << alignof<T>()));
if (value !== null) estLen += value.length;
}
var offset = 0;
var result = ALLOCATE((estLen + sepLen * lastIndex) << 1);
var value: String;
for (let i = 0; i < lastIndex; ++i) {
value = load<string>(dataStart + (<usize>i << alignof<T>()));
if (value) {
if (value !== null) {
let valueLen = changetype<string>(value).length;
memory.copy(
result + (<usize>offset << 1),
@ -534,12 +538,11 @@ export class Array<T> extends ArrayBufferView {
}
}
value = load<string>(dataStart + (<usize>lastIndex << alignof<T>()));
if (value) {
let valueLen = changetype<string>(value).length;
if (value !== null) {
memory.copy(
result + (<usize>offset << 1),
changetype<usize>(value),
<usize>valueLen << 1
<usize>changetype<string>(value).length << 1
);
}
return REGISTER<string>(result);

View File

@ -1,11 +1,13 @@
import { MAX_BYTELENGTH } from "./runtime";
import { ArrayBuffer } from "./arraybuffer";
// TODO: there is probably a smarter way to check byteOffset for accesses larger than 1 byte
export class DataView {
private data: ArrayBuffer;
private dataStart: usize;
private dataLength: u32;
private dataLength: i32;
constructor(
buffer: ArrayBuffer,
@ -34,7 +36,10 @@ export class DataView {
}
getFloat32(byteOffset: i32, littleEndian: boolean = false): f32 {
if (byteOffset + 4 > this.dataLength) throw new Error("Offset out of bounds");
if (
i32(byteOffset < 0) |
i32(byteOffset + 4 > this.dataLength)
) throw new Error("Offset out of bounds");
return littleEndian
? load<f32>(this.dataStart + <usize>byteOffset)
: reinterpret<f32>(
@ -45,7 +50,10 @@ export class DataView {
}
getFloat64(byteOffset: i32, littleEndian: boolean = false): f64 {
if (byteOffset + 4 > this.dataLength) throw new Error("Offset out of bounds");
if (
i32(byteOffset < 0) |
i32(byteOffset + 8 > this.dataLength)
) throw new Error("Offset out of bounds");
return littleEndian
? load<f64>(this.dataStart + <usize>byteOffset)
: reinterpret<f64>(
@ -56,102 +64,144 @@ export class DataView {
}
getInt8(byteOffset: i32): i8 {
if (byteOffset >= this.dataLength) throw new Error("Offset out of bounds");
if (<u32>byteOffset >= <u32>this.dataLength) throw new Error("Offset out of bounds");
return load<i8>(this.dataStart + <usize>byteOffset);
}
getInt16(byteOffset: i32, littleEndian: boolean = false): i16 {
if (byteOffset + 2 > this.dataLength) throw new Error("Offset out of bounds");
if (
i32(byteOffset < 0) |
i32(byteOffset + 2 > this.dataLength)
) throw new Error("Offset out of bounds");
var result: i16 = load<i16>(this.dataStart + <usize>byteOffset);
return littleEndian ? result : bswap<i16>(result);
}
getInt32(byteOffset: i32, littleEndian: boolean = false): i32 {
if (byteOffset + 4 > this.dataLength) throw new Error("Offset out of bounds");
if (
i32(byteOffset < 0) |
i32(byteOffset + 4 > this.dataLength)
) throw new Error("Offset out of bounds");
var result: i32 = load<i32>(this.dataStart + <usize>byteOffset);
return littleEndian ? result : bswap<i32>(result);
}
getUint8(byteOffset: i32): u8 {
if (byteOffset >= this.dataLength) throw new Error("Offset out of bounds");
if (<u32>byteOffset >= <u32>this.dataLength) throw new Error("Offset out of bounds");
return load<u8>(this.dataStart + <usize>byteOffset);
}
getUint16(byteOffset: i32, littleEndian: boolean = false): u16 {
if (byteOffset + 2 > this.dataLength) throw new Error("Offset out of bounds");
if (
i32(byteOffset < 0) |
i32(byteOffset + 2 > this.dataLength)
) throw new Error("Offset out of bounds");
var result: u16 = load<u16>(this.dataStart + <usize>byteOffset);
return littleEndian ? result : bswap<u16>(result);
}
getUint32(byteOffset: i32, littleEndian: boolean = false): u32 {
if (byteOffset + 2 > this.dataLength) throw new Error("Offset out of bounds");
if (
i32(byteOffset < 0) |
i32(byteOffset + 4 > this.dataLength)
) throw new Error("Offset out of bounds");
var result: u32 = load<u32>(this.dataStart + <usize>byteOffset);
return littleEndian ? result : bswap<u32>(result);
}
setFloat32(byteOffset: i32, value: f32, littleEndian: boolean = false): void {
if (byteOffset + 4 > this.dataLength) throw new Error("Offset out of bounds");
if (
i32(byteOffset < 0) |
i32(byteOffset + 4 > this.dataLength)
) throw new Error("Offset out of bounds");
if (littleEndian) store<f32>(this.dataStart + <usize>byteOffset, value);
else store<u32>(this.dataStart + <usize>byteOffset, bswap<u32>(reinterpret<u32>(value)));
}
setFloat64(byteOffset: i32, value: f64, littleEndian: boolean = false): void {
if (byteOffset + 8 > this.dataLength) throw new Error("Offset out of bounds");
if (
i32(byteOffset < 0) |
i32(byteOffset + 8 > this.dataLength)
) throw new Error("Offset out of bounds");
if (littleEndian) store<f64>(this.dataStart + <usize>byteOffset, value);
else store<u64>(this.dataStart + <usize>byteOffset, bswap<u64>(reinterpret<u64>(value)));
}
setInt8(byteOffset: i32, value: i8): void {
if (byteOffset >= this.dataLength) throw new Error("Offset out of bounds");
if (<u32>byteOffset >= <u32>this.dataLength) throw new Error("Offset out of bounds");
store<i8>(this.dataStart + <usize>byteOffset, value);
}
setInt16(byteOffset: i32, value: i16, littleEndian: boolean = false): void {
if (byteOffset + 2 > this.dataLength) throw new Error("Offset out of bounds");
if (
i32(byteOffset < 0) |
i32(byteOffset + 2 > this.dataLength)
) throw new Error("Offset out of bounds");
store<i16>(this.dataStart + <usize>byteOffset, littleEndian ? value : bswap<i16>(value));
}
setInt32(byteOffset: i32, value: i32, littleEndian: boolean = false): void {
if (byteOffset + 4 > this.dataLength) throw new Error("Offset out of bounds");
if (
i32(byteOffset < 0) |
i32(byteOffset + 4 > this.dataLength)
) throw new Error("Offset out of bounds");
store<i32>(this.dataStart + <usize>byteOffset, littleEndian ? value : bswap<i32>(value));
}
setUint8(byteOffset: i32, value: u8): void {
if (byteOffset >= this.dataLength) throw new Error("Offset out of bounds");
if (<u32>byteOffset >= <u32>this.dataLength) throw new Error("Offset out of bounds");
store<u8>(this.dataStart + <usize>byteOffset, value);
}
setUint16(byteOffset: i32, value: u16, littleEndian: boolean = false): void {
if (byteOffset + 2 > this.dataLength) throw new Error("Offset out of bounds");
if (
i32(byteOffset < 0) |
i32(byteOffset + 2 > this.dataLength)
) throw new Error("Offset out of bounds");
store<u16>(this.dataStart + <usize>byteOffset, littleEndian ? value : bswap<u16>(value));
}
setUint32(byteOffset: i32, value: u32, littleEndian: boolean = false): void {
if (byteOffset + 4 > this.dataLength) throw new Error("Offset out of bounds");
if (
i32(byteOffset < 0) |
i32(byteOffset + 4 > this.dataLength)
) throw new Error("Offset out of bounds");
store<u32>(this.dataStart + <usize>byteOffset, littleEndian ? value : bswap<u32>(value));
}
// Non-standard additions that make sense in WebAssembly, but won't work in JS:
getInt64(byteOffset: i32, littleEndian: boolean = false): i64 {
if (byteOffset + 8 > this.dataLength) throw new Error("Offset out of bounds");
if (
i32(byteOffset < 0) |
i32(byteOffset + 8 > this.dataLength)
) throw new Error("Offset out of bounds");
var result: i64 = load<i64>(this.dataStart + <usize>byteOffset);
return littleEndian ? result : bswap<i64>(result);
}
getUint64(byteOffset: i32, littleEndian: boolean = false): u64 {
if (byteOffset + 8 > this.dataLength) throw new Error("Offset out of bounds");
if (
i32(byteOffset < 0) |
i32(byteOffset + 8 > this.dataLength)
) throw new Error("Offset out of bounds");
var result = load<u64>(this.dataStart + <usize>byteOffset);
return littleEndian ? result : bswap<u64>(result);
}
setInt64(byteOffset: i32, value: i64, littleEndian: boolean = false): void {
if (byteOffset + 8 > this.dataLength) throw new Error("Offset out of bounds");
if (
i32(byteOffset < 0) |
i32(byteOffset + 8 > this.dataLength)
) throw new Error("Offset out of bounds");
store<i64>(this.dataStart + <usize>byteOffset, littleEndian ? value : bswap<i64>(value));
}
setUint64(byteOffset: i32, value: u64, littleEndian: boolean = false): void {
if (byteOffset + 8 > this.dataLength) throw new Error("Offset out of bounds");
if (
i32(byteOffset < 0) |
i32(byteOffset + 8 > this.dataLength)
) throw new Error("Offset out of bounds");
store<u64>(this.dataStart + <usize>byteOffset, littleEndian ? value : bswap<u64>(value));
}

View File

@ -84,6 +84,10 @@ export class Uint8Array extends ArrayBufferView {
super(length, alignof<u8>());
}
get buffer(): ArrayBuffer {
return this.data;
}
get length(): i32 {
return this.byteLength;
}