@@ -17,14 +17,44 @@ export function computeSize(byteLength: i32): usize {
1717 return < usize > 1 << < usize > ( < u32 > 32 - clz < u32 > ( byteLength + HEADER_SIZE - 1 ) ) ;
1818}
1919
20- /** Allocates a raw ArrayBuffer with uninitialized contents . */
21- export function allocate ( byteLength : i32 ) : ArrayBuffer {
20+ /** Allocates a raw ArrayBuffer. Contents remain uninitialized . */
21+ export function allocUnsafe ( byteLength : i32 ) : ArrayBuffer {
2222 assert ( < u32 > byteLength <= < u32 > MAX_BLENGTH ) ;
2323 var buffer = allocate_memory ( computeSize ( byteLength ) ) ;
2424 store < i32 > ( buffer , byteLength , offsetof < ArrayBuffer > ( "byteLength" ) ) ;
2525 return changetype < ArrayBuffer > ( buffer ) ;
2626}
2727
28+ /** Reallocates an ArrayBuffer, resizing it as requested. Tries to modify the buffer in place. */
29+ export function reallocUnsafe ( buffer : ArrayBuffer , newByteLength : i32 ) : ArrayBuffer {
30+ var oldByteLength = buffer . byteLength ;
31+ if ( newByteLength > oldByteLength ) {
32+ assert ( newByteLength <= MAX_BLENGTH ) ;
33+ let oldSize = computeSize ( oldByteLength ) ;
34+ if ( < i32 > ( oldSize - HEADER_SIZE ) <= newByteLength ) { // fast path: zero out additional space
35+ store < i32 > ( changetype < usize > ( buffer ) , newByteLength , offsetof < ArrayBuffer > ( "byteLength" ) ) ;
36+ set_memory (
37+ changetype < usize > ( buffer ) + HEADER_SIZE + oldByteLength ,
38+ 0 ,
39+ < usize > ( newByteLength - oldByteLength )
40+ ) ;
41+ } else { // slow path: copy to new buffer
42+ let newBuffer = allocUnsafe ( newByteLength ) ;
43+ move_memory (
44+ changetype < usize > ( newBuffer ) + HEADER_SIZE ,
45+ changetype < usize > ( buffer ) + HEADER_SIZE ,
46+ < usize > newByteLength
47+ ) ;
48+ return newBuffer ;
49+ }
50+ } else if ( newByteLength < oldByteLength ) { // fast path: override size
51+ // TBD: worth to copy and release if size is significantly less than before?
52+ assert ( newByteLength >= 0 ) ;
53+ store < i32 > ( changetype < usize > ( buffer ) , newByteLength , offsetof < ArrayBuffer > ( "byteLength" ) ) ;
54+ }
55+ return buffer ;
56+ }
57+
2858/** Common typed array interface. Not a global object. */
2959// export declare interface ArrayBufferView<T> {
3060// readonly buffer: ArrayBuffer;
0 commit comments