Skip to content

Commit b650c20

Browse files
committed
[Java.Interop] Do not dispose live references on return to JNI
Fixes #374 Also refactor the code generation to not create `_handle` variable when returning value to JNI Example generated marshal method: using Android.OS; using Android.Views; using Java.Interop; using System; public static IntPtr n_onCreateView_Landroid_view_LayoutInflater_Landroid_view_ViewGroup_Landroid_os_Bundle_ (IntPtr __jnienv, IntPtr __this, IntPtr inflater, IntPtr container, IntPtr savedInstanceState) { JniTransition jniTransition = new JniTransition (__jnienv); JniRuntime runtime = default(JniRuntime); global::Android.Views.View view = default(global::Android.Views.View); try { runtime = JniEnvironment.Runtime; JniRuntime.JniValueManager valueManager = runtime.ValueManager; valueManager.WaitForGCBridgeProcessing (); FragmentContainer value = valueManager.GetValue<FragmentContainer> (__this); LayoutInflater value2 = valueManager.GetValue<LayoutInflater> (inflater); ViewGroup value3 = valueManager.GetValue<ViewGroup> (container); Bundle value4 = valueManager.GetValue<Bundle> (savedInstanceState); view = value.OnCreateView (value2, value3, value4); JniObjectReference value5 = (view != null) ? view.PeerReference : default(JniObjectReference); return JniEnvironment.References.NewReturnToJniRef (value5); } catch (Exception ex) when (runtime.ExceptionShouldTransitionToJni (ex)) { jniTransition.SetPendingException (ex); return default(IntPtr); } finally { if (view != null) { ((IJavaPeerable)view).DisposeUnlessReferenced (); } jniTransition.Dispose (); } IntPtr intPtr = default(IntPtr); return intPtr; }
1 parent 94c6bb5 commit b650c20

File tree

1 file changed

+19
-8
lines changed

1 file changed

+19
-8
lines changed

src/Java.Interop/Java.Interop/JniRuntime.JniValueManager.cs

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -590,6 +590,17 @@ public override void DestroyGenericArgumentState (IJavaPeerable value, ref JniVa
590590
}
591591

592592
public override Expression CreateParameterFromManagedExpression (JniValueMarshalerContext context, ParameterExpression sourceValue, ParameterAttributes synchronize)
593+
{
594+
var r = CreateIntermediaryExpressionFromManagedExpression (context, sourceValue);
595+
596+
var h = Expression.Variable (typeof (IntPtr), sourceValue + "_handle");
597+
context.LocalVariables.Add (h);
598+
context.CreationStatements.Add (Expression.Assign (h, Expression.Property (r, "Handle")));
599+
600+
return h;
601+
}
602+
603+
Expression CreateIntermediaryExpressionFromManagedExpression (JniValueMarshalerContext context, ParameterExpression sourceValue)
593604
{
594605
var r = Expression.Variable (typeof (JniObjectReference), sourceValue.Name + "_ref");
595606
context.LocalVariables.Add (r);
@@ -598,19 +609,19 @@ public override Expression CreateParameterFromManagedExpression (JniValueMarshal
598609
test: Expression.Equal (Expression.Constant (null), sourceValue),
599610
ifTrue: Expression.Assign (r, Expression.New (typeof (JniObjectReference))),
600611
ifFalse: Expression.Assign (r, Expression.Property (sourceValue, "PeerReference"))));
601-
context.CleanupStatements.Add (DisposeObjectReference (r));
602612

603-
var h = Expression.Variable (typeof (IntPtr), sourceValue + "_handle");
604-
context.LocalVariables.Add (h);
605-
context.CreationStatements.Add (Expression.Assign (h, Expression.Property (r, "Handle")));
606-
return h;
613+
if (typeof (IJavaPeerable).GetTypeInfo ().IsAssignableFrom (sourceValue.Type.GetTypeInfo ())) {
614+
context.CleanupStatements.Add (Expression.IfThen (
615+
test: Expression.NotEqual (Expression.Constant (null), sourceValue),
616+
ifTrue: Expression.Call (sourceValue, typeof (IJavaPeerable).GetTypeInfo ().GetDeclaredMethod ("DisposeUnlessReferenced"))));
617+
}
618+
619+
return r;
607620
}
608621

609622
public override Expression CreateReturnValueFromManagedExpression (JniValueMarshalerContext context, ParameterExpression sourceValue)
610623
{
611-
CreateParameterFromManagedExpression (context, sourceValue, 0);
612-
var r = context.LocalVariables [sourceValue + "_ref"];
613-
return ReturnObjectReferenceToJni (context, sourceValue.Name, r);
624+
return ReturnObjectReferenceToJni (context, sourceValue.Name, CreateIntermediaryExpressionFromManagedExpression (context, sourceValue));
614625
}
615626

616627
public override Expression CreateParameterToManagedExpression (JniValueMarshalerContext context, ParameterExpression sourceValue, ParameterAttributes synchronize, Type targetType)

0 commit comments

Comments
 (0)