Skip to content

Commit 1c969f1

Browse files
MaxGraeyWillem Wyndham
authored andcommitted
Fix implementation of Array#splice (AssemblyScript#347)
1 parent 0c40d2f commit 1c969f1

File tree

7 files changed

+2365
-1203
lines changed

7 files changed

+2365
-1203
lines changed

std/assembly/array.ts

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -369,19 +369,28 @@ export class Array<T> {
369369
return sliced;
370370
}
371371

372-
splice(start: i32, deleteCount: i32 = i32.MAX_VALUE): void {
373-
if (deleteCount < 1) return;
374-
var length = this.length_;
375-
if (start < 0) start = max(length + start, 0);
376-
if (start >= length) return;
377-
deleteCount = min(deleteCount, length - start);
378-
var buffer = this.buffer_;
372+
splice(start: i32, deleteCount: i32 = i32.MAX_VALUE): Array<T> {
373+
var length = this.length_;
374+
start = start < 0 ? max<i32>(length + start, 0) : min<i32>(start, length);
375+
deleteCount = max<i32>(min<i32>(deleteCount, length - start), 0);
376+
var buffer = this.buffer_;
377+
var spliced = new Array<T>(deleteCount);
378+
var source = changetype<usize>(buffer) + HEADER_SIZE + (<usize>start << alignof<T>());
379379
memory.copy(
380-
changetype<usize>(buffer) + HEADER_SIZE + (<usize>start << alignof<T>()),
381-
changetype<usize>(buffer) + HEADER_SIZE + (<usize>(start + deleteCount) << alignof<T>()),
380+
changetype<usize>(spliced.buffer_) + HEADER_SIZE,
381+
source,
382382
<usize>deleteCount << alignof<T>()
383383
);
384+
var offset = start + deleteCount;
385+
if (length != offset) {
386+
memory.copy(
387+
source,
388+
changetype<usize>(buffer) + HEADER_SIZE + (<usize>offset << alignof<T>()),
389+
<usize>(length - offset) << alignof<T>()
390+
);
391+
}
384392
this.length_ = length - deleteCount;
393+
return spliced;
385394
}
386395

387396
reverse(): Array<T> {

std/assembly/index.d.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -717,8 +717,8 @@ declare class Array<T> {
717717
shift(): T;
718718
some(callbackfn: (element: T, index: i32, array?: Array<T>) => bool): bool;
719719
unshift(element: T): i32;
720-
slice(from: i32, to?: i32): T[];
721-
splice(start: i32, deleteCount?: i32): void;
720+
slice(from: i32, to?: i32): Array<T>;
721+
splice(start: i32, deleteCount?: i32): Array<T>;
722722
sort(comparator?: (a: T, b: T) => i32): this;
723723
join(separator?: string): string;
724724
reverse(): T[];

std/assembly/internal/memory.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ export function memcpy(dest: usize, src: usize, n: usize): void { // see: musl/s
144144

145145
// this function will go away once `memory.copy` becomes an intrinsic
146146
export function memmove(dest: usize, src: usize, n: usize): void { // see: musl/src/string/memmove.c
147-
if (dest == src) return;
147+
if (dest === src) return;
148148
if (src + n <= dest || dest + n <= src) {
149149
memcpy(dest, src, n);
150150
return;

std/portable/index.d.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -373,8 +373,8 @@ declare class Array<T> {
373373
shift(): T;
374374
some(callbackfn: (element: T, index: i32, array?: Array<T>) => bool): bool;
375375
unshift(element: T): i32;
376-
slice(from?: i32, to?: i32): T[];
377-
splice(start: i32, deleteCount?: i32): void;
376+
slice(from?: i32, to?: i32): Array<T>;
377+
splice(start: i32, deleteCount?: i32): Array<T>;
378378
sort(comparator?: (a: T, b: T) => i32): this;
379379
join(separator?: string): string;
380380
reverse(): T[];

tests/compiler/std/array.optimized.wat

Lines changed: 1127 additions & 577 deletions
Large diffs are not rendered by default.

tests/compiler/std/array.ts

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,60 @@ assert(internalCapacity<i32>(arr) == 5);
330330
assert(arr[0] == 44);
331331
assert(arr[1] == 42);
332332

333+
// Array#splice ////////////////////////////////////////////////////////////////////////////////////
334+
335+
var sarr: i32[] = [1, 2, 3, 4, 5];
336+
assert(isArraysEqual<i32>(sarr.splice(0), <i32[]>[1, 2, 3, 4, 5]));
337+
assert(isArraysEqual<i32>(sarr, <i32[]>[]));
338+
339+
sarr = <i32[]>[1, 2, 3, 4, 5];
340+
assert(isArraysEqual<i32>(sarr.splice(2), <i32[]>[3, 4, 5]));
341+
assert(isArraysEqual<i32>(sarr, <i32[]>[1, 2]));
342+
343+
sarr = <i32[]>[1, 2, 3, 4, 5];
344+
assert(isArraysEqual<i32>(sarr.splice(2, 2), <i32[]>[3, 4]));
345+
assert(isArraysEqual<i32>(sarr, <i32[]>[1, 2, 5]));
346+
347+
sarr = <i32[]>[1, 2, 3, 4, 5];
348+
assert(isArraysEqual<i32>(sarr.splice(0, 1), <i32[]>[1]));
349+
assert(isArraysEqual<i32>(sarr, <i32[]>[2, 3, 4, 5]));
350+
351+
sarr = <i32[]>[1, 2, 3, 4, 5];
352+
assert(isArraysEqual<i32>(sarr.splice(-1), <i32[]>[5]));
353+
assert(isArraysEqual<i32>(sarr, <i32[]>[1, 2, 3, 4]));
354+
355+
sarr = <i32[]>[1, 2, 3, 4, 5];
356+
assert(isArraysEqual<i32>(sarr.splice(-2), <i32[]>[4, 5]));
357+
assert(isArraysEqual<i32>(sarr, <i32[]>[1, 2, 3]));
358+
359+
sarr = <i32[]>[1, 2, 3, 4, 5];
360+
assert(isArraysEqual<i32>(sarr.splice(-2, 1), <i32[]>[4]));
361+
assert(isArraysEqual<i32>(sarr, <i32[]>[1, 2, 3, 5]));
362+
363+
sarr = <i32[]>[1, 2, 3, 4, 5];
364+
assert(isArraysEqual<i32>(sarr.splice(-7, 1), <i32[]>[1]));
365+
assert(isArraysEqual<i32>(sarr, <i32[]>[2, 3, 4, 5]));
366+
367+
sarr = <i32[]>[1, 2, 3, 4, 5];
368+
assert(isArraysEqual<i32>(sarr.splice(-2, -1), <i32[]>[]));
369+
assert(isArraysEqual<i32>(sarr, <i32[]>[1, 2, 3, 4, 5]));
370+
371+
sarr = <i32[]>[1, 2, 3, 4, 5];
372+
assert(isArraysEqual<i32>(sarr.splice(1, -2), <i32[]>[]));
373+
assert(isArraysEqual<i32>(sarr, <i32[]>[1, 2, 3, 4, 5]));
374+
375+
sarr = <i32[]>[1, 2, 3, 4, 5];
376+
assert(isArraysEqual<i32>(sarr.splice(4, 0), <i32[]>[]));
377+
assert(isArraysEqual<i32>(sarr, <i32[]>[1, 2, 3, 4, 5]));
378+
379+
sarr = <i32[]>[1, 2, 3, 4, 5];
380+
assert(isArraysEqual<i32>(sarr.splice(7, 0), <i32[]>[]));
381+
assert(isArraysEqual<i32>(sarr, <i32[]>[1, 2, 3, 4, 5]));
382+
383+
sarr = <i32[]>[1, 2, 3, 4, 5];
384+
assert(isArraysEqual<i32>(sarr.splice(7, 5), <i32[]>[]));
385+
assert(isArraysEqual<i32>(sarr, <i32[]>[1, 2, 3, 4, 5]));
386+
333387
// Array#findIndex /////////////////////////////////////////////////////////////////////////////////
334388

335389
arr[0] = 0;

0 commit comments

Comments
 (0)