@@ -199,29 +199,43 @@ init_icall_table (void)
199
199
static void *
200
200
get_native_to_interp (MonoMethod * method , void * extra_arg )
201
201
{
202
- void * addr ;
203
-
202
+ void * addr = NULL ;
204
203
MONO_ENTER_GC_UNSAFE ;
205
204
MonoClass * klass = mono_method_get_class (method );
206
205
MonoImage * image = mono_class_get_image (klass );
207
206
MonoAssembly * assembly = mono_image_get_assembly (image );
208
207
MonoAssemblyName * aname = mono_assembly_get_name (assembly );
209
208
const char * name = mono_assembly_name_get_name (aname );
209
+ const char * namespace = mono_class_get_namespace (klass );
210
210
const char * class_name = mono_class_get_name (klass );
211
211
const char * method_name = mono_method_get_name (method );
212
- char key [128 ];
212
+ MonoMethodSignature * sig = mono_method_signature (method );
213
+ uint32_t param_count = mono_signature_get_param_count (sig );
214
+ uint32_t token = mono_method_get_token (method );
215
+
216
+ char buf [128 ];
217
+ char * key = buf ;
213
218
int len ;
219
+ if (name != NULL ) {
220
+ // the key must match the one used in PInvokeTableGenerator
221
+ len = snprintf (key , sizeof (buf ), "%s#%d:%s:%s:%s" , method_name , param_count , name , namespace , class_name );
222
+
223
+ if (len >= sizeof (buf )) {
224
+ // The key is too long, try again with a larger buffer
225
+ key = g_new (char , len + 1 );
226
+ snprintf (key , len + 1 , "%s#%d:%s:%s:%s" , method_name , param_count , name , namespace , class_name );
227
+ }
214
228
215
- assert ( strlen ( name ) < 100 );
216
- snprintf ( key , sizeof ( key ), "%s_%s_%s" , name , class_name , method_name );
217
- char * fixedName = mono_fixup_symbol_name ( "" , key , "" );
218
- addr = wasm_dl_get_native_to_interp ( fixedName , extra_arg );
219
- free ( fixedName );
229
+ addr = wasm_dl_get_native_to_interp ( token , key , extra_arg );
230
+
231
+ if ( key != buf )
232
+ free ( key );
233
+ }
220
234
MONO_EXIT_GC_UNSAFE ;
221
235
return addr ;
222
236
}
223
237
224
- static void * sysglobal_native_handle ;
238
+ static void * sysglobal_native_handle = ( void * ) 0xDeadBeef ;
225
239
226
240
static void *
227
241
wasm_dl_load (const char * name , int flags , char * * err , void * user_data )
@@ -248,24 +262,33 @@ wasm_dl_load (const char *name, int flags, char **err, void *user_data)
248
262
return NULL ;
249
263
}
250
264
265
+ int
266
+ import_compare_name (const void * k1 , const void * k2 )
267
+ {
268
+ const PinvokeImport * e1 = (const PinvokeImport * )k1 ;
269
+ const PinvokeImport * e2 = (const PinvokeImport * )k2 ;
270
+
271
+ return strcmp (e1 -> name , e2 -> name );
272
+ }
273
+
251
274
static void *
252
275
wasm_dl_symbol (void * handle , const char * name , char * * err , void * user_data )
253
276
{
254
- if (handle == sysglobal_native_handle )
255
- assert (0 );
277
+ assert (handle != sysglobal_native_handle );
256
278
257
279
#if WASM_SUPPORTS_DLOPEN
258
280
if (!wasm_dl_is_pinvoke_tables (handle )) {
259
281
return dlsym (handle , name );
260
282
}
261
283
#endif
262
-
263
- PinvokeImport * table = (PinvokeImport * )handle ;
264
- for (int i = 0 ; table [i ].name ; ++ i ) {
265
- if (!strcmp (table [i ].name , name ))
266
- return table [i ].func ;
267
- }
268
- return NULL ;
284
+ PinvokeTable * index = (PinvokeTable * )handle ;
285
+ PinvokeImport key = { name , NULL };
286
+ PinvokeImport * result = (PinvokeImport * )bsearch (& key , index -> imports , index -> count , sizeof (PinvokeImport ), import_compare_name );
287
+ if (!result ) {
288
+ // *err = g_strdup_printf ("Symbol not found: %s", name);
289
+ return NULL ;
290
+ }
291
+ return result -> func ;
269
292
}
270
293
271
294
MonoDomain *
@@ -363,24 +386,50 @@ mono_wasm_assembly_find_method (MonoClass *klass, const char *name, int argument
363
386
return result ;
364
387
}
365
388
389
+ MonoMethod *
390
+ mono_wasm_get_method_matching (MonoImage * image , uint32_t token , MonoClass * klass , const char * name , int param_count )
391
+ {
392
+ MonoMethod * result = NULL ;
393
+ MONO_ENTER_GC_UNSAFE ;
394
+ MonoMethod * method = mono_get_method (image , token , klass );
395
+ MonoMethodSignature * sig = mono_method_signature (method );
396
+ // Lookp by token but verify the name and param count in case assembly was trimmed
397
+ if (mono_signature_get_param_count (sig ) == param_count ) {
398
+ const char * method_name = mono_method_get_name (method );
399
+ if (!strcmp (method_name , name )) {
400
+ result = method ;
401
+ }
402
+ }
403
+ // If the token lookup failed, try to find the method by name and param count
404
+ if (!result ) {
405
+ result = mono_class_get_method_from_name (klass , name , param_count );
406
+ }
407
+ MONO_EXIT_GC_UNSAFE ;
408
+ return result ;
409
+ }
410
+
366
411
/*
367
412
* mono_wasm_marshal_get_managed_wrapper:
368
413
* Creates a wrapper for a function pointer to a method marked with
369
414
* UnamangedCallersOnlyAttribute.
370
415
* This wrapper ensures that the interpreter initializes the pointers.
371
416
*/
372
417
void
373
- mono_wasm_marshal_get_managed_wrapper (const char * assemblyName , const char * namespaceName , const char * typeName , const char * methodName , int num_params )
418
+ mono_wasm_marshal_get_managed_wrapper (const char * assemblyName , const char * namespaceName , const char * typeName , const char * methodName , uint32_t token , int param_count )
374
419
{
375
420
MonoError error ;
376
421
mono_error_init (& error );
422
+ MONO_ENTER_GC_UNSAFE ;
377
423
MonoAssembly * assembly = mono_wasm_assembly_load (assemblyName );
378
424
assert (assembly );
379
- MonoClass * class = mono_wasm_assembly_find_class (assembly , namespaceName , typeName );
380
- assert (class );
381
- MonoMethod * method = mono_wasm_assembly_find_method (class , methodName , num_params );
425
+ MonoImage * image = mono_assembly_get_image (assembly );
426
+ assert (image );
427
+ MonoClass * klass = mono_class_from_name (image , namespaceName , typeName );
428
+ assert (klass );
429
+ MonoMethod * method = mono_wasm_get_method_matching (image , token , klass , methodName , param_count );
382
430
assert (method );
383
431
MonoMethod * managedWrapper = mono_marshal_get_managed_wrapper (method , NULL , 0 , & error );
384
432
assert (managedWrapper );
385
433
mono_compile_method (managedWrapper );
386
- }
434
+ MONO_EXIT_GC_UNSAFE ;
435
+ }
0 commit comments