@@ -27,11 +27,19 @@ import {
2727 MAX_DOUBLE_LENGTH
2828} from "./internal/number" ;
2929
30+ import {
31+ isArray as builtin_isArray
32+ } from "./builtins" ;
33+
3034export class Array < T > {
3135
3236 /* @internal */ buffer_ : ArrayBuffer ;
3337 /* @internal */ length_ : i32 ;
3438
39+ @inline static isArray < U > ( value : U ) : bool {
40+ return builtin_isArray ( value ) && value !== null ;
41+ }
42+
3543 constructor ( length : i32 = 0 ) {
3644 const MAX_LENGTH = MAX_BLENGTH >>> alignof < T > ( ) ;
3745 if ( < u32 > length > < u32 > MAX_LENGTH ) throw new RangeError ( "Invalid array length" ) ;
@@ -116,8 +124,10 @@ export class Array<T> {
116124 fill ( value : T , start : i32 = 0 , end : i32 = i32 . MAX_VALUE ) : this {
117125 var buffer = this . buffer_ ;
118126 var len = this . length_ ;
127+
119128 start = start < 0 ? max ( len + start , 0 ) : min ( start , len ) ;
120129 end = end < 0 ? max ( len + end , 0 ) : min ( end , len ) ;
130+
121131 if ( sizeof < T > ( ) == 1 ) {
122132 if ( start < end ) {
123133 memory . fill (
@@ -182,24 +192,55 @@ export class Array<T> {
182192 }
183193
184194 concat ( items : Array < T > ) : Array < T > {
185- var thisLen : isize = this . length_ ;
186- var otherLen = ( items == null ) ? 0 : items . length_ ;
187- var outLen = thisLen + otherLen ;
188- var out : Array < T > = new Array < T > ( outLen ) ;
195+ var thisLen = this . length_ ;
196+ var otherLen = items === null ? 0 : items . length_ ;
197+ var outLen = thisLen + otherLen ;
198+ var out = new Array < T > ( outLen ) ;
189199
190200 if ( thisLen ) {
191- memory . copy ( changetype < usize > ( out . buffer_ ) + HEADER_SIZE ,
192- changetype < usize > ( this . buffer_ ) + HEADER_SIZE ,
193- < usize > ( thisLen << alignof < T > ( ) ) ) ;
201+ memory . copy (
202+ changetype < usize > ( out . buffer_ ) + HEADER_SIZE ,
203+ changetype < usize > ( this . buffer_ ) + HEADER_SIZE ,
204+ < usize > thisLen << alignof < T > ( )
205+ ) ;
194206 }
195207 if ( otherLen ) {
196- memory . copy ( changetype < usize > ( out . buffer_ ) + HEADER_SIZE + < usize > ( thisLen << alignof < T > ( ) ) ,
197- changetype < usize > ( items . buffer_ ) + HEADER_SIZE ,
198- < usize > ( otherLen << alignof < T > ( ) ) ) ;
208+ memory . copy (
209+ changetype < usize > ( out . buffer_ ) + HEADER_SIZE + ( < usize > thisLen << alignof < T > ( ) ) ,
210+ changetype < usize > ( items . buffer_ ) + HEADER_SIZE ,
211+ < usize > otherLen << alignof < T > ( )
212+ ) ;
199213 }
200214 return out ;
201215 }
202216
217+ copyWithin ( target : i32 , start : i32 , end : i32 = i32 . MAX_VALUE ) : this {
218+ var buffer = this . buffer_ ;
219+ var len = this . length_ ;
220+
221+ end = min < i32 > ( end , len ) ;
222+ var to = target < 0 ? max ( len + target , 0 ) : min ( target , len ) ;
223+ var from = start < 0 ? max ( len + start , 0 ) : min ( start , len ) ;
224+ var last = end < 0 ? max ( len + end , 0 ) : min ( end , len ) ;
225+ var count = min ( last - from , len - to ) ;
226+
227+ if ( from < to && to < ( from + count ) ) {
228+ from += count - 1 ;
229+ to += count - 1 ;
230+ while ( count ) {
231+ storeUnsafe < T , T > ( buffer , to , loadUnsafe < T , T > ( buffer , from ) ) ;
232+ -- from , -- to , -- count ;
233+ }
234+ } else {
235+ memory . copy (
236+ changetype < usize > ( buffer ) + HEADER_SIZE + ( < usize > to << alignof < T > ( ) ) ,
237+ changetype < usize > ( buffer ) + HEADER_SIZE + ( < usize > from << alignof < T > ( ) ) ,
238+ < usize > count << alignof < T > ( )
239+ ) ;
240+ }
241+ return this ;
242+ }
243+
203244 pop ( ) : T {
204245 var length = this . length_ ;
205246 if ( length < 1 ) throw new RangeError ( "Array is empty" ) ;
@@ -309,6 +350,7 @@ export class Array<T> {
309350 }
310351
311352 slice ( begin : i32 = 0 , end : i32 = i32 . MAX_VALUE ) : Array < T > {
353+ var len = this . length_ ;
312354 var length = this . length_ ;
313355 if ( begin < 0 ) begin = max ( length + begin , 0 ) ;
314356 else if ( begin > length ) begin = length ;
0 commit comments