From 121ad5ea03b56545cba2b3541146b9e107205984 Mon Sep 17 00:00:00 2001 From: Jonathan Pryor Date: Fri, 18 Dec 2020 13:13:44 -0500 Subject: [PATCH] [Java.Interop] Prevent premature collection w/ JniInstance* MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Context: https://github.com/xamarin/xamarin-android/commit/e88cfbcf9ff4f4e179a60f1e8af2bef3537a66b4 While writing the commit message for xamarin/xamarin-android@e88cfbcf, it occurred to me that the same fundamental scenario of: CallIntoJava (new JavaLangObjectSubclass ().Handle); // GC collects instance after `.Handle`, before `CallIntoJava()` could apply to `JniPeerMembers.JniInstanceMethods.Invoke*()` invocations: JniArgumentValue* __args = …; _members.InstanceMethods.InvokeVirtualObjectMethod (__id, this, __args); // What prevents `this` from being collected "too soon"? Address this: update `JniPeerMembers.JniInstanceMethods.Invoke*()` so that there is a `GC.KeepAlive(self)` after accessing `self.PeerReference`. This will ensure that `self` isn't collected "during" `JniEnvironment.InstanceMethods.Call*Method()` invocations. Likewise update `JniPeerMembers.JniInstanceFields.Get*Value()` and `JniPeerMembers.JniInstanceFields.Set*Value()` so that there is a `GC.KeepAlive(self)` after the `JniEnvironment.InstanceFields.*` invocation. --- .../Java.Interop/JniPeerMembers.JniFields.cs | 47 ++++- .../Java.Interop/JniPeerMembers.JniFields.tt | 7 +- ...niPeerMembers.JniInstanceMethods_Invoke.cs | 184 +++++++++++------- ...niPeerMembers.JniInstanceMethods_Invoke.tt | 20 +- 4 files changed, 168 insertions(+), 90 deletions(-) diff --git a/src/Java.Interop/Java.Interop/JniPeerMembers.JniFields.cs b/src/Java.Interop/Java.Interop/JniPeerMembers.JniFields.cs index 134f21a9d..ea9d0cb51 100644 --- a/src/Java.Interop/Java.Interop/JniPeerMembers.JniFields.cs +++ b/src/Java.Interop/Java.Interop/JniPeerMembers.JniFields.cs @@ -1,5 +1,7 @@ #nullable enable +using System; + namespace Java.Interop { partial class JniPeerMembers { @@ -12,7 +14,9 @@ public bool GetBooleanValue ( JniPeerMembers.AssertSelf (self); var f = GetFieldInfo (encodedMember); - return JniEnvironment.InstanceFields.GetBooleanField (self.PeerReference, f); + var r = JniEnvironment.InstanceFields.GetBooleanField (self.PeerReference, f); + GC.KeepAlive (self); + return r; } public void SetValue (string encodedMember, IJavaPeerable self, bool value) @@ -21,6 +25,7 @@ public void SetValue (string encodedMember, IJavaPeerable self, bool value) var f = GetFieldInfo (encodedMember); JniEnvironment.InstanceFields.SetBooleanField (self.PeerReference, f, value); + GC.KeepAlive (self); } public sbyte GetSByteValue ( @@ -30,7 +35,9 @@ public sbyte GetSByteValue ( JniPeerMembers.AssertSelf (self); var f = GetFieldInfo (encodedMember); - return JniEnvironment.InstanceFields.GetByteField (self.PeerReference, f); + var r = JniEnvironment.InstanceFields.GetByteField (self.PeerReference, f); + GC.KeepAlive (self); + return r; } public void SetValue (string encodedMember, IJavaPeerable self, sbyte value) @@ -39,6 +46,7 @@ public void SetValue (string encodedMember, IJavaPeerable self, sbyte value) var f = GetFieldInfo (encodedMember); JniEnvironment.InstanceFields.SetByteField (self.PeerReference, f, value); + GC.KeepAlive (self); } public char GetCharValue ( @@ -48,7 +56,9 @@ public char GetCharValue ( JniPeerMembers.AssertSelf (self); var f = GetFieldInfo (encodedMember); - return JniEnvironment.InstanceFields.GetCharField (self.PeerReference, f); + var r = JniEnvironment.InstanceFields.GetCharField (self.PeerReference, f); + GC.KeepAlive (self); + return r; } public void SetValue (string encodedMember, IJavaPeerable self, char value) @@ -57,6 +67,7 @@ public void SetValue (string encodedMember, IJavaPeerable self, char value) var f = GetFieldInfo (encodedMember); JniEnvironment.InstanceFields.SetCharField (self.PeerReference, f, value); + GC.KeepAlive (self); } public short GetInt16Value ( @@ -66,7 +77,9 @@ public short GetInt16Value ( JniPeerMembers.AssertSelf (self); var f = GetFieldInfo (encodedMember); - return JniEnvironment.InstanceFields.GetShortField (self.PeerReference, f); + var r = JniEnvironment.InstanceFields.GetShortField (self.PeerReference, f); + GC.KeepAlive (self); + return r; } public void SetValue (string encodedMember, IJavaPeerable self, short value) @@ -75,6 +88,7 @@ public void SetValue (string encodedMember, IJavaPeerable self, short value) var f = GetFieldInfo (encodedMember); JniEnvironment.InstanceFields.SetShortField (self.PeerReference, f, value); + GC.KeepAlive (self); } public int GetInt32Value ( @@ -84,7 +98,9 @@ public int GetInt32Value ( JniPeerMembers.AssertSelf (self); var f = GetFieldInfo (encodedMember); - return JniEnvironment.InstanceFields.GetIntField (self.PeerReference, f); + var r = JniEnvironment.InstanceFields.GetIntField (self.PeerReference, f); + GC.KeepAlive (self); + return r; } public void SetValue (string encodedMember, IJavaPeerable self, int value) @@ -93,6 +109,7 @@ public void SetValue (string encodedMember, IJavaPeerable self, int value) var f = GetFieldInfo (encodedMember); JniEnvironment.InstanceFields.SetIntField (self.PeerReference, f, value); + GC.KeepAlive (self); } public long GetInt64Value ( @@ -102,7 +119,9 @@ public long GetInt64Value ( JniPeerMembers.AssertSelf (self); var f = GetFieldInfo (encodedMember); - return JniEnvironment.InstanceFields.GetLongField (self.PeerReference, f); + var r = JniEnvironment.InstanceFields.GetLongField (self.PeerReference, f); + GC.KeepAlive (self); + return r; } public void SetValue (string encodedMember, IJavaPeerable self, long value) @@ -111,6 +130,7 @@ public void SetValue (string encodedMember, IJavaPeerable self, long value) var f = GetFieldInfo (encodedMember); JniEnvironment.InstanceFields.SetLongField (self.PeerReference, f, value); + GC.KeepAlive (self); } public float GetSingleValue ( @@ -120,7 +140,9 @@ public float GetSingleValue ( JniPeerMembers.AssertSelf (self); var f = GetFieldInfo (encodedMember); - return JniEnvironment.InstanceFields.GetFloatField (self.PeerReference, f); + var r = JniEnvironment.InstanceFields.GetFloatField (self.PeerReference, f); + GC.KeepAlive (self); + return r; } public void SetValue (string encodedMember, IJavaPeerable self, float value) @@ -129,6 +151,7 @@ public void SetValue (string encodedMember, IJavaPeerable self, float value) var f = GetFieldInfo (encodedMember); JniEnvironment.InstanceFields.SetFloatField (self.PeerReference, f, value); + GC.KeepAlive (self); } public double GetDoubleValue ( @@ -138,7 +161,9 @@ public double GetDoubleValue ( JniPeerMembers.AssertSelf (self); var f = GetFieldInfo (encodedMember); - return JniEnvironment.InstanceFields.GetDoubleField (self.PeerReference, f); + var r = JniEnvironment.InstanceFields.GetDoubleField (self.PeerReference, f); + GC.KeepAlive (self); + return r; } public void SetValue (string encodedMember, IJavaPeerable self, double value) @@ -147,6 +172,7 @@ public void SetValue (string encodedMember, IJavaPeerable self, double value) var f = GetFieldInfo (encodedMember); JniEnvironment.InstanceFields.SetDoubleField (self.PeerReference, f, value); + GC.KeepAlive (self); } public JniObjectReference GetObjectValue ( @@ -156,7 +182,9 @@ public JniObjectReference GetObjectValue ( JniPeerMembers.AssertSelf (self); var f = GetFieldInfo (encodedMember); - return JniEnvironment.InstanceFields.GetObjectField (self.PeerReference, f); + var r = JniEnvironment.InstanceFields.GetObjectField (self.PeerReference, f); + GC.KeepAlive (self); + return r; } public void SetValue (string encodedMember, IJavaPeerable self, JniObjectReference value) @@ -165,6 +193,7 @@ public void SetValue (string encodedMember, IJavaPeerable self, JniObjectReferen var f = GetFieldInfo (encodedMember); JniEnvironment.InstanceFields.SetObjectField (self.PeerReference, f, value); + GC.KeepAlive (self); } } diff --git a/src/Java.Interop/Java.Interop/JniPeerMembers.JniFields.tt b/src/Java.Interop/Java.Interop/JniPeerMembers.JniFields.tt index 0c333b41f..f569b372b 100644 --- a/src/Java.Interop/Java.Interop/JniPeerMembers.JniFields.tt +++ b/src/Java.Interop/Java.Interop/JniPeerMembers.JniFields.tt @@ -19,6 +19,8 @@ #> #nullable enable +using System; + namespace Java.Interop { partial class JniPeerMembers { @@ -34,7 +36,9 @@ namespace Java.Interop { JniPeerMembers.AssertSelf (self); var f = GetFieldInfo (encodedMember); - return JniEnvironment.InstanceFields.Get<#= info.JniCallType #>Field (self.PeerReference, f); + var r = JniEnvironment.InstanceFields.Get<#= info.JniCallType #>Field (self.PeerReference, f); + GC.KeepAlive (self); + return r; } public void SetValue (string encodedMember, IJavaPeerable self, <#= info.ParameterType #> value) @@ -43,6 +47,7 @@ namespace Java.Interop { var f = GetFieldInfo (encodedMember); JniEnvironment.InstanceFields.Set<#= info.JniCallType #>Field (self.PeerReference, f, value); + GC.KeepAlive (self); } <# } diff --git a/src/Java.Interop/Java.Interop/JniPeerMembers.JniInstanceMethods_Invoke.cs b/src/Java.Interop/Java.Interop/JniPeerMembers.JniInstanceMethods_Invoke.cs index a2eb530f1..df5325a22 100644 --- a/src/Java.Interop/Java.Interop/JniPeerMembers.JniInstanceMethods_Invoke.cs +++ b/src/Java.Interop/Java.Interop/JniPeerMembers.JniInstanceMethods_Invoke.cs @@ -15,6 +15,7 @@ public unsafe void InvokeAbstractVoidMethod (string encodedMember, IJavaPeerable var m = GetMethodInfo (encodedMember); JniEnvironment.InstanceMethods.CallVoidMethod (self.PeerReference, m, parameters); + GC.KeepAlive (self); return; } @@ -26,11 +27,13 @@ public unsafe void InvokeVirtualVoidMethod (string encodedMember, IJavaPeerable if (Members.UsesVirtualDispatch (self, declaringType)) { var m = GetMethodInfo (encodedMember); JniEnvironment.InstanceMethods.CallVoidMethod (self.PeerReference, m, parameters); + GC.KeepAlive (self); return; } var j = Members.GetPeerMembers (self); var n = j.InstanceMethods.GetMethodInfo (encodedMember); JniEnvironment.InstanceMethods.CallNonvirtualVoidMethod (self.PeerReference, j.JniPeerType.PeerReference, n, parameters); + GC.KeepAlive (self); return; } @@ -41,6 +44,7 @@ public unsafe void InvokeNonvirtualVoidMethod (string encodedMember, IJavaPeerab var m = GetMethodInfo (encodedMember); JniEnvironment.InstanceMethods.CallNonvirtualVoidMethod (self.PeerReference, JniPeerType.PeerReference, m, parameters); + GC.KeepAlive (self); return; } @@ -50,8 +54,9 @@ public unsafe bool InvokeAbstractBooleanMethod (string encodedMember, IJavaPeera var m = GetMethodInfo (encodedMember); - return JniEnvironment.InstanceMethods.CallBooleanMethod (self.PeerReference, m, parameters); - + var r = JniEnvironment.InstanceMethods.CallBooleanMethod (self.PeerReference, m, parameters); + GC.KeepAlive (self); + return r; } public unsafe bool InvokeVirtualBooleanMethod (string encodedMember, IJavaPeerable self, JniArgumentValue* parameters) @@ -61,13 +66,15 @@ public unsafe bool InvokeVirtualBooleanMethod (string encodedMember, IJavaPeerab var declaringType = DeclaringType; if (Members.UsesVirtualDispatch (self, declaringType)) { var m = GetMethodInfo (encodedMember); - return JniEnvironment.InstanceMethods.CallBooleanMethod (self.PeerReference, m, parameters); - + var _nr = JniEnvironment.InstanceMethods.CallBooleanMethod (self.PeerReference, m, parameters); + GC.KeepAlive (self); + return _nr; } var j = Members.GetPeerMembers (self); var n = j.InstanceMethods.GetMethodInfo (encodedMember); - return JniEnvironment.InstanceMethods.CallNonvirtualBooleanMethod (self.PeerReference, j.JniPeerType.PeerReference, n, parameters); - + var r = JniEnvironment.InstanceMethods.CallNonvirtualBooleanMethod (self.PeerReference, j.JniPeerType.PeerReference, n, parameters); + GC.KeepAlive (self); + return r; } public unsafe bool InvokeNonvirtualBooleanMethod (string encodedMember, IJavaPeerable self, JniArgumentValue* parameters) @@ -76,8 +83,9 @@ public unsafe bool InvokeNonvirtualBooleanMethod (string encodedMember, IJavaPee var m = GetMethodInfo (encodedMember); - return JniEnvironment.InstanceMethods.CallNonvirtualBooleanMethod (self.PeerReference, JniPeerType.PeerReference, m, parameters); - + var r = JniEnvironment.InstanceMethods.CallNonvirtualBooleanMethod (self.PeerReference, JniPeerType.PeerReference, m, parameters); + GC.KeepAlive (self); + return r; } public unsafe sbyte InvokeAbstractSByteMethod (string encodedMember, IJavaPeerable self, JniArgumentValue* parameters) @@ -86,8 +94,9 @@ public unsafe sbyte InvokeAbstractSByteMethod (string encodedMember, IJavaPeerab var m = GetMethodInfo (encodedMember); - return JniEnvironment.InstanceMethods.CallByteMethod (self.PeerReference, m, parameters); - + var r = JniEnvironment.InstanceMethods.CallByteMethod (self.PeerReference, m, parameters); + GC.KeepAlive (self); + return r; } public unsafe sbyte InvokeVirtualSByteMethod (string encodedMember, IJavaPeerable self, JniArgumentValue* parameters) @@ -97,13 +106,15 @@ public unsafe sbyte InvokeVirtualSByteMethod (string encodedMember, IJavaPeerabl var declaringType = DeclaringType; if (Members.UsesVirtualDispatch (self, declaringType)) { var m = GetMethodInfo (encodedMember); - return JniEnvironment.InstanceMethods.CallByteMethod (self.PeerReference, m, parameters); - + var _nr = JniEnvironment.InstanceMethods.CallByteMethod (self.PeerReference, m, parameters); + GC.KeepAlive (self); + return _nr; } var j = Members.GetPeerMembers (self); var n = j.InstanceMethods.GetMethodInfo (encodedMember); - return JniEnvironment.InstanceMethods.CallNonvirtualByteMethod (self.PeerReference, j.JniPeerType.PeerReference, n, parameters); - + var r = JniEnvironment.InstanceMethods.CallNonvirtualByteMethod (self.PeerReference, j.JniPeerType.PeerReference, n, parameters); + GC.KeepAlive (self); + return r; } public unsafe sbyte InvokeNonvirtualSByteMethod (string encodedMember, IJavaPeerable self, JniArgumentValue* parameters) @@ -112,8 +123,9 @@ public unsafe sbyte InvokeNonvirtualSByteMethod (string encodedMember, IJavaPeer var m = GetMethodInfo (encodedMember); - return JniEnvironment.InstanceMethods.CallNonvirtualByteMethod (self.PeerReference, JniPeerType.PeerReference, m, parameters); - + var r = JniEnvironment.InstanceMethods.CallNonvirtualByteMethod (self.PeerReference, JniPeerType.PeerReference, m, parameters); + GC.KeepAlive (self); + return r; } public unsafe char InvokeAbstractCharMethod (string encodedMember, IJavaPeerable self, JniArgumentValue* parameters) @@ -122,8 +134,9 @@ public unsafe char InvokeAbstractCharMethod (string encodedMember, IJavaPeerable var m = GetMethodInfo (encodedMember); - return JniEnvironment.InstanceMethods.CallCharMethod (self.PeerReference, m, parameters); - + var r = JniEnvironment.InstanceMethods.CallCharMethod (self.PeerReference, m, parameters); + GC.KeepAlive (self); + return r; } public unsafe char InvokeVirtualCharMethod (string encodedMember, IJavaPeerable self, JniArgumentValue* parameters) @@ -133,13 +146,15 @@ public unsafe char InvokeVirtualCharMethod (string encodedMember, IJavaPeerable var declaringType = DeclaringType; if (Members.UsesVirtualDispatch (self, declaringType)) { var m = GetMethodInfo (encodedMember); - return JniEnvironment.InstanceMethods.CallCharMethod (self.PeerReference, m, parameters); - + var _nr = JniEnvironment.InstanceMethods.CallCharMethod (self.PeerReference, m, parameters); + GC.KeepAlive (self); + return _nr; } var j = Members.GetPeerMembers (self); var n = j.InstanceMethods.GetMethodInfo (encodedMember); - return JniEnvironment.InstanceMethods.CallNonvirtualCharMethod (self.PeerReference, j.JniPeerType.PeerReference, n, parameters); - + var r = JniEnvironment.InstanceMethods.CallNonvirtualCharMethod (self.PeerReference, j.JniPeerType.PeerReference, n, parameters); + GC.KeepAlive (self); + return r; } public unsafe char InvokeNonvirtualCharMethod (string encodedMember, IJavaPeerable self, JniArgumentValue* parameters) @@ -148,8 +163,9 @@ public unsafe char InvokeNonvirtualCharMethod (string encodedMember, IJavaPeerab var m = GetMethodInfo (encodedMember); - return JniEnvironment.InstanceMethods.CallNonvirtualCharMethod (self.PeerReference, JniPeerType.PeerReference, m, parameters); - + var r = JniEnvironment.InstanceMethods.CallNonvirtualCharMethod (self.PeerReference, JniPeerType.PeerReference, m, parameters); + GC.KeepAlive (self); + return r; } public unsafe short InvokeAbstractInt16Method (string encodedMember, IJavaPeerable self, JniArgumentValue* parameters) @@ -158,8 +174,9 @@ public unsafe short InvokeAbstractInt16Method (string encodedMember, IJavaPeerab var m = GetMethodInfo (encodedMember); - return JniEnvironment.InstanceMethods.CallShortMethod (self.PeerReference, m, parameters); - + var r = JniEnvironment.InstanceMethods.CallShortMethod (self.PeerReference, m, parameters); + GC.KeepAlive (self); + return r; } public unsafe short InvokeVirtualInt16Method (string encodedMember, IJavaPeerable self, JniArgumentValue* parameters) @@ -169,13 +186,15 @@ public unsafe short InvokeVirtualInt16Method (string encodedMember, IJavaPeerabl var declaringType = DeclaringType; if (Members.UsesVirtualDispatch (self, declaringType)) { var m = GetMethodInfo (encodedMember); - return JniEnvironment.InstanceMethods.CallShortMethod (self.PeerReference, m, parameters); - + var _nr = JniEnvironment.InstanceMethods.CallShortMethod (self.PeerReference, m, parameters); + GC.KeepAlive (self); + return _nr; } var j = Members.GetPeerMembers (self); var n = j.InstanceMethods.GetMethodInfo (encodedMember); - return JniEnvironment.InstanceMethods.CallNonvirtualShortMethod (self.PeerReference, j.JniPeerType.PeerReference, n, parameters); - + var r = JniEnvironment.InstanceMethods.CallNonvirtualShortMethod (self.PeerReference, j.JniPeerType.PeerReference, n, parameters); + GC.KeepAlive (self); + return r; } public unsafe short InvokeNonvirtualInt16Method (string encodedMember, IJavaPeerable self, JniArgumentValue* parameters) @@ -184,8 +203,9 @@ public unsafe short InvokeNonvirtualInt16Method (string encodedMember, IJavaPeer var m = GetMethodInfo (encodedMember); - return JniEnvironment.InstanceMethods.CallNonvirtualShortMethod (self.PeerReference, JniPeerType.PeerReference, m, parameters); - + var r = JniEnvironment.InstanceMethods.CallNonvirtualShortMethod (self.PeerReference, JniPeerType.PeerReference, m, parameters); + GC.KeepAlive (self); + return r; } public unsafe int InvokeAbstractInt32Method (string encodedMember, IJavaPeerable self, JniArgumentValue* parameters) @@ -194,8 +214,9 @@ public unsafe int InvokeAbstractInt32Method (string encodedMember, IJavaPeerable var m = GetMethodInfo (encodedMember); - return JniEnvironment.InstanceMethods.CallIntMethod (self.PeerReference, m, parameters); - + var r = JniEnvironment.InstanceMethods.CallIntMethod (self.PeerReference, m, parameters); + GC.KeepAlive (self); + return r; } public unsafe int InvokeVirtualInt32Method (string encodedMember, IJavaPeerable self, JniArgumentValue* parameters) @@ -205,13 +226,15 @@ public unsafe int InvokeVirtualInt32Method (string encodedMember, IJavaPeerable var declaringType = DeclaringType; if (Members.UsesVirtualDispatch (self, declaringType)) { var m = GetMethodInfo (encodedMember); - return JniEnvironment.InstanceMethods.CallIntMethod (self.PeerReference, m, parameters); - + var _nr = JniEnvironment.InstanceMethods.CallIntMethod (self.PeerReference, m, parameters); + GC.KeepAlive (self); + return _nr; } var j = Members.GetPeerMembers (self); var n = j.InstanceMethods.GetMethodInfo (encodedMember); - return JniEnvironment.InstanceMethods.CallNonvirtualIntMethod (self.PeerReference, j.JniPeerType.PeerReference, n, parameters); - + var r = JniEnvironment.InstanceMethods.CallNonvirtualIntMethod (self.PeerReference, j.JniPeerType.PeerReference, n, parameters); + GC.KeepAlive (self); + return r; } public unsafe int InvokeNonvirtualInt32Method (string encodedMember, IJavaPeerable self, JniArgumentValue* parameters) @@ -220,8 +243,9 @@ public unsafe int InvokeNonvirtualInt32Method (string encodedMember, IJavaPeerab var m = GetMethodInfo (encodedMember); - return JniEnvironment.InstanceMethods.CallNonvirtualIntMethod (self.PeerReference, JniPeerType.PeerReference, m, parameters); - + var r = JniEnvironment.InstanceMethods.CallNonvirtualIntMethod (self.PeerReference, JniPeerType.PeerReference, m, parameters); + GC.KeepAlive (self); + return r; } public unsafe long InvokeAbstractInt64Method (string encodedMember, IJavaPeerable self, JniArgumentValue* parameters) @@ -230,8 +254,9 @@ public unsafe long InvokeAbstractInt64Method (string encodedMember, IJavaPeerabl var m = GetMethodInfo (encodedMember); - return JniEnvironment.InstanceMethods.CallLongMethod (self.PeerReference, m, parameters); - + var r = JniEnvironment.InstanceMethods.CallLongMethod (self.PeerReference, m, parameters); + GC.KeepAlive (self); + return r; } public unsafe long InvokeVirtualInt64Method (string encodedMember, IJavaPeerable self, JniArgumentValue* parameters) @@ -241,13 +266,15 @@ public unsafe long InvokeVirtualInt64Method (string encodedMember, IJavaPeerable var declaringType = DeclaringType; if (Members.UsesVirtualDispatch (self, declaringType)) { var m = GetMethodInfo (encodedMember); - return JniEnvironment.InstanceMethods.CallLongMethod (self.PeerReference, m, parameters); - + var _nr = JniEnvironment.InstanceMethods.CallLongMethod (self.PeerReference, m, parameters); + GC.KeepAlive (self); + return _nr; } var j = Members.GetPeerMembers (self); var n = j.InstanceMethods.GetMethodInfo (encodedMember); - return JniEnvironment.InstanceMethods.CallNonvirtualLongMethod (self.PeerReference, j.JniPeerType.PeerReference, n, parameters); - + var r = JniEnvironment.InstanceMethods.CallNonvirtualLongMethod (self.PeerReference, j.JniPeerType.PeerReference, n, parameters); + GC.KeepAlive (self); + return r; } public unsafe long InvokeNonvirtualInt64Method (string encodedMember, IJavaPeerable self, JniArgumentValue* parameters) @@ -256,8 +283,9 @@ public unsafe long InvokeNonvirtualInt64Method (string encodedMember, IJavaPeera var m = GetMethodInfo (encodedMember); - return JniEnvironment.InstanceMethods.CallNonvirtualLongMethod (self.PeerReference, JniPeerType.PeerReference, m, parameters); - + var r = JniEnvironment.InstanceMethods.CallNonvirtualLongMethod (self.PeerReference, JniPeerType.PeerReference, m, parameters); + GC.KeepAlive (self); + return r; } public unsafe float InvokeAbstractSingleMethod (string encodedMember, IJavaPeerable self, JniArgumentValue* parameters) @@ -266,8 +294,9 @@ public unsafe float InvokeAbstractSingleMethod (string encodedMember, IJavaPeera var m = GetMethodInfo (encodedMember); - return JniEnvironment.InstanceMethods.CallFloatMethod (self.PeerReference, m, parameters); - + var r = JniEnvironment.InstanceMethods.CallFloatMethod (self.PeerReference, m, parameters); + GC.KeepAlive (self); + return r; } public unsafe float InvokeVirtualSingleMethod (string encodedMember, IJavaPeerable self, JniArgumentValue* parameters) @@ -277,13 +306,15 @@ public unsafe float InvokeVirtualSingleMethod (string encodedMember, IJavaPeerab var declaringType = DeclaringType; if (Members.UsesVirtualDispatch (self, declaringType)) { var m = GetMethodInfo (encodedMember); - return JniEnvironment.InstanceMethods.CallFloatMethod (self.PeerReference, m, parameters); - + var _nr = JniEnvironment.InstanceMethods.CallFloatMethod (self.PeerReference, m, parameters); + GC.KeepAlive (self); + return _nr; } var j = Members.GetPeerMembers (self); var n = j.InstanceMethods.GetMethodInfo (encodedMember); - return JniEnvironment.InstanceMethods.CallNonvirtualFloatMethod (self.PeerReference, j.JniPeerType.PeerReference, n, parameters); - + var r = JniEnvironment.InstanceMethods.CallNonvirtualFloatMethod (self.PeerReference, j.JniPeerType.PeerReference, n, parameters); + GC.KeepAlive (self); + return r; } public unsafe float InvokeNonvirtualSingleMethod (string encodedMember, IJavaPeerable self, JniArgumentValue* parameters) @@ -292,8 +323,9 @@ public unsafe float InvokeNonvirtualSingleMethod (string encodedMember, IJavaPee var m = GetMethodInfo (encodedMember); - return JniEnvironment.InstanceMethods.CallNonvirtualFloatMethod (self.PeerReference, JniPeerType.PeerReference, m, parameters); - + var r = JniEnvironment.InstanceMethods.CallNonvirtualFloatMethod (self.PeerReference, JniPeerType.PeerReference, m, parameters); + GC.KeepAlive (self); + return r; } public unsafe double InvokeAbstractDoubleMethod (string encodedMember, IJavaPeerable self, JniArgumentValue* parameters) @@ -302,8 +334,9 @@ public unsafe double InvokeAbstractDoubleMethod (string encodedMember, IJavaPeer var m = GetMethodInfo (encodedMember); - return JniEnvironment.InstanceMethods.CallDoubleMethod (self.PeerReference, m, parameters); - + var r = JniEnvironment.InstanceMethods.CallDoubleMethod (self.PeerReference, m, parameters); + GC.KeepAlive (self); + return r; } public unsafe double InvokeVirtualDoubleMethod (string encodedMember, IJavaPeerable self, JniArgumentValue* parameters) @@ -313,13 +346,15 @@ public unsafe double InvokeVirtualDoubleMethod (string encodedMember, IJavaPeera var declaringType = DeclaringType; if (Members.UsesVirtualDispatch (self, declaringType)) { var m = GetMethodInfo (encodedMember); - return JniEnvironment.InstanceMethods.CallDoubleMethod (self.PeerReference, m, parameters); - + var _nr = JniEnvironment.InstanceMethods.CallDoubleMethod (self.PeerReference, m, parameters); + GC.KeepAlive (self); + return _nr; } var j = Members.GetPeerMembers (self); var n = j.InstanceMethods.GetMethodInfo (encodedMember); - return JniEnvironment.InstanceMethods.CallNonvirtualDoubleMethod (self.PeerReference, j.JniPeerType.PeerReference, n, parameters); - + var r = JniEnvironment.InstanceMethods.CallNonvirtualDoubleMethod (self.PeerReference, j.JniPeerType.PeerReference, n, parameters); + GC.KeepAlive (self); + return r; } public unsafe double InvokeNonvirtualDoubleMethod (string encodedMember, IJavaPeerable self, JniArgumentValue* parameters) @@ -328,8 +363,9 @@ public unsafe double InvokeNonvirtualDoubleMethod (string encodedMember, IJavaPe var m = GetMethodInfo (encodedMember); - return JniEnvironment.InstanceMethods.CallNonvirtualDoubleMethod (self.PeerReference, JniPeerType.PeerReference, m, parameters); - + var r = JniEnvironment.InstanceMethods.CallNonvirtualDoubleMethod (self.PeerReference, JniPeerType.PeerReference, m, parameters); + GC.KeepAlive (self); + return r; } public unsafe JniObjectReference InvokeAbstractObjectMethod (string encodedMember, IJavaPeerable self, JniArgumentValue* parameters) @@ -338,8 +374,9 @@ public unsafe JniObjectReference InvokeAbstractObjectMethod (string encodedMembe var m = GetMethodInfo (encodedMember); - return JniEnvironment.InstanceMethods.CallObjectMethod (self.PeerReference, m, parameters); - + var r = JniEnvironment.InstanceMethods.CallObjectMethod (self.PeerReference, m, parameters); + GC.KeepAlive (self); + return r; } public unsafe JniObjectReference InvokeVirtualObjectMethod (string encodedMember, IJavaPeerable self, JniArgumentValue* parameters) @@ -349,13 +386,15 @@ public unsafe JniObjectReference InvokeVirtualObjectMethod (string encodedMember var declaringType = DeclaringType; if (Members.UsesVirtualDispatch (self, declaringType)) { var m = GetMethodInfo (encodedMember); - return JniEnvironment.InstanceMethods.CallObjectMethod (self.PeerReference, m, parameters); - + var _nr = JniEnvironment.InstanceMethods.CallObjectMethod (self.PeerReference, m, parameters); + GC.KeepAlive (self); + return _nr; } var j = Members.GetPeerMembers (self); var n = j.InstanceMethods.GetMethodInfo (encodedMember); - return JniEnvironment.InstanceMethods.CallNonvirtualObjectMethod (self.PeerReference, j.JniPeerType.PeerReference, n, parameters); - + var r = JniEnvironment.InstanceMethods.CallNonvirtualObjectMethod (self.PeerReference, j.JniPeerType.PeerReference, n, parameters); + GC.KeepAlive (self); + return r; } public unsafe JniObjectReference InvokeNonvirtualObjectMethod (string encodedMember, IJavaPeerable self, JniArgumentValue* parameters) @@ -364,8 +403,9 @@ public unsafe JniObjectReference InvokeNonvirtualObjectMethod (string encodedMem var m = GetMethodInfo (encodedMember); - return JniEnvironment.InstanceMethods.CallNonvirtualObjectMethod (self.PeerReference, JniPeerType.PeerReference, m, parameters); - + var r = JniEnvironment.InstanceMethods.CallNonvirtualObjectMethod (self.PeerReference, JniPeerType.PeerReference, m, parameters); + GC.KeepAlive (self); + return r; } } } diff --git a/src/Java.Interop/Java.Interop/JniPeerMembers.JniInstanceMethods_Invoke.tt b/src/Java.Interop/Java.Interop/JniPeerMembers.JniInstanceMethods_Invoke.tt index 57babde01..04f8178fd 100644 --- a/src/Java.Interop/Java.Interop/JniPeerMembers.JniInstanceMethods_Invoke.tt +++ b/src/Java.Interop/Java.Interop/JniPeerMembers.JniInstanceMethods_Invoke.tt @@ -37,8 +37,9 @@ namespace Java.Interop { var m = GetMethodInfo (encodedMember); - <#= returnType.ReturnType != "void" ? "return " : "" #>JniEnvironment.InstanceMethods.Call<#= returnType.JniCallType #>Method (self.PeerReference, m, parameters); - <#= returnType.ReturnType == "void" ? "return;" : "" #> + <#= returnType.ReturnType != "void" ? "var r = " : "" #>JniEnvironment.InstanceMethods.Call<#= returnType.JniCallType #>Method (self.PeerReference, m, parameters); + GC.KeepAlive (self); + return<#= returnType.ReturnType == "void" ? "" : " r" #>; } public unsafe <#= returnType.ReturnType #> InvokeVirtual<#= returnType.ManagedType #>Method (string encodedMember, IJavaPeerable self, JniArgumentValue* parameters) @@ -48,13 +49,15 @@ namespace Java.Interop { var declaringType = DeclaringType; if (Members.UsesVirtualDispatch (self, declaringType)) { var m = GetMethodInfo (encodedMember); - <#= returnType.ReturnType != "void" ? "return " : "" #>JniEnvironment.InstanceMethods.Call<#= returnType.JniCallType #>Method (self.PeerReference, m, parameters); - <#= returnType.ReturnType == "void" ? "return;" : "" #> + <#= returnType.ReturnType != "void" ? "var _nr = " : "" #>JniEnvironment.InstanceMethods.Call<#= returnType.JniCallType #>Method (self.PeerReference, m, parameters); + GC.KeepAlive (self); + return<#= returnType.ReturnType == "void" ? "" : " _nr" #>; } var j = Members.GetPeerMembers (self); var n = j.InstanceMethods.GetMethodInfo (encodedMember); - <#= returnType.ReturnType != "void" ? "return " : "" #>JniEnvironment.InstanceMethods.CallNonvirtual<#= returnType.JniCallType #>Method (self.PeerReference, j.JniPeerType.PeerReference, n, parameters); - <#= returnType.ReturnType == "void" ? "return;" : "" #> + <#= returnType.ReturnType != "void" ? "var r = " : "" #>JniEnvironment.InstanceMethods.CallNonvirtual<#= returnType.JniCallType #>Method (self.PeerReference, j.JniPeerType.PeerReference, n, parameters); + GC.KeepAlive (self); + return<#= returnType.ReturnType == "void" ? "" : " r" #>; } public unsafe <#= returnType.ReturnType #> InvokeNonvirtual<#= returnType.ManagedType #>Method (string encodedMember, IJavaPeerable self, JniArgumentValue* parameters) @@ -63,8 +66,9 @@ namespace Java.Interop { var m = GetMethodInfo (encodedMember); - <#= returnType.ReturnType != "void" ? "return " : "" #>JniEnvironment.InstanceMethods.CallNonvirtual<#= returnType.JniCallType #>Method (self.PeerReference, JniPeerType.PeerReference, m, parameters); - <#= returnType.ReturnType == "void" ? "return;" : "" #> + <#= returnType.ReturnType != "void" ? "var r = " : "" #>JniEnvironment.InstanceMethods.CallNonvirtual<#= returnType.JniCallType #>Method (self.PeerReference, JniPeerType.PeerReference, m, parameters); + GC.KeepAlive (self); + return<#= returnType.ReturnType == "void" ? "" : " r" #>; } <# }