@@ -12,20 +12,21 @@ const ARRAYBUFFERVIEW_ID = 2;
1212// Runtime type information
1313const ARRAYBUFFERVIEW = 1 << 0 ;
1414const ARRAY = 1 << 1 ;
15- const SET = 1 << 2 ;
16- const MAP = 1 << 3 ;
17- const VAL_ALIGN_OFFSET = 5 ;
15+ const STATICARRAY = 1 << 2 ;
16+ const SET = 1 << 3 ;
17+ const MAP = 1 << 4 ;
18+ const VAL_ALIGN_OFFSET = 6 ;
1819const VAL_ALIGN = 1 << VAL_ALIGN_OFFSET ;
19- const VAL_SIGNED = 1 << 10 ;
20- const VAL_FLOAT = 1 << 11 ;
21- const VAL_NULLABLE = 1 << 12 ;
22- const VAL_MANAGED = 1 << 13 ;
23- const KEY_ALIGN_OFFSET = 14 ;
20+ const VAL_SIGNED = 1 << 11 ;
21+ const VAL_FLOAT = 1 << 12 ;
22+ const VAL_NULLABLE = 1 << 13 ;
23+ const VAL_MANAGED = 1 << 14 ;
24+ const KEY_ALIGN_OFFSET = 15 ;
2425const KEY_ALIGN = 1 << KEY_ALIGN_OFFSET ;
25- const KEY_SIGNED = 1 << 19 ;
26- const KEY_FLOAT = 1 << 20 ;
27- const KEY_NULLABLE = 1 << 21 ;
28- const KEY_MANAGED = 1 << 22 ;
26+ const KEY_SIGNED = 1 << 20 ;
27+ const KEY_FLOAT = 1 << 21 ;
28+ const KEY_NULLABLE = 1 << 22 ;
29+ const KEY_MANAGED = 1 << 23 ;
2930
3031// Array(BufferView) layout
3132const ARRAYBUFFERVIEW_BUFFER_OFFSET = 0 ;
@@ -162,23 +163,29 @@ function postInstantiate(extendedExports, instance) {
162163 /** Allocates a new array in the module's memory and returns its retained pointer. */
163164 function __allocArray ( id , values ) {
164165 const info = getInfo ( id ) ;
165- if ( ! ( info & ( ARRAYBUFFERVIEW | ARRAY ) ) ) throw Error ( "not an array: " + id + ", flags= " + info ) ;
166+ if ( ! ( info & ( ARRAYBUFFERVIEW | ARRAY | STATICARRAY ) ) ) throw Error ( "not an array: " + id + ", flags= " + info ) ;
166167 const align = getValueAlign ( info ) ;
167168 const length = values . length ;
168- const buf = alloc ( length << align , ARRAYBUFFER_ID ) ;
169- const arr = alloc ( info & ARRAY ? ARRAY_SIZE : ARRAYBUFFERVIEW_SIZE , id ) ;
170- const U32 = new Uint32Array ( memory . buffer ) ;
171- U32 [ arr + ARRAYBUFFERVIEW_BUFFER_OFFSET >>> 2 ] = retain ( buf ) ;
172- U32 [ arr + ARRAYBUFFERVIEW_DATASTART_OFFSET >>> 2 ] = buf ;
173- U32 [ arr + ARRAYBUFFERVIEW_DATALENGTH_OFFSET >>> 2 ] = length << align ;
174- if ( info & ARRAY ) U32 [ arr + ARRAY_LENGTH_OFFSET >>> 2 ] = length ;
169+ const buf = alloc ( length << align , info & STATICARRAY ? id : ARRAYBUFFER_ID ) ;
170+ let result ;
171+ if ( info & STATICARRAY ) {
172+ result = buf ;
173+ } else {
174+ const arr = alloc ( info & ARRAY ? ARRAY_SIZE : ARRAYBUFFERVIEW_SIZE , id ) ;
175+ const U32 = new Uint32Array ( memory . buffer ) ;
176+ U32 [ arr + ARRAYBUFFERVIEW_BUFFER_OFFSET >>> 2 ] = retain ( buf ) ;
177+ U32 [ arr + ARRAYBUFFERVIEW_DATASTART_OFFSET >>> 2 ] = buf ;
178+ U32 [ arr + ARRAYBUFFERVIEW_DATALENGTH_OFFSET >>> 2 ] = length << align ;
179+ if ( info & ARRAY ) U32 [ arr + ARRAY_LENGTH_OFFSET >>> 2 ] = length ;
180+ result = arr ;
181+ }
175182 const view = getView ( align , info & VAL_SIGNED , info & VAL_FLOAT ) ;
176183 if ( info & VAL_MANAGED ) {
177184 for ( let i = 0 ; i < length ; ++ i ) view [ ( buf >>> align ) + i ] = retain ( values [ i ] ) ;
178185 } else {
179186 view . set ( values , buf >>> align ) ;
180187 }
181- return arr ;
188+ return result ;
182189 }
183190
184191 extendedExports . __allocArray = __allocArray ;
@@ -188,9 +195,11 @@ function postInstantiate(extendedExports, instance) {
188195 const U32 = new Uint32Array ( memory . buffer ) ;
189196 const id = U32 [ arr + ID_OFFSET >>> 2 ] ;
190197 const info = getInfo ( id ) ;
191- if ( ! ( info & ( ARRAYBUFFERVIEW | ARRAY ) ) ) throw Error ( "not an array: " + id + ", flags=" + info ) ;
198+ if ( ! ( info & ( ARRAYBUFFERVIEW | ARRAY | STATICARRAY ) ) ) throw Error ( "not an array: " + id + ", flags=" + info ) ;
192199 const align = getValueAlign ( info ) ;
193- let buf = U32 [ arr + ARRAYBUFFERVIEW_DATASTART_OFFSET >>> 2 ] ;
200+ let buf = info & STATICARRAY
201+ ? arr
202+ : U32 [ arr + ARRAYBUFFERVIEW_DATASTART_OFFSET >>> 2 ] ;
194203 const length = info & ARRAY
195204 ? U32 [ arr + ARRAY_LENGTH_OFFSET >>> 2 ]
196205 : U32 [ buf + SIZE_OFFSET >>> 2 ] >>> align ;
@@ -233,30 +242,31 @@ function postInstantiate(extendedExports, instance) {
233242 return new Type ( buffer , bufPtr , U32 [ bufPtr + SIZE_OFFSET >>> 2 ] >>> alignLog2 ) ;
234243 }
235244
236- extendedExports . __getInt8Array = getTypedArray . bind ( null , Int8Array , 0 ) ;
237- extendedExports . __getInt8ArrayView = getTypedArrayView . bind ( null , Int8Array , 0 ) ;
238- extendedExports . __getUint8Array = getTypedArray . bind ( null , Uint8Array , 0 ) ;
239- extendedExports . __getUint8ArrayView = getTypedArrayView . bind ( null , Uint8Array , 0 ) ;
240- extendedExports . __getUint8ClampedArray = getTypedArray . bind ( null , Uint8ClampedArray , 0 ) ;
241- extendedExports . __getUint8ClampedArrayView = getTypedArrayView . bind ( null , Uint8ClampedArray , 0 ) ;
242- extendedExports . __getInt16Array = getTypedArray . bind ( null , Int16Array , 1 ) ;
243- extendedExports . __getInt16ArrayView = getTypedArrayView . bind ( null , Int16Array , 1 ) ;
244- extendedExports . __getUint16Array = getTypedArray . bind ( null , Uint16Array , 1 ) ;
245- extendedExports . __getUint16ArrayView = getTypedArrayView . bind ( null , Uint16Array , 1 ) ;
246- extendedExports . __getInt32Array = getTypedArray . bind ( null , Int32Array , 2 ) ;
247- extendedExports . __getInt32ArrayView = getTypedArrayView . bind ( null , Int32Array , 2 ) ;
248- extendedExports . __getUint32Array = getTypedArray . bind ( null , Uint32Array , 2 ) ;
249- extendedExports . __getUint32ArrayView = getTypedArrayView . bind ( null , Uint32Array , 2 ) ;
245+ /** Attach a set of get TypedArray and View functions to the exports. */
246+ function attachTypedArrayFunctions ( ctor , name , align ) {
247+ extendedExports [ "__get" + name ] = getTypedArray . bind ( null , ctor , align ) ;
248+ extendedExports [ "__get" + name + "View" ] = getTypedArrayView . bind ( null , ctor , align ) ;
249+ }
250+
251+ [
252+ Int8Array ,
253+ Uint8Array ,
254+ Uint8ClampedArray ,
255+ Int16Array ,
256+ Uint16Array ,
257+ Int32Array ,
258+ Uint32Array ,
259+ Float32Array ,
260+ Float64Array
261+ ] . forEach ( ctor => {
262+ attachTypedArrayFunctions ( ctor , ctor . name , 31 - Math . clz32 ( ctor . BYTES_PER_ELEMENT ) ) ;
263+ } ) ;
264+
250265 if ( BIGINT ) {
251- extendedExports . __getInt64Array = getTypedArray . bind ( null , BigInt64Array , 3 ) ;
252- extendedExports . __getInt64ArrayView = getTypedArrayView . bind ( null , BigInt64Array , 3 ) ;
253- extendedExports . __getUint64Array = getTypedArray . bind ( null , BigUint64Array , 3 ) ;
254- extendedExports . __getUint64ArrayView = getTypedArrayView . bind ( null , BigUint64Array , 3 ) ;
266+ [ BigUint64Array , BigInt64Array ] . forEach ( ctor => {
267+ attachTypedArrayFunctions ( ctor , ctor . name . slice ( 3 ) , 3 ) ;
268+ } ) ;
255269 }
256- extendedExports . __getFloat32Array = getTypedArray . bind ( null , Float32Array , 2 ) ;
257- extendedExports . __getFloat32ArrayView = getTypedArrayView . bind ( null , Float32Array , 2 ) ;
258- extendedExports . __getFloat64Array = getTypedArray . bind ( null , Float64Array , 3 ) ;
259- extendedExports . __getFloat64ArrayView = getTypedArrayView . bind ( null , Float64Array , 3 ) ;
260270
261271 /** Tests whether an object is an instance of the class represented by the specified base id. */
262272 function __instanceof ( ptr , baseId ) {
0 commit comments