Skip to content

Commit fd77663

Browse files
committed
fixedarray specific interface
1 parent 0f845f7 commit fd77663

File tree

4 files changed

+95
-5
lines changed

4 files changed

+95
-5
lines changed

std/assembly/fixedarray.ts

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,75 @@ export type fixed<T> = FixedArray<T>;
1212
export class FixedArray<T> {
1313
[key: number]: T;
1414

15+
// Note that the interface of FixedArray instances must be a semantically
16+
// compatible subset of Array<T> in order for syntax highlighting to work
17+
// properly, for instance when creating fixed arrays from array literals.
18+
// The additionally provided static methods take care of dealing with fixed
19+
// arrays exclusively, without having to converte to Array<T> first.
20+
21+
static fromArray<T>(source: Array<T>): FixedArray<T> {
22+
var length = source.length;
23+
var outSize = <usize>length << alignof<T>();
24+
var out = __alloc(outSize, idof<FixedArray<T>>());
25+
if (isManaged<T>()) {
26+
let sourcePtr = source.dataStart;
27+
for (let i = 0; i < length; ++i) {
28+
let off = <usize>i << alignof<T>();
29+
store<usize>(out + off, __retain(load<usize>(sourcePtr + off)));
30+
}
31+
} else {
32+
memory.copy(out, source.dataStart, outSize);
33+
}
34+
return changetype<FixedArray<T>>(out);
35+
}
36+
37+
static concat<T>(source: FixedArray<T>, other: FixedArray<T>): FixedArray<T> {
38+
var sourceLen = source.length;
39+
var otherLen = select(0, other.length, other === null);
40+
var outLen = sourceLen + otherLen;
41+
if (<u32>outLen > <u32>BLOCK_MAXSIZE >>> alignof<T>()) throw new Error(E_INVALIDLENGTH);
42+
var out = changetype<FixedArray<T>>(__alloc(<usize>outLen << alignof<T>(), idof<FixedArray<T>>())); // retains
43+
var outStart = changetype<usize>(out);
44+
var sourceSize = <usize>sourceLen << alignof<T>();
45+
if (isManaged<T>()) {
46+
for (let offset: usize = 0; offset < sourceSize; offset += sizeof<T>()) {
47+
let ref = load<usize>(changetype<usize>(source) + offset);
48+
store<usize>(outStart + offset, __retain(ref));
49+
}
50+
outStart += sourceSize;
51+
let otherSize = <usize>otherLen << alignof<T>();
52+
for (let offset: usize = 0; offset < otherSize; offset += sizeof<T>()) {
53+
let ref = load<usize>(changetype<usize>(other) + offset);
54+
store<usize>(outStart + offset, __retain(ref));
55+
}
56+
} else {
57+
memory.copy(outStart, changetype<usize>(source), sourceSize);
58+
memory.copy(outStart + sourceSize, changetype<usize>(other), <usize>otherLen << alignof<T>());
59+
}
60+
return out;
61+
}
62+
63+
static slice<T>(source: FixedArray<T>, start: i32 = 0, end: i32 = i32.MAX_VALUE): FixedArray<T> {
64+
var length = source.length;
65+
start = start < 0 ? max(start + length, 0) : min(start, length);
66+
end = end < 0 ? max(end + length, 0) : min(end , length);
67+
length = max(end - start, 0);
68+
var sliceSize = <usize>length << alignof<T>();
69+
var slice = changetype<FixedArray<T>>(__alloc(sliceSize, idof<FixedArray<T>>())); // retains
70+
var sourcePtr = changetype<usize>(source) + (<usize>start << alignof<T>());
71+
if (isManaged<T>()) {
72+
let off: usize = 0;
73+
while (off < sliceSize) {
74+
let ref = load<usize>(sourcePtr + off);
75+
store<usize>(changetype<usize>(slice) + off, __retain(ref));
76+
off += sizeof<usize>();
77+
}
78+
} else {
79+
memory.copy(changetype<usize>(slice), sourcePtr, sliceSize);
80+
}
81+
return slice;
82+
}
83+
1584
constructor(length: i32) {
1685
if (<u32>length > <u32>BLOCK_MAXSIZE >>> alignof<T>()) throw new RangeError(E_INVALIDLENGTH);
1786
var outSize = <usize>length << alignof<T>();
@@ -57,6 +126,23 @@ export class FixedArray<T> {
57126
}
58127
}
59128

129+
includes(value: T, fromIndex: i32 = 0): bool {
130+
if (isFloat<T>()) {
131+
let length = this.length;
132+
if (length == 0 || fromIndex >= length) return false;
133+
if (fromIndex < 0) fromIndex = max(length + fromIndex, 0);
134+
while (fromIndex < length) {
135+
let elem = load<T>(changetype<usize>(this) + (<usize>fromIndex << alignof<T>()));
136+
// @ts-ignore
137+
if (elem == value || isNaN(elem) & isNaN(value)) return true;
138+
++fromIndex;
139+
}
140+
return false;
141+
} else {
142+
return this.indexOf(value, fromIndex) >= 0;
143+
}
144+
}
145+
60146
indexOf(value: T, fromIndex: i32 = 0): i32 {
61147
var length = this.length;
62148
if (length == 0 || fromIndex >= length) return -1;

std/assembly/index.d.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1404,11 +1404,15 @@ declare type fixed<T> = FixedArray<T>;
14041404
/** Class representing a readonly sequence of values of type `T`. */
14051405
declare abstract class FixedArray<T> {
14061406
[key: number]: T;
1407+
static fromArray<T>(source: Array<T>): FixedArray<T>;
1408+
static concat<T>(source: FixedArray<T>, other: FixedArray<T>): FixedArray<T>;
1409+
static slice<T>(source: FixedArray<T>, start?: i32, end?: i32): FixedArray<T>;
14071410
readonly length: i32;
14081411
constructor(length?: i32);
1412+
includes(searchElement: T, fromIndex?: i32): bool;
14091413
indexOf(searchElement: T, fromIndex?: i32): i32;
14101414
lastIndexOf(searchElement: T, fromIndex?: i32): i32;
1411-
concat(items: T[]): T[];
1415+
concat(items: Array<T>): Array<T>;
14121416
slice(from: i32, to?: i32): Array<T>;
14131417
join(separator?: string): string;
14141418
toString(): string;

tests/compiler/std/fixedarray.optimized.wat

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
if
4848
i32.const 64
4949
i32.const 128
50-
i32.const 28
50+
i32.const 97
5151
i32.const 40
5252
call $~lib/builtins/abort
5353
unreachable
@@ -67,7 +67,7 @@
6767
if
6868
i32.const 64
6969
i32.const 128
70-
i32.const 43
70+
i32.const 112
7171
i32.const 40
7272
call $~lib/builtins/abort
7373
unreachable

tests/compiler/std/fixedarray.untouched.wat

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@
6363
if
6464
i32.const 64
6565
i32.const 128
66-
i32.const 28
66+
i32.const 97
6767
i32.const 40
6868
call $~lib/builtins/abort
6969
unreachable
@@ -91,7 +91,7 @@
9191
if
9292
i32.const 64
9393
i32.const 128
94-
i32.const 43
94+
i32.const 112
9595
i32.const 40
9696
call $~lib/builtins/abort
9797
unreachable

0 commit comments

Comments
 (0)