diff --git a/src/Mono.Android/Android.Runtime/AndroidRuntime.cs b/src/Mono.Android/Android.Runtime/AndroidRuntime.cs index 778fee09692..0f65c689326 100644 --- a/src/Mono.Android/Android.Runtime/AndroidRuntime.cs +++ b/src/Mono.Android/Android.Runtime/AndroidRuntime.cs @@ -685,7 +685,7 @@ internal void RemovePeer (IJavaPeerable value, IntPtr hash) public override void ActivatePeer (IJavaPeerable? self, JniObjectReference reference, ConstructorInfo cinfo, object? []? argumentValues) { - Java.Interop.TypeManager.Activate (self, reference.Handle, cinfo, argumentValues); + Java.Interop.TypeManager.Activate (reference.Handle, cinfo, argumentValues); } protected override bool TryUnboxPeerObject (IJavaPeerable value, [NotNullWhen (true)]out object? result) diff --git a/src/Mono.Android/Android.Runtime/ConstructorBuilder.cs b/src/Mono.Android/Android.Runtime/ConstructorBuilder.cs deleted file mode 100644 index 20ecf1ac58a..00000000000 --- a/src/Mono.Android/Android.Runtime/ConstructorBuilder.cs +++ /dev/null @@ -1,56 +0,0 @@ -using System; -using System.Reflection; -using System.Reflection.Emit; -using System.Collections.Generic; -using System.Runtime.InteropServices; -using System.Threading; - -namespace Android.Runtime { - internal static class ConstructorBuilder { - static readonly MethodInfo newobject = -#if NETFRAMEWORK || NET_2_0 - typeof (System.Runtime.Serialization.FormatterServices).GetMethod ("GetUninitializedObject", BindingFlags.Public | BindingFlags.Static)!; -#else - typeof (System.Runtime.CompilerServices.RuntimeHelpers).GetMethod ("GetUninitializedObject", BindingFlags.Public | BindingFlags.Static)!; -#endif - static MethodInfo gettype = typeof (System.Type).GetMethod ("GetTypeFromHandle", BindingFlags.Public | BindingFlags.Static)!; - static FieldInfo handlefld = typeof (Java.Lang.Object).GetField ("handle", BindingFlags.NonPublic | BindingFlags.Instance)!; - static FieldInfo Throwable_handle = typeof (Java.Lang.Throwable).GetField ("handle", BindingFlags.NonPublic | BindingFlags.Instance)!; - - - internal static Action CreateDelegate (ConstructorInfo cinfo) { - var type = cinfo.DeclaringType; - var handle = handlefld; - if (typeof (Java.Lang.Throwable).IsAssignableFrom (type)) { - handle = Throwable_handle; - } - - DynamicMethod method = new DynamicMethod (DynamicMethodNameCounter.GetUniqueName (), typeof (void), new Type [] {typeof (IntPtr), typeof (object []) }, typeof (DynamicMethodNameCounter), true); - ILGenerator il = method.GetILGenerator (); - - il.DeclareLocal (typeof (object)); - - il.Emit (OpCodes.Ldtoken, type); - il.Emit (OpCodes.Call, gettype); - il.Emit (OpCodes.Call, newobject); - il.Emit (OpCodes.Stloc_0); - il.Emit (OpCodes.Ldloc_0); - il.Emit (OpCodes.Ldarg_0); - il.Emit (OpCodes.Stfld, handle); - - il.Emit (OpCodes.Ldloc_0); - - var len = cinfo.GetParameters ().Length; - for (int i = 0; i < len; i++) { - il.Emit (OpCodes.Ldarg, 1); - il.Emit (OpCodes.Ldc_I4, i); - il.Emit (OpCodes.Ldelem_Ref); - } - il.Emit (OpCodes.Call, cinfo); - - il.Emit (OpCodes.Ret); - - return (Action) method.CreateDelegate (typeof (Action )); - } - } -} diff --git a/src/Mono.Android/Java.Interop/TypeManager.cs b/src/Mono.Android/Java.Interop/TypeManager.cs index 9dbaed1c368..73ee1b84f25 100644 --- a/src/Mono.Android/Java.Interop/TypeManager.cs +++ b/src/Mono.Android/Java.Interop/TypeManager.cs @@ -166,14 +166,21 @@ static void n_Activate (IntPtr jnienv, IntPtr jclass, IntPtr typename_ptr, IntPt return; } - Activate (o, jobject, cinfo, parms); + Activate (jobject, cinfo, parms); } - internal static void Activate (IJavaPeerable? o, IntPtr jobject, ConstructorInfo cinfo, object? []? parms) + internal static void Activate (IntPtr jobject, ConstructorInfo cinfo, object? []? parms) { try { - var activator = ConstructorBuilder.CreateDelegate (cinfo); - activator (jobject, parms); + var newobj = RuntimeHelpers.GetUninitializedObject (cinfo.DeclaringType); + if (newobj is Java.Lang.Object o) { + o.handle = jobject; + } else if (newobj is Java.Lang.Throwable throwable) { + throwable.handle = jobject; + } else { + throw new InvalidOperationException ($"Unsupported type: '{newobj}'"); + } + cinfo.Invoke (newobj, parms); } catch (Exception e) { var m = string.Format ("Could not activate JNI Handle 0x{0} (key_handle 0x{1}) of Java type '{2}' as managed type '{3}'.", jobject.ToString ("x"), JNIEnv.IdentityHash! (jobject).ToString ("x"), JNIEnv.GetClassNameFromInstance (jobject), cinfo.DeclaringType.FullName); diff --git a/src/Mono.Android/Java.Lang/Object.cs b/src/Mono.Android/Java.Lang/Object.cs index 8d01578b39b..76618d7026e 100644 --- a/src/Mono.Android/Java.Lang/Object.cs +++ b/src/Mono.Android/Java.Lang/Object.cs @@ -24,7 +24,7 @@ public partial class Object : IDisposable, IJavaObject, IJavaObjectEx [NonSerialized] int refs_added; #pragma warning restore CS0649, CS0169, CS0414 [NonSerialized] JObjectRefType handle_type; - [NonSerialized] IntPtr handle; + [NonSerialized] internal IntPtr handle; [NonSerialized] bool needsActivation; [NonSerialized] bool isProxy; diff --git a/src/Mono.Android/Java.Lang/Throwable.cs b/src/Mono.Android/Java.Lang/Throwable.cs index c1a537e9a33..b483c557c76 100644 --- a/src/Mono.Android/Java.Lang/Throwable.cs +++ b/src/Mono.Android/Java.Lang/Throwable.cs @@ -16,7 +16,7 @@ public partial class Throwable : global::System.Exception, IJavaObject, IDisposa { protected bool is_generated; - IntPtr handle; + internal IntPtr handle; IntPtr key_handle; JObjectRefType handle_type; diff --git a/src/Mono.Android/Mono.Android.csproj b/src/Mono.Android/Mono.Android.csproj index 41419fc4984..fad2401b228 100644 --- a/src/Mono.Android/Mono.Android.csproj +++ b/src/Mono.Android/Mono.Android.csproj @@ -225,7 +225,6 @@ -