@@ -59,7 +59,7 @@ class SwiftRuntimeHeap {
59
59
60
60
allocHeap ( value : any ) {
61
61
const isObject = typeof value == "object" ;
62
- const entry = this . _heapEntryByValue . get ( value ) ;
62
+ const entry = this . _heapEntryByValue . get ( value ) ;
63
63
if ( isObject && entry ) {
64
64
entry . rc ++
65
65
return entry . id
@@ -124,10 +124,12 @@ export class SwiftRuntime {
124
124
const exports = this . instance . exports as any as SwiftRuntimeExportedFunctions ;
125
125
const argc = args . length
126
126
const argv = exports . swjs_prepare_host_function_call ( argc )
127
+ const uint32Memory = new Uint32Array ( memory ( ) . buffer , argv , args . length * 3 )
127
128
for ( let index = 0 ; index < args . length ; index ++ ) {
128
129
const argument = args [ index ]
129
- const base = argv + 24 * index
130
- writeValue ( argument , base , base + 4 , base + 8 , base + 16 )
130
+ const offset = 12 * index
131
+ const dataView = new DataView ( memory ( ) . buffer , argv + offset , 12 ) ;
132
+ writeValue ( argument , dataView )
131
133
}
132
134
let output : any ;
133
135
const callback_func_ref = this . heap . allocHeap ( function ( result : any ) {
@@ -142,24 +144,20 @@ export class SwiftRuntime {
142
144
const textEncoder = new TextEncoder ( ) ; // Only support utf-8
143
145
144
146
const readString = ( ptr : pointer , len : number ) => {
145
- const uint8Memory = new Uint8Array ( memory ( ) . buffer ) ;
146
- return textDecoder . decode ( uint8Memory . subarray ( ptr , ptr + len ) ) ;
147
+ const uint8Memory = new Uint8Array ( memory ( ) . buffer , ptr , len ) ;
148
+ return textDecoder . decode ( uint8Memory ) ;
147
149
}
148
150
149
151
const writeString = ( ptr : pointer , bytes : Uint8Array ) => {
150
- const uint8Memory = new Uint8Array ( memory ( ) . buffer ) ;
152
+ const uint8Memory = new Uint8Array ( memory ( ) . buffer , ptr ) ;
151
153
for ( const [ index , byte ] of bytes . entries ( ) ) {
152
- uint8Memory [ ptr + index ] = byte
154
+ uint8Memory [ index ] = byte
153
155
}
154
- uint8Memory [ ptr ]
155
156
}
156
157
157
158
const readUInt32 = ( ptr : pointer ) => {
158
- const uint8Memory = new Uint8Array ( memory ( ) . buffer ) ;
159
- return uint8Memory [ ptr + 0 ]
160
- + ( uint8Memory [ ptr + 1 ] << 8 )
161
- + ( uint8Memory [ ptr + 2 ] << 16 )
162
- + ( uint8Memory [ ptr + 3 ] << 24 )
159
+ const uint32Memory = new Uint32Array ( memory ( ) . buffer , ptr , 1 ) ;
160
+ return uint32Memory [ 0 ] ;
163
161
}
164
162
165
163
const readFloat64 = ( ptr : pointer ) => {
@@ -168,37 +166,37 @@ export class SwiftRuntime {
168
166
}
169
167
170
168
const writeUint32 = ( ptr : pointer , value : number ) => {
171
- const uint8Memory = new Uint8Array ( memory ( ) . buffer ) ;
172
- uint8Memory [ ptr + 0 ] = ( value & 0x000000ff ) >> 0
173
- uint8Memory [ ptr + 1 ] = ( value & 0x0000ff00 ) >> 8
174
- uint8Memory [ ptr + 2 ] = ( value & 0x00ff0000 ) >> 16
175
- uint8Memory [ ptr + 3 ] = ( value & 0xff000000 ) >> 24
169
+ const uint32Memory = new Uint32Array ( memory ( ) . buffer , ptr ) ;
170
+ uint32Memory [ 0 ] = ( value & 0xffffffff ) ;
176
171
}
177
172
178
173
const writeFloat64 = ( ptr : pointer , value : number ) => {
179
174
const dataView = new DataView ( memory ( ) . buffer ) ;
180
175
dataView . setFloat64 ( ptr , value , true ) ;
181
176
}
182
177
183
- const decodeValue = (
184
- kind : JavaScriptValueKind ,
185
- payload1 : number , payload2 : number , payload3 : number
186
- ) => {
178
+ const decodeValue = ( dataView : DataView ) => {
179
+ const kind = dataView . getUint32 ( 0 , true ) ;
180
+ const payload1_ptr = Uint32Array . BYTES_PER_ELEMENT
181
+ const payload2_ptr = 2 * Uint32Array . BYTES_PER_ELEMENT
187
182
switch ( kind ) {
188
183
case JavaScriptValueKind . Boolean : {
189
- switch ( payload1 ) {
184
+ switch ( dataView . getUint32 ( payload1_ptr , true ) ) {
190
185
case 0 : return false
191
186
case 1 : return true
192
187
}
193
188
}
194
189
case JavaScriptValueKind . Number : {
195
- return payload3 ;
190
+ return dataView . getFloat64 ( payload1_ptr , true ) ;
196
191
}
197
192
case JavaScriptValueKind . String : {
198
- return readString ( payload1 , payload2 )
193
+ return readString (
194
+ dataView . getUint32 ( payload1_ptr , true ) ,
195
+ dataView . getUint32 ( payload2_ptr , true )
196
+ ) ;
199
197
}
200
198
case JavaScriptValueKind . Object : {
201
- return this . heap . referenceHeap ( payload1 )
199
+ return this . heap . referenceHeap ( dataView . getUint32 ( payload1_ptr , true ) )
202
200
}
203
201
case JavaScriptValueKind . Null : {
204
202
return null
@@ -207,60 +205,57 @@ export class SwiftRuntime {
207
205
return undefined
208
206
}
209
207
case JavaScriptValueKind . Function : {
210
- return this . heap . referenceHeap ( payload1 )
208
+ return this . heap . referenceHeap ( dataView . getUint32 ( payload1_ptr , true ) )
211
209
}
212
210
default :
213
211
throw new Error ( `Type kind "${ kind } " is not supported` )
214
212
}
215
213
}
216
214
217
- const writeValue = (
218
- value : any , kind_ptr : pointer ,
219
- payload1_ptr : pointer , payload2_ptr : pointer , payload3_ptr : pointer
220
- ) => {
215
+ const writeValue = ( value : any , dataView : DataView ) => {
216
+ const payload1_ptr = Uint32Array . BYTES_PER_ELEMENT
217
+ const payload2_ptr = 2 * Uint32Array . BYTES_PER_ELEMENT
221
218
if ( value === null ) {
222
- writeUint32 ( kind_ptr , JavaScriptValueKind . Null ) ;
223
- writeUint32 ( payload1_ptr , 0 ) ;
224
- writeUint32 ( payload2_ptr , 0 ) ;
219
+ dataView . setUint32 ( 0 , JavaScriptValueKind . Null , true ) ;
220
+ dataView . setUint32 ( payload1_ptr , 0 , true ) ;
221
+ dataView . setUint32 ( payload2_ptr , 0 , true ) ;
225
222
return ;
226
223
}
227
224
switch ( typeof value ) {
228
225
case "boolean" : {
229
- writeUint32 ( kind_ptr , JavaScriptValueKind . Boolean ) ;
230
- writeUint32 ( payload1_ptr , value ? 1 : 0 ) ;
231
- writeUint32 ( payload2_ptr , 0 ) ;
226
+ dataView . setUint32 ( 0 , JavaScriptValueKind . Boolean , true ) ;
227
+ dataView . setUint32 ( payload1_ptr , value ? 1 : 0 , true ) ;
228
+ dataView . setUint32 ( payload2_ptr , 0 , true ) ;
232
229
break ;
233
230
}
234
231
case "number" : {
235
- writeUint32 ( kind_ptr , JavaScriptValueKind . Number ) ;
236
- writeUint32 ( payload1_ptr , 0 ) ;
237
- writeUint32 ( payload2_ptr , 0 ) ;
238
- writeFloat64 ( payload3_ptr , value ) ;
232
+ dataView . setUint32 ( 0 , JavaScriptValueKind . Number , true ) ;
233
+ dataView . setFloat64 ( payload1_ptr , value , true ) ;
239
234
break ;
240
235
}
241
236
case "string" : {
242
237
const bytes = textEncoder . encode ( value ) ;
243
- writeUint32 ( kind_ptr , JavaScriptValueKind . String ) ;
244
- writeUint32 ( payload1_ptr , this . heap . allocHeap ( bytes ) ) ;
245
- writeUint32 ( payload2_ptr , bytes . length ) ;
238
+ dataView . setUint32 ( 0 , JavaScriptValueKind . String , true ) ;
239
+ dataView . setUint32 ( payload1_ptr , this . heap . allocHeap ( bytes ) , true ) ;
240
+ dataView . setUint32 ( payload2_ptr , bytes . length , true ) ;
246
241
break ;
247
242
}
248
243
case "undefined" : {
249
- writeUint32 ( kind_ptr , JavaScriptValueKind . Undefined ) ;
250
- writeUint32 ( payload1_ptr , 0 ) ;
251
- writeUint32 ( payload2_ptr , 0 ) ;
244
+ dataView . setUint32 ( 0 , JavaScriptValueKind . Undefined , true ) ;
245
+ dataView . setUint32 ( payload1_ptr , 0 , true ) ;
246
+ dataView . setUint32 ( payload2_ptr , 0 , true ) ;
252
247
break ;
253
248
}
254
249
case "object" : {
255
- writeUint32 ( kind_ptr , JavaScriptValueKind . Object ) ;
256
- writeUint32 ( payload1_ptr , this . heap . allocHeap ( value ) ) ;
257
- writeUint32 ( payload2_ptr , 0 ) ;
250
+ dataView . setUint32 ( 0 , JavaScriptValueKind . Object , true ) ;
251
+ dataView . setUint32 ( payload1_ptr , this . heap . allocHeap ( value ) , true ) ;
252
+ dataView . setUint32 ( payload2_ptr , 0 , true ) ;
258
253
break ;
259
254
}
260
255
case "function" : {
261
- writeUint32 ( kind_ptr , JavaScriptValueKind . Function ) ;
262
- writeUint32 ( payload1_ptr , this . heap . allocHeap ( value ) ) ;
263
- writeUint32 ( payload2_ptr , 0 ) ;
256
+ dataView . setUint32 ( 0 , JavaScriptValueKind . Function , true ) ;
257
+ dataView . setUint32 ( payload1_ptr , this . heap . allocHeap ( value ) , true ) ;
258
+ dataView . setUint32 ( payload2_ptr , 0 , true ) ;
264
259
break ;
265
260
}
266
261
default :
@@ -274,74 +269,71 @@ export class SwiftRuntime {
274
269
const decodeValues = ( ptr : pointer , length : number ) => {
275
270
let result = [ ]
276
271
for ( let index = 0 ; index < length ; index ++ ) {
277
- const base = ptr + 24 * index
278
- const kind = readUInt32 ( base )
279
- const payload1 = readUInt32 ( base + 4 )
280
- const payload2 = readUInt32 ( base + 8 )
281
- const payload3 = readFloat64 ( base + 16 )
282
- result . push ( decodeValue ( kind , payload1 , payload2 , payload3 ) )
272
+ const offset = 12 * index
273
+ const dataView = new DataView ( memory ( ) . buffer , ptr + offset , 12 ) ;
274
+ result . push ( decodeValue ( dataView ) )
283
275
}
284
276
return result
285
277
}
286
278
287
279
return {
288
280
swjs_set_prop : (
289
281
ref : ref , name : pointer , length : number ,
290
- kind : JavaScriptValueKind ,
291
- payload1 : number , payload2 : number , payload3 : number
282
+ rawJSValuePtr : pointer
292
283
) => {
293
284
const obj = this . heap . referenceHeap ( ref ) ;
294
- Reflect . set ( obj , readString ( name , length ) , decodeValue ( kind , payload1 , payload2 , payload3 ) )
285
+ const dataView = new DataView ( memory ( ) . buffer , rawJSValuePtr , 12 ) ;
286
+ Reflect . set ( obj , readString ( name , length ) , decodeValue ( dataView ) )
295
287
} ,
296
288
swjs_get_prop : (
297
289
ref : ref , name : pointer , length : number ,
298
- kind_ptr : pointer ,
299
- payload1_ptr : pointer , payload2_ptr : pointer , payload3_ptr : number
290
+ rawJSValuePtr : pointer
300
291
) => {
301
292
const obj = this . heap . referenceHeap ( ref ) ;
302
293
const result = Reflect . get ( obj , readString ( name , length ) ) ;
303
- writeValue ( result , kind_ptr , payload1_ptr , payload2_ptr , payload3_ptr ) ;
294
+ const dataView = new DataView ( memory ( ) . buffer , rawJSValuePtr , 12 ) ;
295
+ writeValue ( result , dataView ) ;
304
296
} ,
305
297
swjs_set_subscript : (
306
298
ref : ref , index : number ,
307
- kind : JavaScriptValueKind ,
308
- payload1 : number , payload2 : number , payload3 : number
299
+ rawJSValuePtr : pointer
309
300
) => {
310
301
const obj = this . heap . referenceHeap ( ref ) ;
311
- Reflect . set ( obj , index , decodeValue ( kind , payload1 , payload2 , payload3 ) )
302
+ const dataView = new DataView ( memory ( ) . buffer , rawJSValuePtr , 12 ) ;
303
+ Reflect . set ( obj , index , decodeValue ( dataView ) )
312
304
} ,
313
305
swjs_get_subscript : (
314
306
ref : ref , index : number ,
315
- kind_ptr : pointer ,
316
- payload1_ptr : pointer , payload2_ptr : pointer , payload3_ptr : pointer
307
+ rawJSValuePtr : pointer
317
308
) => {
318
309
const obj = this . heap . referenceHeap ( ref ) ;
319
310
const result = Reflect . get ( obj , index ) ;
320
- writeValue ( result , kind_ptr , payload1_ptr , payload2_ptr , payload3_ptr ) ;
311
+ const dataView = new DataView ( memory ( ) . buffer , rawJSValuePtr , 12 ) ;
312
+ writeValue ( result , dataView ) ;
321
313
} ,
322
314
swjs_load_string : ( ref : ref , buffer : pointer ) => {
323
315
const bytes = this . heap . referenceHeap ( ref ) ;
324
316
writeString ( buffer , bytes ) ;
325
317
} ,
326
318
swjs_call_function : (
327
319
ref : ref , argv : pointer , argc : number ,
328
- kind_ptr : pointer ,
329
- payload1_ptr : pointer , payload2_ptr : pointer , payload3_ptr : pointer
320
+ rawJSValuePtr : pointer
330
321
) => {
331
322
const func = this . heap . referenceHeap ( ref )
332
323
const result = Reflect . apply ( func , undefined , decodeValues ( argv , argc ) )
333
- writeValue ( result , kind_ptr , payload1_ptr , payload2_ptr , payload3_ptr ) ;
324
+ const dataView = new DataView ( memory ( ) . buffer , rawJSValuePtr , 12 ) ;
325
+ writeValue ( result , dataView ) ;
334
326
} ,
335
327
swjs_call_function_with_this : (
336
328
obj_ref : ref , func_ref : ref ,
337
329
argv : pointer , argc : number ,
338
- kind_ptr : pointer ,
339
- payload1_ptr : pointer , payload2_ptr : pointer , payload3_ptr : pointer
330
+ rawJSValuePtr : pointer
340
331
) => {
341
332
const obj = this . heap . referenceHeap ( obj_ref )
342
333
const func = this . heap . referenceHeap ( func_ref )
343
334
const result = Reflect . apply ( func , obj , decodeValues ( argv , argc ) )
344
- writeValue ( result , kind_ptr , payload1_ptr , payload2_ptr , payload3_ptr ) ;
335
+ const dataView = new DataView ( memory ( ) . buffer , rawJSValuePtr , 12 ) ;
336
+ writeValue ( result , dataView ) ;
345
337
} ,
346
338
swjs_create_function : (
347
339
host_func_id : number ,
0 commit comments