Skip to content
18 changes: 7 additions & 11 deletions std/assembly/array.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,25 @@

import { BLOCK_MAXSIZE } from "./rt/common";
import { COMPARATOR, SORT } from "./util/sort";
import { ArrayBuffer, ArrayBufferView } from "./arraybuffer";
import { ArrayBufferView } from "./arraybuffer";
import { joinBooleanArray, joinIntegerArray, joinFloatArray, joinStringArray, joinArrays, joinObjectArray } from "./util/string";
import { idof, isArray as builtin_isArray } from "./builtins";
import { E_INDEXOUTOFRANGE, E_INVALIDLENGTH, E_EMPTYARRAY, E_HOLEYARRAY } from "./util/error";

/** Ensures that the given array has _at least_ the specified backing size. */
function ensureSize(array: usize, minSize: usize, alignLog2: u32): void {
var oldCapacity = changetype<ArrayBufferView>(array).dataLength;
var oldCapacity = changetype<ArrayBufferView>(array).byteLength;
if (minSize > oldCapacity >>> alignLog2) {
if (minSize > BLOCK_MAXSIZE >>> alignLog2) throw new RangeError(E_INVALIDLENGTH);
let oldData = changetype<usize>(changetype<ArrayBufferView>(array).data);
let oldData = changetype<usize>(changetype<ArrayBufferView>(array).buffer);
let newCapacity = minSize << alignLog2;
let newData = __realloc(oldData, newCapacity);
memory.fill(newData + oldCapacity, 0, newCapacity - oldCapacity);
if (newData !== oldData) { // oldData has been free'd
store<usize>(changetype<usize>(array), __retain(newData), offsetof<ArrayBufferView>("data"));
changetype<ArrayBufferView>(array).dataStart = newData;
store<usize>(array, __retain(newData), offsetof<ArrayBufferView>("buffer"));
store<usize>(array, newData, offsetof<ArrayBufferView>("dataStart"));
}
changetype<ArrayBufferView>(array).dataLength = <u32>newCapacity;
store<u32>(array, newCapacity, offsetof<ArrayBufferView>("byteLength"));
}
}

Expand Down Expand Up @@ -53,10 +53,6 @@ export class Array<T> extends ArrayBufferView {
this.length_ = length;
}

@unsafe get buffer(): ArrayBuffer {
return this.data;
}

get length(): i32 {
return this.length_;
}
Expand Down Expand Up @@ -492,6 +488,6 @@ export class Array<T> extends ArrayBufferView {
cur += sizeof<usize>();
}
}
// automatically visits ArrayBufferView (.data) next
// automatically visits ArrayBufferView (.buffer) next
}
}
31 changes: 13 additions & 18 deletions std/assembly/arraybuffer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,32 +5,27 @@ import { idof } from "./builtins";
import { E_INVALIDLENGTH } from "./util/error";

export abstract class ArrayBufferView {

@unsafe data: ArrayBuffer;
@unsafe dataStart: usize;
@unsafe dataLength: u32;

protected constructor(length: i32, alignLog2: i32) {
if (<u32>length > <u32>BLOCK_MAXSIZE >>> alignLog2) throw new RangeError(E_INVALIDLENGTH);
var buffer = __alloc(length = length << alignLog2, idof<ArrayBuffer>());
memory.fill(buffer, 0, <usize>length);
this.data = changetype<ArrayBuffer>(buffer); // retains
this.dataStart = buffer;
this.dataLength = length;
}
readonly buffer: ArrayBuffer;
readonly dataStart: usize;
readonly byteLength: i32;

get byteOffset(): i32 {
return <i32>(this.dataStart - changetype<usize>(this.data));
}

get byteLength(): i32 {
return this.dataLength;
return <i32>(this.dataStart - changetype<usize>(this.buffer));
}

get length(): i32 {
ERROR("missing implementation: subclasses must implement ArrayBufferView#length");
return unreachable();
}

protected constructor(length: i32, alignLog2: i32) {
if (<u32>length > <u32>BLOCK_MAXSIZE >>> alignLog2) throw new RangeError(E_INVALIDLENGTH);
var buffer = __alloc(length = length << alignLog2, idof<ArrayBuffer>());
memory.fill(buffer, 0, <usize>length);
this.buffer = changetype<ArrayBuffer>(buffer); // retains
this.dataStart = buffer;
this.byteLength = length;
}
}

@sealed export class ArrayBuffer {
Expand Down
Loading