Skip to content

Commit

Permalink
Implement TypedArray#copyWithin (#830)
Browse files Browse the repository at this point in the history
  • Loading branch information
MaxGraey authored and dcodeIO committed Sep 9, 2019
1 parent c65a056 commit 19d06a3
Show file tree
Hide file tree
Showing 8 changed files with 3,506 additions and 2,218 deletions.
2 changes: 1 addition & 1 deletion examples/n-body/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"tsbuild": "tsc -p assembly -t ES2017 -m commonjs --outDir build",
"build": "npm run asbuild && npm run tsbuild",
"server": "http-server . -o -c-1",
"test": "node --noliftoff --nowasm-tier-up --wasm-lazy-compilation --wasm-no-bounds-checks --expose-gc tests"
"test": "node --wasm-lazy-compilation --wasm-no-bounds-checks --expose-gc tests"
},
"devDependencies": {
"http-server": "^0.11.1",
Expand Down
2 changes: 2 additions & 0 deletions std/assembly/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1141,6 +1141,8 @@ declare abstract class TypedArray<T> implements ArrayBufferView<T> {
slice(begin?: i32, end?: i32): TypedArray<T>;
/** Returns a new TypedArray of this type on the same ArrayBuffer from begin inclusive to end exclusive. */
subarray(begin?: i32, end?: i32): TypedArray<T>;
/** The copyWithin() method copies the sequence of array elements within the array to the position starting at target. The copy is taken from the index positions of the second and third arguments start and end. The end argument is optional and defaults to the length of the array. */
copyWithin(target: i32, start: i32, end?: i32): this;
/** The reduce() method applies a function against an accumulator and each value of the typed array (from left-to-right) has to reduce it to a single value. This method has the same algorithm as Array.prototype.reduce(). */
reduce<U>(callbackfn: (accumulator: U, value: T, index: i32, self: this) => U, initialValue: U): U;
/** The reduceRight() method applies a function against an accumulator and each value of the typed array (from left-to-right) has to reduce it to a single value, starting from the end of the array. This method has the same algorithm as Array.prototype.reduceRight(). */
Expand Down
69 changes: 69 additions & 0 deletions std/assembly/typedarray.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@ export class Int8Array extends ArrayBufferView {
return SUBARRAY<Int8Array, i8>(this, begin, end);
}

copyWithin(target: i32, start: i32, end: i32 = i32.MAX_VALUE): Int8Array {
return COPY_WITHIN<Int8Array, i8>(this, target, start, end);
}

reduce<T>(
fn: (accumulator: T, value: i8, index: i32, array: Int8Array) => T,
initialValue: T,
Expand Down Expand Up @@ -188,6 +192,10 @@ export class Uint8Array extends ArrayBufferView {
return SUBARRAY<Uint8Array, u8>(this, begin, end);
}

copyWithin(target: i32, start: i32, end: i32 = i32.MAX_VALUE): Uint8Array {
return COPY_WITHIN<Uint8Array, u8>(this, target, start, end);
}

reduce<T>(
fn: (accumulator: T, value: u8, index: i32, array: Uint8Array) => T,
initialValue: T,
Expand Down Expand Up @@ -304,6 +312,10 @@ export class Uint8ClampedArray extends ArrayBufferView {
return SUBARRAY<Uint8ClampedArray, u8>(this, start, end);
}

copyWithin(target: i32, start: i32, end: i32 = i32.MAX_VALUE): Uint8ClampedArray {
return COPY_WITHIN<Uint8ClampedArray, u8>(this, target, start, end);
}

reduce<T>(
fn: (accumulator: T, value: u8, index: i32, array: Uint8ClampedArray) => T,
initialValue: T,
Expand Down Expand Up @@ -420,6 +432,10 @@ export class Int16Array extends ArrayBufferView {
return SUBARRAY<Int16Array, i16>(this, begin, end);
}

copyWithin(target: i32, start: i32, end: i32 = i32.MAX_VALUE): Int16Array {
return COPY_WITHIN<Int16Array, i16>(this, target, start, end);
}

reduce<T>(
fn: (accumulator: T, value: i16, index: i32, array: Int16Array) => T,
initialValue: T,
Expand Down Expand Up @@ -536,6 +552,10 @@ export class Uint16Array extends ArrayBufferView {
return SUBARRAY<Uint16Array, u16>(this, begin, end);
}

copyWithin(target: i32, start: i32, end: i32 = i32.MAX_VALUE): Uint16Array {
return COPY_WITHIN<Uint16Array, u16>(this, target, start, end);
}

reduce<T>(
fn: (accumulator: T, value: u16, index: i32, array: Uint16Array) => T,
initialValue: T,
Expand Down Expand Up @@ -652,6 +672,10 @@ export class Int32Array extends ArrayBufferView {
return SUBARRAY<Int32Array, i32>(this, begin, end);
}

copyWithin(target: i32, start: i32, end: i32 = i32.MAX_VALUE): Int32Array {
return COPY_WITHIN<Int32Array, i32>(this, target, start, end);
}

reduce<T>(
fn: (accumulator: T, value: i32, index: i32, array: Int32Array) => T,
initialValue: T,
Expand Down Expand Up @@ -768,6 +792,10 @@ export class Uint32Array extends ArrayBufferView {
return SUBARRAY<Uint32Array, u32>(this, begin, end);
}

copyWithin(target: i32, start: i32, end: i32 = i32.MAX_VALUE): Uint32Array {
return COPY_WITHIN<Uint32Array, u32>(this, target, start, end);
}

reduce<T>(
fn: (accumulator: T, value: u32, index: i32, array: Uint32Array) => T,
initialValue: T,
Expand Down Expand Up @@ -884,6 +912,10 @@ export class Int64Array extends ArrayBufferView {
return SUBARRAY<Int64Array, i64>(this, begin, end);
}

copyWithin(target: i32, start: i32, end: i32 = i32.MAX_VALUE): Int64Array {
return COPY_WITHIN<Int64Array, i64>(this, target, start, end);
}

reduce<T>(
fn: (accumulator: T, value: i64, index: i32, array: Int64Array) => T,
initialValue: T,
Expand Down Expand Up @@ -1000,6 +1032,10 @@ export class Uint64Array extends ArrayBufferView {
return SUBARRAY<Uint64Array, u64>(this, begin, end);
}

copyWithin(target: i32, start: i32, end: i32 = i32.MAX_VALUE): Uint64Array {
return COPY_WITHIN<Uint64Array, u64>(this, target, start, end);
}

reduce<T>(
fn: (accumulator: T, value: u64, index: i32, array: Uint64Array) => T,
initialValue: T,
Expand Down Expand Up @@ -1116,6 +1152,10 @@ export class Float32Array extends ArrayBufferView {
return SUBARRAY<Float32Array, f32>(this, begin, end);
}

copyWithin(target: i32, start: i32, end: i32 = i32.MAX_VALUE): Float32Array {
return COPY_WITHIN<Float32Array, f32>(this, target, start, end);
}

reduce<T>(
fn: (accumulator: T, value: f32, index: i32, array: Float32Array) => T,
initialValue: T,
Expand Down Expand Up @@ -1232,6 +1272,10 @@ export class Float64Array extends ArrayBufferView {
return SUBARRAY<Float64Array, f64>(this, begin, end);
}

copyWithin(target: i32, start: i32, end: i32 = i32.MAX_VALUE): Float64Array {
return COPY_WITHIN<Float64Array, f64>(this, target, start, end);
}

reduce<T>(
fn: (accumulator: T, value: f64, index: i32, array: Float64Array) => T,
initialValue: T,
Expand Down Expand Up @@ -1361,6 +1405,31 @@ function SUBARRAY<TArray extends ArrayBufferView, T>(
return out;
}

// @ts-ignore: decorator
@inline
function COPY_WITHIN<TArray extends ArrayBufferView, T>(
array: TArray,
target: i32,
start: i32,
end: i32
): TArray {
var len = array.length;
var dataStart = array.dataStart;

end = min<i32>(end, len);
var to = target < 0 ? max(len + target, 0) : min(target, len);
var from = start < 0 ? max(len + start, 0) : min(start, len);
var last = end < 0 ? max(len + end, 0) : min(end, len);
var count = min(last - from, len - to);

memory.copy(
dataStart + (<usize>to << alignof<T>()),
dataStart + (<usize>from << alignof<T>()),
<usize>count << alignof<T>()
);
return array;
}

// @ts-ignore: decorator
@inline
function REDUCE<TArray extends ArrayBufferView, T, TRet>(
Expand Down
2 changes: 1 addition & 1 deletion tests/compiler/std/dataview.optimized.wat
Original file line number Diff line number Diff line change
Expand Up @@ -1634,7 +1634,7 @@
if
i32.const 280
i32.const 376
i32.const 154
i32.const 158
i32.const 44
call $~lib/builtins/abort
unreachable
Expand Down
2 changes: 1 addition & 1 deletion tests/compiler/std/dataview.untouched.wat
Original file line number Diff line number Diff line change
Expand Up @@ -3327,7 +3327,7 @@
if
i32.const 280
i32.const 376
i32.const 154
i32.const 158
i32.const 44
call $~lib/builtins/abort
unreachable
Expand Down
Loading

0 comments on commit 19d06a3

Please sign in to comment.