@@ -31,9 +31,9 @@ export class Array<T> extends ArrayBufferView {
3131 // to work with typed and normal arrays interchangeably. Technically, normal arrays do not need
3232 // `dataStart` (equals `data`) and `dataLength` (equals computed `data.byteLength`).
3333
34- // Also note that Array<T> with non-nullable T must guard against implicit null values whenever
35- // length is modified in a way that a null value would exist . Otherwise, the compiler wouldn't be
36- // able to guarantee type-safety anymore. For lack of a better word, such an array is "holey".
34+ // Also note that Array<T> with non-nullable T must guard against uninitialized null values
35+ // whenever an element is accessed . Otherwise, the compiler wouldn't be able to guarantee
36+ // type-safety anymore. For lack of a better word, such an array is "holey".
3737
3838 private length_ : i32 ;
3939
@@ -42,20 +42,14 @@ export class Array<T> extends ArrayBufferView {
4242 }
4343
4444 static create < T > ( capacity : i32 = 0 ) : Array < T > {
45- if ( < u32 > capacity > < u32 > BLOCK_MAXSIZE >>> alignof < T > ( ) ) throw new RangeError ( E_INVALIDLENGTH ) ;
46- var array = changetype < Array < T > > ( __allocArray ( capacity , alignof < T > ( ) , idof < T [ ] > ( ) ) ) ; // retains
47- changetype < Array < T > > ( array ) . length_ = 0 ; // safe even if T is a non-nullable reference
48- memory . fill ( array . dataStart , 0 , < usize > array . dataLength ) ;
45+ WARNING ( "'Array.create' is deprecated. Use 'new Array' instead, making sure initial elements are initialized." ) ;
46+ var array = new Array < T > ( capacity ) ;
47+ array . length = 0 ;
4948 return array ;
5049 }
5150
5251 constructor ( length : i32 = 0 ) {
5352 super ( length , alignof < T > ( ) ) ;
54- if ( isReference < T > ( ) ) {
55- if ( ! isNullable < T > ( ) ) {
56- if ( length ) throw new Error ( E_HOLEYARRAY ) ;
57- }
58- }
5953 this . length_ = length ;
6054 }
6155
@@ -69,19 +63,17 @@ export class Array<T> extends ArrayBufferView {
6963
7064 set length ( newLength : i32 ) {
7165 var oldLength = this . length_ ;
72- if ( isReference < T > ( ) ) {
73- if ( ! isNullable < T > ( ) ) {
74- if ( < u32 > newLength > < u32 > oldLength ) throw new Error ( E_HOLEYARRAY ) ;
75- }
76- }
77- ensureSize ( changetype < usize > ( this ) , newLength , alignof < T > ( ) ) ;
78- if ( isManaged < T > ( ) ) { // release no longer used refs
79- if ( oldLength > newLength ) {
80- let dataStart = this . dataStart ;
81- do __release ( load < usize > ( dataStart + ( < usize > -- oldLength << alignof < T > ( ) ) ) ) ;
82- while ( oldLength > newLength ) ;
83- // no need to zero memory on shrink -> is zeroed on grow
66+ if ( isManaged < T > ( ) ) {
67+ if ( oldLength > newLength ) { // release no longer used refs
68+ let cur = ( < usize > newLength << alignof < T > ( ) ) ;
69+ let end = ( < usize > oldLength << alignof < T > ( ) ) ;
70+ do __release ( load < usize > ( cur ) ) ;
71+ while ( ( cur += sizeof < T > ( ) ) < end ) ;
72+ } else {
73+ ensureSize ( changetype < usize > ( this ) , newLength , alignof < T > ( ) ) ;
8474 }
75+ } else {
76+ ensureSize ( changetype < usize > ( this ) , newLength , alignof < T > ( ) ) ;
8577 }
8678 this . length_ = newLength ;
8779 }
@@ -101,35 +93,30 @@ export class Array<T> extends ArrayBufferView {
10193 }
10294
10395 @operator ( "[]" ) private __get ( index : i32 ) : T {
96+ if ( < u32 > index >= < u32 > this . length_ ) throw new RangeError ( E_INDEXOUTOFRANGE ) ;
97+ var value = this . __unchecked_get ( index ) ;
10498 if ( isReference < T > ( ) ) {
10599 if ( ! isNullable < T > ( ) ) {
106- if ( < u32 > index >= < u32 > this . length_ ) throw new Error ( E_HOLEYARRAY ) ;
100+ if ( ! changetype < usize > ( value ) ) throw new Error ( E_HOLEYARRAY ) ;
107101 }
108102 }
109- if ( < u32 > index >= < u32 > this . dataLength >>> alignof < T > ( ) ) throw new RangeError ( E_INDEXOUTOFRANGE ) ;
110- return this . __unchecked_get ( index ) ;
103+ return value ;
111104 }
112105
113- @operator ( "{}" ) private __unchecked_get ( index : i32 ) : T {
106+ @unsafe @ operator ( "{}" ) private __unchecked_get ( index : i32 ) : T {
114107 return load < T > ( this . dataStart + ( < usize > index << alignof < T > ( ) ) ) ;
115108 }
116109
117110 @operator ( "[]=" ) private __set ( index : i32 , value : T ) : void {
118- var length = this . length_ ;
119- if ( isReference < T > ( ) ) {
120- if ( ! isNullable < T > ( ) ) {
121- if ( < u32 > index > < u32 > length ) throw new Error ( E_HOLEYARRAY ) ;
122- }
123- }
124111 ensureSize ( changetype < usize > ( this ) , index + 1 , alignof < T > ( ) ) ;
125112 this . __unchecked_set ( index , value ) ;
126- if ( index >= length ) this . length_ = index + 1 ;
113+ if ( index >= this . length_ ) this . length_ = index + 1 ;
127114 }
128115
129- @operator ( "{}=" ) private __unchecked_set ( index : i32 , value : T ) : void {
116+ @unsafe @ operator ( "{}=" ) private __unchecked_set ( index : i32 , value : T ) : void {
130117 if ( isManaged < T > ( ) ) {
131118 let offset = this . dataStart + ( < usize > index << alignof < T > ( ) ) ;
132- let oldRef : usize = load < usize > ( offset ) ;
119+ let oldRef = load < usize > ( offset ) ;
133120 if ( changetype < usize > ( value ) != oldRef ) {
134121 store < usize > ( offset , __retain ( changetype < usize > ( value ) ) ) ;
135122 __release ( oldRef ) ;
0 commit comments