diff --git a/std/assembly/internal/typedarray.ts b/std/assembly/internal/typedarray.ts index a129dfeb..e901267a 100644 --- a/std/assembly/internal/typedarray.ts +++ b/std/assembly/internal/typedarray.ts @@ -90,7 +90,7 @@ export abstract class TypedArray { else end = max(min(end, length), begin); var slice = memory.allocate(offsetof()); store(slice, this.buffer, offsetof("buffer")); - store(slice, begin << alignof(), offsetof("byteOffset")); + store(slice, this.byteOffset + (begin << alignof()), offsetof("byteOffset")); store(slice, (end - begin) << alignof(), offsetof("byteLength")); return changetype(slice); } diff --git a/tests/compiler/std/typedarray.ts b/tests/compiler/std/typedarray.ts index 30545a91..6c583867 100644 --- a/tests/compiler/std/typedarray.ts +++ b/tests/compiler/std/typedarray.ts @@ -199,3 +199,29 @@ import { MAX_BLENGTH } from "internal/arraybuffer"; const MAX_F64LENGTH = MAX_BLENGTH >> alignof(); new Float64Array(MAX_F64LENGTH); // 1GB // new Float64Array(MAX_F64 + 1); // throws + +var multisubarr = new Int8Array(6); +multisubarr[0] = 1; +multisubarr[1] = 2; +multisubarr[2] = 3; +multisubarr[3] = 4; +multisubarr[4] = 5; +multisubarr[5] = 6; + +var multisubarr1 = multisubarr.subarray(1, 6); +assert(multisubarr1[0] === 2); +assert(multisubarr1.length === 5); +assert(multisubarr1.byteOffset === 1); +assert(multisubarr1.byteLength === 5); + +var multisubarr2 = multisubarr1.subarray(1, 5); +assert(multisubarr2[0] === 3); +assert(multisubarr2.length === 4); +assert(multisubarr2.byteOffset === 2); +assert(multisubarr2.byteLength === 4); + +var multisubarr3 = multisubarr2.subarray(1, 4); +assert(multisubarr3[0] === 4); +assert(multisubarr3.length === 3); +assert(multisubarr3.byteOffset === 3); +assert(multisubarr3.byteLength === 3); diff --git a/tests/compiler/std/typedarray.untouched.wat b/tests/compiler/std/typedarray.untouched.wat index 0b76b80a..c68919af 100644 --- a/tests/compiler/std/typedarray.untouched.wat +++ b/tests/compiler/std/typedarray.untouched.wat @@ -74,6 +74,10 @@ (global $std/typedarray/arr32 (mut i32) (i32.const 0)) (global $std/typedarray/sub32 (mut i32) (i32.const 0)) (global $std/typedarray/MAX_F64LENGTH i32 (i32.const 134217727)) + (global $std/typedarray/multisubarr (mut i32) (i32.const 0)) + (global $std/typedarray/multisubarr1 (mut i32) (i32.const 0)) + (global $std/typedarray/multisubarr2 (mut i32) (i32.const 0)) + (global $std/typedarray/multisubarr3 (mut i32) (i32.const 0)) (global $HEAP_BASE i32 (i32.const 624)) (export "memory" (memory $0)) (export "table" (table $0)) @@ -1831,9 +1835,12 @@ i32.load i32.store get_local $4 + get_local $0 + i32.load offset=4 get_local $1 i32.const 2 i32.shl + i32.add i32.store offset=4 get_local $4 get_local $2 @@ -1962,9 +1969,12 @@ i32.load i32.store get_local $4 + get_local $0 + i32.load offset=4 get_local $1 i32.const 3 i32.shl + i32.add i32.store offset=4 get_local $4 get_local $2 @@ -3173,9 +3183,12 @@ i32.load i32.store get_local $4 + get_local $0 + i32.load offset=4 get_local $1 i32.const 0 i32.shl + i32.add i32.store offset=4 get_local $4 get_local $2 @@ -4335,6 +4348,238 @@ get_global $std/typedarray/MAX_F64LENGTH call $~lib/internal/typedarray/TypedArray#constructor drop + i32.const 0 + i32.const 6 + call $~lib/internal/typedarray/TypedArray#constructor + set_global $std/typedarray/multisubarr + get_global $std/typedarray/multisubarr + i32.const 0 + i32.const 1 + call $~lib/internal/typedarray/TypedArray#__set + get_global $std/typedarray/multisubarr + i32.const 1 + i32.const 2 + call $~lib/internal/typedarray/TypedArray#__set + get_global $std/typedarray/multisubarr + i32.const 2 + i32.const 3 + call $~lib/internal/typedarray/TypedArray#__set + get_global $std/typedarray/multisubarr + i32.const 3 + i32.const 4 + call $~lib/internal/typedarray/TypedArray#__set + get_global $std/typedarray/multisubarr + i32.const 4 + i32.const 5 + call $~lib/internal/typedarray/TypedArray#__set + get_global $std/typedarray/multisubarr + i32.const 5 + i32.const 6 + call $~lib/internal/typedarray/TypedArray#__set + get_global $std/typedarray/multisubarr + i32.const 1 + i32.const 6 + call $~lib/typedarray/Int8Array#subarray + set_global $std/typedarray/multisubarr1 + get_global $std/typedarray/multisubarr1 + i32.const 0 + call $~lib/internal/typedarray/TypedArray#__get + i32.const 24 + i32.shl + i32.const 24 + i32.shr_s + i32.const 2 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 8 + i32.const 212 + i32.const 0 + call $~lib/env/abort + unreachable + end + block $~lib/internal/typedarray/TypedArray#get:length|inlined.7 (result i32) + get_global $std/typedarray/multisubarr1 + set_local $0 + get_local $0 + i32.load offset=8 + i32.const 0 + i32.shr_u + end + i32.const 5 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 8 + i32.const 213 + i32.const 0 + call $~lib/env/abort + unreachable + end + get_global $std/typedarray/multisubarr1 + i32.load offset=4 + i32.const 1 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 8 + i32.const 214 + i32.const 0 + call $~lib/env/abort + unreachable + end + get_global $std/typedarray/multisubarr1 + i32.load offset=8 + i32.const 5 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 8 + i32.const 215 + i32.const 0 + call $~lib/env/abort + unreachable + end + get_global $std/typedarray/multisubarr1 + i32.const 1 + i32.const 5 + call $~lib/typedarray/Int8Array#subarray + set_global $std/typedarray/multisubarr2 + get_global $std/typedarray/multisubarr2 + i32.const 0 + call $~lib/internal/typedarray/TypedArray#__get + i32.const 24 + i32.shl + i32.const 24 + i32.shr_s + i32.const 3 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 8 + i32.const 218 + i32.const 0 + call $~lib/env/abort + unreachable + end + block $~lib/internal/typedarray/TypedArray#get:length|inlined.8 (result i32) + get_global $std/typedarray/multisubarr2 + set_local $0 + get_local $0 + i32.load offset=8 + i32.const 0 + i32.shr_u + end + i32.const 4 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 8 + i32.const 219 + i32.const 0 + call $~lib/env/abort + unreachable + end + get_global $std/typedarray/multisubarr2 + i32.load offset=4 + i32.const 2 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 8 + i32.const 220 + i32.const 0 + call $~lib/env/abort + unreachable + end + get_global $std/typedarray/multisubarr2 + i32.load offset=8 + i32.const 4 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 8 + i32.const 221 + i32.const 0 + call $~lib/env/abort + unreachable + end + get_global $std/typedarray/multisubarr2 + i32.const 1 + i32.const 4 + call $~lib/typedarray/Int8Array#subarray + set_global $std/typedarray/multisubarr3 + get_global $std/typedarray/multisubarr3 + i32.const 0 + call $~lib/internal/typedarray/TypedArray#__get + i32.const 24 + i32.shl + i32.const 24 + i32.shr_s + i32.const 4 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 8 + i32.const 224 + i32.const 0 + call $~lib/env/abort + unreachable + end + block $~lib/internal/typedarray/TypedArray#get:length|inlined.9 (result i32) + get_global $std/typedarray/multisubarr3 + set_local $0 + get_local $0 + i32.load offset=8 + i32.const 0 + i32.shr_u + end + i32.const 3 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 8 + i32.const 225 + i32.const 0 + call $~lib/env/abort + unreachable + end + get_global $std/typedarray/multisubarr3 + i32.load offset=4 + i32.const 3 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 8 + i32.const 226 + i32.const 0 + call $~lib/env/abort + unreachable + end + get_global $std/typedarray/multisubarr3 + i32.load offset=8 + i32.const 3 + i32.eq + i32.eqz + if + i32.const 0 + i32.const 8 + i32.const 227 + i32.const 0 + call $~lib/env/abort + unreachable + end ) (func $null (; 44 ;) (type $v) )