|
1 | 1 | using System; |
2 | 2 | using System.Collections.Generic; |
3 | 3 | using System.IO; |
| 4 | +using System.Linq; |
4 | 5 | using System.Linq.Expressions; |
5 | 6 | using System.Reflection; |
6 | 7 | using System.Reflection.Emit; |
|
12 | 13 | using Mono.Options; |
13 | 14 | using Mono.Collections.Generic; |
14 | 15 | using Java.Interop.Tools.Cecil; |
| 16 | +using System.Text; |
15 | 17 |
|
16 | 18 | #if _DUMP_REGISTER_NATIVE_MEMBERS |
17 | 19 | using Mono.Linq.Expressions; |
@@ -423,7 +425,7 @@ void CreateMarshalMethodAssembly (string path) |
423 | 425 | if (signature == null) |
424 | 426 | signature = builder.GetJniMethodSignature (method); |
425 | 427 |
|
426 | | - registrationElements.Add (CreateRegistration (name, signature, lambda, targetType, methodName)); |
| 428 | + registrationElements.Add (CreateRegistration (name, signature, lambda, targetType, methodName, dm)); |
427 | 429 |
|
428 | 430 | addedMethods.Add (methodName); |
429 | 431 | } |
@@ -469,17 +471,69 @@ void CreateMarshalMethodAssembly (string path) |
469 | 471 | typeof (string), |
470 | 472 | }); |
471 | 473 |
|
472 | | - static Expression CreateRegistration (string method, string signature, LambdaExpression lambda, ParameterExpression targetType, string methodName) |
| 474 | + static void CreateDelegateRuntimeManagedMethod (TypeBuilder tb, string name, Type returnType, Type[] parameterTypes) |
| 475 | + { |
| 476 | + var mb = tb.DefineMethod (name, |
| 477 | + System.Reflection.MethodAttributes.Public | |
| 478 | + System.Reflection.MethodAttributes.HideBySig | |
| 479 | + System.Reflection.MethodAttributes.NewSlot | |
| 480 | + System.Reflection.MethodAttributes.Virtual, |
| 481 | + CallingConventions.Standard, returnType, parameterTypes); |
| 482 | + mb.SetImplementationFlags (System.Reflection.MethodImplAttributes.Runtime | System.Reflection.MethodImplAttributes.Managed); |
| 483 | + } |
| 484 | + |
| 485 | + static Expression CreateRegistration (string method, string signature, LambdaExpression lambda, ParameterExpression targetType, string methodName, ModuleBuilder dm) |
473 | 486 | { |
474 | 487 | Expression registrationDelegateType = null; |
475 | 488 | if (lambda.Type.Assembly == typeof (object).Assembly || |
476 | 489 | lambda.Type.Assembly == typeof (System.Linq.Enumerable).Assembly) { |
477 | 490 | registrationDelegateType = Expression.Constant (lambda.Type, typeof (Type)); |
478 | 491 | } |
479 | 492 | else { |
| 493 | + string delegateTypeName; |
| 494 | + if (lambda.Type.Assembly.IsDynamic) { |
| 495 | + var typeNameBuilder = new StringBuilder ("__<$>_jni_marshal_"); |
| 496 | + var parameterTypes = new List<Type> (); |
| 497 | + foreach (var p in lambda.Parameters) { |
| 498 | + parameterTypes.Add (p.Type); |
| 499 | + } |
| 500 | + |
| 501 | + MarshalMemberBuilder.AddMarshalerTypeNameSuffix (typeNameBuilder, lambda.ReturnType, parameterTypes); |
| 502 | + |
| 503 | + var typeName = typeNameBuilder.ToString (); |
| 504 | + var existingType = dm.GetType (typeName); |
| 505 | + if (existingType == null) { |
| 506 | + var dtb = dm.DefineType (typeName, |
| 507 | + System.Reflection.TypeAttributes.AnsiClass | |
| 508 | + System.Reflection.TypeAttributes.Sealed, |
| 509 | + typeof (MulticastDelegate)); |
| 510 | + |
| 511 | + var dc = dtb.DefineConstructor ( |
| 512 | + System.Reflection.MethodAttributes.Public | |
| 513 | + System.Reflection.MethodAttributes.HideBySig | |
| 514 | + System.Reflection.MethodAttributes.RTSpecialName | |
| 515 | + System.Reflection.MethodAttributes.SpecialName, |
| 516 | + CallingConventions.Standard, new Type [] { typeof (object), typeof (IntPtr) }); |
| 517 | + dc.SetImplementationFlags (System.Reflection.MethodImplAttributes.Runtime | System.Reflection.MethodImplAttributes.Managed); |
| 518 | + |
| 519 | + CreateDelegateRuntimeManagedMethod (dtb, "Invoke", null, parameterTypes.ToArray ()); |
| 520 | + |
| 521 | + parameterTypes.Add (typeof (AsyncCallback)); |
| 522 | + parameterTypes.Add (typeof (object)); |
| 523 | + |
| 524 | + CreateDelegateRuntimeManagedMethod (dtb, "BeginInvoke", typeof (IAsyncResult), parameterTypes.ToArray ()); |
| 525 | + CreateDelegateRuntimeManagedMethod (dtb, "EndInvoke", typeof (bool), new Type [] { typeof (IAsyncResult) }); |
| 526 | + |
| 527 | + existingType = dtb.CreateType (); |
| 528 | + } |
| 529 | + |
| 530 | + delegateTypeName = existingType.FullName; |
| 531 | + } else |
| 532 | + delegateTypeName = lambda.Type.FullName; |
| 533 | + |
480 | 534 | Func<string, bool, Type> getType = Type.GetType; |
481 | 535 | registrationDelegateType = Expression.Call (getType.GetMethodInfo (), |
482 | | - Expression.Constant (lambda.Type.FullName, typeof (string)), |
| 536 | + Expression.Constant (delegateTypeName, typeof (string)), |
483 | 537 | Expression.Constant (true, typeof (bool))); |
484 | 538 | registrationDelegateType = Expression.Convert (registrationDelegateType, typeof (Type)); |
485 | 539 | } |
|
0 commit comments