Skip to content

Commit 496be27

Browse files
bowenwang1996dcodeIO
authored andcommitted
Add TypedArray#wrap as an alternative to ctor overloading (AssemblyScript#695)
1 parent 94efa59 commit 496be27

File tree

7 files changed

+6113
-306
lines changed

7 files changed

+6113
-306
lines changed

std/assembly/index.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1109,6 +1109,8 @@ declare abstract class TypedArray<T> implements ArrayBufferView<T> {
11091109
[key: number]: T;
11101110
/** Number of bytes per element. */
11111111
static readonly BYTES_PER_ELEMENT: usize;
1112+
/** Wrap an ArrayBuffer */
1113+
static wrap(buffer: ArrayBuffer, byteOffset?: i32, length?: i32): TypedArray<T>;
11121114
/** Constructs a new typed array. */
11131115
constructor(length: i32);
11141116
/** The {@link ArrayBuffer} referenced by this view. */

std/assembly/typedarray.ts

Lines changed: 77 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { COMPARATOR, SORT as SORT_IMPL } from "./util/sort";
2-
import { E_INDEXOUTOFRANGE } from "./util/error";
2+
import { E_INDEXOUTOFRANGE, E_INVALIDLENGTH } from "./util/error";
33
import { idof } from "./builtins";
44
import { ArrayBufferView } from "./arraybuffer";
55

@@ -95,6 +95,10 @@ export class Int8Array extends ArrayBufferView {
9595
reverse(): this {
9696
return REVERSE<this, i8>(this);
9797
}
98+
99+
static wrap(buffer: ArrayBuffer, byteOffset: i32 = 0, length: i32 = -1): Int8Array {
100+
return WRAP<Int8Array, i8>(buffer, byteOffset, length);
101+
}
98102
}
99103

100104
export class Uint8Array extends ArrayBufferView {
@@ -189,6 +193,10 @@ export class Uint8Array extends ArrayBufferView {
189193
reverse(): this {
190194
return REVERSE<this, u8>(this);
191195
}
196+
197+
static wrap(buffer: ArrayBuffer, byteOffset: i32 = 0, length: i32 = -1): Uint8Array {
198+
return WRAP<Uint8Array, u8>(buffer, byteOffset, length);
199+
}
192200
}
193201

194202
export class Uint8ClampedArray extends ArrayBufferView {
@@ -283,6 +291,10 @@ export class Uint8ClampedArray extends ArrayBufferView {
283291
reverse(): this {
284292
return REVERSE<this, u8>(this);
285293
}
294+
295+
static wrap(buffer: ArrayBuffer, byteOffset: i32 = 0, length: i32 = -1): Uint8ClampedArray {
296+
return WRAP<Uint8ClampedArray, u8>(buffer, byteOffset, length);
297+
}
286298
}
287299

288300
export class Int16Array extends ArrayBufferView {
@@ -377,6 +389,10 @@ export class Int16Array extends ArrayBufferView {
377389
reverse(): this {
378390
return REVERSE<this, i16>(this);
379391
}
392+
393+
static wrap(buffer: ArrayBuffer, byteOffset: i32 = 0, length: i32 = -1): Int16Array {
394+
return WRAP<Int16Array, i16>(buffer, byteOffset, length);
395+
}
380396
}
381397

382398
export class Uint16Array extends ArrayBufferView {
@@ -471,6 +487,10 @@ export class Uint16Array extends ArrayBufferView {
471487
reverse(): this {
472488
return REVERSE<this, u16>(this);
473489
}
490+
491+
static wrap(buffer: ArrayBuffer, byteOffset: i32 = 0, length: i32 = -1): Uint16Array {
492+
return WRAP<Uint16Array, u16>(buffer, byteOffset, length);
493+
}
474494
}
475495

476496
export class Int32Array extends ArrayBufferView {
@@ -565,6 +585,10 @@ export class Int32Array extends ArrayBufferView {
565585
reverse(): this {
566586
return REVERSE<this, i32>(this);
567587
}
588+
589+
static wrap(buffer: ArrayBuffer, byteOffset: i32 = 0, length: i32 = -1): Int32Array {
590+
return WRAP<Int32Array, i32>(buffer, byteOffset, length);
591+
}
568592
}
569593

570594
export class Uint32Array extends ArrayBufferView {
@@ -659,6 +683,10 @@ export class Uint32Array extends ArrayBufferView {
659683
reverse(): this {
660684
return REVERSE<this, u32>(this);
661685
}
686+
687+
static wrap(buffer: ArrayBuffer, byteOffset: i32 = 0, length: i32 = -1): Uint32Array {
688+
return WRAP<Uint32Array, u32>(buffer, byteOffset, length);
689+
}
662690
}
663691

664692
export class Int64Array extends ArrayBufferView {
@@ -753,6 +781,10 @@ export class Int64Array extends ArrayBufferView {
753781
reverse(): this {
754782
return REVERSE<this, i64>(this);
755783
}
784+
785+
static wrap(buffer: ArrayBuffer, byteOffset: i32 = 0, length: i32 = -1): Int64Array {
786+
return WRAP<Int64Array, i64>(buffer, byteOffset, length);
787+
}
756788
}
757789

758790
export class Uint64Array extends ArrayBufferView {
@@ -847,6 +879,10 @@ export class Uint64Array extends ArrayBufferView {
847879
reverse(): this {
848880
return REVERSE<this, u64>(this);
849881
}
882+
883+
static wrap(buffer: ArrayBuffer, byteOffset: i32 = 0, length: i32 = -1): Uint64Array {
884+
return WRAP<Uint64Array, u64>(buffer, byteOffset, length);
885+
}
850886
}
851887

852888
export class Float32Array extends ArrayBufferView {
@@ -941,6 +977,10 @@ export class Float32Array extends ArrayBufferView {
941977
reverse(): this {
942978
return REVERSE<this, f32>(this);
943979
}
980+
981+
static wrap(buffer: ArrayBuffer, byteOffset: i32 = 0, length: i32 = -1): Float32Array {
982+
return WRAP<Float32Array, f32>(buffer, byteOffset, length);
983+
}
944984
}
945985

946986
export class Float64Array extends ArrayBufferView {
@@ -1035,6 +1075,10 @@ export class Float64Array extends ArrayBufferView {
10351075
reverse(): this {
10361076
return REVERSE<this, f64>(this);
10371077
}
1078+
1079+
static wrap(buffer: ArrayBuffer, byteOffset: i32 = 0, length: i32 = -1): Float64Array {
1080+
return WRAP<Float64Array, f64>(buffer, byteOffset, length);
1081+
}
10381082
}
10391083

10401084
// @ts-ignore: decorator
@@ -1260,3 +1304,35 @@ function REVERSE<TArray extends ArrayBufferView, T>(array: TArray): TArray {
12601304
}
12611305
return array;
12621306
}
1307+
1308+
// @ts-ignore: decorator
1309+
@inline
1310+
function WRAP<TArray extends ArrayBufferView, T>(buffer: ArrayBuffer, byteOffset: i32 = 0, length: i32 = -1): TArray {
1311+
var bufferByteLength = buffer.byteLength;
1312+
if (<u32>byteOffset >= <u32>bufferByteLength) {
1313+
throw new RangeError(E_INDEXOUTOFRANGE);
1314+
}
1315+
var byteLength: i32;
1316+
if (length < 0) {
1317+
if (length == -1) {
1318+
const mask = <i32>(1 << alignof<T>() - 1);
1319+
if (buffer.byteLength & mask) {
1320+
throw new RangeError(E_INVALIDLENGTH);
1321+
} else {
1322+
byteLength = buffer.byteLength;
1323+
}
1324+
} else {
1325+
throw new RangeError(E_INVALIDLENGTH);
1326+
}
1327+
} else {
1328+
byteLength = length << alignof<T>();
1329+
}
1330+
if (byteOffset + byteLength > buffer.byteLength) {
1331+
throw new RangeError(E_INVALIDLENGTH);
1332+
}
1333+
var out = changetype<TArray>(__alloc(offsetof<TArray>(), idof<TArray>()));
1334+
out.data = buffer;
1335+
out.dataLength = byteLength;
1336+
out.dataStart = changetype<usize>(buffer) + <usize>byteOffset;
1337+
return out;
1338+
}

tests/compiler/std/dataview.optimized.wat

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1609,7 +1609,7 @@
16091609
if
16101610
i32.const 280
16111611
i32.const 376
1612-
i32.const 127
1612+
i32.const 131
16131613
i32.const 44
16141614
call $~lib/builtins/abort
16151615
unreachable

tests/compiler/std/dataview.untouched.wat

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3296,7 +3296,7 @@
32963296
if
32973297
i32.const 280
32983298
i32.const 376
3299-
i32.const 127
3299+
i32.const 131
33003300
i32.const 44
33013301
call $~lib/builtins/abort
33023302
unreachable

0 commit comments

Comments
 (0)