@@ -160,8 +160,7 @@ FieldBuilder CreateDelegateField(MethodInfo method)
160
160
161
161
FieldInfo delegateField = implementationType . GetField (
162
162
fieldName , BindingFlags . NonPublic | BindingFlags . Static ) ! ;
163
- delegateField . SetValue (
164
- null , marshaller . BuildToJSMethodExpression ( method ) . Compile ( ) ) ;
163
+ delegateField . SetValue ( null , marshaller . GetToJSMethodDelegate ( method ) ) ;
165
164
}
166
165
167
166
return implementationType ;
@@ -232,28 +231,21 @@ private static void BuildPropertyImplementation(
232
231
ILGenerator il = getMethodBuilder . GetILGenerator ( ) ;
233
232
234
233
/*
235
- * return this._get_property. DynamicInvoke( new object[] { Value });
234
+ * return this.DynamicInvoke._get_property, new object[] { Value });
236
235
*/
237
236
237
+ il . Emit ( OpCodes . Ldarg_0 ) ; // this
238
+
238
239
// Load the static field for the delegate that implements the method by marshalling to JS.
239
240
il . Emit ( OpCodes . Ldsfld , getDelegateField ! ) ;
240
241
241
242
// Create an array to hold the arguments passed to the delegate invocation.
242
243
il . Emit ( OpCodes . Ldc_I4_1 ) ;
243
244
il . Emit ( OpCodes . Newarr , typeof ( object ) ) ;
244
245
245
- // Store the value from the Value property in the first array slot.
246
- il . Emit ( OpCodes . Dup ) ; // Duplicate the array reference on the stack.
247
- il . Emit ( OpCodes . Ldc_I4_0 ) ;
248
- il . Emit ( OpCodes . Ldarg_0 ) ; // this
249
- PropertyInfo valueProperty = typeof ( JSInterface ) . GetProperty (
250
- "Value" , BindingFlags . NonPublic | BindingFlags . Instance ) ! ;
251
- il . Emit ( OpCodes . Call , valueProperty . GetMethod ! ) ;
252
- il . Emit ( OpCodes . Box , typeof ( JSValue ) ) ;
253
- il . Emit ( OpCodes . Stelem_Ref ) ;
254
-
255
246
// Invoke the delegate.
256
- il . Emit ( OpCodes . Callvirt , typeof ( Delegate ) . GetMethod ( nameof ( Delegate . DynamicInvoke ) ) ! ) ;
247
+ il . Emit ( OpCodes . Callvirt , typeof ( JSInterface ) . GetMethod (
248
+ nameof ( Delegate . DynamicInvoke ) , BindingFlags . NonPublic | BindingFlags . Instance ) ! ) ;
257
249
258
250
// Return the result, casting to the return type.
259
251
if ( property . PropertyType . IsValueType )
@@ -284,26 +276,18 @@ private static void BuildPropertyImplementation(
284
276
ILGenerator il = setMethodBuilder . GetILGenerator ( ) ;
285
277
286
278
/*
287
- * return this._set_property. DynamicInvoke(new object[] { Value, value });
279
+ * return this.DynamicInvoke(_set_property, new object[] { Value, value });
288
280
*/
289
281
282
+ il . Emit ( OpCodes . Ldarg_0 ) ; // this
283
+
290
284
// Load the static field for the delegate that implements the method by marshalling to JS.
291
285
il . Emit ( OpCodes . Ldsfld , setDelegateField ! ) ;
292
286
293
287
// Create an array to hold the arguments passed to the delegate invocation.
294
288
il . Emit ( OpCodes . Ldc_I4_2 ) ;
295
289
il . Emit ( OpCodes . Newarr , typeof ( object ) ) ;
296
290
297
- // Store the value from the Value property in the first array slot.
298
- il . Emit ( OpCodes . Dup ) ; // Duplicate the array reference on the stack.
299
- il . Emit ( OpCodes . Ldc_I4_0 ) ;
300
- il . Emit ( OpCodes . Ldarg_0 ) ; // this
301
- PropertyInfo valueProperty = typeof ( JSInterface ) . GetProperty (
302
- "Value" , BindingFlags . NonPublic | BindingFlags . Instance ) ! ;
303
- il . Emit ( OpCodes . Call , valueProperty . GetMethod ! ) ;
304
- il . Emit ( OpCodes . Box , typeof ( JSValue ) ) ;
305
- il . Emit ( OpCodes . Stelem_Ref ) ;
306
-
307
291
// Store the set argument "value" in the second array slot.
308
292
il . Emit ( OpCodes . Dup ) ; // Duplicate the array reference on the stack.
309
293
il . Emit ( OpCodes . Ldc_I4_1 ) ;
@@ -312,7 +296,8 @@ private static void BuildPropertyImplementation(
312
296
il . Emit ( OpCodes . Stelem_Ref ) ;
313
297
314
298
// Invoke the delegate.
315
- il . Emit ( OpCodes . Callvirt , typeof ( Delegate ) . GetMethod ( nameof ( Delegate . DynamicInvoke ) ) ! ) ;
299
+ il . Emit ( OpCodes . Callvirt , typeof ( JSInterface ) . GetMethod (
300
+ nameof ( Delegate . DynamicInvoke ) , BindingFlags . NonPublic | BindingFlags . Instance ) ! ) ;
316
301
317
302
// Remove unused return value from the stack.
318
303
il . Emit ( OpCodes . Pop ) ;
@@ -357,17 +342,7 @@ void EmitArgs()
357
342
il . Emit ( OpCodes . Ldc_I4 , 1 + parameters . Length ) ;
358
343
il . Emit ( OpCodes . Newarr , typeof ( object ) ) ;
359
344
360
- // Store the value from the Value property in the first array slot.
361
- il . Emit ( OpCodes . Dup ) ; // Duplicate the array reference on the stack.
362
- il . Emit ( OpCodes . Ldc_I4_0 ) ;
363
- il . Emit ( OpCodes . Ldarg_0 ) ; // this
364
- PropertyInfo valueProperty = typeof ( JSInterface ) . GetProperty (
365
- "Value" , BindingFlags . NonPublic | BindingFlags . Instance ) ! ;
366
- il . Emit ( OpCodes . Call , valueProperty . GetMethod ! ) ;
367
- il . Emit ( OpCodes . Box , typeof ( JSValue ) ) ;
368
- il . Emit ( OpCodes . Stelem_Ref ) ;
369
-
370
- // Store the arguments in the remaining array slots.
345
+ // Store the arguments in the array, leaving index 0 for the JS `this` value.
371
346
for ( int i = 0 ; i < parameters . Length ; i ++ )
372
347
{
373
348
il . Emit ( OpCodes . Dup ) ; // Duplicate the array reference on the stack.
@@ -384,12 +359,14 @@ void EmitArgs()
384
359
}
385
360
}
386
361
362
+ il . Emit ( OpCodes . Ldarg_0 ) ; // this
363
+
387
364
if ( method . IsGenericMethodDefinition )
388
365
{
389
366
/*
390
- * return JSMarshaller.Current.GetToJSMethodDelegate(
391
- * MethodBase.GetCurrentMethod().MakeGenericMethod(new Type[] { typeArgs... }))
392
- * .DynamicInvoke( new object[] { Value, args... });
367
+ * return this.DynamicInvoke( JSMarshaller.Current.GetToJSMethodDelegate(
368
+ * MethodBase.GetCurrentMethod().MakeGenericMethod(new Type[] { typeArgs... })),
369
+ * new object[] { Value, args... });
393
370
*/
394
371
395
372
il . Emit (
@@ -422,32 +399,25 @@ void EmitArgs()
422
399
il . Emit (
423
400
OpCodes . Callvirt ,
424
401
typeof ( JSMarshaller ) . GetInstanceMethod ( nameof ( JSMarshaller . GetToJSMethodDelegate ) ) ) ;
425
-
426
- // Dynamically invoke the JS method delegate.
427
- EmitArgs ( ) ;
428
- il . Emit ( OpCodes . Call ,
429
- typeof ( Delegate ) . GetInstanceMethod ( nameof ( Delegate . DynamicInvoke ) ) ) ;
430
402
}
431
403
else
432
404
{
433
405
/*
434
- * return this._method. DynamicInvoke(new object[] { Value, args... });
406
+ * return this.DynamicInvoke(_method, new object[] { Value, args... });
435
407
*/
436
408
437
409
// TODO: Consider defining delegate types as needed for method signatures so the
438
410
// delegate invocations are not "dynamic". It would avoid boxing value types.
439
411
440
412
// Load the static field for the delegate that implements the method by marshalling to JS.
441
413
il . Emit ( OpCodes . Ldsfld , delegateField ) ;
442
-
443
- EmitArgs ( ) ;
444
-
445
- // Invoke the delegate.
446
- il . Emit (
447
- OpCodes . Callvirt ,
448
- typeof ( Delegate ) . GetInstanceMethod ( nameof ( Delegate . DynamicInvoke ) ) ) ;
449
414
}
450
415
416
+ EmitArgs ( ) ;
417
+
418
+ // Invoke the delegate.
419
+ il . Emit ( OpCodes . Callvirt , typeof ( JSInterface ) . GetMethod (
420
+ nameof ( Delegate . DynamicInvoke ) , BindingFlags . NonPublic | BindingFlags . Instance ) ! ) ;
451
421
452
422
// Return the result, casting to the return type if necessary.
453
423
if ( method . ReturnType == typeof ( void ) )
0 commit comments