Skip to content

Commit 57f7bc8

Browse files
authored
[generator] Avoid non-blittable types in native callback methods (#1296)
Fixes: #1027 Context: dotnet/android@8bc7a3e Context: 356485e Context: dotnet/android#9724 `generator --codegen-target=XAJavaInterop1` -emitted marshal methods can involve non-[blittable][0] types, specifically `bool` and `char`. Consider: namespace Java.Nio.Charset; partial class CharsetEncoder { public virtual unsafe bool CanEncode (char c) => … static bool n_CanEncode_C (IntPtr jnienv, IntPtr native__this, char c) => … } Historically this hadn't mattered, because we always had a runtime marshaler. This started changing with the introduction of LLVM Marshal Methods in dotnet/android@8bc7a3e8: instead of the previous method registration approach, in which a bunch of `Delegate` instances were collected and passed to `JNIEnv::RegisterNatives()`, the idea was to instead emit LLVM-IR for a `Java_…` native symbol which would lookup and invoke a [`[UnmanagedCallersOnly]`][1]-attributed method, and `[UnmanagedCallersOnly]` requires that all parameter and return types be *blittable*. There were two potential solutions: 1. Add a wrapper around the marshal method which converts parameter and return types, or 2. Skip them entirely, and require use of `JNIEnv::RegisterNatives()` for types overriding Java methods which involve `bool` or `char`. dotnet/android@8bc7a3e8 went with (2). ((1) is complicated.) We now introduce solution (3): update `generator` so that the generated marshal methods always use blittable types: * We marshal `bool` as `sbyte` * We marshal `char` as `ushort`. `generator` has built in support for conversions when the native type does not match the managed type, via `ISymbol.ToNative()` and `ISymbol.FromNative()`. However this affects marshaling both ways: managed to Java and Java to managed. We do not want to affect managed to Java marshaling, so we introduce a new `ISymbol.OnlyFormatOnMarshal` property to control this. This also requires some changes in `dotnet/android`; see dotnet/android#9724. [0]: https://learn.microsoft.com/en-us/dotnet/framework/interop/blittable-and-non-blittable-types [1]: https://learn.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.unmanagedcallersonlyattribute?view=net-6.0
1 parent 9369d4f commit 57f7bc8

19 files changed

+213
-42
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
using System;
2+
using MonoDroid.Generation;
3+
using NUnit.Framework;
4+
using Xamarin.Android.Binder;
5+
6+
namespace generatortests;
7+
8+
[TestFixture]
9+
class BlittableTypeTests : CodeGeneratorTestBase
10+
{
11+
protected override CodeGenerationTarget Target => CodeGenerationTarget.XAJavaInterop1;
12+
13+
[Test]
14+
public void MethodWithBoolReturnType ()
15+
{
16+
var klass = new TestClass ("Object", "java.code.MyClass");
17+
var method = SupportTypeBuilder.CreateMethod (klass, "IsEmpty", options, "boolean");
18+
19+
klass.Methods.Add (method);
20+
21+
var actual = GetGeneratedTypeOutput (klass);
22+
23+
// Return type should be byte
24+
Assert.That (actual, Contains.Substring ("static sbyte n_IsEmpty"));
25+
26+
// Return statement should convert to 0 or 1
27+
Assert.That (actual, Contains.Substring ("return __this.IsEmpty () ? (sbyte)1 : (sbyte)0"));
28+
29+
// Ensure the marshal delegate is byte
30+
Assert.That (actual, Contains.Substring ("new _JniMarshal_PP_B"));
31+
Assert.That (actual, Does.Not.Contains ("new _JniMarshal_PP_Z"));
32+
}
33+
34+
[Test]
35+
public void MethodWithBoolParameter ()
36+
{
37+
var klass = new TestClass ("Object", "java.code.MyClass");
38+
var method = SupportTypeBuilder.CreateMethod (klass, "SetEmpty", options, "void", parameters: new Parameter ("value", "boolean", "bool", false));
39+
40+
klass.Methods.Add (method);
41+
42+
var actual = GetGeneratedTypeOutput (klass);
43+
44+
// Method parameter should be byte
45+
Assert.That (actual, Contains.Substring ("static void n_SetEmpty_Z (IntPtr jnienv, IntPtr native__this, sbyte native_value)"));
46+
47+
// Method should convert from 0 or 1
48+
Assert.That (actual, Contains.Substring ("var value = native_value != 0;"));
49+
50+
// Ensure the marshal delegate is byte
51+
Assert.That (actual, Contains.Substring ("new _JniMarshal_PPB_V"));
52+
Assert.That (actual, Does.Not.Contains ("new _JniMarshal_PPZ_V"));
53+
}
54+
55+
[Test]
56+
public void BoolProperty ()
57+
{
58+
var klass = SupportTypeBuilder.CreateClassWithProperty ("MyClass", "com.example.myClass", "IsEmpty", "boolean", options);
59+
var actual = GetGeneratedTypeOutput (klass);
60+
61+
// Getter return type should be byte
62+
Assert.That (actual, Contains.Substring ("static sbyte n_get_IsEmpty"));
63+
64+
// Getter return statement should convert to 0 or 1
65+
Assert.That (actual, Contains.Substring ("return __this.IsEmpty ? (sbyte)1 : (sbyte)0"));
66+
67+
// Setter parameter should be byte
68+
Assert.That (actual, Contains.Substring ("static void n_set_IsEmpty_Z (IntPtr jnienv, IntPtr native__this, sbyte native_value)"));
69+
70+
// Setter should convert from 0 or 1
71+
Assert.That (actual, Contains.Substring ("var value = native_value != 0;"));
72+
73+
// Ensure the marshal delegate is byte
74+
Assert.That (actual, Contains.Substring ("new _JniMarshal_PP_B"));
75+
Assert.That (actual, Does.Not.Contains ("new _JniMarshal_PP_Z"));
76+
}
77+
78+
[Test]
79+
public void MethodWithCharReturnType ()
80+
{
81+
var klass = new TestClass ("Object", "java.code.MyClass");
82+
var method = SupportTypeBuilder.CreateMethod (klass, "GetFirstLetter", options, "char");
83+
84+
klass.Methods.Add (method);
85+
86+
var actual = GetGeneratedTypeOutput (klass);
87+
88+
// Return type should be ushort
89+
Assert.That (actual, Contains.Substring ("static ushort n_GetFirstLetter"));
90+
91+
// Return statement should convert to ushort
92+
Assert.That (actual, Contains.Substring ("return (ushort)__this.GetFirstLetter ()"));
93+
94+
// Ensure the marshal delegate is ushort
95+
Assert.That (actual, Contains.Substring ("new _JniMarshal_PP_s"));
96+
Assert.That (actual, Does.Not.Contains ("new _JniMarshal_PP_C"));
97+
}
98+
99+
[Test]
100+
public void MethodWithCharParameter ()
101+
{
102+
var klass = new TestClass ("Object", "java.code.MyClass");
103+
var method = SupportTypeBuilder.CreateMethod (klass, "SetFirstLetter", options, "void", parameters: new Parameter ("value", "char", "char", false));
104+
105+
klass.Methods.Add (method);
106+
107+
var actual = GetGeneratedTypeOutput (klass);
108+
109+
// Method parameter should be ushort
110+
Assert.That (actual, Contains.Substring ("static void n_SetFirstLetter_C (IntPtr jnienv, IntPtr native__this, ushort native_value)"));
111+
112+
// Method should convert from ushort to char
113+
Assert.That (actual, Contains.Substring ("var value = (char)native_value;"));
114+
115+
// Ensure the marshal delegate is ushort
116+
Assert.That (actual, Contains.Substring ("new _JniMarshal_PPs_V"));
117+
Assert.That (actual, Does.Not.Contains ("new _JniMarshal_PPC_V"));
118+
}
119+
120+
[Test]
121+
public void CharProperty ()
122+
{
123+
var klass = SupportTypeBuilder.CreateClassWithProperty ("MyClass", "com.example.myClass", "FirstLetter", "char", options);
124+
var actual = GetGeneratedTypeOutput (klass);
125+
126+
// Getter return type should be ushort
127+
Assert.That (actual, Contains.Substring ("static ushort n_get_FirstLetter"));
128+
129+
// Getter return statement should convert to ushort
130+
Assert.That (actual, Contains.Substring ("return (ushort)__this.FirstLetter"));
131+
132+
// Setter parameter should be ushort
133+
Assert.That (actual, Contains.Substring ("static void n_set_FirstLetter_C (IntPtr jnienv, IntPtr native__this, ushort native_value)"));
134+
135+
// Setter should convert from ushort to char
136+
Assert.That (actual, Contains.Substring ("var value = (char)native_value;"));
137+
138+
// Ensure the marshal delegate is ushort
139+
Assert.That (actual, Contains.Substring ("new _JniMarshal_PP_s"));
140+
Assert.That (actual, Does.Not.Contains ("new _JniMarshal_PP_C"));
141+
}
142+
}

tests/generator-Tests/Unit-Tests/CodeGeneratorExpectedResults/Common/WriteDuplicateInterfaceEventArgs.txt

+6-6
Original file line numberDiff line numberDiff line change
@@ -70,18 +70,18 @@ internal partial class AnimatorListenerInvoker : global::Java.Lang.Object, Anima
7070
#pragma warning disable 0169
7171
static Delegate GetOnAnimationEnd_IHandler ()
7272
{
73-
return cb_OnAnimationEnd_OnAnimationEnd_I_Z ??= new _JniMarshal_PPI_Z (n_OnAnimationEnd_I);
73+
return cb_OnAnimationEnd_OnAnimationEnd_I_Z ??= new _JniMarshal_PPI_B (n_OnAnimationEnd_I);
7474
}
7575

7676
[global::System.Diagnostics.DebuggerDisableUserUnhandledExceptions]
77-
static bool n_OnAnimationEnd_I (IntPtr jnienv, IntPtr native__this, int param1)
77+
static sbyte n_OnAnimationEnd_I (IntPtr jnienv, IntPtr native__this, int param1)
7878
{
7979
if (!global::Java.Interop.JniEnvironment.BeginMarshalMethod (jnienv, out var __envp, out var __r))
8080
return default;
8181

8282
try {
8383
var __this = global::Java.Lang.Object.GetObject<java.code.AnimatorListener> (jnienv, native__this, JniHandleOwnership.DoNotTransfer);
84-
return __this.OnAnimationEnd (param1);
84+
return __this.OnAnimationEnd (param1) ? (sbyte)1 : (sbyte)0;
8585
} catch (global::System.Exception __e) {
8686
__r.OnUserUnhandledException (ref __envp, __e);
8787
return default;
@@ -105,18 +105,18 @@ internal partial class AnimatorListenerInvoker : global::Java.Lang.Object, Anima
105105
#pragma warning disable 0169
106106
static Delegate GetOnAnimationEnd_IIHandler ()
107107
{
108-
return cb_OnAnimationEnd_OnAnimationEnd_II_Z ??= new _JniMarshal_PPII_Z (n_OnAnimationEnd_II);
108+
return cb_OnAnimationEnd_OnAnimationEnd_II_Z ??= new _JniMarshal_PPII_B (n_OnAnimationEnd_II);
109109
}
110110

111111
[global::System.Diagnostics.DebuggerDisableUserUnhandledExceptions]
112-
static bool n_OnAnimationEnd_II (IntPtr jnienv, IntPtr native__this, int param1, int param2)
112+
static sbyte n_OnAnimationEnd_II (IntPtr jnienv, IntPtr native__this, int param1, int param2)
113113
{
114114
if (!global::Java.Interop.JniEnvironment.BeginMarshalMethod (jnienv, out var __envp, out var __r))
115115
return default;
116116

117117
try {
118118
var __this = global::Java.Lang.Object.GetObject<java.code.AnimatorListener> (jnienv, native__this, JniHandleOwnership.DoNotTransfer);
119-
return __this.OnAnimationEnd (param1, param2);
119+
return __this.OnAnimationEnd (param1, param2) ? (sbyte)1 : (sbyte)0;
120120
} catch (global::System.Exception __e) {
121121
__r.OnUserUnhandledException (ref __envp, __e);
122122
return default;

tests/generator-Tests/Unit-Tests/CodeGeneratorExpectedResults/XAJavaInterop1/WriteDuplicateInterfaceEventArgs.txt

+6-6
Original file line numberDiff line numberDiff line change
@@ -70,18 +70,18 @@ internal partial class AnimatorListenerInvoker : global::Java.Lang.Object, Anima
7070
#pragma warning disable 0169
7171
static Delegate GetOnAnimationEnd_IHandler ()
7272
{
73-
return cb_OnAnimationEnd_OnAnimationEnd_I_Z ??= new _JniMarshal_PPI_Z (n_OnAnimationEnd_I);
73+
return cb_OnAnimationEnd_OnAnimationEnd_I_Z ??= new _JniMarshal_PPI_B (n_OnAnimationEnd_I);
7474
}
7575

7676
[global::System.Diagnostics.DebuggerDisableUserUnhandledExceptions]
77-
static bool n_OnAnimationEnd_I (IntPtr jnienv, IntPtr native__this, int param1)
77+
static sbyte n_OnAnimationEnd_I (IntPtr jnienv, IntPtr native__this, int param1)
7878
{
7979
if (!global::Java.Interop.JniEnvironment.BeginMarshalMethod (jnienv, out var __envp, out var __r))
8080
return default;
8181

8282
try {
8383
var __this = global::Java.Lang.Object.GetObject<java.code.AnimatorListener> (jnienv, native__this, JniHandleOwnership.DoNotTransfer);
84-
return __this.OnAnimationEnd (param1);
84+
return __this.OnAnimationEnd (param1) ? (sbyte)1 : (sbyte)0;
8585
} catch (global::System.Exception __e) {
8686
__r.OnUserUnhandledException (ref __envp, __e);
8787
return default;
@@ -105,18 +105,18 @@ internal partial class AnimatorListenerInvoker : global::Java.Lang.Object, Anima
105105
#pragma warning disable 0169
106106
static Delegate GetOnAnimationEnd_IIHandler ()
107107
{
108-
return cb_OnAnimationEnd_OnAnimationEnd_II_Z ??= new _JniMarshal_PPII_Z (n_OnAnimationEnd_II);
108+
return cb_OnAnimationEnd_OnAnimationEnd_II_Z ??= new _JniMarshal_PPII_B (n_OnAnimationEnd_II);
109109
}
110110

111111
[global::System.Diagnostics.DebuggerDisableUserUnhandledExceptions]
112-
static bool n_OnAnimationEnd_II (IntPtr jnienv, IntPtr native__this, int param1, int param2)
112+
static sbyte n_OnAnimationEnd_II (IntPtr jnienv, IntPtr native__this, int param1, int param2)
113113
{
114114
if (!global::Java.Interop.JniEnvironment.BeginMarshalMethod (jnienv, out var __envp, out var __r))
115115
return default;
116116

117117
try {
118118
var __this = global::Java.Lang.Object.GetObject<java.code.AnimatorListener> (jnienv, native__this, JniHandleOwnership.DoNotTransfer);
119-
return __this.OnAnimationEnd (param1, param2);
119+
return __this.OnAnimationEnd (param1, param2) ? (sbyte)1 : (sbyte)0;
120120
} catch (global::System.Exception __e) {
121121
__r.OnUserUnhandledException (ref __envp, __e);
122122
return default;

tests/generator-Tests/Unit-Tests/CodeGeneratorTestBase.cs

+9
Original file line numberDiff line numberDiff line change
@@ -131,5 +131,14 @@ protected static string GetAssertionMessage (string header, string expected, str
131131
$"Expected:\n```\n{expected}\n```\n" +
132132
$"Actual:\n```\n{actual}\n```";
133133
}
134+
135+
protected string GetGeneratedTypeOutput (GenBase gen)
136+
{
137+
generator.Context.ContextTypes.Push (gen);
138+
generator.WriteType (gen, string.Empty, new GenerationInfo ("", "", "MyAssembly"));
139+
generator.Context.ContextTypes.Pop ();
140+
141+
return writer.ToString ();
142+
}
134143
}
135144
}

tests/generator-Tests/expected.xaji/GenericArguments/Com.Google.Android.Exoplayer.Drm.IExoMediaCrypto.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -48,19 +48,19 @@ public IExoMediaCryptoInvoker (IntPtr handle, JniHandleOwnership transfer) : bas
4848
#pragma warning disable 0169
4949
static Delegate GetRequiresSecureDecoderComponent_Ljava_lang_String_Handler ()
5050
{
51-
return cb_requiresSecureDecoderComponent_RequiresSecureDecoderComponent_Ljava_lang_String__Z ??= new _JniMarshal_PPL_Z (n_RequiresSecureDecoderComponent_Ljava_lang_String_);
51+
return cb_requiresSecureDecoderComponent_RequiresSecureDecoderComponent_Ljava_lang_String__Z ??= new _JniMarshal_PPL_B (n_RequiresSecureDecoderComponent_Ljava_lang_String_);
5252
}
5353

5454
[global::System.Diagnostics.DebuggerDisableUserUnhandledExceptions]
55-
static bool n_RequiresSecureDecoderComponent_Ljava_lang_String_ (IntPtr jnienv, IntPtr native__this, IntPtr native_p0)
55+
static sbyte n_RequiresSecureDecoderComponent_Ljava_lang_String_ (IntPtr jnienv, IntPtr native__this, IntPtr native_p0)
5656
{
5757
if (!global::Java.Interop.JniEnvironment.BeginMarshalMethod (jnienv, out var __envp, out var __r))
5858
return default;
5959

6060
try {
6161
var __this = global::Java.Lang.Object.GetObject<global::Com.Google.Android.Exoplayer.Drm.IExoMediaCrypto> (jnienv, native__this, JniHandleOwnership.DoNotTransfer);
6262
var p0 = JNIEnv.GetString (native_p0, JniHandleOwnership.DoNotTransfer);
63-
bool __ret = __this.RequiresSecureDecoderComponent (p0);
63+
sbyte __ret = __this.RequiresSecureDecoderComponent (p0) ? (sbyte)1 : (sbyte)0;
6464
return __ret;
6565
} catch (global::System.Exception __e) {
6666
__r.OnUserUnhandledException (ref __envp, __e);

tests/generator-Tests/expected.xaji/GenericArguments/__NamespaceMapping__.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
[assembly:global::Android.Runtime.NamespaceMapping (Java = "com.google.android.exoplayer.drm", Managed="Com.Google.Android.Exoplayer.Drm")]
55

66
[global::System.Runtime.InteropServices.UnmanagedFunctionPointer (global::System.Runtime.InteropServices.CallingConvention.Winapi)]
7-
delegate void _JniMarshal_PPL_V (IntPtr jnienv, IntPtr klass, IntPtr p0);
7+
delegate sbyte _JniMarshal_PPL_B (IntPtr jnienv, IntPtr klass, IntPtr p0);
88
[global::System.Runtime.InteropServices.UnmanagedFunctionPointer (global::System.Runtime.InteropServices.CallingConvention.Winapi)]
9-
delegate bool _JniMarshal_PPL_Z (IntPtr jnienv, IntPtr klass, IntPtr p0);
9+
delegate void _JniMarshal_PPL_V (IntPtr jnienv, IntPtr klass, IntPtr p0);
1010
[global::System.Runtime.InteropServices.UnmanagedFunctionPointer (global::System.Runtime.InteropServices.CallingConvention.Winapi)]
1111
delegate void _JniMarshal_PPLLIIL_V (IntPtr jnienv, IntPtr klass, IntPtr p0, IntPtr p1, int p2, int p3, IntPtr p4);
1212
#if !NET

tests/generator-Tests/expected.xaji/Streams/Java.IO.InputStream.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -176,18 +176,18 @@ public virtual unsafe void Mark (int readlimit)
176176
#pragma warning disable 0169
177177
static Delegate GetMarkSupportedHandler ()
178178
{
179-
return cb_markSupported_MarkSupported_Z ??= new _JniMarshal_PP_Z (n_MarkSupported);
179+
return cb_markSupported_MarkSupported_Z ??= new _JniMarshal_PP_B (n_MarkSupported);
180180
}
181181

182182
[global::System.Diagnostics.DebuggerDisableUserUnhandledExceptions]
183-
static bool n_MarkSupported (IntPtr jnienv, IntPtr native__this)
183+
static sbyte n_MarkSupported (IntPtr jnienv, IntPtr native__this)
184184
{
185185
if (!global::Java.Interop.JniEnvironment.BeginMarshalMethod (jnienv, out var __envp, out var __r))
186186
return default;
187187

188188
try {
189189
var __this = global::Java.Lang.Object.GetObject<global::Java.IO.InputStream> (jnienv, native__this, JniHandleOwnership.DoNotTransfer);
190-
return __this.MarkSupported ();
190+
return __this.MarkSupported () ? (sbyte)1 : (sbyte)0;
191191
} catch (global::System.Exception __e) {
192192
__r.OnUserUnhandledException (ref __envp, __e);
193193
return default;

tests/generator-Tests/expected.xaji/Streams/__NamespaceMapping__.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,15 @@
33
[assembly:global::Android.Runtime.NamespaceMapping (Java = "java.lang", Managed="Java.Lang")]
44
[assembly:global::Android.Runtime.NamespaceMapping (Java = "java.io", Managed="Java.IO")]
55

6+
[global::System.Runtime.InteropServices.UnmanagedFunctionPointer (global::System.Runtime.InteropServices.CallingConvention.Winapi)]
7+
delegate sbyte _JniMarshal_PP_B (IntPtr jnienv, IntPtr klass);
68
[global::System.Runtime.InteropServices.UnmanagedFunctionPointer (global::System.Runtime.InteropServices.CallingConvention.Winapi)]
79
delegate int _JniMarshal_PP_I (IntPtr jnienv, IntPtr klass);
810
[global::System.Runtime.InteropServices.UnmanagedFunctionPointer (global::System.Runtime.InteropServices.CallingConvention.Winapi)]
911
delegate IntPtr _JniMarshal_PP_L (IntPtr jnienv, IntPtr klass);
1012
[global::System.Runtime.InteropServices.UnmanagedFunctionPointer (global::System.Runtime.InteropServices.CallingConvention.Winapi)]
1113
delegate void _JniMarshal_PP_V (IntPtr jnienv, IntPtr klass);
1214
[global::System.Runtime.InteropServices.UnmanagedFunctionPointer (global::System.Runtime.InteropServices.CallingConvention.Winapi)]
13-
delegate bool _JniMarshal_PP_Z (IntPtr jnienv, IntPtr klass);
14-
[global::System.Runtime.InteropServices.UnmanagedFunctionPointer (global::System.Runtime.InteropServices.CallingConvention.Winapi)]
1515
delegate void _JniMarshal_PPI_V (IntPtr jnienv, IntPtr klass, int p0);
1616
[global::System.Runtime.InteropServices.UnmanagedFunctionPointer (global::System.Runtime.InteropServices.CallingConvention.Winapi)]
1717
delegate long _JniMarshal_PPJ_J (IntPtr jnienv, IntPtr klass, long p0);

tests/generator-Tests/expected.xaji/TestInterface/Java.Util.ICollection.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -53,19 +53,19 @@ public ICollectionInvoker (IntPtr handle, JniHandleOwnership transfer) : base (h
5353
#pragma warning disable 0169
5454
static Delegate GetAdd_Ljava_lang_Object_Handler ()
5555
{
56-
return cb_add_Add_Ljava_lang_Object__Z ??= new _JniMarshal_PPL_Z (n_Add_Ljava_lang_Object_);
56+
return cb_add_Add_Ljava_lang_Object__Z ??= new _JniMarshal_PPL_B (n_Add_Ljava_lang_Object_);
5757
}
5858

5959
[global::System.Diagnostics.DebuggerDisableUserUnhandledExceptions]
60-
static bool n_Add_Ljava_lang_Object_ (IntPtr jnienv, IntPtr native__this, IntPtr native_e)
60+
static sbyte n_Add_Ljava_lang_Object_ (IntPtr jnienv, IntPtr native__this, IntPtr native_e)
6161
{
6262
if (!global::Java.Interop.JniEnvironment.BeginMarshalMethod (jnienv, out var __envp, out var __r))
6363
return default;
6464

6565
try {
6666
var __this = global::Java.Lang.Object.GetObject<global::Java.Util.ICollection> (jnienv, native__this, JniHandleOwnership.DoNotTransfer);
6767
var e = global::Java.Lang.Object.GetObject<global::Java.Lang.Object> (native_e, JniHandleOwnership.DoNotTransfer);
68-
bool __ret = __this.Add (e);
68+
sbyte __ret = __this.Add (e) ? (sbyte)1 : (sbyte)0;
6969
return __ret;
7070
} catch (global::System.Exception __e) {
7171
__r.OnUserUnhandledException (ref __envp, __e);

tests/generator-Tests/expected.xaji/TestInterface/Java.Util.IDeque.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -53,19 +53,19 @@ public IDequeInvoker (IntPtr handle, JniHandleOwnership transfer) : base (handle
5353
#pragma warning disable 0169
5454
static Delegate GetAdd_Ljava_lang_Object_Handler ()
5555
{
56-
return cb_add_Add_Ljava_lang_Object__Z ??= new _JniMarshal_PPL_Z (n_Add_Ljava_lang_Object_);
56+
return cb_add_Add_Ljava_lang_Object__Z ??= new _JniMarshal_PPL_B (n_Add_Ljava_lang_Object_);
5757
}
5858

5959
[global::System.Diagnostics.DebuggerDisableUserUnhandledExceptions]
60-
static bool n_Add_Ljava_lang_Object_ (IntPtr jnienv, IntPtr native__this, IntPtr native_e)
60+
static sbyte n_Add_Ljava_lang_Object_ (IntPtr jnienv, IntPtr native__this, IntPtr native_e)
6161
{
6262
if (!global::Java.Interop.JniEnvironment.BeginMarshalMethod (jnienv, out var __envp, out var __r))
6363
return default;
6464

6565
try {
6666
var __this = global::Java.Lang.Object.GetObject<global::Java.Util.IDeque> (jnienv, native__this, JniHandleOwnership.DoNotTransfer);
6767
var e = global::Java.Lang.Object.GetObject<global::Java.Lang.Object> (native_e, JniHandleOwnership.DoNotTransfer);
68-
bool __ret = __this.Add (e);
68+
sbyte __ret = __this.Add (e) ? (sbyte)1 : (sbyte)0;
6969
return __ret;
7070
} catch (global::System.Exception __e) {
7171
__r.OnUserUnhandledException (ref __envp, __e);

tests/generator-Tests/expected.xaji/TestInterface/Java.Util.IQueue.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -51,19 +51,19 @@ public IQueueInvoker (IntPtr handle, JniHandleOwnership transfer) : base (handle
5151
#pragma warning disable 0169
5252
static Delegate GetAdd_Ljava_lang_Object_Handler ()
5353
{
54-
return cb_add_Add_Ljava_lang_Object__Z ??= new _JniMarshal_PPL_Z (n_Add_Ljava_lang_Object_);
54+
return cb_add_Add_Ljava_lang_Object__Z ??= new _JniMarshal_PPL_B (n_Add_Ljava_lang_Object_);
5555
}
5656

5757
[global::System.Diagnostics.DebuggerDisableUserUnhandledExceptions]
58-
static bool n_Add_Ljava_lang_Object_ (IntPtr jnienv, IntPtr native__this, IntPtr native_e)
58+
static sbyte n_Add_Ljava_lang_Object_ (IntPtr jnienv, IntPtr native__this, IntPtr native_e)
5959
{
6060
if (!global::Java.Interop.JniEnvironment.BeginMarshalMethod (jnienv, out var __envp, out var __r))
6161
return default;
6262

6363
try {
6464
var __this = global::Java.Lang.Object.GetObject<global::Java.Util.IQueue> (jnienv, native__this, JniHandleOwnership.DoNotTransfer);
6565
var e = global::Java.Lang.Object.GetObject<global::Java.Lang.Object> (native_e, JniHandleOwnership.DoNotTransfer);
66-
bool __ret = __this.Add (e);
66+
sbyte __ret = __this.Add (e) ? (sbyte)1 : (sbyte)0;
6767
return __ret;
6868
} catch (global::System.Exception __e) {
6969
__r.OnUserUnhandledException (ref __envp, __e);

0 commit comments

Comments
 (0)