diff --git a/std/assembly/array.ts b/std/assembly/array.ts index cc54a6be57..4d7fdfb989 100644 --- a/std/assembly/array.ts +++ b/std/assembly/array.ts @@ -34,7 +34,7 @@ export class Array { // block is 16 bytes anyway so it's fine to have a couple extra fields in there. private buffer: ArrayBuffer; - private dataStart: usize; + @unsafe readonly dataStart: usize; private byteLength: i32; // Also note that Array with non-nullable T must guard against uninitialized null values @@ -395,7 +395,7 @@ export class Array { var length = this.length_; start = start < 0 ? max(length + start, 0) : min(start, length); deleteCount = max(min(deleteCount, length - start), 0); - var result = changetype>(__newArray(deleteCount, alignof(), idof>())); + var result = changetype>(__newArray(deleteCount, alignof(), idof>())); var resultStart = result.dataStart; var thisStart = this.dataStart; var thisBase = thisStart + (start << alignof()); diff --git a/std/assembly/index.d.ts b/std/assembly/index.d.ts index d33ed93d55..2f149c6e4c 100644 --- a/std/assembly/index.d.ts +++ b/std/assembly/index.d.ts @@ -1459,6 +1459,8 @@ interface ArrayBufferView { readonly byteOffset: i32; /** The length in bytes from the start of the referenced {@link ArrayBuffer}. */ readonly byteLength: i32; + /** Returns raw pointer to data storage including offset (unsafe). */ + readonly dataStart: usize; } /* @internal */ @@ -1474,6 +1476,8 @@ declare abstract class TypedArray implements ArrayBufferView { readonly byteOffset: i32; /** The length in bytes from the start of the referenced {@link ArrayBuffer}. */ readonly byteLength: i32; + /** Returns raw pointer to data storage including offset (unsafe). */ + readonly dataStart: usize; /** The length (in elements). */ readonly length: i32; /** Returns value using relative indexing. Index may be negative */ @@ -1585,6 +1589,8 @@ declare class Array { [key: number]: T; /** Current length of the array. */ length: i32; + /** Returns raw pointer to data storage (unsafe). */ + readonly dataStart: usize; /** Constructs a new array. */ constructor(length?: i32); at(index: i32): T; diff --git a/tests/compiler/std/array.optimized.wat b/tests/compiler/std/array.optimized.wat index 1496959a36..c1e01485ea 100644 --- a/tests/compiler/std/array.optimized.wat +++ b/tests/compiler/std/array.optimized.wat @@ -590,6 +590,7 @@ (export "memory" (memory $0)) (export "__setArgumentsLength" (func $~setArgumentsLength)) (export "_start" (func $~start)) + (export "ArrayU32#get:dataStart" (func $export:~lib/array/Array#get:dataStart)) (export "ArrayU32#constructor" (func $export:std/array/ArrayU32#constructor@varargs)) (export "ArrayU32#get:length" (func $export:~lib/array/Array#get:length)) (export "ArrayU32#set:length" (func $export:~lib/array/Array#set:length)) @@ -616,6 +617,7 @@ (export "ArrayU32#join" (func $export:~lib/array/Array#join@varargs)) (export "ArrayU32#flat" (func $export:~lib/array/Array#flat)) (export "ArrayU32#toString" (func $export:~lib/array/Array#toString)) + (export "ArrayU8#get:dataStart" (func $export:~lib/array/Array#get:dataStart)) (export "ArrayU8#constructor" (func $export:std/array/ArrayU8#constructor@varargs)) (export "ArrayU8#get:length" (func $export:~lib/array/Array#get:length)) (export "ArrayU8#set:length" (func $export:~lib/array/Array#set:length)) @@ -642,6 +644,7 @@ (export "ArrayU8#join" (func $export:~lib/array/Array#join@varargs)) (export "ArrayU8#flat" (func $export:~lib/array/Array#flat)) (export "ArrayU8#toString" (func $export:~lib/array/Array#toString)) + (export "ArrayStr#get:dataStart" (func $export:~lib/array/Array#get:dataStart)) (export "ArrayStr#constructor" (func $export:std/array/ArrayStr#constructor@varargs)) (export "ArrayStr#get:length" (func $export:~lib/array/Array#get:length)) (export "ArrayStr#set:length" (func $export:~lib/array/Array#set:length)) @@ -22236,6 +22239,22 @@ global.set $~lib/memory/__stack_pointer local.get $4 ) + (func $export:~lib/array/Array#get:dataStart (param $0 i32) (result i32) + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.sub + global.set $~lib/memory/__stack_pointer + call $~stack_check + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store + local.get $0 + i32.load offset=4 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + ) (func $export:std/array/ArrayU32#constructor@varargs (param $0 i32) (param $1 i32) (result i32) global.get $~lib/memory/__stack_pointer i32.const 4 diff --git a/tests/compiler/std/array.untouched.wat b/tests/compiler/std/array.untouched.wat index 80cbbbafdb..1a004e5f65 100644 --- a/tests/compiler/std/array.untouched.wat +++ b/tests/compiler/std/array.untouched.wat @@ -351,6 +351,7 @@ (export "memory" (memory $0)) (export "__setArgumentsLength" (func $~setArgumentsLength)) (export "_start" (func $~start)) + (export "ArrayU32#get:dataStart" (func $export:~lib/array/Array#get:dataStart)) (export "ArrayU32#constructor" (func $export:std/array/ArrayU32#constructor@varargs)) (export "ArrayU32#get:length" (func $export:~lib/array/Array#get:length)) (export "ArrayU32#set:length" (func $export:~lib/array/Array#set:length)) @@ -377,6 +378,7 @@ (export "ArrayU32#join" (func $export:~lib/array/Array#join@varargs)) (export "ArrayU32#flat" (func $export:~lib/array/Array#flat)) (export "ArrayU32#toString" (func $export:~lib/array/Array#toString)) + (export "ArrayU8#get:dataStart" (func $export:~lib/array/Array#get:dataStart)) (export "ArrayU8#constructor" (func $export:std/array/ArrayU8#constructor@varargs)) (export "ArrayU8#get:length" (func $export:~lib/array/Array#get:length)) (export "ArrayU8#set:length" (func $export:~lib/array/Array#set:length)) @@ -403,6 +405,7 @@ (export "ArrayU8#join" (func $export:~lib/array/Array#join@varargs)) (export "ArrayU8#flat" (func $export:~lib/array/Array#flat)) (export "ArrayU8#toString" (func $export:~lib/array/Array#toString)) + (export "ArrayStr#get:dataStart" (func $export:~lib/array/Array<~lib/string/String>#get:dataStart)) (export "ArrayStr#constructor" (func $export:std/array/ArrayStr#constructor@varargs)) (export "ArrayStr#get:length" (func $export:~lib/array/Array<~lib/string/String>#get:length)) (export "ArrayStr#set:length" (func $export:~lib/array/Array<~lib/string/String>#set:length)) @@ -35312,6 +35315,25 @@ global.set $~lib/memory/__stack_pointer local.get $2 ) + (func $export:~lib/array/Array#get:dataStart (param $0 i32) (result i32) + (local $1 i32) + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.sub + global.set $~lib/memory/__stack_pointer + call $~stack_check + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store + local.get $0 + call $~lib/array/Array#get:dataStart + local.set $1 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $1 + ) (func $export:std/array/ArrayU32#constructor@varargs (param $0 i32) (param $1 i32) (result i32) (local $2 i32) global.get $~lib/memory/__stack_pointer @@ -35853,6 +35875,25 @@ global.set $~lib/memory/__stack_pointer local.get $1 ) + (func $export:~lib/array/Array#get:dataStart (param $0 i32) (result i32) + (local $1 i32) + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.sub + global.set $~lib/memory/__stack_pointer + call $~stack_check + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store + local.get $0 + call $~lib/array/Array#get:dataStart + local.set $1 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $1 + ) (func $export:std/array/ArrayU8#constructor@varargs (param $0 i32) (param $1 i32) (result i32) (local $2 i32) global.get $~lib/memory/__stack_pointer @@ -36394,6 +36435,25 @@ global.set $~lib/memory/__stack_pointer local.get $1 ) + (func $export:~lib/array/Array<~lib/string/String>#get:dataStart (param $0 i32) (result i32) + (local $1 i32) + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.sub + global.set $~lib/memory/__stack_pointer + call $~stack_check + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store + local.get $0 + call $~lib/array/Array<~lib/string/String>#get:dataStart + local.set $1 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $1 + ) (func $export:std/array/ArrayStr#constructor@varargs (param $0 i32) (param $1 i32) (result i32) (local $2 i32) global.get $~lib/memory/__stack_pointer