@@ -24,6 +24,8 @@ const KEY_SIGNED = 1 << 19;
24
24
const KEY_FLOAT = 1 << 20 ;
25
25
const KEY_NULLABLE = 1 << 21 ;
26
26
const KEY_MANAGED = 1 << 22 ;
27
+ const KEY_ALIGN_OFFSET = 14 ;
28
+ const VAL_ALIGN_OFFSET = 5 ;
27
29
28
30
// Array(BufferView) layout
29
31
const ARRAYBUFFERVIEW_BUFFER_OFFSET = 0 ;
@@ -109,6 +111,7 @@ function postInstantiate(baseModule, instance) {
109
111
F64 = new Float64Array ( buffer ) ;
110
112
}
111
113
}
114
+
112
115
checkMem ( ) ;
113
116
114
117
/** Gets the runtime type info for the given id. */
@@ -125,28 +128,43 @@ function postInstantiate(baseModule, instance) {
125
128
return U32 [ ( rttiBase + 4 >>> 2 ) + id * 2 + 1 ] ;
126
129
}
127
130
128
- /** Gets the runtime alignment of a collection's values or keys. */
129
- function getAlign ( which , info ) {
130
- return 31 - Math . clz32 ( ( info / which ) & 31 ) ; // -1 if none
131
+ /** Gets the runtime alignment of a collection's values. */
132
+ function getAlignValue ( info ) {
133
+ return 31 - Math . clz32 ( ( info >>> VAL_ALIGN_OFFSET ) & 31 ) ; // -1 if none
134
+ }
135
+
136
+ /** Gets the runtime alignment of a collection's keys. */
137
+ function getAlignKey ( info ) {
138
+ return 31 - Math . clz32 ( ( info >>> KEY_ALIGN_OFFSET ) & 31 ) ; // -1 if none
139
+ }
140
+
141
+ function getTypedArray ( Type , shift , arr ) {
142
+ var buffer = memory . buffer ;
143
+ var u32 = new Uint32Array ( buffer ) ;
144
+ var buf = u32 [ arr + ARRAYBUFFERVIEW_DATASTART_OFFSET >>> 2 ] ;
145
+ var length = u32 [ buf + SIZE_OFFSET >>> 2 ] ;
146
+ return new Type ( buffer ) . slice ( buf >>> shift , buf + length >>> shift ) ;
131
147
}
132
148
133
149
/** Allocates a new string in the module's memory and returns its retained pointer. */
134
150
function __allocString ( str ) {
135
- const length = str . length ;
136
- const ref = alloc ( length << 1 , STRING_ID ) ;
137
- checkMem ( ) ;
138
- for ( let i = 0 , j = ref >>> 1 ; i < length ; ++ i ) U16 [ j + i ] = str . charCodeAt ( i ) ;
151
+ var length = str . length ;
152
+ var ref = alloc ( length << 1 , STRING_ID ) ;
153
+ var u16 = new Uint16Array ( memory . buffer ) ;
154
+ for ( var i = 0 , p = ref >>> 1 ; i < length ; ++ i ) u16 [ p + i ] = str . charCodeAt ( i ) ;
139
155
return ref ;
140
156
}
141
157
142
158
baseModule . __allocString = __allocString ;
143
159
144
160
/** Reads a string from the module's memory by its pointer. */
145
161
function __getString ( ref ) {
146
- checkMem ( ) ;
147
- const id = U32 [ ref + ID_OFFSET >>> 2 ] ;
162
+ var buf = memory . buffer ;
163
+ var u16 = new Uint16Array ( buf ) ;
164
+ var u32 = new Uint32Array ( buf ) ;
165
+ var id = u32 [ ref + ID_OFFSET >>> 2 ] ;
148
166
if ( id !== STRING_ID ) throw Error ( "not a string: " + ref ) ;
149
- return getStringImpl ( U32 , U16 , ref ) ;
167
+ return getStringImpl ( u32 , u16 , ref ) ;
150
168
}
151
169
152
170
baseModule . __getString = __getString ;
@@ -173,7 +191,7 @@ function postInstantiate(baseModule, instance) {
173
191
function __allocArray ( id , values ) {
174
192
const info = getInfo ( id ) ;
175
193
if ( ! ( info & ( ARRAYBUFFERVIEW | ARRAY ) ) ) throw Error ( "not an array: " + id + " @ " + info ) ;
176
- const align = getAlign ( VAL_ALIGN , info ) ;
194
+ const align = getAlignValue ( info ) ;
177
195
const length = values . length ;
178
196
const buf = alloc ( length << align , ARRAYBUFFER_ID ) ;
179
197
const arr = alloc ( info & ARRAY ? ARRAY_SIZE : ARRAYBUFFERVIEW_SIZE , id ) ;
@@ -183,8 +201,11 @@ function postInstantiate(baseModule, instance) {
183
201
U32 [ arr + ARRAYBUFFERVIEW_DATALENGTH_OFFSET >>> 2 ] = length << align ;
184
202
if ( info & ARRAY ) U32 [ arr + ARRAY_LENGTH_OFFSET >>> 2 ] = length ;
185
203
const view = getView ( align , info & VAL_SIGNED , info & VAL_FLOAT ) ;
186
- for ( let i = 0 ; i < length ; ++ i ) view [ ( buf >> align ) + i ] = values [ i ] ;
187
- if ( info & VAL_MANAGED ) for ( let i = 0 ; i < length ; ++ i ) retain ( values [ i ] ) ;
204
+ if ( info & VAL_MANAGED ) {
205
+ for ( let i = 0 ; i < length ; ++ i ) view [ ( buf >>> align ) + i ] = retain ( values [ i ] ) ;
206
+ } else {
207
+ view . set ( values , buf >>> align ) ;
208
+ }
188
209
return arr ;
189
210
}
190
211
@@ -196,7 +217,7 @@ function postInstantiate(baseModule, instance) {
196
217
const id = U32 [ arr + ID_OFFSET >>> 2 ] ;
197
218
const info = getInfo ( id ) ;
198
219
if ( ! ( info & ARRAYBUFFERVIEW ) ) throw Error ( "not an array: " + id ) ;
199
- const align = getAlign ( VAL_ALIGN , info ) ;
220
+ const align = getAlignValue ( info ) ;
200
221
var buf = U32 [ arr + ARRAYBUFFERVIEW_DATASTART_OFFSET >>> 2 ] ;
201
222
const length = info & ARRAY
202
223
? U32 [ arr + ARRAY_LENGTH_OFFSET >>> 2 ]
@@ -214,6 +235,23 @@ function postInstantiate(baseModule, instance) {
214
235
215
236
baseModule . __getArray = __getArray ;
216
237
238
+ function __getArrayBuffer ( buf ) {
239
+ var buffer = memory . buffer ;
240
+ var length = ( new Uint32Array ( buffer ) ) [ buf + SIZE_OFFSET >>> 2 ] ;
241
+ return buffer . slice ( buf , buf + length ) ;
242
+ }
243
+
244
+ baseModule . __getArrayBuffer = __getArrayBuffer ;
245
+
246
+ baseModule . __getUint8Array = getTypedArray . bind ( null , Uint8Array , 0 ) ;
247
+ baseModule . __getInt8Array = getTypedArray . bind ( null , Int8Array , 0 ) ;
248
+ baseModule . __getUint16Array = getTypedArray . bind ( null , Uint16Array , 1 ) ;
249
+ baseModule . __getInt16Array = getTypedArray . bind ( null , Int16Array , 1 ) ;
250
+ baseModule . __getUint32Array = getTypedArray . bind ( null , Uint32Array , 2 ) ;
251
+ baseModule . __getInt32Array = getTypedArray . bind ( null , Int32Array , 2 ) ;
252
+ baseModule . __getFloat32Array = getTypedArray . bind ( null , Float32Array , 2 ) ;
253
+ baseModule . __getFloat64Array = getTypedArray . bind ( null , Float64Array , 3 ) ;
254
+
217
255
/** Tests whether an object is an instance of the class represented by the specified base id. */
218
256
function __instanceof ( ref , baseId ) {
219
257
var id = U32 [ ( ref + ID_OFFSET ) >>> 2 ] ;
@@ -228,7 +266,7 @@ function postInstantiate(baseModule, instance) {
228
266
229
267
// Pull basic exports to baseModule so code in preInstantiate can use them
230
268
baseModule . memory = baseModule . memory || memory ;
231
- baseModule . table = baseModule . table || table ;
269
+ baseModule . table = baseModule . table || table ;
232
270
233
271
// Demangle exports and provide the usual utility on the prototype
234
272
return demangle ( rawExports , Object . defineProperties ( baseModule , {
0 commit comments