diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md
index 36818352a..eb83eb26b 100644
--- a/.github/copilot-instructions.md
+++ b/.github/copilot-instructions.md
@@ -35,7 +35,6 @@
### Core Libraries (`src/`)
- **`Java.Interop/`**: Main JNI binding library with core types and runtime
- **`Java.Interop.Export/`**: `[Export]` attribute support for exposing managed methods to Java
-- **`Java.Runtime.Environment/`**: JVM loading and lifecycle management
- **`Java.Base/`**: Bindings for core Java types (`java.lang.*`, etc.)
### Code Generation Tools (`tools/`)
@@ -52,13 +51,11 @@
- **`Xamarin.SourceWriter/`**: Code generation utilities
### Testing (`tests/`)
-- Unit tests for all major components
-- Integration tests with real JVM instances
+- Unit tests for the core JNI binding and code-generation components
+- Integration tests with real JVM instances where needed
- Generator tests with sample API descriptions
### Samples (`samples/`)
-- **`Hello-Core/`**: Minimal JNI usage without object mapping
-- **`Hello-Java.Base/`**: Using core Java type bindings
- **`Hello-NativeAOT*/`**: Ahead-of-time compilation scenarios
## Development Patterns & Conventions
@@ -133,7 +130,7 @@ dotnet build -t:Prepare
dotnet build
# Run specific tests
-dotnet test tests/Java.Interop-Tests/Java.Interop-Tests.csproj
+dotnet test tests/Java.Interop.Tools.Generator-Tests/Java.Interop.Tools.Generator-Tests.csproj
# Build with specific configuration
dotnet build -c Release
diff --git a/Documentation/BuildConfiguration.md b/Documentation/BuildConfiguration.md
index 3cff9e86e..13984d292 100644
--- a/Documentation/BuildConfiguration.md
+++ b/Documentation/BuildConfiguration.md
@@ -17,10 +17,9 @@ Overridable MSBuild properties include:
* `$(CecilSourceDirectory)`: If the empty string, Cecil will be obtained from
NuGet packages. Otherwise, `$(UtilityOutputFullPath)Xamarin.Android.Cecil.dll`
will be used to reference Cecil.
-* `$(JdkJvmPath)`: Full path name to the JVM native library to link
- [`java-interop`](src/java-interop) against. By default this is
- probed for from numerous locations within
- [`build-tools/scripts/jdk.mk`](build-tools/scripts/jdk.mk).
+* `$(JdkJvmPath)`: Full path name to the JVM native library to use for
+ tests which require a desktop JVM. By default this is probed from the
+ configured JDK.
* `$(JavaCPath)`: Path to the `javac` command-line tool, by default set to `javac`.
* `$(JarPath)`: Path to the `jar` command-line tool, by default set to `jar`.
* It may be desirable to override these on Windows, depending on your `PATH`.
diff --git a/Java.Interop.sln b/Java.Interop.sln
index 7fb468cc9..06bff52de 100644
--- a/Java.Interop.sln
+++ b/Java.Interop.sln
@@ -1,4 +1,4 @@
-
+
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29424.173
@@ -21,8 +21,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Java.Interop.Tools.JavaSour
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Desktop", "Desktop", "{0998E45F-8BCE-4791-A944-962CD54E2D80}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Java.Runtime.Environment", "src\Java.Runtime.Environment\Java.Runtime.Environment.csproj", "{5887B410-D448-4257-A46B-EAC03C80BE93}"
-EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Xamarin.Android.Tools.Bytecode", "src\Xamarin.Android.Tools.Bytecode\Xamarin.Android.Tools.Bytecode.csproj", "{B17475BC-45A2-47A3-B8FC-62F3A0959EE0}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Xamarin.Android.Tools.AnnotationSupport", "src\Xamarin.Android.Tools.AnnotationSupport\Xamarin.Android.Tools.AnnotationSupport.csproj", "{07BC4495-1267-4B78-9EA6-B76FEEA2A64A}"
@@ -45,12 +43,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Xamarin.Android.Tools.ApiXm
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "generator-Tests", "tests\generator-Tests\generator-Tests.csproj", "{4EEAB1A7-99C1-4302-9C18-01A7B481409B}"
EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Samples", "Samples", "{D5A93398-AEB1-49F3-89DC-3904A47DB0C7}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Hello-Java.Base", "samples\Hello-Java.Base\Hello-Java.Base.csproj", "{F3ECB73D-9263-4E42-A5B4-3FC0D1D829F9}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Hello-Core", "samples\Hello-Core\Hello-Core.csproj", "{0E6DE9F9-35B1-4DFB-BB8B-7E4A2D362461}"
-EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build-Tools", "Build-Tools", "{172B608B-E6F3-41CC-9949-203A76BA247C}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "jnienv-gen", "build-tools\jnienv-gen\jnienv-gen.csproj", "{6410DA0F-5E14-4FC0-9AEE-F4C542C96C7A}"
@@ -83,8 +75,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Xamarin.SourceWriter-Tests"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Java.Interop.Localization", "src\Java.Interop.Localization\Java.Interop.Localization.csproj", "{998D178B-F4C7-48B5-BDEE-44E2F869BB22}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "invocation-overhead", "tests\invocation-overhead\invocation-overhead.csproj", "{3CF58D34-693C-408A-BFE7-BC5E4BE44A26}"
-EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NativeTiming", "tests\NativeTiming\NativeTiming.csproj", "{BF5A4019-F2FF-45AC-949D-EF7E8C94196B}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Java.Interop.Tools.JavaTypeSystem", "src\Java.Interop.Tools.JavaTypeSystem\Java.Interop.Tools.JavaTypeSystem.csproj", "{B173F53B-986C-4E0D-881C-063BBB116E1D}"
@@ -93,23 +83,15 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Java.Interop.Tools.JavaType
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Java.Base", "src\Java.Base\Java.Base.csproj", "{30DCECA5-16FD-4FD0-883C-E5E83B11565D}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Java.Base-Tests", "tests\Java.Base-Tests\Java.Base-Tests.csproj", "{CB05E11B-B96F-4179-A4E9-5D6BDE29A8FC}"
-EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Java.Interop.Tools.Maven", "src\Java.Interop.Tools.Maven\Java.Interop.Tools.Maven.csproj", "{DA458F90-218B-4FE3-995F-AF4B27895FA2}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Java.Interop.Tools.Maven-Tests", "tests\Java.Interop.Tools.Maven-Tests\Java.Interop.Tools.Maven-Tests.csproj", "{6BC04C7F-949E-4F93-BF1F-E3B1DF0B888D}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Hello-NativeAOTFromJNI", "samples\Hello-NativeAOTFromJNI\Hello-NativeAOTFromJNI.csproj", "{8DB3842B-73D7-491C-96F9-EBC863E2C917}"
-EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{40B3CE2F-B8DE-45CD-A43A-0F1A89BDB803}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Java.Interop.Tools.TypeNameMappings", "src\Java.Interop.Tools.TypeNameMappings\Java.Interop.Tools.TypeNameMappings.csproj", "{C2AF6ACF-04F6-4B41-95EA-97A372C075F9}"
EndProject
Global
- GlobalSection(SharedMSBuildProjectFiles) = preSolution
- src\Java.Interop.NamingCustomAttributes\Java.Interop.NamingCustomAttributes.projitems*{58b564a1-570d-4da2-b02d-25bddb1a9f4f}*SharedItemsImports = 5
- src\Java.Interop.NamingCustomAttributes\Java.Interop.NamingCustomAttributes.projitems*{d18fcf91-8876-48a0-a693-2dc1e7d3d80a}*SharedItemsImports = 5
- EndGlobalSection
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
@@ -139,10 +121,6 @@ Global
{5C0B3562-8DA0-4726-9762-75B9709ED6B7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5C0B3562-8DA0-4726-9762-75B9709ED6B7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5C0B3562-8DA0-4726-9762-75B9709ED6B7}.Release|Any CPU.Build.0 = Release|Any CPU
- {5887B410-D448-4257-A46B-EAC03C80BE93}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {5887B410-D448-4257-A46B-EAC03C80BE93}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {5887B410-D448-4257-A46B-EAC03C80BE93}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {5887B410-D448-4257-A46B-EAC03C80BE93}.Release|Any CPU.Build.0 = Release|Any CPU
{B17475BC-45A2-47A3-B8FC-62F3A0959EE0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B17475BC-45A2-47A3-B8FC-62F3A0959EE0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B17475BC-45A2-47A3-B8FC-62F3A0959EE0}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -183,14 +161,6 @@ Global
{4EEAB1A7-99C1-4302-9C18-01A7B481409B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4EEAB1A7-99C1-4302-9C18-01A7B481409B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4EEAB1A7-99C1-4302-9C18-01A7B481409B}.Release|Any CPU.Build.0 = Release|Any CPU
- {F3ECB73D-9263-4E42-A5B4-3FC0D1D829F9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {F3ECB73D-9263-4E42-A5B4-3FC0D1D829F9}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {F3ECB73D-9263-4E42-A5B4-3FC0D1D829F9}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {F3ECB73D-9263-4E42-A5B4-3FC0D1D829F9}.Release|Any CPU.Build.0 = Release|Any CPU
- {0E6DE9F9-35B1-4DFB-BB8B-7E4A2D362461}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {0E6DE9F9-35B1-4DFB-BB8B-7E4A2D362461}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {0E6DE9F9-35B1-4DFB-BB8B-7E4A2D362461}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {0E6DE9F9-35B1-4DFB-BB8B-7E4A2D362461}.Release|Any CPU.Build.0 = Release|Any CPU
{6410DA0F-5E14-4FC0-9AEE-F4C542C96C7A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6410DA0F-5E14-4FC0-9AEE-F4C542C96C7A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6410DA0F-5E14-4FC0-9AEE-F4C542C96C7A}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -251,10 +221,6 @@ Global
{998D178B-F4C7-48B5-BDEE-44E2F869BB22}.Debug|Any CPU.Build.0 = Debug|Any CPU
{998D178B-F4C7-48B5-BDEE-44E2F869BB22}.Release|Any CPU.ActiveCfg = Release|Any CPU
{998D178B-F4C7-48B5-BDEE-44E2F869BB22}.Release|Any CPU.Build.0 = Release|Any CPU
- {3CF58D34-693C-408A-BFE7-BC5E4BE44A26}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {3CF58D34-693C-408A-BFE7-BC5E4BE44A26}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {3CF58D34-693C-408A-BFE7-BC5E4BE44A26}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {3CF58D34-693C-408A-BFE7-BC5E4BE44A26}.Release|Any CPU.Build.0 = Release|Any CPU
{BF5A4019-F2FF-45AC-949D-EF7E8C94196B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BF5A4019-F2FF-45AC-949D-EF7E8C94196B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BF5A4019-F2FF-45AC-949D-EF7E8C94196B}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -271,10 +237,6 @@ Global
{30DCECA5-16FD-4FD0-883C-E5E83B11565D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{30DCECA5-16FD-4FD0-883C-E5E83B11565D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{30DCECA5-16FD-4FD0-883C-E5E83B11565D}.Release|Any CPU.Build.0 = Release|Any CPU
- {CB05E11B-B96F-4179-A4E9-5D6BDE29A8FC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {CB05E11B-B96F-4179-A4E9-5D6BDE29A8FC}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {CB05E11B-B96F-4179-A4E9-5D6BDE29A8FC}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {CB05E11B-B96F-4179-A4E9-5D6BDE29A8FC}.Release|Any CPU.Build.0 = Release|Any CPU
{DA458F90-218B-4FE3-995F-AF4B27895FA2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DA458F90-218B-4FE3-995F-AF4B27895FA2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DA458F90-218B-4FE3-995F-AF4B27895FA2}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -283,10 +245,6 @@ Global
{6BC04C7F-949E-4F93-BF1F-E3B1DF0B888D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6BC04C7F-949E-4F93-BF1F-E3B1DF0B888D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6BC04C7F-949E-4F93-BF1F-E3B1DF0B888D}.Release|Any CPU.Build.0 = Release|Any CPU
- {8DB3842B-73D7-491C-96F9-EBC863E2C917}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {8DB3842B-73D7-491C-96F9-EBC863E2C917}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {8DB3842B-73D7-491C-96F9-EBC863E2C917}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {8DB3842B-73D7-491C-96F9-EBC863E2C917}.Release|Any CPU.Build.0 = Release|Any CPU
{C2AF6ACF-04F6-4B41-95EA-97A372C075F9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C2AF6ACF-04F6-4B41-95EA-97A372C075F9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C2AF6ACF-04F6-4B41-95EA-97A372C075F9}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -302,7 +260,6 @@ Global
{94BD81F7-B06F-4295-9636-F8A3B6BDC762} = {4C173212-371D-45D8-BA83-9226194F48DC}
{BB0AB9F7-0979-41A7-B7A9-877260655F94} = {4C173212-371D-45D8-BA83-9226194F48DC}
{5C0B3562-8DA0-4726-9762-75B9709ED6B7} = {0998E45F-8BCE-4791-A944-962CD54E2D80}
- {5887B410-D448-4257-A46B-EAC03C80BE93} = {0998E45F-8BCE-4791-A944-962CD54E2D80}
{B17475BC-45A2-47A3-B8FC-62F3A0959EE0} = {0998E45F-8BCE-4791-A944-962CD54E2D80}
{07BC4495-1267-4B78-9EA6-B76FEEA2A64A} = {0998E45F-8BCE-4791-A944-962CD54E2D80}
{1268EADF-8344-431C-81F6-FCB7CBC99F49} = {0998E45F-8BCE-4791-A944-962CD54E2D80}
@@ -313,8 +270,6 @@ Global
{C9FA4492-DEB0-4932-A6B8-E2C4E0581692} = {271C9F30-F679-4793-942B-0D9527CB3E2F}
{891F2E04-5614-4A26-A78F-3778025ECF43} = {271C9F30-F679-4793-942B-0D9527CB3E2F}
{4EEAB1A7-99C1-4302-9C18-01A7B481409B} = {271C9F30-F679-4793-942B-0D9527CB3E2F}
- {F3ECB73D-9263-4E42-A5B4-3FC0D1D829F9} = {D5A93398-AEB1-49F3-89DC-3904A47DB0C7}
- {0E6DE9F9-35B1-4DFB-BB8B-7E4A2D362461} = {D5A93398-AEB1-49F3-89DC-3904A47DB0C7}
{6410DA0F-5E14-4FC0-9AEE-F4C542C96C7A} = {172B608B-E6F3-41CC-9949-203A76BA247C}
{D18FCF91-8876-48A0-A693-2DC1E7D3D80A} = {0998E45F-8BCE-4791-A944-962CD54E2D80}
{D48EE8D0-0A0A-4493-AEF5-DAF5F8CF86AD} = {0998E45F-8BCE-4791-A944-962CD54E2D80}
@@ -330,18 +285,19 @@ Global
{C5B732C8-7AF3-41D3-B903-AEDFC392E5BA} = {0998E45F-8BCE-4791-A944-962CD54E2D80}
{6CF94627-BA74-4336-88CD-7EDA20C8F292} = {271C9F30-F679-4793-942B-0D9527CB3E2F}
{998D178B-F4C7-48B5-BDEE-44E2F869BB22} = {0998E45F-8BCE-4791-A944-962CD54E2D80}
- {3CF58D34-693C-408A-BFE7-BC5E4BE44A26} = {271C9F30-F679-4793-942B-0D9527CB3E2F}
{BF5A4019-F2FF-45AC-949D-EF7E8C94196B} = {271C9F30-F679-4793-942B-0D9527CB3E2F}
{B173F53B-986C-4E0D-881C-063BBB116E1D} = {0998E45F-8BCE-4791-A944-962CD54E2D80}
{11942DE9-AEC2-4B95-87AB-CA707C37643D} = {271C9F30-F679-4793-942B-0D9527CB3E2F}
{30DCECA5-16FD-4FD0-883C-E5E83B11565D} = {0998E45F-8BCE-4791-A944-962CD54E2D80}
- {CB05E11B-B96F-4179-A4E9-5D6BDE29A8FC} = {271C9F30-F679-4793-942B-0D9527CB3E2F}
{DA458F90-218B-4FE3-995F-AF4B27895FA2} = {0998E45F-8BCE-4791-A944-962CD54E2D80}
{6BC04C7F-949E-4F93-BF1F-E3B1DF0B888D} = {271C9F30-F679-4793-942B-0D9527CB3E2F}
- {8DB3842B-73D7-491C-96F9-EBC863E2C917} = {D5A93398-AEB1-49F3-89DC-3904A47DB0C7}
{C2AF6ACF-04F6-4B41-95EA-97A372C075F9} = {40B3CE2F-B8DE-45CD-A43A-0F1A89BDB803}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {29204E0C-382A-49A0-A814-AD7FBF9774A5}
EndGlobalSection
+ GlobalSection(SharedMSBuildProjectFiles) = preSolution
+ src\Java.Interop.NamingCustomAttributes\Java.Interop.NamingCustomAttributes.projitems*{58b564a1-570d-4da2-b02d-25bddb1a9f4f}*SharedItemsImports = 5
+ src\Java.Interop.NamingCustomAttributes\Java.Interop.NamingCustomAttributes.projitems*{d18fcf91-8876-48a0-a693-2dc1e7d3d80a}*SharedItemsImports = 5
+ EndGlobalSection
EndGlobal
diff --git a/Makefile b/Makefile
index ddf68c88f..d8ede4a32 100644
--- a/Makefile
+++ b/Makefile
@@ -15,33 +15,29 @@ endif
PREPARE_EXTERNAL_FILES = \
external/xamarin-android-tools/src/Xamarin.Android.Tools.AndroidSdk/Xamarin.Android.Tools.AndroidSdk.csproj
-DEPENDENCIES = \
- bin/Test$(CONFIGURATION)/libNativeTiming$(NATIVE_EXT)
-
-NET_SUFFIX = -net7.0
-
-TESTS = \
- bin/Test$(CONFIGURATION)/Java.Interop-Tests.dll \
- bin/Test$(CONFIGURATION)/Java.Interop.Tools.JavaCallableWrappers-Tests.dll \
- bin/Test$(CONFIGURATION)/Java.Interop.Tools.JavaSource-Tests.dll \
- bin/Test$(CONFIGURATION)/logcat-parse-Tests.dll \
- bin/Test$(CONFIGURATION)/generator-Tests.dll \
- bin/Test$(CONFIGURATION)/Xamarin.Android.Tools.ApiXmlAdjuster-Tests.dll \
- bin/Test$(CONFIGURATION)/Java.Interop.Tools.JavaTypeSystem-Tests.dll \
- bin/Test$(CONFIGURATION)/Xamarin.Android.Tools.Bytecode-Tests.dll \
- bin/Test$(CONFIGURATION)/Java.Interop.Tools.Generator-Tests.dll \
- bin/Test$(CONFIGURATION)/Xamarin.SourceWriter-Tests.dll
+DEPENDENCIES =
-NET_TESTS = \
- bin/Test$(CONFIGURATION)$(NET_SUFFIX)/Java.Base-Tests.dll
-
-PTESTS = \
- bin/Test$(CONFIGURATION)/Java.Interop-PerformanceTests.dll
+NET_SUFFIX = -net10.0
+TEST_OUTPUT = bin/Test$(CONFIGURATION)$(NET_SUFFIX)
-ATESTS = \
- bin/Test$(CONFIGURATION)/Android.Interop-Tests.dll
+TESTS =
-all: $(DEPENDENCIES) $(TESTS)
+NET_TESTS = \
+ $(TEST_OUTPUT)/Java.Interop-Tests.dll \
+ $(TEST_OUTPUT)/Java.Interop.Tools.JavaCallableWrappers-Tests.dll \
+ $(TEST_OUTPUT)/Java.Interop.Tools.JavaSource-Tests.dll \
+ $(TEST_OUTPUT)/Java.Interop.Tools.Maven-Tests.dll \
+ $(TEST_OUTPUT)/Java.Interop.Tools.JavaTypeSystem-Tests.dll \
+ $(TEST_OUTPUT)/Java.Interop.Tools.Generator-Tests.dll \
+ $(TEST_OUTPUT)/Xamarin.Android.Tools.ApiXmlAdjuster-Tests.dll \
+ $(TEST_OUTPUT)/Xamarin.Android.Tools.Bytecode-Tests.dll \
+ $(TEST_OUTPUT)/Xamarin.SourceWriter-Tests.dll \
+ $(TEST_OUTPUT)/generator-Tests.dll \
+ $(TEST_OUTPUT)/logcat-parse-Tests.dll
+
+PTESTS =
+
+all: $(DEPENDENCIES) $(TESTS) $(NET_TESTS)
bin/ilverify:
-mkdir bin
@@ -50,7 +46,6 @@ bin/ilverify:
run-all-tests:
r=0; \
$(MAKE) run-tests || r=1 ; \
- $(MAKE) run-test-jnimarshal || r=1 ; \
$(MAKE) run-net-tests || r=1 ; \
$(MAKE) run-ptests || r=1 ; \
$(MAKE) run-java-source-utils-tests || r=1 ; \
@@ -72,38 +67,29 @@ include build-tools/scripts/mono.mk
-include bin/Build$(CONFIGURATION)/mono.mk
-include bin/Build$(CONFIGURATION)/JdkInfo.mk
-JAVA_RUNTIME_ENVIRONMENT_DLLMAP_OVERRIDE = Java.Runtime.Environment.Override.dllmap
-ifeq ($(wildcard $(JAVA_RUNTIME_ENVIRONMENT_DLLMAP_OVERRIDE)),)
- JAVA_RUNTIME_ENVIRONMENT_DLLMAP_OVERRIDE_CMD = '/@JAVA_RUNTIME_ENVIRONMENT_DLLMAP@/d'
-else
- JAVA_RUNTIME_ENVIRONMENT_DLLMAP_OVERRIDE_CMD = '/@JAVA_RUNTIME_ENVIRONMENT_DLLMAP@/ {' -e 'r $(JAVA_RUNTIME_ENVIRONMENT_DLLMAP_OVERRIDE)' -e 'd' -e '}'
-endif
-
-JAVA_INTEROP_LIB = libjava-interop$(NATIVE_EXT)
NATIVE_TIMING_LIB = libNativeTiming$(NATIVE_EXT)
bin/Test$(CONFIGURATION)/$(NATIVE_TIMING_LIB): tests/NativeTiming/timing.c $(wildcard $(JI_JDK_INCLUDE_PATHS)/jni.h)
mkdir -p `dirname "$@"`
gcc -g -shared -m64 -fPIC -o $@ $< $(JI_JDK_INCLUDE_PATHS:%=-I%)
-# Usage: $(call TestAssemblyTemplate,assembly-basename)
define TestAssemblyTemplate
-bin/Test$$(CONFIGURATION)/$(1)-Tests.dll: $(wildcard src/$(1)/*/*.cs src/$(1)/Test*/*/*.cs)
+$(TEST_OUTPUT)/$(1)-Tests.dll: tests/$(1)-Tests/$(1)-Tests.csproj
$$(MSBUILD) $$(MSBUILD_FLAGS)
touch $$@
-endef # TestAssemblyTemplate
+endef
$(eval $(call TestAssemblyTemplate,Java.Interop))
-$(eval $(call TestAssemblyTemplate,Java.Interop.Export))
$(eval $(call TestAssemblyTemplate,Java.Interop.Tools.JavaCallableWrappers))
-
-bin/Test$(CONFIGURATION)/Java.Interop-PerformanceTests.dll: $(wildcard tests/Java.Interop-PerformanceTests/*.cs) bin/Test$(CONFIGURATION)/$(NATIVE_TIMING_LIB)
- $(MSBUILD) $(MSBUILD_FLAGS)
- touch $@
-
-bin/Test$(CONFIGURATION)/Android.Interop-Tests.dll: $(wildcard src/Android.Interop/*/*.cs src/Android.Interop/Tests/*/*.cs)
- $(MSBUILD) $(MSBUILD_FLAGS)
- touch $@
+$(eval $(call TestAssemblyTemplate,Java.Interop.Tools.JavaSource))
+$(eval $(call TestAssemblyTemplate,Java.Interop.Tools.Maven))
+$(eval $(call TestAssemblyTemplate,Java.Interop.Tools.JavaTypeSystem))
+$(eval $(call TestAssemblyTemplate,Java.Interop.Tools.Generator))
+$(eval $(call TestAssemblyTemplate,Xamarin.Android.Tools.ApiXmlAdjuster))
+$(eval $(call TestAssemblyTemplate,Xamarin.Android.Tools.Bytecode))
+$(eval $(call TestAssemblyTemplate,Xamarin.SourceWriter))
+$(eval $(call TestAssemblyTemplate,generator))
+$(eval $(call TestAssemblyTemplate,logcat-parse))
bin/$(CONFIGURATION)/Java.Interop.dll: $(wildcard src/Java.Interop/*/*.cs) src/Java.Interop/Java.Interop.csproj
$(MSBUILD) $(if $(V),/v:diag,) /p:Configuration=$(CONFIGURATION) $(if $(SNK),"/p:AssemblyOriginatorKeyFile=$(SNK)",)
@@ -111,8 +97,6 @@ bin/$(CONFIGURATION)/Java.Interop.dll: $(wildcard src/Java.Interop/*/*.cs) src/J
CSHARP_REFS = \
bin/$(CONFIGURATION)/Java.Interop.dll \
bin/$(CONFIGURATION)/Java.Interop.Export.dll \
- bin/$(CONFIGURATION)/Java.Runtime.Environment.dll \
- bin/Test$(CONFIGURATION)/TestJVM.dll \
$(PTESTS) \
$(TESTS)
@@ -125,17 +109,17 @@ define RUN_TEST
$(MSBUILD) $(MSBUILD_FLAGS) build-tools/scripts/RunNUnitTests.targets /p:TestAssembly=$(1) || r=1;
endef
-run-tests: $(TESTS) bin/Test$(CONFIGURATION)/$(JAVA_INTEROP_LIB)
+run-tests: $(TESTS)
r=0; \
$(foreach t,$(TESTS), $(call RUN_TEST,$(t),1)) \
exit $$r;
-run-net-tests: $(NET_TESTS) bin/Test$(CONFIGURATION)$(NET_SUFFIX)/$(JAVA_INTEROP_LIB)
+run-net-tests: $(NET_TESTS)
r=0; \
- $(foreach t,$(NET_TESTS), dotnet test $(t) || r=1) \
+ $(foreach t,$(NET_TESTS), dotnet test $(t) || r=1;) \
exit $$r;
-run-ptests: $(PTESTS) bin/Test$(CONFIGURATION)/$(JAVA_INTEROP_LIB)
+run-ptests: $(PTESTS)
r=0; \
$(foreach t,$(PTESTS), $(call RUN_TEST,$(t))) \
exit $$r;
@@ -143,14 +127,6 @@ run-ptests: $(PTESTS) bin/Test$(CONFIGURATION)/$(JAVA_INTEROP_LIB)
run-java-source-utils-tests:
$(MSBUILD) $(MSBUILD_FLAGS) tools/java-source-utils/java-source-utils.csproj /t:RunTests
-bin/Test$(CONFIGURATION)/$(JAVA_INTEROP_LIB): bin/$(CONFIGURATION)/$(JAVA_INTEROP_LIB)
- cp $< $@
-
-JRE_DLL_CONFIG=bin/$(CONFIGURATION)/Java.Runtime.Environment.dll.config
-
-$(JRE_DLL_CONFIG): src/Java.Runtime.Environment/Java.Runtime.Environment.csproj
- $(MSBUILD) $(MSBUILD_FLAGS) $<
-
bin/Test$(CONFIGURATION)/generator.exe: bin/$(CONFIGURATION)/generator.exe
cp $<* `dirname "$@"`
diff --git a/build-tools/automation/templates/core-tests.yaml b/build-tools/automation/templates/core-tests.yaml
index d736d80ea..34f399b12 100644
--- a/build-tools/automation/templates/core-tests.yaml
+++ b/build-tools/automation/templates/core-tests.yaml
@@ -62,13 +62,6 @@ steps:
condition: or(eq('${{ parameters.runNativeDotnetTests }}', 'true'), eq('${{ parameters.runNativeTests }}', 'true'))
retryCount: 1
-- template: run-dotnet-test.yaml
- parameters:
- testRunTitle: Java.Base ($(DotNetTargetFramework) - ${{ parameters.platformName }})
- testAssemblyName: Java.Base-Tests
- condition: or(eq('${{ parameters.runNativeDotnetTests }}', 'true'), eq('${{ parameters.runNativeTests }}', 'true'))
- retryCount: 1
-
- task: DotNetCoreCLI@2
displayName: 'Tests: java-source-utils'
inputs:
diff --git a/samples/Hello-Core/Hello-Core.csproj b/samples/Hello-Core/Hello-Core.csproj
deleted file mode 100644
index c490735a9..000000000
--- a/samples/Hello-Core/Hello-Core.csproj
+++ /dev/null
@@ -1,23 +0,0 @@
-
-
-
- $(DotNetTargetFramework)
- Exe
- Hello
- enable
- enable
- true
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/samples/Hello-Core/Program.cs b/samples/Hello-Core/Program.cs
deleted file mode 100644
index 157aa80b2..000000000
--- a/samples/Hello-Core/Program.cs
+++ /dev/null
@@ -1,87 +0,0 @@
-using Java.Interop;
-
-using Mono.Options;
-
-bool showHelp = false;
-
-var jreOptions = new JreRuntimeOptions {
-};
-
-var options = new OptionSet {
- "Using the JVM from C#!",
- "",
- "Options:",
- { "jvm=",
- $"{{PATH}} to JVM to use.",
- v => jreOptions.JvmLibraryPath = v },
- { "cp=|classpath",
- $"Add {{JAR-OR-DIRECTORY}} to JVM classpath.",
- v => jreOptions.ClassPath.Add (v)},
- { "J=",
- $"Pass the specified option to the JVM.",
- v => jreOptions.AddOption (v) },
- { "h|help",
- "Show this message and exit.",
- v => showHelp = v != null },
-};
-options.Parse (args);
-
-if (showHelp) {
- options.WriteOptionDescriptions (Console.Out);
- return;
-}
-
-if (string.IsNullOrEmpty (jreOptions.JvmLibraryPath) || !File.Exists (jreOptions.JvmLibraryPath)) {
- Error ("Option -jvm=PATH is required. PATH is a full path to the JVM native library to use, e.g. `libjli.dylib`.");
- return;
-}
-
-var jre = jreOptions.CreateJreVM ();
-
-// We now have a JVM!
-// The current thread is implicitly attached to the JVM.
-// Access of `JniEnvironment` members on other threads will implicitly attach those threads to the JVM.
-
-//
-// Useful background info: the JNI documentation! https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html
-//
-
-var Object_class = JniEnvironment.Types.FindClass ("java/lang/Object");
-Console.WriteLine ($"Object_class={Object_class}");
-var Object_ctor = JniEnvironment.InstanceMethods.GetMethodID (Object_class, "", "()V");
-var Object_val = JniEnvironment.Object.NewObject (Object_class, Object_ctor);
-
-Console.WriteLine ($"Object_val={Object_val}");
-
-// Invoke `Object.toString()`
-var Object_toString = JniEnvironment.InstanceMethods.GetMethodID (Object_class, "toString", "()Ljava/lang/String;");
-unsafe {
- var Object_desc = JniEnvironment.InstanceMethods.CallObjectMethod (Object_val, Object_toString, null);
- Console.WriteLine ($"Object_val.toString()={JniEnvironment.Strings.ToString (Object_desc)}");
-
- // When JNI returns a `jobject` or `jclass` value, JNI returns a *JNI Object Reference*.
- // The `JniObjectReference` struct is used to store JNI Local, Global, and Weak Global references.
- //
- // When an object reference is no longer required, it should be explicitly deleted.
-
- JniObjectReference.Dispose (ref Object_desc);
-}
-
-JniObjectReference.Dispose (ref Object_class);
-JniObjectReference.Dispose (ref Object_val);
-
-// There are some OO wrappers over the core `JniEnvironment` members. `JniType` is useful.
-var Object_type = new JniType ("java/lang/Object");
-var Object_ctor2 = Object_type.GetConstructor ("()V");
-
-unsafe {
- var Object_val2 = Object_type.NewObject (Object_ctor2, null);
- var Object_desc = JniEnvironment.InstanceMethods.CallObjectMethod (Object_val2, Object_toString, null);
- Console.WriteLine ($"Object_val.toString()={JniEnvironment.Strings.ToString (Object_desc)}");
-}
-
-void Error (string message)
-{
- var app = Path.GetFileNameWithoutExtension (Environment.GetCommandLineArgs ()[0]);
- Console.Error.WriteLine ($"{app}: {message}");
-}
diff --git a/samples/Hello-Core/README.md b/samples/Hello-Core/README.md
deleted file mode 100644
index 30893d6b8..000000000
--- a/samples/Hello-Core/README.md
+++ /dev/null
@@ -1,35 +0,0 @@
-# Hello-Core
-
-Use as little of `Java.Interop.dll` as possible. No object mapping.
-
-Usage:
-
-```
-Options:
- --jvm=PATH PATH to JVM to use.
- --cp, --classpath=JAR-OR-DIRECTORY
- Add JAR-OR-DIRECTORY to JVM classpath.
- -J=VALUE Pass the specified option to the JVM.
- -h, --help Show this message and exit.
-```
-
-`-J` can be used to add runtime options to the JVM instance, e.g.
-
-```shell
-# Enable verbose JNI logging from the JVM
-% dotnet run -- --jvm /Library/Java/JavaVirtualMachines/microsoft-11.jdk/Contents/Home/lib/jli/libjli.dylib -J-verbose:jni
-[Dynamic-linking native method java.lang.Object.registerNatives ... JNI]
-[Registering JNI native method java.lang.Object.hashCode]
-[Registering JNI native method java.lang.Object.wait]
-…
-```
-
-The sample will create a `java.lang.Object` instance and invoke `Object.toString()` on it.
-
-```
-% dotnet run -- --jvm /Library/Java/JavaVirtualMachines/microsoft-11.jdk/Contents/Home/lib/jli/libjli.dylib
-Object_class=0x7ff04f105b98/L
-Object_val=0x7ff04f105ba8/L
-Object_val.toString()=java.lang.Object@5cbc508c
-Object_val.toString()=java.lang.Object@3419866c
-```
diff --git a/samples/Hello-Java.Base/Hello-Java.Base.csproj b/samples/Hello-Java.Base/Hello-Java.Base.csproj
deleted file mode 100644
index f66c58ab7..000000000
--- a/samples/Hello-Java.Base/Hello-Java.Base.csproj
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
- $(DotNetTargetFramework)
- Exe
- true
- enable
- Hello.App
-
-
-
-
-
-
-
- $(MSBuildThisFileDirectory)bin\$(Configuration)\
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/samples/Hello-Java.Base/Program.cs b/samples/Hello-Java.Base/Program.cs
deleted file mode 100644
index 7b5355e3a..000000000
--- a/samples/Hello-Java.Base/Program.cs
+++ /dev/null
@@ -1,152 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Linq;
-using System.IO;
-using System.Threading;
-
-using Mono.Options;
-
-using Java.Interop;
-
-namespace Hello
-{
- class App
- {
- const int N = 1000000;
-
- public static void Main (string[] args)
- {
- var logger = (Action?) null;
- string? jvmPath = null;
- bool createMultipleVMs = false;
- bool reportTiming = false;
- bool showHelp = false;
- int verbosity = 0;
- var options = new OptionSet () {
- "Using the JVM from C#!",
- "",
- "Options:",
- { "jvm=",
- $"{{PATH}} to JVM to use. Default is:\n{Java.InteropTests.TestJVM.GetJvmLibraryPath (logger)}",
- v => jvmPath = v },
- { "m",
- "Create multiple Java VMs. This will likely crash.",
- v => createMultipleVMs = v != null },
- { "t",
- $"Timing; invoke Object.hashCode() {N} times, print average.",
- v => reportTiming = v != null },
- { "v|verbosity:",
- $"Set console log verbosity to {{LEVEL}}. Default is 0.",
- (int? v) => verbosity = v.HasValue ? v.Value : verbosity + 1 },
- { "h|help",
- "Show this message and exit.",
- v => showHelp = v != null },
- };
- options.Parse (args);
- if (showHelp) {
- options.WriteOptionDescriptions (Console.Out);
- return;
- }
- if (verbosity > 0) {
- logger = CreateConsoleLogger ();
- }
- var builder = new JreRuntimeOptions () {
- JniAddNativeMethodRegistrationAttributePresent = true,
- JvmLibraryPath = jvmPath ?? global::Java.InteropTests.TestJVM.GetJvmLibraryPath (logger),
- ClassPath = {
- Path.Combine (Path.GetDirectoryName (typeof (App).Assembly.Location)!, "Hello-Java.Base.jar"),
- },
- TypeMappings = {
- [MyJLO.JniTypeName] = typeof (MyJLO),
- },
- };
- builder.AddOption ("-Xcheck:jni");
-
- var jvm = builder.CreateJreVM ();
-
- if (reportTiming) {
- ReportTiming ();
- return;
- }
-
- if (createMultipleVMs) {
- CreateAnotherJVM ();
- return;
- }
-
- CreateJLO ();
-
- GC.Collect ();
- GC.Collect ();
- GC.WaitForPendingFinalizers ();
- GC.WaitForPendingFinalizers ();
- }
-
- static Action CreateConsoleLogger ()
- {
- return (level, message) => {
- Console.WriteLine ($"# {level}: {message}");
- };
- }
-
- static void CreateJLO ()
- {
- var jlo = new MyJLO ();
- Console.WriteLine ($"binding? {jlo.ToString ()}");
- }
-
- static void ReportTiming ()
- {
- var jlo = new Java.Lang.Object ();
- var t = Stopwatch.StartNew ();
- for (int i = 0; i < N; ++i) {
- jlo.GetHashCode ();
- }
- t.Stop ();
- Console.WriteLine ($"Object.hashCode: {N} invocations. Total={t.Elapsed}; Average={t.Elapsed.TotalMilliseconds / (double) N}ms");
- }
-
- static unsafe void CreateAnotherJVM ()
- {
- Console.WriteLine ("Part 2!");
- using (var vm = new JreRuntimeOptions ().CreateJreVM ()) {
- Console.WriteLine ("# JniEnvironment.EnvironmentPointer={0}", JniEnvironment.EnvironmentPointer);
- Console.WriteLine ("vm.SafeHandle={0}", vm.InvocationPointer);
- var t = new JniType ("java/lang/Object");
- var c = t.GetConstructor ("()V");
- var o = t.NewObject (c, null);
- var m = t.GetInstanceMethod ("hashCode", "()I");
- int i = JniEnvironment.InstanceMethods.CallIntMethod (o, m);
- Console.WriteLine ("java.lang.Object={0}", o);
- Console.WriteLine ("hashcode={0}", i);
- JniObjectReference.Dispose (ref o);
- t.Dispose ();
- // var o = JniTypes.FindClass ("java/lang/Object");
- /*
- var waitForCreation = new CountdownEvent (1);
- var exitThread = new CountdownEvent (1);
- var t = new Thread (() => {
- var vm2 = new JavaVMBuilder ().CreateJavaVM ();
- waitForCreation.Signal ();
- exitThread.Wait ();
- });
- t.Start ();
- waitForCreation.Wait ();
- */
- foreach (var h in vm.GetAvailableInvocationPointers ()) {
- Console.WriteLine ("WITHIN: GetCreatedJavaVMs: {0}", h);
- }
- // exitThread.Signal ();
- }
- foreach (var h in JniRuntime.GetRegisteredRuntimes ()) {
- Console.WriteLine ("POST: GetCreatedJavaVMs: {0}", h);
- }
- }
- }
-
- [JniTypeSignature (JniTypeName)]
- class MyJLO : Java.Lang.Object {
- internal const string JniTypeName = "net/dot/jni/sample/MyJLO";
- }
-}
diff --git a/samples/Hello-NativeAOTFromAndroid/.gitignore b/samples/Hello-NativeAOTFromAndroid/.gitignore
deleted file mode 100644
index 405190315..000000000
--- a/samples/Hello-NativeAOTFromAndroid/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-.gradle
-build/
-local.properties
-android.xml.fixed
diff --git a/samples/Hello-NativeAOTFromAndroid/Hello-NativeAOTFromAndroid.csproj b/samples/Hello-NativeAOTFromAndroid/Hello-NativeAOTFromAndroid.csproj
deleted file mode 100644
index 5923127ff..000000000
--- a/samples/Hello-NativeAOTFromAndroid/Hello-NativeAOTFromAndroid.csproj
+++ /dev/null
@@ -1,46 +0,0 @@
-
-
-
- $(DotNetTargetFramework)
-
-
-
-
-
- Java.Interop.Samples.NativeAotFromAndroid
- enable
- enable
- true
- true
- true
- Shared
- linux-bionic-arm64
-
- AnyCPU
-
- true
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/samples/Hello-NativeAOTFromAndroid/Hello-NativeAOTFromAndroid.targets b/samples/Hello-NativeAOTFromAndroid/Hello-NativeAOTFromAndroid.targets
deleted file mode 100644
index bcf5c5977..000000000
--- a/samples/Hello-NativeAOTFromAndroid/Hello-NativeAOTFromAndroid.targets
+++ /dev/null
@@ -1,219 +0,0 @@
-
-
-
-
-
- $(UtilityOutputFullPath)generator.dll
- <_JcwOutputDir>app/src/main/java/my/
- <_GradleJniLibsDir>app/src/main/jniLibs/arm64-v8a
- $(ANDROID_NDK_HOME)
- $(ANDROID_HOME)
-
-
-
- <_NdkSysrootAbi Condition=" '$(RuntimeIdentifier)' == 'linux-bionic-arm64' ">aarch64-linux-android
- <_NdkClangPrefix Condition=" '$(RuntimeIdentifier)' == 'linux-bionic-arm64' ">aarch64-linux-android21-
- <_NdkSysrootAbi Condition=" '$(RuntimeIdentifier)' == 'linux-bionic-x64' ">x86_64-linux-android
- <_NdkClangPrefix Condition=" '$(RuntimeIdentifier)' == 'linux-bionic-x64' ">x86_64-linux-android21-
- <_NdkPrebuiltAbi Condition=" $([MSBuild]::IsOSPlatform('osx')) ">darwin-x86_64
- <_NdkPrebuiltAbi Condition=" $([MSBuild]::IsOSPlatform('linux')) ">linux-x86_64
- <_NdkPrebuiltAbi Condition=" $([MSBuild]::IsOSPlatform('windows')) ">windows-x86_64
- <_NdkSysrootLibDir>$(AndroidNdkDirectory)/toolchains/llvm/prebuilt/$(_NdkPrebuiltAbi)/sysroot/usr/lib/$(_NdkSysrootAbi)
- <_NdkBinDir>$(AndroidNdkDirectory)/toolchains/llvm/prebuilt/$(_NdkPrebuiltAbi)/bin
-
-
-
- $(_NdkClangPrefix)clang.cmd
- $(_NdkBinDir)/$(_NdkClangPrefix)clang
- llvm-objcopy.exe
- $(_NdkBinDir)/llvm-objcopy
-
-
-
-
-
-
-
- <_HomeDir Condition=" '$(OS)' != 'Windows_NT' ">$(HOME)/
- <_HomeDir Condition=" '$(OS)' == 'Windows_NT' ">$(HOMEDRIVE)$(HOMEPATH)\
-
-
-
-
-
-
-
- <_DebugKeystorePath>$(_HomeDir).android/debug.keystore
-
-
-
- <_WinNdkBinDir>$(_NdkBinDir.Replace('/', '%5c'))
-
-
-
-
-
- <_GenerateAndroidBindingInputs Include="$(GeneratorPath)" />
- <_GenerateAndroidBindingInputs Include="$(MSBuildThisFileFullPath)" />
- <_GenerateAndroidBindingInputs Include="Transforms\**" />
- <_GenerateAndroidBindingInputs Include="$(IntermediateOutputPath)mcw\api.xml" />
-
-
-
-
-
- "$(GeneratorPath)"
- <_GenFlags>--public --global
- <_Out>-o "$(IntermediateOutputPath)mcw"
- <_Codegen>--codegen-target=JavaInterop1
- <_Fixup>--fixup=Transforms/Metadata.xml
- <_Enums1>--preserve-enums --enumflags=Transforms/enumflags --enumfields=Transforms/map.csv --enummethods=Transforms/methodmap.csv
- <_Enums2>--enummetadata=$(IntermediateOutputPath)mcw/enummetadata
- <_Assembly>"--assembly=$(AssemblyName)"
- <_TypeMap>--type-map-report=$(IntermediateOutputPath)mcw/type-mapping.txt
- <_Api>android.xml
- <_Dirs>--enumdir=$(IntermediateOutputPath)mcw
- <_FullIntermediateOutputPath>$([System.IO.Path]::GetFullPath('$(IntermediateOutputPath)'))
- <_LangFeatures>--lang-features=nullable-reference-types,default-interface-methods,nested-interface-types,interface-constants
-
-
- <_RefAsmDir Include="@(ReferencePathWithRefAssemblies->'%(RootDir)%(Directory).'->Distinct())" />
- <_Lib Include="@(_RefAsmDir->'-L "%(Identity)"')" />
- <_JavaBaseRef Include="@(ReferencePathWithRefAssemblies)"
- Condition=" '%(FileName)' == 'Java.Base' "
- />
- <_Ref Include="@(_JavaBaseRef->'-r "%(FullPath)"')" />
-
-
-
-
-
-
-
-
-
-
-
-
- $(DefineConstants);$([System.String]::Copy('$(_GeneratedDefineConstants)').Replace ('%24(DefineConstants);', ''))
-
-
-
-
-
-
-
-
- <_JcwGenRefAsmDirs Include="@(ReferencePathWithRefAssemblies->'%(RootDir)%(Directory).'->Distinct())" />
-
-
- <_JcwGen>"$(UtilityOutputFullPath)/jcw-gen.dll"
- <_Target>--codegen-target JavaInterop1
- <_Output>-o "$(_JcwOutputDir)"
- <_Libpath>@(_JcwGenRefAsmDirs->'-L "%(Identity)"', ' ')
-
-
-
-
-
-
- <_BuildAppApkInput Include="$(MSBuildThisFileFullPath)" />
- <_BuildAppApkInput Include="app\src\main\java\**\*.java" />
- <_BuildAppApkInput Include="app\src\main\AndroidManifest.xml" />
- <_BuildAppApkInput Include="app\**\build.gradle" />
- <_BuildAppApkInput Include="$(NativeBinary)" />
- <_BuildAppApkInput Include="$(OutputPath)java-interop.jar" />
-
-
-
- <_AfterBuildDependsOnTargets>
- _CreateJavaCallableWrappers;
-
-
-
-
-
-
- <_GradleRtxtPath>app\build\intermediates\runtime_symbol_list\release\R.txt
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- <_GradleBuildSource Include="$(NativeBinary)" />
- <_GradleBuildTarget Include="$(_GradleJniLibsDir)\lib$(AssemblyName)$(NativeBinaryExt)" />
-
- <_GradleBuildSource Include="$(OutputPath)java-interop.jar" />
- <_GradleBuildTarget Include="app\lib\java-interop.jar" />
-
-
-
-
-
-
diff --git a/samples/Hello-NativeAOTFromAndroid/JavaInteropRuntime.cs b/samples/Hello-NativeAOTFromAndroid/JavaInteropRuntime.cs
deleted file mode 100644
index 3b22b56d6..000000000
--- a/samples/Hello-NativeAOTFromAndroid/JavaInteropRuntime.cs
+++ /dev/null
@@ -1,49 +0,0 @@
-using System.Runtime.InteropServices;
-
-using Java.Interop;
-
-namespace Java.Interop.Samples.NativeAotFromAndroid;
-
-static class JavaInteropRuntime
-{
- static JniRuntime? runtime;
-
- [UnmanagedCallersOnly (EntryPoint="JNI_OnLoad")]
- static int JNI_OnLoad (IntPtr vm, IntPtr reserved)
- {
- try {
- AndroidLog.Print (AndroidLogLevel.Info, "JavaInteropRuntime", "JNI_OnLoad()");
- LogcatTextWriter.Init ();
- return (int) JniVersion.v1_6;
- }
- catch (Exception e) {
- AndroidLog.Print (AndroidLogLevel.Error, "JavaInteropRuntime", $"JNI_OnLoad() failed: {e}");
- return 0;
- }
- }
-
- [UnmanagedCallersOnly (EntryPoint="JNI_OnUnload")]
- static void JNI_OnUnload (IntPtr vm, IntPtr reserved)
- {
- AndroidLog.Print(AndroidLogLevel.Info, "JavaInteropRuntime", "JNI_OnUnload");
- runtime?.Dispose ();
- }
-
- // symbol name from `$(IntermediateOutputPath)obj/Release/osx-arm64/h-classes/net_dot_jni_hello_JavaInteropRuntime.h`
- [UnmanagedCallersOnly (EntryPoint="Java_net_dot_jni_nativeaot_JavaInteropRuntime_init")]
- static void init (IntPtr jnienv, IntPtr klass)
- {
- Console.WriteLine ($"C# init()");
- try {
- var options = new JreRuntimeOptions {
- EnvironmentPointer = jnienv,
- JniGlobalReferenceLogWriter = new LogcatTextWriter (AndroidLogLevel.Debug, "NativeAot:GREF"),
- JniLocalReferenceLogWriter = new LogcatTextWriter (AndroidLogLevel.Debug, "NativeAot:LREF"),
- };
- runtime = options.CreateJreVM (new NativeAotTypeManager ());
- }
- catch (Exception e) {
- AndroidLog.Print (AndroidLogLevel.Error, "JavaInteropRuntime", $"JavaInteropRuntime.init: error: {e}");
- }
- }
-}
diff --git a/samples/Hello-NativeAOTFromAndroid/LogcatTextWriter.cs b/samples/Hello-NativeAOTFromAndroid/LogcatTextWriter.cs
deleted file mode 100644
index 36f2f2a90..000000000
--- a/samples/Hello-NativeAOTFromAndroid/LogcatTextWriter.cs
+++ /dev/null
@@ -1,73 +0,0 @@
-using System.IO;
-using System.Runtime.InteropServices;
-using System.Text;
-
-namespace Java.Interop.Samples.NativeAotFromAndroid;
-
-internal sealed class LogcatTextWriter : TextWriter {
-
- public static void Init ()
- {
- // This method is a no-op, but it's necessary to ensure the static
- // constructor is executed.
- }
-
- static LogcatTextWriter ()
- {
- Console.SetOut (new LogcatTextWriter (AndroidLogLevel.Info));
- Console.SetError (new LogcatTextWriter (AndroidLogLevel.Error));
- }
-
- AndroidLogLevel Level;
- string Tag;
-
- internal LogcatTextWriter (AndroidLogLevel level, string tag = "NativeAotFromAndroid")
- {
- Level = level;
- Tag = tag;
- }
-
- public override Encoding Encoding => Encoding.UTF8;
- public override string NewLine => "\n";
-
- public override void WriteLine (string? value)
- {
- if (value == null) {
- AndroidLog.Print (Level, Tag, "");
- return;
- }
- ReadOnlySpan span = value;
- while (!span.IsEmpty) {
- if (span.IndexOf ('\n') is int n && n < 0) {
- break;
- }
- var line = span.Slice (0, n);
- AndroidLog.Print (Level, Tag, line.ToString ());
- span = span.Slice (n + 1);
- }
- AndroidLog.Print (Level, Tag, span.ToString ());
- }
-}
-
-static class AndroidLog {
-
- [DllImport ("log", EntryPoint = "__android_log_print", CallingConvention = CallingConvention.Cdecl)]
- private static extern void __android_log_print(AndroidLogLevel level, string? tag, string format, string args, IntPtr ptr);
-
- internal static void Print(AndroidLogLevel level, string? tag, string message) =>
- __android_log_print(level, tag, "%s", message, IntPtr.Zero);
-
-}
-
-internal enum AndroidLogLevel
-{
- Unknown = 0x00,
- Default = 0x01,
- Verbose = 0x02,
- Debug = 0x03,
- Info = 0x04,
- Warn = 0x05,
- Error = 0x06,
- Fatal = 0x07,
- Silent = 0x08
-}
diff --git a/samples/Hello-NativeAOTFromAndroid/MainActivity.cs b/samples/Hello-NativeAOTFromAndroid/MainActivity.cs
deleted file mode 100644
index 6eefab692..000000000
--- a/samples/Hello-NativeAOTFromAndroid/MainActivity.cs
+++ /dev/null
@@ -1,39 +0,0 @@
-using Java.Interop;
-
-namespace Java.Interop.Samples.NativeAotFromAndroid;
-
-[JniTypeSignature ("my/MainActivity")]
-public class MainActivity : Android.App.Activity {
-
- public MainActivity ()
- {
- Console.WriteLine ("MainActivity..ctor()");
- }
-
- protected override void OnCreate (Android.OS.Bundle? savedInstanceState)
- {
- Console.WriteLine ($"MainActivity.OnCreate(): savedInstanceState? {savedInstanceState != null}");
- base.OnCreate (savedInstanceState);
- SetContentView (R.layout.activity_main);
-
- PrintGrefInfo ();
- }
-
- static void PrintGrefInfo ()
- {
- var runtime = JniEnvironment.Runtime;
- var peers = runtime.ValueManager.GetSurfacedPeers ();
- Console.WriteLine ($"Created {runtime.ObjectReferenceManager.GlobalReferenceCount} GREFs; Surfaced {peers.Count} peers");
- for (int i = 0; i < peers.Count; ++i) {
- Console.WriteLine ($" SurfacedPeers[{i,3}] = {ToString (peers[i])}");
- }
- }
-
- static string ToString (JniSurfacedPeerInfo peer)
- {
- if (!peer.SurfacedPeer.TryGetTarget (out var p)) {
- return $"JniSurfacedPeerInfo(IdentityHashCode=0x{peer.JniIdentityHashCode:x})";
- }
- return $"JniSurfacedPeerInfo(PeerReference={p.PeerReference} IdentityHashCode=0x{peer.JniIdentityHashCode:x} Instance.Type={p.GetType ()})";
- }
-}
diff --git a/samples/Hello-NativeAOTFromAndroid/NativeAotTypeManager.cs b/samples/Hello-NativeAOTFromAndroid/NativeAotTypeManager.cs
deleted file mode 100644
index caa5187a7..000000000
--- a/samples/Hello-NativeAOTFromAndroid/NativeAotTypeManager.cs
+++ /dev/null
@@ -1,155 +0,0 @@
-using System.Diagnostics.CodeAnalysis;
-
-using Java.Interop;
-
-namespace Java.Interop.Samples.NativeAotFromAndroid;
-
-partial class NativeAotTypeManager : JniRuntime.JniTypeManager {
-
- internal const DynamicallyAccessedMemberTypes Methods = DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods;
- internal const DynamicallyAccessedMemberTypes MethodsAndPrivateNested = Methods | DynamicallyAccessedMemberTypes.NonPublicNestedTypes;
- internal const DynamicallyAccessedMemberTypes MethodsConstructors = MethodsAndPrivateNested | DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors;
-
- Dictionary typeMappings = new () {
- ["android/app/Activity"] = typeof (Android.App.Activity),
- ["android/content/Context"] = typeof (Android.Content.Context),
- ["android/content/ContextWrapper"] = typeof (Android.Content.ContextWrapper),
- ["android/os/BaseBundle"] = typeof (Android.OS.BaseBundle),
- ["android/os/Bundle"] = typeof (Android.OS.Bundle),
- ["android/view/ContextThemeWrapper"] = typeof (Android.View.ContextThemeWrapper),
- ["my/MainActivity"] = typeof (MainActivity),
- };
-
- public override void RegisterNativeMembers (
- JniType nativeClass,
- [DynamicallyAccessedMembers (MethodsAndPrivateNested)]
- Type type,
- ReadOnlySpan methods)
- {
- if (TryRegisterBuiltInNativeMembers (nativeClass, nativeClass.Name, methods))
- return;
- if (!methods.IsEmpty)
- throw new NotSupportedException ($"Could not register native members for type '{type.FullName}'.");
- }
-
- [Obsolete ("Use RegisterNativeMembers(JniType, Type, ReadOnlySpan)")]
- public override void RegisterNativeMembers (
- JniType nativeClass,
- [DynamicallyAccessedMembers (MethodsAndPrivateNested)]
- Type type,
- string? methods)
- {
- RegisterNativeMembers (nativeClass, type, methods.AsSpan ());
- }
-
- protected override IEnumerable GetTypesForSimpleReference (string jniSimpleReference)
- {
- var target = GetTypeForSimpleReference (jniSimpleReference);
- if (target != null)
- yield return target;
- }
-
- protected override string? GetSimpleReference (Type type)
- {
- return GetSimpleReferences (type).FirstOrDefault ();
- }
-
- [return: DynamicallyAccessedMembers (MethodsConstructors)]
- protected override Type? GetTypeForSimpleReference (string jniSimpleReference)
- {
- return jniSimpleReference switch {
- "V" => typeof (void),
- "Z" => typeof (bool),
- "java/lang/Boolean" => typeof (bool?),
- "B" => typeof (sbyte),
- "java/lang/Byte" => typeof (sbyte?),
- "C" => typeof (char),
- "java/lang/Character" => typeof (char?),
- "S" => typeof (short),
- "java/lang/Short" => typeof (short?),
- "I" => typeof (int),
- "java/lang/Integer" => typeof (int?),
- "J" => typeof (long),
- "java/lang/Long" => typeof (long?),
- "F" => typeof (float),
- "java/lang/Float" => typeof (float?),
- "D" => typeof (double),
- "java/lang/Double" => typeof (double?),
- "android/app/Activity" => typeof (Android.App.Activity),
- "android/content/Context" => typeof (Android.Content.Context),
- "android/content/ContextWrapper" => typeof (Android.Content.ContextWrapper),
- "android/os/BaseBundle" => typeof (Android.OS.BaseBundle),
- "android/os/Bundle" => typeof (Android.OS.Bundle),
- "android/view/ContextThemeWrapper" => typeof (Android.View.ContextThemeWrapper),
- "my/MainActivity" => typeof (MainActivity),
- _ => null,
- };
- }
-
- protected override IEnumerable GetSimpleReferences (Type type)
- {
- return CreateSimpleReferencesEnumerator (type);
- }
-
- IEnumerable CreateSimpleReferencesEnumerator (Type type)
- {
- if (typeMappings == null)
- yield break;
- foreach (var e in typeMappings) {
- if (e.Value == type)
- yield return e.Key;
- }
- }
-
- public override IEnumerable GetTypes (JniTypeSignature typeSignature)
- {
- if (!typeSignature.IsValid || typeSignature.ArrayRank != 0 || typeSignature.SimpleReference == null)
- return [];
- return GetTypesForSimpleReference (typeSignature.SimpleReference);
- }
-
- public override IEnumerable GetReflectionConstructibleTypes (JniTypeSignature typeSignature)
- {
- if (!typeSignature.IsValid || typeSignature.ArrayRank != 0 || typeSignature.SimpleReference == null)
- yield break;
- var target = GetTypeForSimpleReference (typeSignature.SimpleReference);
- if (target != null)
- yield return new JniRuntime.JniTypeManager.ReflectionConstructibleType (target);
- }
-
- protected override JniTypeSignature GetTypeSignatureCore (Type type)
- {
- var simpleReference = GetSimpleReferences (type).FirstOrDefault ();
- return simpleReference == null ? default : new JniTypeSignature (simpleReference, 0, false);
- }
-
- protected override IEnumerable GetTypeSignaturesCore (Type type)
- {
- var signature = GetTypeSignatureCore (type);
- if (signature.IsValid)
- yield return signature;
- }
-
- [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)]
- protected override Type? GetInvokerTypeCore (
- [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)]
- Type type)
- {
- return null;
- }
-
- protected override IReadOnlyList? GetStaticMethodFallbackTypesCore (string jniSimpleReference)
- {
- return null;
- }
-
- protected override string? GetReplacementTypeCore (string jniSimpleReference)
- {
- return null;
- }
-
- protected override JniRuntime.ReplacementMethodInfo? GetReplacementMethodInfoCore (string jniSourceType, string jniMethodName, string jniMethodSignature)
- {
- return null;
- }
-}
diff --git a/samples/Hello-NativeAOTFromAndroid/README.md b/samples/Hello-NativeAOTFromAndroid/README.md
deleted file mode 100644
index e988722a5..000000000
--- a/samples/Hello-NativeAOTFromAndroid/README.md
+++ /dev/null
@@ -1,264 +0,0 @@
-# Hello From Android
-
-[Hello-NativeAOTFromJNI](../Hello-NativeAOTFromJNI) demonstrated how
-to use [NativeAOT][0] to create a native library which could be loaded
-by a Java Virtual Machine (JVM).
-
-Extend this idea for Android!
-
-## Prerequisites
-
-In order to build this sample, the Android SDK and Android NDK must be present.
-*An* easy way to provision these is to build dotnet/android:
-
- * [Windows build instructions](https://github.com/dotnet/android/blob/155709f9917666ca046c79a4e9769924ff4ab9bb/Documentation/building/windows/instructions.md)
- * [Linux and macOS build instructions](https://github.com/dotnet/android/blob/main/Documentation/building/unix/instructions.md)
-
-Once you've run `make prepar` or `dotnet msbuild Xamarin.Android.sln -t:Prepare`,
-then an `android-toolchain` directory will exist in your home directory.
-
-A `.android/debug.keystore` file must also exist within your home directory.
-This file can be created by using
-[`keytool -genkeypair`](https://docs.oracle.com/en/java/javase/11/tools/keytool.html).
-
- * On **Windows**, run the following command within a `CMD.EXE` window:
-
- ```cmd
- %HOMEDRIVE%%HOMEPATH%\android-toolchain\jdk-17\bin\keytool.exe -genkeypair ^
- -keyalg RSA -validity 10950 -dname "CN=Android Debug,O=Android,C=US" ^
- -keystore %HOMEDRIVE%%HOMEPATH%\.android\debug.keystore ^
- -alias androiddebugkey -storepass android -keypass android
- ```
-
- * On **Linux** and **macOS**, run:
-
- ```sh
- $HOME/android-toolchain/jdk-17/bin/keytool -genkeypair \
- -keyalg RSA -validity 10950 -dname "CN=Android Debug,O=Android,C=US" \
- -keystore $HOME/.android/debug.keystore \
- -alias androiddebugkey -storepass android -keypass android
- ```
-
-The NativeAOT toolchain on Windows also requires that the NDK "prebuilt"
-directory be located within `%PATH%`
-
-```cmd
-set PATH=%HOMEDRIVE%%HOMEPATH%\android-toolchain\ndk\toolchains\llvm\prebuilt\windows-x86_64\bin;%PATH%
-```
-
-## Building
-
-Building a native library with NativeAOT requires a Release configuration build.
-For in-repo use, that means that xamarin/Java.Interop itself needs to be built in
-Release configuration:
-
-```sh
-% dotnet build -c Release -t:Prepare
-% dotnet build -c Release
-```
-
-Once Java.Interop itself is built, you can *publish* the sample:
-
-```sh
-% cd samples/Hello-NativeAOTFromAndroid
-
-# set the ANDROID_NDK_HOME environment variable or set the AndroidNdkDirectory property
-# set the ANDROID_HOME environment variable or set the AndroidSdkDirectory property
-# values here are valid if you have a xamarin/xamarin-android build environment.
-% dotnet publish -c Release -p:AndroidNdkDirectory=$HOME/android-toolchain/ndk \
- -p:AndroidSdkDirectory=$HOME/android-toolchain/sdk
-```
-
-The resulting native library contains various import symbols:
-
-```sh
-% nm -D bin/Release/linux-bionic-arm64/native/Hello-NativeAOTFromAndroid.so | grep ' T '
-0000000000240950 T JNI_OnLoad@@V1.0
-0000000000240ab0 T JNI_OnUnload@@V1.0
-0000000000240b30 T Java_net_dot_jni_nativeaot_JavaInteropRuntime_init@@V1.0
-00000000002392e0 T __start___managedcode
-00000000004394d0 T __start___unbox
-00000000004394d0 T __stop___managedcode
-000000000043a720 T __stop___unbox
-```
-
-The build system also produces a `net.dot.jni.helloandroid-Signed.apk`,
-which can be installed and launched:
-
-```sh
-% adb install bin/Release/linux-bionic-arm64/net.dot.jni.helloandroid-Signed.apk
-% adb shell am start net.dot.jni.helloandroid/my.MainActivity
-
-# Only-java codepath for testing; doesn't use NativeAOT:
-% adb shell am start net.dot.jni.helloandroid/net.dot.jni.nativeaot.JavaMainActivity
-```
-
-## Logging
-
-By default this sample writes quite a bit to `adb logcat`, including:
-
- * Initialization messages
-
- ```
- D NativeAotRuntimeProvider: NativeAotRuntimeProvider()
- D NativeAotRuntimeProvider: NativeAotRuntimeProvider.attachInfo(): calling JavaInteropRuntime.init()…
- D JavaInteropRuntime: Loading libHello-NativeAOTFromAndroid.so…
- I JavaInteropRuntime: JNI_OnLoad()
- I NativeAotFromAndroid: C# init()
- D NativeAotRuntimeProvider: NativeAotRuntimeProvider.onCreate()
- ```
-
- * JNI Global Reference and Local Reference messages
-
- ```
- D NativeAot:LREF: +l+ lrefc 1 handle 0x7eb64ae01d/L from thread ''(1)
- D NativeAot:GREF: +g+ grefc 1 obj-handle 0x7eb64ae01d/L -> new-handle 0x2af2/G from thread ''(1)
- ```
-
- * `MainActivity` messages
-
- ```
- I NativeAotFromAndroid: MainActivity..ctor()
- I NativeAotFromAndroid: MainActivity.OnCreate(): savedInstanceState? False
- ```
-
-Additionally, the end of `MainActivity.OnCreate()` will print out how many
-GREFs have been created, and information about the created "surfaced peers":
-
-```
-I NativeAotFromAndroid: Created 6 GREFs; Surfaced 1 peers
-I NativeAotFromAndroid: SurfacedPeers[ 0] = JniSurfacedPeerInfo(PeerReference=0x2bc6/G IdentityHashCode=0x1d64f40 Instance.Type=Java.Interop.Samples.NativeAotFromAndroid.MainActivity)
-```
-
-The (very!) extensive logging around JNI Global and Local references mean that
-this sample should *not* be used as-is for startup timing comparison.
-That said, on my Pixel 6, we get:
-
-```
-I ActivityTaskManager: Displayed net.dot.jni.helloandroid/my.MainActivity for user 0: +282ms
-```
-
-## What does this mean for .NET for Android?
-
-Short-term? Nothing. Long-term? *Maybe* something.
-
-While .NET for Android uses Java.Interop, it uses a different *style* of Java.Interop.
-.NET for Android *could* be updated to support NativeAot, but it would not be as simple
-as this sample may suggest. Difficulties will include:
-
- * [GC](#gc)
- * [Marshal Methods](#marshal-methods)
- * [Process Startup miscellany, including the important question "what is an Assembly?"](#miscellany)
-
-### GC
-
-.NET for Android relies on .NET's MonoVM, which provides a
-[GC bridge](https://github.com/dotnet/runtime/blob/c5c7f0d3d11cc82eddf1747fbdcaec9cb850c3aa/src/native/public/mono/metadata/details/sgen-bridge-types.h),
-which is used to support cross-VM object references. This allows an object
-reference within a Java VM to keep an object instance within the .NET VM alive.
-
-Neither CoreCLR nor NativeAot runtimes support such a GC bridge, and without
-something like it, developers would need to take *significantly* more care in
-object lifetimes and cleanup.
-
-Until a cross-VM GC solution is found, .NET for Android must remain on MonoVM.
-
-### Marshal Methods
-
-"Marshal Methods" are methods that are:
-
- * Invoked by the Java Virtual Machine when a `native` Java method is invoked.
- * Responsible for parameter marshaling, invoking C# method overrides, and
-marshaling the return type back to Java.
-
-.NET for Android uses `generator --codegen-target=XAJavaInterop1` for binding
-assemblies, which "bakes in" marshal methods. There is an implicit ABI for
-marshal methods, and part of that ABI is that they don't catch exceptions:
-
-```csharp
-partial class Activity {
- protected virtual unsafe void OnCreate (Android.OS.Bundle? savedInstanceState) => …
-
- static Delegate? cb_onCreate_Landroid_os_Bundle_;
- static Delegate GetOnCreate_Landroid_os_Bundle_Handler ()
- {
- if (cb_onCreate_Landroid_os_Bundle_ == null)
- cb_onCreate_Landroid_os_Bundle_ = JNINativeWrapper.CreateDelegate (new _JniMarshal_PPL_V (n_OnCreate_Landroid_os_Bundle_));
- return cb_onCreate_Landroid_os_Bundle_;
- }
-
- static void n_OnCreate_Landroid_os_Bundle_ (IntPtr jnienv, IntPtr native__this, IntPtr native_savedInstanceState)
- {
- // Note: no try/catch block! If `__this.OnCreate()` throws, Bad Things™ will happen.
- var __this = global::Java.Lang.Object.GetObject (jnienv, native__this, JniHandleOwnership.DoNotTransfer)!;
- var savedInstanceState = global::Java.Lang.Object.GetObject (native_savedInstanceState, JniHandleOwnership.DoNotTransfer);
- __this.OnCreate (savedInstanceState);
- }
-}
-```
-
-`Activity.n_OnCreate_Landroid_os_Bundle_()` is the marshal method responsible for
-invoking `Activity.OnCreate()`. It does not catch exceptions, and if an exception
-*were* thrown from `Activity.OnCreate()`, the entire app could exit. Consequently,
-every such marshal method is wrapped in `JNINativeWrapper.CreateDelegate()`, which
-uses `DynamicMethod` to wrap the marshal method in a `try`/`catch` block, which
-is responsible for notifying the debugger and exception marshaling.
-
-As-is, none of this can work with NativeAot.
-
-Updating .NET for Android to *not* use `DynamicMethod` has both known and unknown
-issues (what new pattern do we use? What about compatibility with existing
-binding assemblies?).
-
-This sample uses `generator --codegen-target=JavaInterop1` for binding assemblies,
-which *skips* the emission of marshal methods *entirely*. As Marshal Methods are
-*required*, `jnimarshalmethod-gen` is invoked as a post-build step to insert
-Marshal Methods into the assemblies, and these marshal methods appropriately
-marshal exceptions.
-
-## Miscellany
-
-.NET for Android deals with assemblies: they can be side-loaded (for Fast Deployment),
-packaged trimmed or untrimmed. Bidirectional mapping between JNI type names and
-`System.Type` instances makes extensive use of MonoVM's embedding API.
-
-None of the above exists in NativeAot: there are no separate assembly files,
-"assembly identity" is a nebulous concept, and there is no equivalent to the MonoVm
-embedding API.
-
-Large portions of .NET for Android would need to be rewritten to support NativeAot,
-and NativeAot would actively prevent features such as Fast Deployment, meaning *both*
-MonoVM and NativeAot would need to be supported.
-
-## Notes
-
-As with `Hello-NativeAOTFromJNI`, the project needs to be built with
-`$(PlatformTarget)`=AnyCPU, so that `jnimarshalmethod-gen` can be used
-to generate JNI Marshal Methods as a post-build step.
-
-This project contains a *tiny* `android.xml` API description for Android.
-This is used to generate a binding, allowing (nominally) intuitive:
-
-```csharp
-[JniTypeSignature ("my/MainActivity")]
-partial class MainActivity : Android.App.Activity {
- protected override void OnCreate (Android.OS.Bundle? savedInstanceState) => …
-}
-```
-
-This project follows what .NET for Android does to initialize things:
-provide a custom [`ContentProvider`][1] which contains Java "bootstrap"
-code to initialize the runtime.
-
-### GC
-
-As with [Hello-NativeAOTFromJNI](../Hello-NativeAOTFromJNI), NativeAOT does not
-provide a GC bridge that we can rely on. Consequently, every "surfaced peer" will
-*never be collected by default*.
-
-This is a *sample*, not a product, and not even the *inkling* of a product.
-
-For exploratory purposes only.
-
-[0]: https://github.com/dotnet/samples/blob/main/core/nativeaot/NativeLibrary/README.md
-[1]: https://developer.android.com/reference/android/content/ContentProvider
diff --git a/samples/Hello-NativeAOTFromAndroid/Transforms/Metadata.xml b/samples/Hello-NativeAOTFromAndroid/Transforms/Metadata.xml
deleted file mode 100644
index 26c2f6238..000000000
--- a/samples/Hello-NativeAOTFromAndroid/Transforms/Metadata.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-
-
diff --git a/samples/Hello-NativeAOTFromAndroid/Transforms/enumflags b/samples/Hello-NativeAOTFromAndroid/Transforms/enumflags
deleted file mode 100644
index e69de29bb..000000000
diff --git a/samples/Hello-NativeAOTFromAndroid/Transforms/map.csv b/samples/Hello-NativeAOTFromAndroid/Transforms/map.csv
deleted file mode 100644
index e69de29bb..000000000
diff --git a/samples/Hello-NativeAOTFromAndroid/Transforms/methodmap.csv b/samples/Hello-NativeAOTFromAndroid/Transforms/methodmap.csv
deleted file mode 100644
index e69de29bb..000000000
diff --git a/samples/Hello-NativeAOTFromAndroid/android.xml b/samples/Hello-NativeAOTFromAndroid/android.xml
deleted file mode 100644
index d52bd14b3..000000000
--- a/samples/Hello-NativeAOTFromAndroid/android.xml
+++ /dev/null
@@ -1,56 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/samples/Hello-NativeAOTFromAndroid/app/.gitignore b/samples/Hello-NativeAOTFromAndroid/app/.gitignore
deleted file mode 100644
index 13775520f..000000000
--- a/samples/Hello-NativeAOTFromAndroid/app/.gitignore
+++ /dev/null
@@ -1,5 +0,0 @@
-/build
-lib/java-interop.jar
-src/main/java/my
-src/main/jniLibs
-
diff --git a/samples/Hello-NativeAOTFromAndroid/app/build.gradle b/samples/Hello-NativeAOTFromAndroid/app/build.gradle
deleted file mode 100644
index 2ac125e3e..000000000
--- a/samples/Hello-NativeAOTFromAndroid/app/build.gradle
+++ /dev/null
@@ -1,49 +0,0 @@
-plugins {
- id 'com.android.application'
-}
-
-dependencies {
- implementation files('lib/java-interop.jar')
-}
-
-android {
- namespace 'net.dot.jni.helloandroid'
- compileSdk 33
- // Doing this to match NDK NativeAOT is using
- ndkVersion "23.2.8568313"
-
- defaultConfig {
- applicationId "net.dot.jni.helloandroid"
- minSdk 21
- targetSdk 33
- versionCode 1
- versionName "1.0"
-
- // NOTE: for now, arm64 only. Might eventually do 4 ABIs
- ndk {
- abiFilters 'arm64-v8a'
- }
- }
-
- // Just use the built-in debug keystore
- signingConfigs {
- release {
- storeFile file("${System.getProperty('user.home')}/.android/debug.keystore")
- storePassword 'android'
- keyAlias 'androiddebugkey'
- keyPassword 'android'
- }
- }
-
- buildTypes {
- release {
- minifyEnabled false
- proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
- signingConfig signingConfigs.release
- }
- }
- compileOptions {
- sourceCompatibility JavaVersion.VERSION_1_8
- targetCompatibility JavaVersion.VERSION_1_8
- }
-}
diff --git a/samples/Hello-NativeAOTFromAndroid/app/proguard-rules.pro b/samples/Hello-NativeAOTFromAndroid/app/proguard-rules.pro
deleted file mode 100644
index f1b424510..000000000
--- a/samples/Hello-NativeAOTFromAndroid/app/proguard-rules.pro
+++ /dev/null
@@ -1,21 +0,0 @@
-# Add project specific ProGuard rules here.
-# You can control the set of applied configuration files using the
-# proguardFiles setting in build.gradle.
-#
-# For more details, see
-# http://developer.android.com/guide/developing/tools/proguard.html
-
-# If your project uses WebView with JS, uncomment the following
-# and specify the fully qualified class name to the JavaScript interface
-# class:
-#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
-# public *;
-#}
-
-# Uncomment this to preserve the line number information for
-# debugging stack traces.
-#-keepattributes SourceFile,LineNumberTable
-
-# If you keep the line number information, uncomment this to
-# hide the original source file name.
-#-renamesourcefileattribute SourceFile
diff --git a/samples/Hello-NativeAOTFromAndroid/app/src/main/AndroidManifest.xml b/samples/Hello-NativeAOTFromAndroid/app/src/main/AndroidManifest.xml
deleted file mode 100644
index 6e1f849a7..000000000
--- a/samples/Hello-NativeAOTFromAndroid/app/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/samples/Hello-NativeAOTFromAndroid/app/src/main/java/net/dot/jni/nativeaot/JavaInteropRuntime.java b/samples/Hello-NativeAOTFromAndroid/app/src/main/java/net/dot/jni/nativeaot/JavaInteropRuntime.java
deleted file mode 100644
index 26811bed8..000000000
--- a/samples/Hello-NativeAOTFromAndroid/app/src/main/java/net/dot/jni/nativeaot/JavaInteropRuntime.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package net.dot.jni.nativeaot;
-
-import android.util.Log;
-
-public class JavaInteropRuntime {
- static {
- Log.d("JavaInteropRuntime", "Loading libHello-NativeAOTFromAndroid.so…");
- System.loadLibrary("Hello-NativeAOTFromAndroid");
- }
-
- private JavaInteropRuntime() {
- }
-
- public static native void init();
-}
diff --git a/samples/Hello-NativeAOTFromAndroid/app/src/main/java/net/dot/jni/nativeaot/JavaMainActivity.java b/samples/Hello-NativeAOTFromAndroid/app/src/main/java/net/dot/jni/nativeaot/JavaMainActivity.java
deleted file mode 100644
index b8334ac25..000000000
--- a/samples/Hello-NativeAOTFromAndroid/app/src/main/java/net/dot/jni/nativeaot/JavaMainActivity.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package net.dot.jni.nativeaot;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.util.Log;
-
-import net.dot.jni.helloandroid.R;
-
-public class JavaMainActivity extends Activity {
- private static final String TAG = "NativeAot:JavaMainActivity";
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- Log.i(TAG, "JavaMainActivity.onCreate()");
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- }
-}
diff --git a/samples/Hello-NativeAOTFromAndroid/app/src/main/java/net/dot/jni/nativeaot/NativeAotRuntimeProvider.java b/samples/Hello-NativeAOTFromAndroid/app/src/main/java/net/dot/jni/nativeaot/NativeAotRuntimeProvider.java
deleted file mode 100644
index 9ac3259af..000000000
--- a/samples/Hello-NativeAOTFromAndroid/app/src/main/java/net/dot/jni/nativeaot/NativeAotRuntimeProvider.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package net.dot.jni.nativeaot;
-
-import android.util.Log;
-
-public class NativeAotRuntimeProvider
- extends android.content.ContentProvider
-{
- private static final String TAG = "NativeAotRuntimeProvider";
-
- public NativeAotRuntimeProvider() {
- Log.d(TAG, "NativeAotRuntimeProvider()");
- }
-
- @Override
- public boolean onCreate() {
- Log.d(TAG, "NativeAotRuntimeProvider.onCreate()");
- return true;
- }
-
- @Override
- public void attachInfo(android.content.Context context, android.content.pm.ProviderInfo info) {
- Log.d(TAG, "NativeAotRuntimeProvider.attachInfo(): calling JavaInteropRuntime.init()…");
- JavaInteropRuntime.init();
- super.attachInfo (context, info);
- }
-
- @Override
- public android.database.Cursor query(android.net.Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
- throw new RuntimeException ("This operation is not supported.");
- }
-
- @Override
- public String getType(android.net.Uri uri) {
- throw new RuntimeException ("This operation is not supported.");
- }
-
- @Override
- public android.net.Uri insert(android.net.Uri uri, android.content.ContentValues initialValues) {
- throw new RuntimeException ("This operation is not supported.");
- }
-
- @Override
- public int delete(android.net.Uri uri, String where, String[] whereArgs) {
- throw new RuntimeException ("This operation is not supported.");
- }
-
- @Override
- public int update(android.net.Uri uri, android.content.ContentValues values, String where, String[] whereArgs) {
- throw new RuntimeException ("This operation is not supported.");
- }
-}
diff --git a/samples/Hello-NativeAOTFromAndroid/app/src/main/libs/arm64-v8a/libdotnet.so.dbg b/samples/Hello-NativeAOTFromAndroid/app/src/main/libs/arm64-v8a/libdotnet.so.dbg
deleted file mode 100644
index dfb82ed6d..000000000
Binary files a/samples/Hello-NativeAOTFromAndroid/app/src/main/libs/arm64-v8a/libdotnet.so.dbg and /dev/null differ
diff --git a/samples/Hello-NativeAOTFromAndroid/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/samples/Hello-NativeAOTFromAndroid/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
deleted file mode 100644
index 2b068d114..000000000
--- a/samples/Hello-NativeAOTFromAndroid/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/samples/Hello-NativeAOTFromAndroid/app/src/main/res/drawable/ic_launcher_background.xml b/samples/Hello-NativeAOTFromAndroid/app/src/main/res/drawable/ic_launcher_background.xml
deleted file mode 100644
index 07d5da9cb..000000000
--- a/samples/Hello-NativeAOTFromAndroid/app/src/main/res/drawable/ic_launcher_background.xml
+++ /dev/null
@@ -1,170 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/samples/Hello-NativeAOTFromAndroid/app/src/main/res/layout/activity_main.xml b/samples/Hello-NativeAOTFromAndroid/app/src/main/res/layout/activity_main.xml
deleted file mode 100644
index dd60405e5..000000000
--- a/samples/Hello-NativeAOTFromAndroid/app/src/main/res/layout/activity_main.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/samples/Hello-NativeAOTFromAndroid/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/samples/Hello-NativeAOTFromAndroid/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
deleted file mode 100644
index 6f3b755bf..000000000
--- a/samples/Hello-NativeAOTFromAndroid/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/samples/Hello-NativeAOTFromAndroid/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/samples/Hello-NativeAOTFromAndroid/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
deleted file mode 100644
index 6f3b755bf..000000000
--- a/samples/Hello-NativeAOTFromAndroid/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/samples/Hello-NativeAOTFromAndroid/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/samples/Hello-NativeAOTFromAndroid/app/src/main/res/mipmap-hdpi/ic_launcher.webp
deleted file mode 100644
index c209e78ec..000000000
Binary files a/samples/Hello-NativeAOTFromAndroid/app/src/main/res/mipmap-hdpi/ic_launcher.webp and /dev/null differ
diff --git a/samples/Hello-NativeAOTFromAndroid/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/samples/Hello-NativeAOTFromAndroid/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
deleted file mode 100644
index b2dfe3d1b..000000000
Binary files a/samples/Hello-NativeAOTFromAndroid/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp and /dev/null differ
diff --git a/samples/Hello-NativeAOTFromAndroid/app/src/main/res/mipmap-mdpi/ic_launcher.webp b/samples/Hello-NativeAOTFromAndroid/app/src/main/res/mipmap-mdpi/ic_launcher.webp
deleted file mode 100644
index 4f0f1d64e..000000000
Binary files a/samples/Hello-NativeAOTFromAndroid/app/src/main/res/mipmap-mdpi/ic_launcher.webp and /dev/null differ
diff --git a/samples/Hello-NativeAOTFromAndroid/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/samples/Hello-NativeAOTFromAndroid/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
deleted file mode 100644
index 62b611da0..000000000
Binary files a/samples/Hello-NativeAOTFromAndroid/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp and /dev/null differ
diff --git a/samples/Hello-NativeAOTFromAndroid/app/src/main/res/mipmap-xhdpi/ic_launcher.webp b/samples/Hello-NativeAOTFromAndroid/app/src/main/res/mipmap-xhdpi/ic_launcher.webp
deleted file mode 100644
index 948a3070f..000000000
Binary files a/samples/Hello-NativeAOTFromAndroid/app/src/main/res/mipmap-xhdpi/ic_launcher.webp and /dev/null differ
diff --git a/samples/Hello-NativeAOTFromAndroid/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/samples/Hello-NativeAOTFromAndroid/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
deleted file mode 100644
index 1b9a6956b..000000000
Binary files a/samples/Hello-NativeAOTFromAndroid/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp and /dev/null differ
diff --git a/samples/Hello-NativeAOTFromAndroid/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/samples/Hello-NativeAOTFromAndroid/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
deleted file mode 100644
index 28d4b77f9..000000000
Binary files a/samples/Hello-NativeAOTFromAndroid/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp and /dev/null differ
diff --git a/samples/Hello-NativeAOTFromAndroid/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/samples/Hello-NativeAOTFromAndroid/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
deleted file mode 100644
index 9287f5083..000000000
Binary files a/samples/Hello-NativeAOTFromAndroid/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp and /dev/null differ
diff --git a/samples/Hello-NativeAOTFromAndroid/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/samples/Hello-NativeAOTFromAndroid/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
deleted file mode 100644
index aa7d6427e..000000000
Binary files a/samples/Hello-NativeAOTFromAndroid/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp and /dev/null differ
diff --git a/samples/Hello-NativeAOTFromAndroid/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/samples/Hello-NativeAOTFromAndroid/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
deleted file mode 100644
index 9126ae37c..000000000
Binary files a/samples/Hello-NativeAOTFromAndroid/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp and /dev/null differ
diff --git a/samples/Hello-NativeAOTFromAndroid/app/src/main/res/values/strings.xml b/samples/Hello-NativeAOTFromAndroid/app/src/main/res/values/strings.xml
deleted file mode 100644
index 4378cbc73..000000000
--- a/samples/Hello-NativeAOTFromAndroid/app/src/main/res/values/strings.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-
- Hello NativeAOT from Android!
-
diff --git a/samples/Hello-NativeAOTFromAndroid/build.gradle b/samples/Hello-NativeAOTFromAndroid/build.gradle
deleted file mode 100644
index 24469b8d3..000000000
--- a/samples/Hello-NativeAOTFromAndroid/build.gradle
+++ /dev/null
@@ -1,5 +0,0 @@
-// Top-level build file where you can add configuration options common to all sub-projects/modules.
-plugins {
- // Need to use < 8.0 in order to use JDK-11
- id 'com.android.application' version '7.4.0' apply false
-}
diff --git a/samples/Hello-NativeAOTFromAndroid/gradle.properties b/samples/Hello-NativeAOTFromAndroid/gradle.properties
deleted file mode 100644
index a03b35489..000000000
--- a/samples/Hello-NativeAOTFromAndroid/gradle.properties
+++ /dev/null
@@ -1,21 +0,0 @@
-# Project-wide Gradle settings.
-# IDE (e.g. Android Studio) users:
-# Gradle settings configured through the IDE *will override*
-# any settings specified in this file.
-# For more details on how to configure your build environment visit
-# http://www.gradle.org/docs/current/userguide/build_environment.html
-# Specifies the JVM arguments used for the daemon process.
-# The setting is particularly useful for tweaking memory settings.
-org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
-# When configured, Gradle will run in incubating parallel mode.
-# This option should only be used with decoupled projects. More details, visit
-# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
-# org.gradle.parallel=true
-# AndroidX package structure to make it clearer which packages are bundled with the
-# Android operating system, and which are packaged with your app's APK
-# https://developer.android.com/topic/libraries/support-library/androidx-rn
-android.useAndroidX=true
-# Enables namespacing of each library's R class so that its R class includes only the
-# resources declared in the library itself and none from the library's dependencies,
-# thereby reducing the size of the R class for that library
-android.nonTransitiveRClass=true
diff --git a/samples/Hello-NativeAOTFromAndroid/settings.gradle b/samples/Hello-NativeAOTFromAndroid/settings.gradle
deleted file mode 100644
index e901c9c1b..000000000
--- a/samples/Hello-NativeAOTFromAndroid/settings.gradle
+++ /dev/null
@@ -1,17 +0,0 @@
-pluginManagement {
- repositories {
- google()
- mavenCentral()
- gradlePluginPortal()
- }
-}
-dependencyResolutionManagement {
- repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
- repositories {
- google()
- mavenCentral()
- }
-}
-
-rootProject.name = "Hello-NativeAOTFromAndroid"
-include ':app'
diff --git a/samples/Hello-NativeAOTFromJNI/App.cs b/samples/Hello-NativeAOTFromJNI/App.cs
index c2e326921..f7d0307d2 100644
--- a/samples/Hello-NativeAOTFromJNI/App.cs
+++ b/samples/Hello-NativeAOTFromJNI/App.cs
@@ -6,26 +6,25 @@ namespace Hello_NativeAOTFromJNI;
static class App {
- // symbol name from `$(IntermediateOutputPath)obj/Release/osx-x64/h-classes/net_dot_jni_hello_App.h`
[UnmanagedCallersOnly (EntryPoint="Java_net_dot_jni_hello_App_sayHello")]
static IntPtr sayHello (IntPtr jnienv, IntPtr klass)
{
var envp = new JniTransition (jnienv);
try {
- var s = $"Hello from .NET NativeAOT!";
- Console.WriteLine (s);
- var h = JniEnvironment.Strings.NewString (s);
+ const string message = "Hello from .NET NativeAOT!";
+ Console.WriteLine (message);
+ var h = JniEnvironment.Strings.NewString (message);
var r = JniEnvironment.References.NewReturnToJniRef (h);
JniObjectReference.Dispose (ref h);
return r;
}
catch (Exception e) {
- Console.Error.WriteLine ($"Error in App.sayHello(): {e.ToString ()}");
+ Console.Error.WriteLine ($"Error in App.sayHello(): {e}");
envp.SetPendingException (e);
}
finally {
envp.Dispose ();
}
- return nint.Zero;
+ return IntPtr.Zero;
}
}
diff --git a/samples/Hello-NativeAOTFromJNI/Hello-NativeAOTFromJNI.csproj b/samples/Hello-NativeAOTFromJNI/Hello-NativeAOTFromJNI.csproj
index bf970f8ae..b8e48837b 100644
--- a/samples/Hello-NativeAOTFromJNI/Hello-NativeAOTFromJNI.csproj
+++ b/samples/Hello-NativeAOTFromJNI/Hello-NativeAOTFromJNI.csproj
@@ -1,4 +1,4 @@
-
+
$(DotNetTargetFramework)
@@ -19,12 +19,6 @@
-
-
-
@@ -32,16 +26,23 @@
-
+
-
+
+
+
+
+
+
+
+
diff --git a/samples/Hello-NativeAOTFromJNI/Hello-NativeAOTFromJNI.targets b/samples/Hello-NativeAOTFromJNI/Hello-NativeAOTFromJNI.targets
index e61081ce1..1a62aef04 100644
--- a/samples/Hello-NativeAOTFromJNI/Hello-NativeAOTFromJNI.targets
+++ b/samples/Hello-NativeAOTFromJNI/Hello-NativeAOTFromJNI.targets
@@ -1,40 +1,11 @@
-
- "$(DOTNET_HOST_PATH)"
-
-
-
-
-
-
-
- <_JcwGenRefAsmDirs Include="@(ReferencePathWithRefAssemblies->'%(RootDir)%(Directory).'->Distinct())" />
-
-
- <_JcwGen>"$(UtilityOutputFullPath)/jcw-gen.dll"
- <_Target>--codegen-target JavaInterop1
- <_Output>-o "$(IntermediateOutputPath)/java"
- <_Libpath>@(_JcwGenRefAsmDirs->'-L "%(Identity)"', ' ')
-
-
-
-
-
- <_JcwSource Include="$(IntermediateOutputPath)java\**\*.java" />
-
-
- <_Source Include="@(_JcwSource->Replace('%5c', '/'))" />
<_Source Include="@(HelloNativeAOTFromJNIJar->Replace('%5c', '/'))" />
+
@@ -79,4 +51,5 @@
WorkingDirectory="$(MSBuildThisFileDirectory)$(PublishDir)"
/>
+
diff --git a/samples/Hello-NativeAOTFromJNI/JavaCallableAttributes.cs b/samples/Hello-NativeAOTFromJNI/JavaCallableAttributes.cs
deleted file mode 100644
index b930761f4..000000000
--- a/samples/Hello-NativeAOTFromJNI/JavaCallableAttributes.cs
+++ /dev/null
@@ -1,32 +0,0 @@
-#nullable enable
-using System;
-
-namespace Java.Interop {
-
- [AttributeUsage (AttributeTargets.Method, AllowMultiple=false)]
- public sealed class JavaCallableAttribute : Attribute {
-
- public JavaCallableAttribute ()
- {
- }
-
- public JavaCallableAttribute (string? name)
- {
- Name = name;
- }
-
- public string? Name {get; private set;}
- public string? Signature {get; set;}
- }
-
- [AttributeUsage (AttributeTargets.Constructor, AllowMultiple=false)]
- public sealed class JavaCallableConstructorAttribute : Attribute {
-
- public JavaCallableConstructorAttribute ()
- {
- }
-
- public string? SuperConstructorExpression {get; set;}
- public string? Signature {get; set;}
- }
-}
diff --git a/samples/Hello-NativeAOTFromJNI/JavaInteropRuntime.cs b/samples/Hello-NativeAOTFromJNI/JavaInteropRuntime.cs
index 130264814..d3f3e8bf1 100644
--- a/samples/Hello-NativeAOTFromJNI/JavaInteropRuntime.cs
+++ b/samples/Hello-NativeAOTFromJNI/JavaInteropRuntime.cs
@@ -1,4 +1,5 @@
-using System.Runtime.InteropServices;
+using System.Diagnostics;
+using System.Runtime.InteropServices;
using Java.Interop;
@@ -18,21 +19,80 @@ static int JNI_OnLoad (IntPtr vm, IntPtr reserved)
static void JNI_OnUnload (IntPtr vm, IntPtr reserved)
{
runtime?.Dispose ();
+ runtime = null;
}
- // symbol name from `$(IntermediateOutputPath)obj/Release/osx-arm64/h-classes/net_dot_jni_hello_JavaInteropRuntime.h`
[UnmanagedCallersOnly (EntryPoint="Java_net_dot_jni_hello_JavaInteropRuntime_init")]
static void init (IntPtr jnienv, IntPtr klass)
{
- Console.WriteLine ($"C# init()");
+ if (runtime != null)
+ return;
+
try {
- var options = new JreRuntimeOptions {
- EnvironmentPointer = jnienv,
- };
- runtime = options.CreateJreVM (new NativeAotTypeManager ());
+ runtime = new ExistingJniRuntime (jnienv);
}
catch (Exception e) {
Console.Error.WriteLine ($"JavaInteropRuntime.init: error: {e}");
}
}
+
+ sealed class ExistingJniRuntime : JniRuntime {
+
+ public ExistingJniRuntime (IntPtr jnienv)
+ : base (new CreationOptions {
+ EnvironmentPointer = jnienv,
+ ObjectReferenceManager = new ObjectReferenceManager (),
+ ValueManager = new ValueManager (),
+ })
+ {
+ }
+
+ public override string? GetCurrentManagedThreadName ()
+ {
+ return Thread.CurrentThread.Name;
+ }
+
+ public override string GetCurrentManagedThreadStackTrace (int skipFrames, bool fNeedFileInfo)
+ {
+ return new StackTrace (skipFrames, fNeedFileInfo).ToString ();
+ }
+ }
+
+ sealed class ObjectReferenceManager : JniRuntime.JniObjectReferenceManager {
+ public override int GlobalReferenceCount => 0;
+
+ public override int WeakGlobalReferenceCount => 0;
+ }
+
+ sealed class ValueManager : JniRuntime.JniValueManager {
+ public override void WaitForGCBridgeProcessing ()
+ {
+ }
+
+ public override void CollectPeers ()
+ {
+ }
+
+ public override void AddPeer (IJavaPeerable value)
+ {
+ }
+
+ public override void RemovePeer (IJavaPeerable value)
+ {
+ }
+
+ public override void FinalizePeer (IJavaPeerable value)
+ {
+ }
+
+ public override List GetSurfacedPeers ()
+ {
+ return new List ();
+ }
+
+ public override IJavaPeerable? PeekPeer (JniObjectReference reference)
+ {
+ return null;
+ }
+ }
}
diff --git a/samples/Hello-NativeAOTFromJNI/ManagedType.cs b/samples/Hello-NativeAOTFromJNI/ManagedType.cs
deleted file mode 100644
index 3f2cd9d1d..000000000
--- a/samples/Hello-NativeAOTFromJNI/ManagedType.cs
+++ /dev/null
@@ -1,47 +0,0 @@
-namespace Example;
-
-using System;
-using Java.Interop;
-
-[System.Runtime.InteropServices.UnmanagedFunctionPointer (System.Runtime.InteropServices.CallingConvention.Winapi)]
-delegate IntPtr _JniMarshal_PP_L (IntPtr jnienv, IntPtr n_self);
-
-[JniTypeSignature (JniTypeName)]
-class ManagedType : Java.Lang.Object {
- internal const string JniTypeName = "example/ManagedType";
-
- [JavaCallableConstructor (SuperConstructorExpression="")]
- public ManagedType (int value)
- {
- this.value = value;
- }
-
- int value;
-
- [JavaCallable ("getString")]
- public Java.Lang.String GetString ()
- {
- return new Java.Lang.String ($"Hello from C#, via Java.Interop! Value={value}");
- }
-
- static IntPtr n_GetString (IntPtr jnienv, IntPtr n_self)
- {
- var r_self = new JniObjectReference (n_self);
- var self = JniEnvironment.Runtime.ValueManager.GetValue (ref r_self, JniObjectReferenceOptions.CopyAndDoNotRegister);
- try {
- var result = self!.GetString ();
- var r = result.PeerReference.NewLocalRef ();
- return JniEnvironment.References.NewReturnToJniRef (r);
- } finally {
- self?.DisposeUnlessReferenced ();
- }
- }
-
- [JniAddNativeMethodRegistration]
- internal static void RegisterNativeMembers (JniNativeMethodRegistrationArguments args)
- {
- args.AddRegistrations (new [] {
- new JniNativeMethodRegistration ("n_GetString", "()Ljava/lang/String;", new _JniMarshal_PP_L (n_GetString)),
- });
- }
-}
diff --git a/samples/Hello-NativeAOTFromJNI/NativeAotTypeManager.cs b/samples/Hello-NativeAOTFromJNI/NativeAotTypeManager.cs
deleted file mode 100644
index e1a3150b3..000000000
--- a/samples/Hello-NativeAOTFromJNI/NativeAotTypeManager.cs
+++ /dev/null
@@ -1,148 +0,0 @@
-using Java.Interop;
-using System.Diagnostics.CodeAnalysis;
-
-namespace Hello_NativeAOTFromJNI;
-
-class NativeAotTypeManager : JniRuntime.JniTypeManager {
- internal const DynamicallyAccessedMemberTypes Methods = DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods;
- internal const DynamicallyAccessedMemberTypes MethodsAndPrivateNested = Methods | DynamicallyAccessedMemberTypes.NonPublicNestedTypes;
- internal const DynamicallyAccessedMemberTypes MethodsConstructors = MethodsAndPrivateNested | DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors;
-
- protected override IEnumerable GetTypesForSimpleReference (string jniSimpleReference)
- {
- var target = GetTypeForSimpleReference (jniSimpleReference);
- if (target != null)
- yield return target;
- }
-
- [return: DynamicallyAccessedMembers (MethodsConstructors)]
- protected override Type? GetTypeForSimpleReference (string jniSimpleReference)
- {
- return jniSimpleReference switch {
- "V" => typeof (void),
- "Z" => typeof (bool),
- "java/lang/Boolean" => typeof (bool?),
- "B" => typeof (sbyte),
- "java/lang/Byte" => typeof (sbyte?),
- "C" => typeof (char),
- "java/lang/Character" => typeof (char?),
- "S" => typeof (short),
- "java/lang/Short" => typeof (short?),
- "I" => typeof (int),
- "java/lang/Integer" => typeof (int?),
- "J" => typeof (long),
- "java/lang/Long" => typeof (long?),
- "F" => typeof (float),
- "java/lang/Float" => typeof (float?),
- "D" => typeof (double),
- "java/lang/Double" => typeof (double?),
- Example.ManagedType.JniTypeName => typeof (Example.ManagedType),
- "java/lang/Object" => typeof (Java.Lang.Object),
- "java/lang/String" => typeof (Java.Lang.String),
- _ => null,
- };
- }
-
- public override IEnumerable GetTypes (JniTypeSignature typeSignature)
- {
- if (!typeSignature.IsValid || typeSignature.ArrayRank != 0 || typeSignature.SimpleReference == null)
- return [];
- return GetTypesForSimpleReference (typeSignature.SimpleReference);
- }
-
- public override IEnumerable GetReflectionConstructibleTypes (JniTypeSignature typeSignature)
- {
- if (!typeSignature.IsValid || typeSignature.ArrayRank != 0 || typeSignature.SimpleReference == null)
- yield break;
- var target = GetTypeForSimpleReference (typeSignature.SimpleReference);
- if (target != null)
- yield return new JniRuntime.JniTypeManager.ReflectionConstructibleType (target);
- }
-
- protected override IEnumerable GetSimpleReferences (Type type)
- {
- return CreateSimpleReferencesEnumerator (type);
- }
-
- IEnumerable CreateSimpleReferencesEnumerator (Type type)
- {
- if (type == typeof (Example.ManagedType))
- yield return Example.ManagedType.JniTypeName;
- else if (type == typeof (Java.Lang.Object))
- yield return "java/lang/Object";
- else if (type == typeof (Java.Lang.String))
- yield return "java/lang/String";
- }
-
- protected override string? GetSimpleReference (Type type)
- {
- return GetSimpleReferences (type).FirstOrDefault ();
- }
-
- protected override JniTypeSignature GetTypeSignatureCore (Type type)
- {
- var simpleReference = GetSimpleReference (type);
- return simpleReference == null ? default : new JniTypeSignature (simpleReference, 0, false);
- }
-
- protected override IEnumerable GetTypeSignaturesCore (Type type)
- {
- var signature = GetTypeSignatureCore (type);
- if (signature.IsValid)
- yield return signature;
- }
-
- [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)]
- protected override Type? GetInvokerTypeCore (
- [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)]
- Type type)
- {
- return null;
- }
-
- protected override IReadOnlyList? GetStaticMethodFallbackTypesCore (string jniSimpleReference)
- {
- return null;
- }
-
- protected override string? GetReplacementTypeCore (string jniSimpleReference)
- {
- return null;
- }
-
- protected override JniRuntime.ReplacementMethodInfo? GetReplacementMethodInfoCore (string jniSourceType, string jniMethodName, string jniMethodSignature)
- {
- return null;
- }
-
- public override void RegisterNativeMembers (
- JniType nativeClass,
- [DynamicallyAccessedMembers (MethodsAndPrivateNested)]
- Type type,
- ReadOnlySpan methods)
- {
- if (TryRegisterBuiltInNativeMembers (nativeClass, nativeClass.Name, methods))
- return;
-
- if (type != typeof (Example.ManagedType)) {
- if (!methods.IsEmpty)
- throw new NotSupportedException ($"Could not register native members for type '{type.FullName}'.");
- return;
- }
-
- var registrations = new List ();
- Example.ManagedType.RegisterNativeMembers (new JniNativeMethodRegistrationArguments (registrations, null));
- if (registrations.Count > 0)
- nativeClass.RegisterNativeMethods (registrations.ToArray ());
- }
-
- [Obsolete ("Use RegisterNativeMembers(JniType, Type, ReadOnlySpan)")]
- public override void RegisterNativeMembers (
- JniType nativeClass,
- [DynamicallyAccessedMembers (MethodsAndPrivateNested)]
- Type type,
- string? methods)
- {
- RegisterNativeMembers (nativeClass, type, methods.AsSpan ());
- }
-}
diff --git a/samples/Hello-NativeAOTFromJNI/README.md b/samples/Hello-NativeAOTFromJNI/README.md
deleted file mode 100644
index bd16e1fc1..000000000
--- a/samples/Hello-NativeAOTFromJNI/README.md
+++ /dev/null
@@ -1,164 +0,0 @@
-# Hello From JNI
-
-[JNI][0] supports *two* modes of operation:
-
- 1. Native code creates the JVM, e.g. via [`JNI_CreateJavaVM()`][1], or
- 2. The JVM already exists, and calls [`JNI_OnLoad()`][2] when loading a native library.
-
-Java.Interop samples and unit tests rely on the first approach.
-
-.NET Android / neé Xamarin.Android is the second approach.
-
-Bring an example of the latter into a Java.Interop sample, using [NativeAOT][3].
-
-## Building
-
-Building a native library with NativeAOT requires a Release configuration build.
-For in-repo use, that means that dotnet/java-interop itself needs to be built in
-Release configuration:
-
-```sh
-% dotnet build -c Release -t:Prepare
-% dotnet build -c Release
-```
-
-Once Java.Interop itself is built, you can *publish* the sample:
-
-```sh
-% cd samples/Hello-NativeAOTFromJNI
-% dotnet publish -c Release -r osx-x64
-```
-
-The resulting native library contains the desired symbols:
-
-```sh
-% nm bin/Release/osx-x64/publish/Hello-NativeAOTFromJNI.dylib | grep ' S '
-00000000000ef880 S _JNI_OnLoad
-00000000000ef8b0 S _JNI_OnUnload
-00000000000ef5d0 S _Java_net_dot_jni_hello_App_sayHello
-00000000000ef900 S _Java_net_dot_jni_hello_JavaInteropRuntime_init
-```
-
-Use the `RunJavaSample` target to run Java, which will run
-`System.loadLibrary("Hello-NativeAOTFromJNI")`, which will cause the
-NativeAOT-generated `libHello-NativeAOTFromJNI.dylib` to be run:
-
-```sh
-% dotnet build -c Release -r osx-x64 -t:RunJavaSample -v m --nologo --no-restore
- Hello from Java!
- C# init()
- Hello from .NET NativeAOT!
- String returned to Java: Hello from .NET NativeAOT!
- # jonp: called `Example.ManagedType/__<$>_jni_marshal_methods.__RegisterNativeMembers()` w/ 1 methods to register.
- mt.getString()=Hello from C#, via Java.Interop! Value=42
-
-Build succeeded.
- 0 Warning(s)
- 0 Error(s)
-
-Time Elapsed 00:00:01.04
-
-% (cd bin/Release/osx-x64/publish ; java -cp hello-from-java.jar:java-interop.jar net/dot/jni/hello/App)
-Hello from Java!
-C# init()
-Hello from .NET NativeAOT!
-String returned to Java: Hello from .NET NativeAOT!
-# jonp: called `Example.ManagedType/__<$>_jni_marshal_methods.__RegisterNativeMembers()` w/ 1 methods to register.
-mt.getString()=Hello from C#, via Java.Interop! Value=42
-```
-
-Note the use of `(cd …; java …)` so that `libHello-NativeAOTFromJNI.dylib` is
-in the current working directory, so that it can be found.
-
-# Notes
-
-To support cross-compilation, the project should set
-`$(PlatformTarget)`=AnyCPU.
-
-# Known Knowns?
-
-With this sample "done" (-ish), there are some
-"potentially solved, if not ideally" used to make NativeAOT + Java *viable*.
-
-## `Type.GetType()`
-
-Commit
-[dotnet/java-interop@005c9141](https://github.com/dotnet/java-interop/commit/005c914170a0af9069ff18fd4dd9d45463dd5dc6)
-uses JNI Type Signatures to avoid `Type.GetType()` invocations, which continue
-to be used in .NET Android.
-
-```Java
-/* partial */ class JavaCallableWrapper
-{
- public static final String __md_methods;
- static {
- __md_methods =
- "n_GetString:()Ljava/lang/String;:__export__\n" +
- "";
- net.dot.jni.ManagedPeer.registerNativeMembers (
- /* nativeClass */ ManagedType.class,
- /* methods */ __md_methods);
- }
-
- public ManagedType (int p0)
- {
- super ();
- if (getClass () == ManagedType.class) {
- net.dot.jni.ManagedPeer.construct (
- /* self */ this,
- /* constructorSignature */ "(I)V",
- /* arguments */ new java.lang.Object[] { p0 });
- }
- }
-}
-```
-
-This requires the use of JNI method signatures within the constructor
-to lookup the corresponding managed constructor to invoke. While this
-works, it requires additional work to lookup the constructor, as there
-may not be a 1:1 relation between types within the JNI method signature
-and managed code. In particular, Java *arrays* may have multiple types
-which can be used from managed code.
-
-
-# Known Unknowns
-
-With this sample "done" (-ish), there are several "future research directions" to
-make NativeAOT + Java *viable*.
-
-## GC
-
-Firstly, there's the open GC question: NativeAOT doesn't provide a "GC Bridge"
-like MonoVM does, so how do we support cross-VM object references?
-
- * [Collecting Cyclic Garbage across Foreign Function Interfaces: Who Takes the Last Piece of Cake?](https://pldi23.sigplan.org/details/pldi-2023-pldi/25/Collecting-Cyclic-Garbage-across-Foreign-Function-Interfaces-Who-Takes-the-Last-Piec)
- * [`JavaScope`?](https://github.com/jonpryor/java.interop/commits/jonp-registration-scope)
- (Less a "solution" and more a "Glorious Workaround".)
-
-
-## Type Maps
-
-A "derivative" of the `Type.GetType()` problem is that Java.Interop needs a way
-to associate a Java type to a .NET `System.Type` instance, for all manner of
-reasons. (One such reason: `JniRuntime.JniValueManager.GetValue()` needs to
-know the associated type so that it can create a "peer wrapper", if needed.)
-
-Java.Interop unit tests "hack" around this by using a dictionary in TestJVM,
-and `Hello-NativeAOTFromJNI` follows suite. This isn't a "real" answer, though.
-
-.NET Android has a very complicated typemap mechanism that involves a table
-between the Java JNI name and an { assembly name, type token } pair, along with
-copious use of MonoVM embedding API such as `mono_class_get()`. ***A Lot***
-of effort has gone into making type maps performant.
-
-How do we "do" type maps in NativeAOT? We may need to consider some equivalent
-to the iOS "static registrar", and this also needs to support getting `Type`
-instances for non-`public` types. There are also concerns about initialization
-overhead; a `Dictionary` will require loading and resolving
-*all* the `Type` instances as part of startup, which *can't* be good for
-reducing startup time. What other data structure could be used?
-
-[0]: https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/jniTOC.html
-[1]: https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/invocation.html#creating_the_vm
-[2]: https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/invocation.html#JNJI_OnLoad
-[3]: https://github.com/dotnet/samples/blob/main/core/nativeaot/NativeLibrary/README.md
\ No newline at end of file
diff --git a/samples/Hello-NativeAOTFromJNI/java/net/dot/jni/hello/App.java b/samples/Hello-NativeAOTFromJNI/java/net/dot/jni/hello/App.java
index 427016263..9b6aef7a0 100644
--- a/samples/Hello-NativeAOTFromJNI/java/net/dot/jni/hello/App.java
+++ b/samples/Hello-NativeAOTFromJNI/java/net/dot/jni/hello/App.java
@@ -1,8 +1,5 @@
package net.dot.jni.hello;
-import net.dot.jni.hello.JavaInteropRuntime;
-import example.ManagedType;
-
class App {
public static void main(String[] args) {
@@ -10,8 +7,6 @@ public static void main(String[] args) {
JavaInteropRuntime.init();
String s = sayHello();
System.out.println("String returned to Java: " + s);
- ManagedType mt = new ManagedType(42);
- System.out.println("mt.getString()=" + mt.getString());
}
static native String sayHello();
diff --git a/src/Java.Interop/Java.Interop/JniRuntime.cs b/src/Java.Interop/Java.Interop/JniRuntime.cs
index 3a68f9b46..c596d109a 100644
--- a/src/Java.Interop/Java.Interop/JniRuntime.cs
+++ b/src/Java.Interop/Java.Interop/JniRuntime.cs
@@ -120,8 +120,7 @@ public static IEnumerable GetRegisteredRuntimes ()
}
[Obsolete ("Not sensible/usable at this level, and cannot work on e.g. Android. " +
- "Try Java.Interop.JreRuntime.GetAvailableInvocationPointers() in Java.Runtime.Environment.dll, " +
- "or rethink your structure.", error: true)]
+ "Please rethink your structure instead of relying on desktop/JRE-specific runtime helpers.", error: true)]
[SuppressMessage ("Design", "CA1024:Use properties where appropriate",
Justification = "ABI compatibility")]
public static IEnumerable GetAvailableInvocationPointers ()
diff --git a/src/Java.Interop/Properties/AssemblyInfo.cs b/src/Java.Interop/Properties/AssemblyInfo.cs
index f59494762..c19d92da4 100644
--- a/src/Java.Interop/Properties/AssemblyInfo.cs
+++ b/src/Java.Interop/Properties/AssemblyInfo.cs
@@ -7,13 +7,6 @@
[assembly: AssemblyCulture ("")]
[assembly: AssemblyTrademark ("Microsoft Corporation")]
-[assembly: InternalsVisibleTo (
- "Java.Runtime.Environment, PublicKey=" +
- "0024000004800000940000000602000000240000525341310004000011000000438ac2a5acfbf1" +
- "6cbd2b2b47a62762f273df9cb2795ceccdf77d10bf508e69e7a362ea7a45455bbf3ac955e1f2e2" +
- "814f144e5d817efc4c6502cc012df310783348304e3ae38573c6d658c234025821fda87a0be8a0" +
- "d504df564e2c93b2b878925f42503e9d54dfef9f9586d9e6f38a305769587b1de01f6c0410328b" +
- "2c9733db")]
[assembly: InternalsVisibleTo (
"Java.Interop-Tests, PublicKey=" +
"0024000004800000940000000602000000240000525341310004000011000000438ac2a5acfbf1" +
diff --git a/src/Java.Runtime.Environment/.gitignore b/src/Java.Runtime.Environment/.gitignore
deleted file mode 100644
index de5c36b91..000000000
--- a/src/Java.Runtime.Environment/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-Java.Runtime.Environment.dll.config
diff --git a/src/Java.Runtime.Environment/Java.Interop/JreRuntime.cs b/src/Java.Runtime.Environment/Java.Interop/JreRuntime.cs
deleted file mode 100644
index c92d69b5a..000000000
--- a/src/Java.Runtime.Environment/Java.Interop/JreRuntime.cs
+++ /dev/null
@@ -1,398 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.Diagnostics;
-using System.Diagnostics.CodeAnalysis;
-using System.IO;
-using System.Linq;
-using System.Reflection;
-using System.Runtime.InteropServices;
-using System.Threading;
-
-namespace Java.Interop {
-
- struct JavaVMInitArgs {
- public JniVersion version; /* use JNI_VERSION_1_2 or later */
-
- public int nOptions;
- public IntPtr /* JavaVMOption[] */ options;
- public byte ignoreUnrecognized;
- }
-
- struct JavaVMOption {
- public IntPtr /* const char* */ optionString;
- public IntPtr /* void * */ extraInfo;
- }
-
- public class JreRuntimeOptions : JniRuntime.CreationOptions {
-
- internal List Options = new List ();
-
- public bool IgnoreUnrecognizedOptions {get; set;}
-
- public Collection ClassPath {get; private set;}
-
- public TextWriter? JniGlobalReferenceLogWriter {get; set;}
- public TextWriter? JniLocalReferenceLogWriter {get; set;}
-
- internal Dictionary? typeMappings;
- public IDictionary TypeMappings => typeMappings ??= new ();
-
- internal JvmLibraryHandler? LibraryHandler {get; set;}
-
- public JreRuntimeOptions ()
- {
- JniVersion = JniVersion.v1_2;
- ClassPath = new Collection ();
- }
-
- public JreRuntimeOptions AddOption (string option)
- {
- Options.Add (option);
- return this;
- }
-
- public JreRuntimeOptions AddSystemProperty (string name, string value)
- {
- if (name == null)
- throw new ArgumentNullException ("name");
- if (value == null)
- throw new ArgumentNullException ("value");
- if (name == "java.class.path")
- throw new ArgumentException ("Do not use AddSystemProperty() for the 'java.class.path' property. Add to the ClassPath collection instead.", "name");
- Options.Add (string.Format ("-D{0}={1}", name, value));
- return this;
- }
-
- [RequiresDynamicCode ("The default JRE type manager is reflection-based and is not compatible with Native AOT. Use CreateJreVM(JniRuntime.JniTypeManager) with an AOT-safe type manager instead.")]
- [RequiresUnreferencedCode ("The default JRE type manager is reflection-based and is not trimming-compatible. Use CreateJreVM(JniRuntime.JniTypeManager) with a trimming-safe type manager instead.")]
- public JreRuntime CreateJreVM ()
- {
- return new JreRuntime (this);
- }
-
- public JreRuntime CreateJreVM (JniRuntime.JniTypeManager typeManager)
- {
- if (typeManager == null)
- throw new ArgumentNullException (nameof (typeManager));
- return new JreRuntime (this, typeManager);
- }
- }
-
- public class JreRuntime : JniRuntime
- {
- static JreRuntime ()
- {
- }
-
- [RequiresDynamicCode ("The default JRE type manager is reflection-based and is not compatible with Native AOT.")]
- [RequiresUnreferencedCode ("The default JRE type manager is reflection-based and is not trimming-compatible.")]
- static unsafe JreRuntimeOptions CreateJreVM (JreRuntimeOptions builder)
- {
- if (builder == null)
- throw new ArgumentNullException ("builder");
- builder.TypeManager ??= new JreTypeManager (builder.typeMappings);
- return CreateJreVMCore (builder);
- }
-
- static unsafe JreRuntimeOptions CreateJreVMWithoutDefaultTypeManager (JreRuntimeOptions builder)
- {
- if (builder == null)
- throw new ArgumentNullException ("builder");
- if (builder.TypeManager == null)
- throw new InvalidOperationException ($"Member `{nameof (JniRuntime.CreationOptions)}.{nameof (JniRuntime.CreationOptions.TypeManager)}` must be set.");
- return CreateJreVMCore (builder);
- }
-
- static unsafe JreRuntimeOptions CreateJreVMCore (JreRuntimeOptions builder)
- {
- if (builder.InvocationPointer == IntPtr.Zero &&
- builder.EnvironmentPointer == IntPtr.Zero &&
- string.IsNullOrEmpty (builder.JvmLibraryPath))
- throw new InvalidOperationException ($"Member `{nameof (JreRuntimeOptions)}.{nameof (JreRuntimeOptions.JvmLibraryPath)}` must be set.");
-
- builder.LibraryHandler = JvmLibraryHandler.Create ();
-
-
- bool onMono = Type.GetType ("Mono.RuntimeStructs", throwOnError: false) != null;
- if (onMono) {
- Console.WriteLine ($"MonoVM support enabled");
- builder.ValueManager = builder.ValueManager ?? new MonoRuntimeValueManager ();
- builder.ObjectReferenceManager = builder.ObjectReferenceManager ?? new MonoRuntimeObjectReferenceManager ();
- }
- else {
- builder.ValueManager = builder.ValueManager ?? new ManagedValueManager ();
- builder.ObjectReferenceManager = builder.ObjectReferenceManager ?? new ManagedObjectReferenceManager (builder.JniGlobalReferenceLogWriter, builder.JniLocalReferenceLogWriter);
- }
-
- if (builder.InvocationPointer != IntPtr.Zero || builder.EnvironmentPointer != IntPtr.Zero)
- return builder;
-
- builder.LibraryHandler.LoadJvmLibrary (builder.JvmLibraryPath!);
-
- if (!builder.ClassPath.Any (p => p.EndsWith ("java-interop.jar", StringComparison.OrdinalIgnoreCase))) {
- var loc = GetAssemblyLocation (typeof (JreRuntimeOptions).Assembly);
- var dir = string.IsNullOrEmpty (loc) ? null : Path.GetDirectoryName (loc);
- var jij = string.IsNullOrEmpty (dir) ? null : Path.Combine (dir, "java-interop.jar");
- if (!File.Exists (jij)) {
- throw new FileNotFoundException ($"`java-interop.jar` is required. Please add to `JreRuntimeOptions.ClassPath`. Tried to find it in `{jij}`.");
- }
- builder.ClassPath.Add (jij);
- }
-
- var args = new JavaVMInitArgs () {
- version = builder.JniVersion,
- nOptions = builder.Options.Count + 1,
- ignoreUnrecognized = builder.IgnoreUnrecognizedOptions ? (byte) 1 : (byte) 0,
- };
- var options = new JavaVMOption [builder.Options.Count + 1];
- try {
- for (int i = 0; i < builder.Options.Count; ++i)
- options [i].optionString = Marshal.StringToHGlobalAnsi (builder.Options [i]);
- var classPath = Marshal.StringToHGlobalAnsi (string.Format ("-Djava.class.path={0}", string.Join (Path.PathSeparator.ToString (), builder.ClassPath)));
- options [builder.Options.Count].optionString = classPath;
- fixed (JavaVMOption* popts = options) {
- args.options = (IntPtr) popts;
- IntPtr javavm;
- IntPtr jnienv;
- int r = builder.LibraryHandler.CreateJavaVM (out javavm, out jnienv, ref args);
- if (r != 0) {
- var message = string.Format (
- "The JDK supports creating at most one JVM per process, ever; " +
- "do you have a JVM running already, or have you already created (and destroyed?) one? " +
- "(JNI_CreateJavaVM returned {0}).",
- r);
- throw new NotSupportedException (message);
- }
- builder.InvocationPointer = javavm;
- builder.EnvironmentPointer = jnienv;
- return builder;
- }
- } finally {
- for (int i = 0; i < options.Length; ++i)
- Marshal.FreeHGlobal (options [i].optionString);
- }
- }
-
- [UnconditionalSuppressMessage ("Trimming", "IL3000", Justification = "We check for a null Assembly.Location value!")]
- internal static string? GetAssemblyLocation (Assembly assembly)
- {
- var location = assembly.Location;
- if (!string.IsNullOrEmpty (location))
- return location;
- return null;
- }
-
- JvmLibraryHandler LibraryHandler;
-
- [RequiresDynamicCode ("The default JRE type manager is reflection-based and is not compatible with Native AOT.")]
- [RequiresUnreferencedCode ("The default JRE type manager is reflection-based and is not trimming-compatible.")]
- internal protected JreRuntime (JreRuntimeOptions builder)
- : base (CreateJreVM (builder))
- {
- LibraryHandler = builder.LibraryHandler!;
- }
-
- internal protected JreRuntime (JreRuntimeOptions builder, JniRuntime.JniTypeManager typeManager)
- : base (CreateJreVMWithoutDefaultTypeManager (SetTypeManager (builder, typeManager)))
- {
- LibraryHandler = builder.LibraryHandler!;
- }
-
- static JreRuntimeOptions SetTypeManager (JreRuntimeOptions builder, JniRuntime.JniTypeManager typeManager)
- {
- if (builder == null)
- throw new ArgumentNullException ("builder");
- if (typeManager == null)
- throw new ArgumentNullException (nameof (typeManager));
- builder.TypeManager = typeManager;
- return builder;
- }
-
- public override string? GetCurrentManagedThreadName ()
- {
- return Thread.CurrentThread.Name;
- }
-
- public override string GetCurrentManagedThreadStackTrace (int skipFrames, bool fNeedFileInfo)
- {
- return new StackTrace (skipFrames, fNeedFileInfo)
- .ToString ();
- }
-
- protected override void Dispose (bool disposing)
- {
- base.Dispose (disposing);
- LibraryHandler?.Dispose ();
- LibraryHandler = null!;
- }
-
- public new IEnumerable GetAvailableInvocationPointers ()
- {
- return LibraryHandler.GetAvailableInvocationPointers ();
- }
- }
-
- internal abstract partial class JvmLibraryHandler : IDisposable {
- public abstract void LoadJvmLibrary (string path);
- public abstract int CreateJavaVM (out IntPtr javavm, out IntPtr jnienv, ref JavaVMInitArgs args);
- public abstract IEnumerable GetAvailableInvocationPointers ();
-
- public abstract void Dispose ();
-
- public static JvmLibraryHandler Create ()
- {
- var handler = Environment.GetEnvironmentVariable ("JI_LOADER_TYPE");
- switch (handler?.ToLowerInvariant ()) {
- case "java-interop":
- return new JavaInteropLibJvmLibraryHandler ();
- case "":
- case null:
- case "native-library":
- return new NativeLibraryJvmLibraryHandler ();
- default:
- Console.Error.WriteLine ($"Unsupported JI_LOADER_TYPE value of `{handler}`.");
- throw new NotSupportedException ();
- }
- }
- }
-
-
- class NativeLibraryJvmLibraryHandler : JvmLibraryHandler {
- IntPtr handle;
-
- IntPtr _Create;
- IntPtr _GetCreated;
-
- public override void LoadJvmLibrary (string path)
- {
- handle = NativeLibrary.Load (path);
- Console.Error.WriteLine ($"# jonp: LoadJvmLibrary({path})={handle}");
-
- IntPtr create, getCreated;
- if (!NativeLibrary.TryGetExport (handle, "JNI_CreateJavaVM", out create) ||
- !NativeLibrary.TryGetExport (handle, "JNI_GetCreatedJavaVMs", out getCreated)) {
- NativeLibrary.Free (handle);
- handle = IntPtr.Zero;
- throw new NotSupportedException ("Library `{path}` does not export the required symbols `JNI_CreateJavaVM` or `JNI_GetCreatedJavaVMs`!");
- }
-
- Console.Error.WriteLine ($"# jonp: JNI_CreateJavaVM={create}; JNI_GetCreatedJavaVMs={getCreated}");
- _Create = create;
- _GetCreated = getCreated;
- }
-
- public unsafe override int CreateJavaVM (out IntPtr javavm, out IntPtr jnienv, ref JavaVMInitArgs args)
- {
- Console.Error.WriteLine ($"# jonp: executing JNI_CreateJavaVM={_Create.ToString("x")}");
- // jint JNI_CreateJavaVM(JavaVM **p_vm, void **p_env, void *vm_args);
-
- var create = (delegate* unmanaged) _Create;
- var r = create (out javavm, out jnienv, ref args);
- Console.Error.WriteLine ($"# jonp: r={r} javavm={javavm.ToString("x")} jnienv={jnienv.ToString ("x")}");
- return r;
- }
-
- public unsafe override IEnumerable GetAvailableInvocationPointers ()
- {
- Console.Error.WriteLine ($"# jonp: executing _GetCreated fnptr={_GetCreated.ToString("x")}");
- var getCreated = (delegate* unmanaged) _GetCreated;
- int nVMs;
- int r = getCreated (null, 0, out nVMs);
- if (r != 0) {
- throw new NotSupportedException ("JNI_GetCreatedJavaVMs() returned: " + r.ToString ());
- }
- var handles = new IntPtr [nVMs];
- fixed (IntPtr* h = handles) {
- r = getCreated (h, handles.Length, out nVMs);
- }
- if (r != 0)
- throw new InvalidOperationException ("JNI_GetCreatedJavaVMs() [take 2!] returned: " + r.ToString ());
- return handles;
- }
-
- public override void Dispose ()
- {
- NativeLibrary.Free (handle);
- handle = IntPtr.Zero;
- _Create = IntPtr.Zero;
- _GetCreated = IntPtr.Zero;
- }
- }
-
-
- class JavaInteropLibJvmLibraryHandler : JvmLibraryHandler {
-
- static JavaInteropLibJvmLibraryHandler ()
- {
- }
-
- const int JAVA_INTEROP_JVM_FAILED_ALREADY_LOADED = -1001;
-
- public override void LoadJvmLibrary (string path)
- {
- IntPtr errorPtr = IntPtr.Zero;
- int r = JreNativeMethods.java_interop_jvm_load_with_error_message (path, out errorPtr);
- if (r != 0) {
- string? error = Marshal.PtrToStringAnsi (errorPtr);
- JreNativeMethods.java_interop_free (errorPtr);
- if (r == JAVA_INTEROP_JVM_FAILED_ALREADY_LOADED) {
- return;
- }
- throw new NotSupportedException ($"Could not load JVM path `{path}`: {error} ({r})!");
- }
- }
-
- public override int CreateJavaVM (out IntPtr javavm, out IntPtr jnienv, ref JavaVMInitArgs args)
- {
- return JreNativeMethods.java_interop_jvm_create (out javavm, out jnienv, ref args);
- }
-
- public override IEnumerable GetAvailableInvocationPointers ()
- {
- int nVMs;
- int r = JreNativeMethods.java_interop_jvm_list (null, 0, out nVMs);
- if (r != 0)
- throw new NotSupportedException ("JNI_GetCreatedJavaVMs() returned: " + r.ToString ());
- var handles = new IntPtr [nVMs];
- r = JreNativeMethods.java_interop_jvm_list (handles, handles.Length, out nVMs);
- if (r != 0)
- throw new InvalidOperationException ("JNI_GetCreatedJavaVMs() [take 2!] returned: " + r.ToString ());
- return handles;
- }
-
- public override void Dispose ()
- {
- }
- }
-
- partial class JreNativeMethods {
-
- static JreNativeMethods ()
- {
- if (Environment.OSVersion.Platform == PlatformID.Win32NT) {
- var loc = JreRuntime.GetAssemblyLocation (typeof (JreRuntime).Assembly) ?? throw new NotSupportedException ();
- var baseDir = Path.GetDirectoryName (loc) ?? throw new NotSupportedException ();
- var newDir = Path.Combine (baseDir, Environment.Is64BitProcess ? "win-x64" : "win-x86");
- JreNativeMethods.AddDllDirectory (newDir);
- }
- }
-
-
- [DllImport (JavaInteropLib, CharSet=CharSet.Ansi, CallingConvention=CallingConvention.Cdecl)]
- internal static extern void java_interop_free (IntPtr p);
-
- [DllImport (JavaInteropLib, CharSet=CharSet.Ansi, CallingConvention=CallingConvention.Cdecl)]
- internal static extern int java_interop_jvm_load_with_error_message (string path, out IntPtr message);
-
- [DllImport (JavaInteropLib, CharSet=CharSet.Ansi, CallingConvention=CallingConvention.Cdecl)]
- internal static extern int java_interop_jvm_create (out IntPtr javavm, out IntPtr jnienv, ref JavaVMInitArgs args);
-
- [DllImport (JavaInteropLib, CallingConvention=CallingConvention.Cdecl)]
- internal static extern int java_interop_jvm_list ([Out] IntPtr[]? handles, int bufLen, out int nVMs);
-
- [DllImport ("kernel32", CharSet=CharSet.Unicode)]
- internal static extern int AddDllDirectory (string NewDirectory);
- }
-}
-
diff --git a/src/Java.Runtime.Environment/Java.Interop/JreTypeManager.cs b/src/Java.Runtime.Environment/Java.Interop/JreTypeManager.cs
deleted file mode 100644
index b6d93f71a..000000000
--- a/src/Java.Runtime.Environment/Java.Interop/JreTypeManager.cs
+++ /dev/null
@@ -1,83 +0,0 @@
-
-using System;
-using System.Collections.Generic;
-using System.Diagnostics.CodeAnalysis;
-using System.Linq;
-using System.Reflection;
-
-
-namespace Java.Interop {
-
- [RequiresDynamicCode ("JreTypeManager uses ReflectionJniTypeManager reflection-based behavior and is not compatible with Native AOT.")]
- [RequiresUnreferencedCode ("JreTypeManager uses ReflectionJniTypeManager reflection-based behavior and is not trimming-compatible.")]
- public class JreTypeManager : JniRuntime.ReflectionJniTypeManager {
-
- IDictionary? typeMappings;
-
- public JreTypeManager ()
- : this (null)
- {
- }
-
- public JreTypeManager (IDictionary? typeMappings)
- {
- this.typeMappings = typeMappings;
- }
-
- protected override IEnumerable GetTypesForSimpleReference (string jniSimpleReference)
- {
- foreach (var t in base.GetTypesForSimpleReference (jniSimpleReference))
- yield return t;
- if (typeMappings == null)
- yield break;
- if (typeMappings.TryGetValue (jniSimpleReference, out var target))
- yield return target;
- }
-
- [return: DynamicallyAccessedMembers (JniRuntime.JniTypeManager.MethodsConstructors)]
- protected override Type? GetTypeForSimpleReference (string jniSimpleReference)
- {
- var type = base.GetTypeForSimpleReference (jniSimpleReference);
- if (type != null)
- return type;
- if (typeMappings == null)
- return null;
- return typeMappings.TryGetValue (jniSimpleReference, out var target) ? target : null;
- }
-
- protected override IEnumerable GetSimpleReferences (Type type)
- {
- return base.GetSimpleReferences (type)
- .Concat (CreateSimpleReferencesEnumerator (type));
- }
-
- IEnumerable CreateSimpleReferencesEnumerator (Type type)
- {
- if (typeMappings == null)
- yield break;
- foreach (var e in typeMappings) {
- if (e.Value == type)
- yield return e.Key;
- }
- }
-
- public override void RegisterNativeMembers (
- JniType nativeClass,
- [DynamicallyAccessedMembers (MethodsAndPrivateNested)]
- Type type,
- ReadOnlySpan methods)
- {
- if (base.TryRegisterNativeMembers (nativeClass, type, methods)) {
- return;
- }
-
- if (methods.IsEmpty) {
- return;
- }
-
- throw new NotSupportedException (
- $"Could not register native members for type '{type.FullName}'. " +
- "Ensure that the type has the appropriate [JniAddNativeMethodRegistration] attribute and static registration method.");
- }
- }
-}
diff --git a/src/Java.Runtime.Environment/Java.Interop/ManagedObjectReferenceManager.cs b/src/Java.Runtime.Environment/Java.Interop/ManagedObjectReferenceManager.cs
deleted file mode 100644
index 700dc3b6a..000000000
--- a/src/Java.Runtime.Environment/Java.Interop/ManagedObjectReferenceManager.cs
+++ /dev/null
@@ -1,228 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.Diagnostics;
-using System.IO;
-using System.Linq;
-using System.Reflection;
-using System.Runtime.InteropServices;
-using System.Text;
-using System.Threading;
-
-namespace Java.Interop {
-
- class ManagedObjectReferenceManager : JniRuntime.JniObjectReferenceManager {
-
- TextWriter? grefLog;
- TextWriter? lrefLog;
-
- int grefCount;
- int wgrefCount;
-
-
- public override int GlobalReferenceCount => grefCount;
- public override int WeakGlobalReferenceCount => wgrefCount;
-
- public override bool LogLocalReferenceMessages => lrefLog != null;
- public override bool LogGlobalReferenceMessages => grefLog != null;
-
- public ManagedObjectReferenceManager (TextWriter? grefLog, TextWriter? lrefLog)
- {
- if (grefLog != null && lrefLog != null && object.ReferenceEquals (grefLog, lrefLog)) {
- this.grefLog = this.lrefLog = TextWriter.Synchronized (grefLog);
- return;
- }
-
- var grefPath = Environment.GetEnvironmentVariable ("JAVA_INTEROP_GREF_LOG");
- var lrefPath = Environment.GetEnvironmentVariable ("JAVA_INTEROP_LREF_LOG");
-
- bool samePath = !string.IsNullOrEmpty (grefPath) &&
- !string.IsNullOrEmpty (lrefPath) &&
- grefPath == lrefPath;
-
- if (grefLog != null) {
- this.grefLog = TextWriter.Synchronized (grefLog);
- }
- if (lrefLog != null) {
- this.lrefLog = TextWriter.Synchronized (lrefLog);
- }
-
- if (this.grefLog == null && !string.IsNullOrEmpty (grefPath)) {
- this.grefLog = TextWriter.Synchronized (CreateTextWriter (grefPath));
- }
- if (this.lrefLog == null && samePath) {
- this.lrefLog = this.grefLog;
- }
- if (this.lrefLog == null && !string.IsNullOrEmpty (lrefPath)) {
- this.lrefLog = TextWriter.Synchronized (CreateTextWriter (lrefPath));
- }
- }
-
- public override void OnSetRuntime (JniRuntime runtime)
- {
- base.OnSetRuntime (runtime);
- }
-
- static TextWriter CreateTextWriter (string path)
- {
- return new StreamWriter (path, append: false, encoding: new UTF8Encoding (encoderShouldEmitUTF8Identifier: false));
- }
-
- public override void WriteLocalReferenceLine (string format, params object[] args)
- {
- if (lrefLog == null)
- return;
- lrefLog.WriteLine (format, args);
- lrefLog.Flush ();
- }
-
- public override JniObjectReference CreateLocalReference (JniObjectReference reference, ref int localReferenceCount)
- {
- if (!reference.IsValid)
- return reference;
-
- var r = base.CreateLocalReference (reference, ref localReferenceCount);
-
- CreatedReference (lrefLog, "+l+ lrefc", localReferenceCount, reference, r, Runtime);
-
- return r;
- }
-
- public override void DeleteLocalReference (ref JniObjectReference reference, ref int localReferenceCount)
- {
- if (!reference.IsValid)
- return;
-
- var r = reference;
-
- base.DeleteLocalReference (ref reference, ref localReferenceCount);
-
- DeletedReference (lrefLog, "-l- lrefc", localReferenceCount, r, Runtime);
- }
-
- public override void CreatedLocalReference (JniObjectReference reference, ref int localReferenceCount)
- {
- if (!reference.IsValid)
- return;
- base.CreatedLocalReference (reference, ref localReferenceCount);
- CreatedReference (lrefLog, "+l+ lrefc", localReferenceCount, reference, Runtime);
- }
-
- public override IntPtr ReleaseLocalReference (ref JniObjectReference reference, ref int localReferenceCount)
- {
- if (!reference.IsValid)
- return IntPtr.Zero;
- var r = reference;
- var p = base.ReleaseLocalReference (ref reference, ref localReferenceCount);
- DeletedReference (lrefLog, "-l- lrefc", localReferenceCount, r, Runtime);
- return p;
- }
-
- public override void WriteGlobalReferenceLine (string format, params object?[]? args)
- {
- if (grefLog == null)
- return;
- grefLog.WriteLine (format, args!);
- grefLog.Flush ();
- }
-
- public override JniObjectReference CreateGlobalReference (JniObjectReference reference)
- {
- if (!reference.IsValid)
- return reference;
- var n = base.CreateGlobalReference (reference);
- int c = Interlocked.Increment (ref grefCount);
- CreatedReference (grefLog, "+g+ grefc", c, reference, n, Runtime);
- return n;
- }
-
- public override void DeleteGlobalReference (ref JniObjectReference reference)
- {
- if (!reference.IsValid)
- return;
- int c = Interlocked.Decrement (ref grefCount);
- DeletedReference (grefLog, "-g- grefc", c, reference, Runtime);
- base.DeleteGlobalReference (ref reference);
- }
-
- public override JniObjectReference CreateWeakGlobalReference (JniObjectReference reference)
- {
- if (!reference.IsValid)
- return reference;
- var n = base.CreateWeakGlobalReference (reference);
-
- int wc = Interlocked.Increment (ref wgrefCount);
- int gc = grefCount;
- if (grefLog != null) {
- string message = $"+w+ grefc {gc} gwrefc {wc} obj-handle {reference.ToString ()} -> new-handle {n.ToString ()} " +
- $"from thread '{Runtime.GetCurrentManagedThreadName ()}'({Environment.CurrentManagedThreadId})" +
- Environment.NewLine +
- Runtime.GetCurrentManagedThreadStackTrace (skipFrames: 2, fNeedFileInfo: true);
- grefLog.WriteLine (message);
- grefLog.Flush ();
- }
-
- return n;
- }
-
- public override void DeleteWeakGlobalReference (ref JniObjectReference reference)
- {
- if (!reference.IsValid)
- return;
-
- int wc = Interlocked.Decrement (ref wgrefCount);
- int gc = grefCount;
-
- if (grefLog != null) {
- string message = $"-w- grefc {gc} gwrefc {wc} handle {reference.ToString ()} " +
- $"from thread '{Runtime.GetCurrentManagedThreadName ()}'({Environment.CurrentManagedThreadId})" +
- Environment.NewLine +
- Runtime.GetCurrentManagedThreadStackTrace (skipFrames: 2, fNeedFileInfo: true);
- grefLog.WriteLine (message);
- grefLog.Flush ();
- }
-
- base.DeleteWeakGlobalReference (ref reference);
- }
-
- protected override void Dispose (bool disposing)
- {
- }
-
- static void CreatedReference (TextWriter? writer, string kind, int count, JniObjectReference reference, JniRuntime runtime)
- {
- if (writer == null)
- return;
- string message = $"{kind} {count} handle {reference.ToString ()} " +
- $"from thread '{runtime.GetCurrentManagedThreadName ()}'({Environment.CurrentManagedThreadId})" +
- Environment.NewLine +
- runtime.GetCurrentManagedThreadStackTrace (skipFrames: 2, fNeedFileInfo: true);
- writer.WriteLine (message);
- writer.Flush ();
- }
-
- static void CreatedReference (TextWriter? writer, string kind, int count, JniObjectReference reference, JniObjectReference newReference, JniRuntime runtime)
- {
- if (writer == null)
- return;
- string message = $"{kind} {count} obj-handle {reference.ToString ()} -> new-handle {newReference.ToString ()} " +
- $"from thread '{runtime.GetCurrentManagedThreadName ()}'({Environment.CurrentManagedThreadId})" +
- Environment.NewLine +
- runtime.GetCurrentManagedThreadStackTrace (skipFrames: 2, fNeedFileInfo: true);
- writer.WriteLine (message);
- writer.Flush ();
- }
-
- static void DeletedReference (TextWriter? writer, string kind, int count, JniObjectReference reference, JniRuntime runtime)
- {
- if (writer == null)
- return;
- string message = $"{kind} {count} handle {reference.ToString ()} " +
- $"from thread '{runtime.GetCurrentManagedThreadName ()}'({Environment.CurrentManagedThreadId})" +
- Environment.NewLine +
- runtime.GetCurrentManagedThreadStackTrace (skipFrames: 2, fNeedFileInfo: true);
- writer.WriteLine (message);
- writer.Flush ();
- }
- }
-}
diff --git a/src/Java.Runtime.Environment/Java.Interop/ManagedValueManager.cs b/src/Java.Runtime.Environment/Java.Interop/ManagedValueManager.cs
deleted file mode 100644
index a17c3ae2e..000000000
--- a/src/Java.Runtime.Environment/Java.Interop/ManagedValueManager.cs
+++ /dev/null
@@ -1,223 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.Diagnostics;
-using System.Diagnostics.CodeAnalysis;
-using System.IO;
-using System.Linq;
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using System.Threading;
-
-namespace Java.Interop {
-
- class ManagedValueManager : JniRuntime.ReflectionJniValueManager {
-
- Dictionary>? RegisteredInstances = new Dictionary>();
-
- [UnconditionalSuppressMessage ("Trimming", "IL2026", Justification = "Java.Runtime.Environment is the desktop/JRE runtime path and is removed by dotnet/java-interop#1447.")]
- [UnconditionalSuppressMessage ("AOT", "IL3050", Justification = "Java.Runtime.Environment is the desktop/JRE runtime path and is removed by dotnet/java-interop#1447.")]
- public ManagedValueManager ()
- {
- }
-
- public override void WaitForGCBridgeProcessing ()
- {
- }
-
- public override void CollectPeers ()
- {
- if (RegisteredInstances == null)
- throw new ObjectDisposedException (nameof (ManagedValueManager));
-
- var peers = new List ();
-
- lock (RegisteredInstances) {
- foreach (var ps in RegisteredInstances.Values) {
- foreach (var p in ps) {
- peers.Add (p);
- }
- }
- RegisteredInstances.Clear ();
- }
- List? exceptions = null;
- foreach (var peer in peers) {
- try {
- peer.Dispose ();
- }
- catch (Exception e) {
- exceptions = exceptions ?? new List ();
- exceptions.Add (e);
- }
- }
- if (exceptions != null)
- throw new AggregateException ("Exceptions while collecting peers.", exceptions);
- }
-
- public override void AddPeer (IJavaPeerable value)
- {
- if (RegisteredInstances == null)
- throw new ObjectDisposedException (nameof (ManagedValueManager));
-
- var r = value.PeerReference;
- if (!r.IsValid)
- throw new ObjectDisposedException (value.GetType ().FullName);
-
- if (r.Type != JniObjectReferenceType.Global) {
- value.SetPeerReference (r.NewGlobalRef ());
- JniObjectReference.Dispose (ref r, JniObjectReferenceOptions.CopyAndDispose);
- }
- int key = value.JniIdentityHashCode;
- lock (RegisteredInstances) {
- List? peers;
- if (!RegisteredInstances.TryGetValue (key, out peers)) {
- peers = new List () {
- value,
- };
- RegisteredInstances.Add (key, peers);
- return;
- }
-
- for (int i = peers.Count - 1; i >= 0; i--) {
- var p = peers [i];
- if (!JniEnvironment.Types.IsSameObject (p.PeerReference, value.PeerReference))
- continue;
- if (Replaceable (p, value)) {
- peers [i] = value;
- } else {
- WarnNotReplacing (key, value, p);
- }
- return;
- }
- peers.Add (value);
- }
- }
-
- static bool Replaceable (IJavaPeerable peer, IJavaPeerable value)
- {
- if (peer == null)
- return true;
- return peer.JniManagedPeerState.HasFlag (JniManagedPeerStates.Replaceable) &&
- !value.JniManagedPeerState.HasFlag (JniManagedPeerStates.Replaceable);
- }
-
- void WarnNotReplacing (int key, IJavaPeerable ignoreValue, IJavaPeerable keepValue)
- {
- Runtime.ObjectReferenceManager.WriteGlobalReferenceLine (
- "Warning: Not registering PeerReference={0} IdentityHashCode=0x{1} Instance={2} Instance.Type={3} Java.Type={4}; " +
- "keeping previously registered PeerReference={5} Instance={6} Instance.Type={7} Java.Type={8}.",
- ignoreValue.PeerReference.ToString (),
- key.ToString ("x"),
- RuntimeHelpers.GetHashCode (ignoreValue).ToString ("x"),
- ignoreValue.GetType ().FullName,
- JniEnvironment.Types.GetJniTypeNameFromInstance (ignoreValue.PeerReference),
- keepValue.PeerReference.ToString (),
- RuntimeHelpers.GetHashCode (keepValue).ToString ("x"),
- keepValue.GetType ().FullName,
- JniEnvironment.Types.GetJniTypeNameFromInstance (keepValue.PeerReference));
- }
-
- public override IJavaPeerable? PeekPeer (JniObjectReference reference)
- {
- if (RegisteredInstances == null)
- throw new ObjectDisposedException (nameof (ManagedValueManager));
-
- if (!reference.IsValid)
- return null;
-
- int key = GetJniIdentityHashCode (reference);
-
- lock (RegisteredInstances) {
- List? peers;
- if (!RegisteredInstances.TryGetValue (key, out peers))
- return null;
-
- for (int i = peers.Count - 1; i >= 0; i--) {
- var p = peers [i];
- if (JniEnvironment.Types.IsSameObject (reference, p.PeerReference))
- return p;
- }
- if (peers.Count == 0)
- RegisteredInstances.Remove (key);
- }
- return null;
- }
-
- public override void RemovePeer (IJavaPeerable value)
- {
- if (RegisteredInstances == null)
- throw new ObjectDisposedException (nameof (ManagedValueManager));
-
- if (value == null)
- throw new ArgumentNullException (nameof (value));
-
- int key = value.JniIdentityHashCode;
- lock (RegisteredInstances) {
- List? peers;
- if (!RegisteredInstances.TryGetValue (key, out peers))
- return;
-
- for (int i = peers.Count - 1; i >= 0; i--) {
- var p = peers [i];
- if (object.ReferenceEquals (value, p)) {
- peers.RemoveAt (i);
- }
- }
- if (peers.Count == 0)
- RegisteredInstances.Remove (key);
- }
- }
-
- public override void FinalizePeer (IJavaPeerable value)
- {
- var h = value.PeerReference;
- var o = Runtime.ObjectReferenceManager;
- // MUST NOT use SafeHandle.ReferenceType: local refs are tied to a JniEnvironment
- // and the JniEnvironment's corresponding thread; it's a thread-local value.
- // Accessing SafeHandle.ReferenceType won't kill anything (so far...), but
- // instead it always returns JniReferenceType.Invalid.
- if (!h.IsValid || h.Type == JniObjectReferenceType.Local) {
- if (o.LogGlobalReferenceMessages) {
- o.WriteGlobalReferenceLine ("Finalizing PeerReference={0} IdentityHashCode=0x{1} Instance=0x{2} Instance.Type={3}",
- h.ToString (),
- value.JniIdentityHashCode.ToString ("x"),
- RuntimeHelpers.GetHashCode (value).ToString ("x"),
- value.GetType ().ToString ());
- }
- RemovePeer (value);
- value.SetPeerReference (new JniObjectReference ());
- value.Finalized ();
- return;
- }
-
- RemovePeer (value);
- if (o.LogGlobalReferenceMessages) {
- o.WriteGlobalReferenceLine ("Finalizing PeerReference={0} IdentityHashCode=0x{1} Instance=0x{2} Instance.Type={3}",
- h.ToString (),
- value.JniIdentityHashCode.ToString ("x"),
- RuntimeHelpers.GetHashCode (value).ToString ("x"),
- value.GetType ().ToString ());
- }
- value.SetPeerReference (new JniObjectReference ());
- JniObjectReference.Dispose (ref h);
- value.Finalized ();
- }
-
- public override List GetSurfacedPeers ()
- {
- if (RegisteredInstances == null)
- throw new ObjectDisposedException (nameof (ManagedValueManager));
-
- lock (RegisteredInstances) {
- var peers = new List (RegisteredInstances.Count);
- foreach (var e in RegisteredInstances) {
- foreach (var p in e.Value) {
- peers.Add (new JniSurfacedPeerInfo (e.Key, new WeakReference (p)));
- }
- }
- return peers;
- }
- }
- }
-}
diff --git a/src/Java.Runtime.Environment/Java.Interop/MonoRuntimeObjectReferenceManager.cs b/src/Java.Runtime.Environment/Java.Interop/MonoRuntimeObjectReferenceManager.cs
deleted file mode 100644
index 47812f237..000000000
--- a/src/Java.Runtime.Environment/Java.Interop/MonoRuntimeObjectReferenceManager.cs
+++ /dev/null
@@ -1,250 +0,0 @@
-using System;
-using System.Diagnostics;
-using System.Runtime.InteropServices;
-
-namespace Java.Interop {
-
- class MonoRuntimeObjectReferenceManager : JniRuntime.JniObjectReferenceManager {
-
- IntPtr bridge;
- bool logGlobalRefs;
- bool logLocalRefs;
-
- public override void OnSetRuntime (JniRuntime runtime)
- {
- base.OnSetRuntime (runtime);
- bridge = JreNativeMethods.java_interop_gc_bridge_get_current ();
- if (bridge != IntPtr.Zero) {
- logLocalRefs = JreNativeMethods.java_interop_gc_bridge_lref_get_log_file (bridge) != IntPtr.Zero;
- logGlobalRefs = JreNativeMethods.java_interop_gc_bridge_gref_get_log_file (bridge) != IntPtr.Zero;
- }
- }
-
- public override int GlobalReferenceCount {
- get {return JreNativeMethods.java_interop_gc_bridge_get_gref_count (bridge);}
- }
-
- public override int WeakGlobalReferenceCount {
- get {return JreNativeMethods.java_interop_gc_bridge_get_weak_gref_count (bridge);}
- }
-
- public override bool LogLocalReferenceMessages {
- get {return logLocalRefs;}
- }
-
- public override void WriteLocalReferenceLine (string format, params object[] args)
- {
- if (!LogLocalReferenceMessages)
- return;
- JreNativeMethods.java_interop_gc_bridge_lref_log_message (bridge, 0, string.Format (format, args));
- JreNativeMethods.java_interop_gc_bridge_lref_log_message (bridge, 0, "\n");
- }
-
- public override JniObjectReference CreateLocalReference (JniObjectReference reference, ref int localReferenceCount)
- {
- if (!reference.IsValid)
- return reference;
-
- var r = base.CreateLocalReference (reference, ref localReferenceCount);
- JreNativeMethods.java_interop_gc_bridge_lref_log_new (bridge,
- localReferenceCount,
- reference.Handle,
- ToByte (reference.Type),
- r.Handle,
- ToByte (r.Type),
- GetCurrentManagedThreadName (LogLocalReferenceMessages),
- Environment.CurrentManagedThreadId,
- GetCurrentManagedThreadStack (LogLocalReferenceMessages));
- return r;
- }
-
- string? GetCurrentManagedThreadName (bool create)
- {
- if (create)
- return Runtime.GetCurrentManagedThreadName ();
- return null;
- }
-
- string? GetCurrentManagedThreadStack (bool create)
- {
- if (create)
- return Runtime.GetCurrentManagedThreadStackTrace (skipFrames: 2, fNeedFileInfo: true);
- return null;
- }
-
- public override void DeleteLocalReference (ref JniObjectReference reference, ref int localReferenceCount)
- {
- if (!reference.IsValid)
- return;
- JreNativeMethods.java_interop_gc_bridge_lref_log_delete (bridge,
- localReferenceCount,
- reference.Handle,
- ToByte (reference.Type),
- GetCurrentManagedThreadName (LogLocalReferenceMessages),
- Environment.CurrentManagedThreadId,
- GetCurrentManagedThreadStack (LogLocalReferenceMessages));
- base.DeleteLocalReference (ref reference, ref localReferenceCount);
- }
-
- public override void CreatedLocalReference (JniObjectReference reference, ref int localReferenceCount)
- {
- if (!reference.IsValid)
- return;
- base.CreatedLocalReference (reference, ref localReferenceCount);
- JreNativeMethods.java_interop_gc_bridge_lref_log_new (bridge,
- localReferenceCount,
- reference.Handle,
- ToByte (reference.Type),
- IntPtr.Zero,
- (byte) 0,
- GetCurrentManagedThreadName (LogLocalReferenceMessages),
- Environment.CurrentManagedThreadId,
- GetCurrentManagedThreadStack (LogLocalReferenceMessages));
- }
-
- public override IntPtr ReleaseLocalReference (ref JniObjectReference reference, ref int localReferenceCount)
- {
- if (!reference.IsValid)
- return IntPtr.Zero;
- JreNativeMethods.java_interop_gc_bridge_lref_log_delete (bridge,
- localReferenceCount,
- reference.Handle,
- ToByte (reference.Type),
- GetCurrentManagedThreadName (LogLocalReferenceMessages),
- Environment.CurrentManagedThreadId,
- GetCurrentManagedThreadStack (LogLocalReferenceMessages));
- return base.ReleaseLocalReference (ref reference, ref localReferenceCount);
- }
-
- public override bool LogGlobalReferenceMessages {
- get {return logGlobalRefs;}
- }
-
- public override void WriteGlobalReferenceLine (string format, params object?[]? args)
- {
- if (!LogGlobalReferenceMessages)
- return;
- JreNativeMethods.java_interop_gc_bridge_gref_log_message (bridge, 0, string.Format (format, args!));
- JreNativeMethods.java_interop_gc_bridge_gref_log_message (bridge, 0, "\n");
- }
-
- public override JniObjectReference CreateGlobalReference (JniObjectReference reference)
- {
- if (!reference.IsValid)
- return reference;
- var n = base.CreateGlobalReference (reference);
- JreNativeMethods.java_interop_gc_bridge_gref_log_new (bridge,
- reference.Handle,
- ToByte (reference.Type),
- n.Handle,
- ToByte (n.Type),
- GetCurrentManagedThreadName (LogGlobalReferenceMessages),
- Environment.CurrentManagedThreadId,
- GetCurrentManagedThreadStack (LogGlobalReferenceMessages));
- return n;
- }
-
- public override void DeleteGlobalReference (ref JniObjectReference reference)
- {
- if (!reference.IsValid)
- return;
- JreNativeMethods.java_interop_gc_bridge_gref_log_delete (bridge,
- reference.Handle,
- ToByte (reference.Type),
- GetCurrentManagedThreadName (LogGlobalReferenceMessages),
- Environment.CurrentManagedThreadId,
- GetCurrentManagedThreadStack (LogGlobalReferenceMessages));
- base.DeleteGlobalReference (ref reference);
- }
-
- public override JniObjectReference CreateWeakGlobalReference (JniObjectReference reference)
- {
- if (!reference.IsValid)
- return reference;
- var n = base.CreateWeakGlobalReference (reference);
- JreNativeMethods.java_interop_gc_bridge_weak_gref_log_new (bridge,
- reference.Handle,
- ToByte (reference.Type),
- n.Handle,
- ToByte (n.Type),
- GetCurrentManagedThreadName (LogGlobalReferenceMessages),
- Environment.CurrentManagedThreadId,
- GetCurrentManagedThreadStack (LogGlobalReferenceMessages));
- return n;
- }
-
- public override void DeleteWeakGlobalReference (ref JniObjectReference reference)
- {
- if (!reference.IsValid)
- return;
- JreNativeMethods.java_interop_gc_bridge_weak_gref_log_delete (bridge,
- reference.Handle,
- ToByte (reference.Type),
- GetCurrentManagedThreadName (LogGlobalReferenceMessages),
- Environment.CurrentManagedThreadId,
- GetCurrentManagedThreadStack (LogGlobalReferenceMessages));
- base.DeleteWeakGlobalReference (ref reference);
- }
-
- protected override void Dispose (bool disposing)
- {
- }
-
- static byte ToByte (JniObjectReferenceType type)
- {
- switch (type) {
- case JniObjectReferenceType.Global: return (byte) 'G';
- case JniObjectReferenceType.Invalid: return (byte) 'I';
- case JniObjectReferenceType.Local: return (byte) 'L';
- case JniObjectReferenceType.WeakGlobal: return (byte) 'W';
- }
- return (byte) '*';
- }
- }
-
- partial class JreNativeMethods {
-
- [DllImport (JavaInteropLib, CallingConvention=CallingConvention.Cdecl)]
- internal static extern int java_interop_gc_bridge_get_gref_count (IntPtr bridge);
-
- [DllImport (JavaInteropLib, CallingConvention=CallingConvention.Cdecl)]
- internal static extern int java_interop_gc_bridge_get_weak_gref_count (IntPtr bridge);
-
- [DllImport (JavaInteropLib, CallingConvention=CallingConvention.Cdecl)]
- internal static extern IntPtr java_interop_gc_bridge_lref_get_log_file (IntPtr bridge);
-
- [DllImport (JavaInteropLib, CallingConvention=CallingConvention.Cdecl)]
- internal static extern int java_interop_gc_bridge_lref_set_log_level (IntPtr bridge, int level);
-
- [DllImport (JavaInteropLib, CallingConvention=CallingConvention.Cdecl)]
- internal static extern void java_interop_gc_bridge_lref_log_message (IntPtr bridge, int level, string? message);
-
- [DllImport (JavaInteropLib, CallingConvention=CallingConvention.Cdecl)]
- internal static extern void java_interop_gc_bridge_lref_log_new (IntPtr bridge, int lref_count, IntPtr curHandle, byte curType, IntPtr newHandle, byte newType, string? thread_name, long thread_id, string? from);
-
- [DllImport (JavaInteropLib, CallingConvention=CallingConvention.Cdecl)]
- internal static extern void java_interop_gc_bridge_lref_log_delete (IntPtr bridge, int lref_count, IntPtr handle, byte type, string? thread_name, long thread_id, string? from);
-
- [DllImport (JavaInteropLib, CallingConvention=CallingConvention.Cdecl)]
- internal static extern IntPtr java_interop_gc_bridge_gref_get_log_file (IntPtr bridge);
-
- [DllImport (JavaInteropLib, CallingConvention=CallingConvention.Cdecl)]
- internal static extern int java_interop_gc_bridge_gref_set_log_level (IntPtr bridge, int level);
-
- [DllImport (JavaInteropLib, CallingConvention=CallingConvention.Cdecl)]
- internal static extern void java_interop_gc_bridge_gref_log_message (IntPtr bridge, int level, string? message);
-
- [DllImport (JavaInteropLib, CallingConvention=CallingConvention.Cdecl)]
- internal static extern int java_interop_gc_bridge_gref_log_new (IntPtr bridge, IntPtr curHandle, byte curType, IntPtr newHandle, byte newType, string? thread_name, long thread_id, string? from);
-
- [DllImport (JavaInteropLib, CallingConvention=CallingConvention.Cdecl)]
- internal static extern int java_interop_gc_bridge_gref_log_delete (IntPtr bridge, IntPtr handle, byte type, string? thread_name, long thread_id, string? from);
-
- [DllImport (JavaInteropLib, CallingConvention=CallingConvention.Cdecl)]
- internal static extern int java_interop_gc_bridge_weak_gref_log_new (IntPtr bridge, IntPtr curHandle, byte curType, IntPtr newHandle, byte newType, string? thread_name, long thread_id, string? from);
-
- [DllImport (JavaInteropLib, CallingConvention=CallingConvention.Cdecl)]
- internal static extern int java_interop_gc_bridge_weak_gref_log_delete (IntPtr bridge, IntPtr handle, byte type, string? thread_name, long thread_id, string? from);
- }
-}
-
diff --git a/src/Java.Runtime.Environment/Java.Interop/MonoRuntimeValueManager.cs b/src/Java.Runtime.Environment/Java.Interop/MonoRuntimeValueManager.cs
deleted file mode 100644
index 2d9e409a4..000000000
--- a/src/Java.Runtime.Environment/Java.Interop/MonoRuntimeValueManager.cs
+++ /dev/null
@@ -1,423 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Diagnostics.CodeAnalysis;
-using System.Linq;
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using System.Text;
-
-namespace Java.Interop {
-
- enum GCBridgeUseWeakReferenceKind {
- Java,
- Jni,
- }
-
- class MonoRuntimeValueManager : JniRuntime.ReflectionJniValueManager {
-
- #pragma warning disable 0649
- // This field is mutated by the java-interop native lib
- static volatile bool GCBridgeProcessingIsActive;
- #pragma warning restore 0649
-
- IntPtr bridge;
-
- [UnconditionalSuppressMessage ("Trimming", "IL2026", Justification = "Java.Runtime.Environment is the desktop/JRE runtime path and is removed by dotnet/java-interop#1447.")]
- [UnconditionalSuppressMessage ("AOT", "IL3050", Justification = "Java.Runtime.Environment is the desktop/JRE runtime path and is removed by dotnet/java-interop#1447.")]
- public MonoRuntimeValueManager ()
- {
- }
-
- public override void OnSetRuntime (JniRuntime runtime)
- {
- base.OnSetRuntime (runtime);
-
- bridge = JreNativeMethods.java_interop_gc_bridge_get_current ();
- if (bridge != IntPtr.Zero)
- return;
-
- bridge = JreNativeMethods.java_interop_gc_bridge_new (runtime.InvocationPointer);
- if (bridge == IntPtr.Zero)
- throw new NotSupportedException ("Could not initialize JNI::Mono GC Bridge!");
-
- try {
- if (JreNativeMethods.java_interop_gc_bridge_set_bridge_processing_field (bridge, typeof (MonoRuntimeValueManager).TypeHandle, nameof (GCBridgeProcessingIsActive)) < 0)
- throw new NotSupportedException ("Could not set bridge processing field!");
- foreach (var t in new[]{typeof (JavaObject), typeof (JavaException)}) {
- if (JreNativeMethods.java_interop_gc_bridge_register_bridgeable_type (bridge, t.TypeHandle) < 0)
- throw new NotSupportedException ("Could not register type " + t.FullName + "!");
- }
- if (JreNativeMethods.java_interop_gc_bridge_add_current_app_domain (bridge) < 0)
- throw new NotSupportedException ("Could not register current AppDomain!");
- if (JreNativeMethods.java_interop_gc_bridge_set_current_once (bridge) < 0)
- throw new NotSupportedException ("Could not set GC Bridge instance!");
- }
- catch (Exception) {
- JreNativeMethods.java_interop_gc_bridge_free (bridge);
- bridge = IntPtr.Zero;
- throw;
- }
- if (JreNativeMethods.java_interop_gc_bridge_register_hooks (bridge, GCBridgeUseWeakReferenceKind.Jni) < 0)
- throw new NotSupportedException ("Could not register GC Bridge with Mono!");
- }
-
- public override void WaitForGCBridgeProcessing ()
- {
- if (!GCBridgeProcessingIsActive)
- return;
- JreNativeMethods.java_interop_gc_bridge_wait_for_bridge_processing (bridge);
- }
-
- public override void CollectPeers ()
- {
- GC.Collect ();
- }
-
- protected override void Dispose (bool disposing)
- {
- base.Dispose (disposing);
-
- if (!disposing)
- return;
-
- if (RegisteredInstances == null)
- return;
-
- lock (RegisteredInstances) {
- foreach (var o in RegisteredInstances.Values) {
- foreach (var r in o) {
- IJavaPeerable? t;
- if (!r.TryGetTarget (out t))
- continue;
- t.Dispose ();
- }
- }
- RegisteredInstances.Clear ();
- RegisteredInstances = null;
- }
-
- if (bridge != IntPtr.Zero) {
- JreNativeMethods.java_interop_gc_bridge_remove_current_app_domain (bridge);
- bridge = IntPtr.Zero;
- }
- }
-
- Dictionary>>? RegisteredInstances = new Dictionary>>();
-
-
- public override List GetSurfacedPeers ()
- {
- if (RegisteredInstances == null)
- throw new ObjectDisposedException (nameof (MonoRuntimeValueManager));
-
- lock (RegisteredInstances) {
- var peers = new List (RegisteredInstances.Count);
- foreach (var e in RegisteredInstances) {
- foreach (var p in e.Value) {
- peers.Add (new JniSurfacedPeerInfo (e.Key, p));
- }
- }
- return peers;
- }
- }
-
- public override void AddPeer (IJavaPeerable value)
- {
- if (RegisteredInstances == null)
- throw new ObjectDisposedException (nameof (MonoRuntimeValueManager));
-
- var r = value.PeerReference;
- if (!r.IsValid)
- throw new ObjectDisposedException (value.GetType ().FullName);
- var o = PeekPeer (value.PeerReference);
- if (o != null)
- return;
-
- if (r.Type != JniObjectReferenceType.Global) {
- value.SetPeerReference (r.NewGlobalRef ());
- JniObjectReference.Dispose (ref r, JniObjectReferenceOptions.CopyAndDispose);
- }
- int key = value.JniIdentityHashCode;
- lock (RegisteredInstances) {
- List>? peers;
- if (!RegisteredInstances.TryGetValue (key, out peers)) {
- peers = new List> () {
- new WeakReference(value, trackResurrection: true),
- };
- RegisteredInstances.Add (key, peers);
- return;
- }
-
- for (int i = peers.Count - 1; i >= 0; i--) {
- var wp = peers [i];
- IJavaPeerable? p;
- if (!wp.TryGetTarget (out p)) {
- // Peer was collected
- peers.RemoveAt (i);
- continue;
- }
- if (!JniEnvironment.Types.IsSameObject (p.PeerReference, value.PeerReference))
- continue;
- if (Replaceable (p)) {
- peers [i] = new WeakReference(value, trackResurrection: true);
- } else {
- WarnNotReplacing (key, value, p);
- }
- return;
- }
- peers.Add (new WeakReference (value, trackResurrection: true));
- }
- }
-
- void WarnNotReplacing (int key, IJavaPeerable ignoreValue, IJavaPeerable keepValue)
- {
- Runtime.ObjectReferenceManager.WriteGlobalReferenceLine (
- "Warning: Not registering PeerReference={0} IdentityHashCode=0x{1} Instance={2} Instance.Type={3} Java.Type={4}; " +
- "keeping previously registered PeerReference={5} Instance={6} Instance.Type={7} Java.Type={8}.",
- ignoreValue.PeerReference.ToString (),
- key.ToString ("x"),
- RuntimeHelpers.GetHashCode (ignoreValue).ToString ("x"),
- ignoreValue.GetType ().FullName,
- JniEnvironment.Types.GetJniTypeNameFromInstance (ignoreValue.PeerReference),
- keepValue.PeerReference.ToString (),
- RuntimeHelpers.GetHashCode (keepValue).ToString ("x"),
- keepValue.GetType ().FullName,
- JniEnvironment.Types.GetJniTypeNameFromInstance (keepValue.PeerReference));
- }
-
- static bool Replaceable (IJavaPeerable peer)
- {
- if (peer == null)
- return true;
- return (peer.JniManagedPeerState & JniManagedPeerStates.Replaceable) == JniManagedPeerStates.Replaceable;
- }
-
- public override void RemovePeer (IJavaPeerable value)
- {
- if (RegisteredInstances == null)
- throw new ObjectDisposedException (nameof (MonoRuntimeValueManager));
-
- if (value == null)
- throw new ArgumentNullException (nameof (value));
-
- int key = value.JniIdentityHashCode;
- lock (RegisteredInstances) {
- List>? peers;
- if (!RegisteredInstances.TryGetValue (key, out peers))
- return;
-
- for (int i = peers.Count - 1; i >= 0; i--) {
- var wp = peers [i];
- IJavaPeerable? p;
- if (!wp.TryGetTarget (out p)) {
- // Peer was collected
- peers.RemoveAt (i);
- continue;
- }
- if (object.ReferenceEquals (value, p)) {
- peers.RemoveAt (i);
- }
- }
- if (peers.Count == 0)
- RegisteredInstances.Remove (key);
- }
- }
-
- public override IJavaPeerable? PeekPeer (JniObjectReference reference)
- {
- if (RegisteredInstances == null)
- throw new ObjectDisposedException (nameof (MonoRuntimeValueManager));
-
- if (!reference.IsValid)
- return null;
-
- int key = GetJniIdentityHashCode (reference);
-
- lock (RegisteredInstances) {
- List>? peers;
- if (!RegisteredInstances.TryGetValue (key, out peers))
- return null;
-
- for (int i = peers.Count - 1; i >= 0; i--) {
- var wp = peers [i];
- IJavaPeerable? p;
- if (!wp.TryGetTarget (out p)) {
- // Peer was collected
- peers.RemoveAt (i);
- continue;
- }
- if (JniEnvironment.Types.IsSameObject (reference, p.PeerReference))
- return p;
- }
- if (peers.Count == 0)
- RegisteredInstances.Remove (key);
- }
- return null;
- }
-
- static Exception CreateJniLocationException ()
- {
- using (var e = new JavaException ()) {
- return new OverrideStackTrace (e.ToString ());
- }
- }
-
- public override void FinalizePeer (IJavaPeerable value)
- {
- var h = value.PeerReference;
- var o = Runtime.ObjectReferenceManager;
- // MUST NOT use SafeHandle.ReferenceType: local refs are tied to a JniEnvironment
- // and the JniEnvironment's corresponding thread; it's a thread-local value.
- // Accessing SafeHandle.ReferenceType won't kill anything (so far...), but
- // instead it always returns JniReferenceType.Invalid.
- if (!h.IsValid || h.Type == JniObjectReferenceType.Local) {
- if (o.LogGlobalReferenceMessages) {
- o.WriteGlobalReferenceLine ("Finalizing PeerReference={0} IdentityHashCode=0x{1} Instance=0x{2} Instance.Type={3}",
- h.ToString (),
- value.JniIdentityHashCode.ToString ("x"),
- RuntimeHelpers.GetHashCode (value).ToString ("x"),
- value.GetType ().ToString ());
- }
- RemovePeer (value);
- value.SetPeerReference (new JniObjectReference ());
- value.Finalized ();
- return;
- }
-
- try {
- bool collected = TryGC (value, ref h);
- if (collected) {
- RemovePeer (value);
- value.SetPeerReference (new JniObjectReference ());
- if (o.LogGlobalReferenceMessages) {
- o.WriteGlobalReferenceLine ("Finalizing PeerReference={0} IdentityHashCode=0x{1} Instance=0x{2} Instance.Type={3}",
- h.ToString (),
- value.JniIdentityHashCode.ToString ("x"),
- RuntimeHelpers.GetHashCode (value).ToString ("x"),
- value.GetType ().ToString ());
- }
- value.Finalized ();
- } else {
- value.SetPeerReference (h);
- GC.ReRegisterForFinalize (value);
- }
- } catch (Exception e) {
- Runtime.FailFast ("Unable to perform a GC! " + e);
- }
- }
-
- ///
- /// Try to garbage collect .
- ///
- ///
- /// true, if was collected and
- /// is invalid; otherwise false.
- ///
- ///
- /// The instance to collect.
- ///
- ///
- /// The of .
- /// This value may be updated, and
- /// will be updated with this value.
- ///
- internal protected virtual bool TryGC (IJavaPeerable value, ref JniObjectReference handle)
- {
- if (!handle.IsValid)
- return true;
- var wgref = handle.NewWeakGlobalRef ();
- JniObjectReference.Dispose (ref handle);
- JniGC.Collect ();
- handle = wgref.NewGlobalRef ();
- JniObjectReference.Dispose (ref wgref);
- return !handle.IsValid;
- }
- }
-
- static class JavaLangRuntime {
- static JniType? _typeRef;
- static JniType TypeRef {
- get {return JniType.GetCachedJniType (ref _typeRef, "java/lang/Runtime");}
- }
-
- static JniMethodInfo? _getRuntime;
- internal static JniObjectReference GetRuntime ()
- {
- TypeRef.GetCachedStaticMethod (ref _getRuntime, "getRuntime", "()Ljava/lang/Runtime;");
- return JniEnvironment.StaticMethods.CallStaticObjectMethod (TypeRef.PeerReference, _getRuntime);
- }
-
- static JniMethodInfo? _gc;
- internal static void GC (JniObjectReference runtime)
- {
- TypeRef.GetCachedInstanceMethod (ref _gc, "gc", "()V");
- JniEnvironment.InstanceMethods.CallVoidMethod (runtime, _gc);
- }
- }
-
- static class JniGC {
-
- internal static void Collect ()
- {
- var runtime = JavaLangRuntime.GetRuntime ();
- try {
- JavaLangRuntime.GC (runtime);
- } finally {
- JniObjectReference.Dispose (ref runtime);
- }
- }
- }
-
- partial class JreNativeMethods {
-
- const string JavaInteropLib = "java-interop";
-
- [DllImport (JavaInteropLib, CallingConvention=CallingConvention.Cdecl)]
- internal static extern IntPtr java_interop_gc_bridge_get_current ();
-
- [DllImport (JavaInteropLib, CallingConvention=CallingConvention.Cdecl)]
- internal static extern int java_interop_gc_bridge_set_current_once (IntPtr bridge);
-
- [DllImport (JavaInteropLib, CallingConvention=CallingConvention.Cdecl)]
- internal static extern int java_interop_gc_bridge_register_hooks (IntPtr bridge, GCBridgeUseWeakReferenceKind weak_ref_kind);
-
- [DllImport (JavaInteropLib, CallingConvention=CallingConvention.Cdecl)]
- internal static extern IntPtr java_interop_gc_bridge_new (IntPtr jvm);
-
- [DllImport (JavaInteropLib, CallingConvention=CallingConvention.Cdecl)]
- internal static extern int java_interop_gc_bridge_free (IntPtr bridge);
-
- [DllImport (JavaInteropLib, CallingConvention=CallingConvention.Cdecl)]
- internal static extern int java_interop_gc_bridge_add_current_app_domain (IntPtr bridge);
-
- [DllImport (JavaInteropLib, CallingConvention=CallingConvention.Cdecl)]
- internal static extern int java_interop_gc_bridge_remove_current_app_domain (IntPtr bridge);
-
- [DllImport (JavaInteropLib, CallingConvention=CallingConvention.Cdecl)]
- internal static extern int java_interop_gc_bridge_set_bridge_processing_field (IntPtr bridge, RuntimeTypeHandle type_handle, string field_name);
-
- [DllImport (JavaInteropLib, CallingConvention=CallingConvention.Cdecl)]
- internal static extern int java_interop_gc_bridge_register_bridgeable_type (IntPtr bridge, RuntimeTypeHandle type_handle);
-
- [DllImport (JavaInteropLib, CallingConvention=CallingConvention.Cdecl)]
- internal static extern void java_interop_gc_bridge_wait_for_bridge_processing (IntPtr bridge);
- }
-
- sealed class OverrideStackTrace : Exception {
-
- readonly string stackTrace;
-
- public OverrideStackTrace (string stackTrace)
- {
- this.stackTrace = stackTrace;
- }
-
- public override string StackTrace {
- get {
- return stackTrace;
- }
- }
- }
-}
diff --git a/src/Java.Runtime.Environment/Java.Runtime.Environment.csproj b/src/Java.Runtime.Environment/Java.Runtime.Environment.csproj
deleted file mode 100644
index 47a1c7ca6..000000000
--- a/src/Java.Runtime.Environment/Java.Runtime.Environment.csproj
+++ /dev/null
@@ -1,36 +0,0 @@
-
-
-
- $(DotNetTargetFramework)
- true
- ..\..\product.snk
- true
- enable
- NU1702
-
-
-
-
-
- $(TestOutputFullPath)
- $(JICoreLibVersion)
-
-
-
-
-
-
-
-
-
-
-
- PreserveNewest
-
-
-
-
-
-
-
-
diff --git a/src/Java.Runtime.Environment/Java.Runtime.Environment.dll.config.in b/src/Java.Runtime.Environment/Java.Runtime.Environment.dll.config.in
deleted file mode 100644
index c1ebf627c..000000000
--- a/src/Java.Runtime.Environment/Java.Runtime.Environment.dll.config.in
+++ /dev/null
@@ -1,3 +0,0 @@
-
-@JAVA_RUNTIME_ENVIRONMENT_DLLMAP@
-
diff --git a/src/Java.Runtime.Environment/Java.Runtime.Environment.targets b/src/Java.Runtime.Environment/Java.Runtime.Environment.targets
deleted file mode 100644
index 674b0a28e..000000000
--- a/src/Java.Runtime.Environment/Java.Runtime.Environment.targets
+++ /dev/null
@@ -1,27 +0,0 @@
-
-
-
-
-
-
- <_OverrideFile>$(MSBuildThisFileDirectory)../../Java.Runtime.Environment.Override.dllmap
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/Java.Runtime.Environment/Properties/AssemblyInfo.cs b/src/Java.Runtime.Environment/Properties/AssemblyInfo.cs
deleted file mode 100644
index 0d3614292..000000000
--- a/src/Java.Runtime.Environment/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,3 +0,0 @@
-using System.Runtime.InteropServices;
-
-[assembly: DefaultDllImportSearchPathsAttribute (DllImportSearchPath.SafeDirectories | DllImportSearchPath.AssemblyDirectory)]
diff --git a/src/java-interop/.gitignore b/src/java-interop/.gitignore
deleted file mode 100644
index dd69cf665..000000000
--- a/src/java-interop/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-coreclr.exp
-jni.c
-jni.g.cs
diff --git a/src/java-interop/CMakeLists.txt b/src/java-interop/CMakeLists.txt
index e5c70c813..4e29d9d27 100644
--- a/src/java-interop/CMakeLists.txt
+++ b/src/java-interop/CMakeLists.txt
@@ -1,8 +1,10 @@
cmake_minimum_required(VERSION 3.10.2)
+set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
+
project(
- java-interop
- DESCRIPTION "Java.Interop native support"
+ java-interop-validation
+ DESCRIPTION "Java.Interop native source validation"
HOMEPAGE_URL "https://github.com/dotnet/java-interop/"
LANGUAGES CXX C
)
@@ -13,49 +15,23 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
-option(ENABLE_MONO_INTEGRATION "Require Mono runtime" OFF)
-option(ENABLE_OSX_ARCHITECTURES "macOS architectures" "")
-
-set(CMAKE_OSX_ARCHITECTURES ${ENABLE_OSX_ARCHITECTURES})
-
-set(JAVA_INTEROP_CORE_SOURCES
- java-interop-dlfcn.cc
- java-interop-jvm.cc
- java-interop-logger.cc
- java-interop-util.cc
- java-interop.cc
- ${JNI_C_PATH}
-)
-set(JAVA_INTEROP_MONO_SOURCES
- java-interop-gc-bridge-mono.cc
- java-interop-mono.cc
-)
-
-add_compile_definitions("JAVA_INTEROP_DLL_EXPORT")
-add_compile_definitions("JI_DLL_EXPORT")
+if(ENABLE_OSX_ARCHITECTURES)
+ set(CMAKE_OSX_ARCHITECTURES ${ENABLE_OSX_ARCHITECTURES})
+endif()
-foreach(dir in ${JDK_INCLUDE_LIST})
+foreach(dir ${MONO_INCLUDE_LIST})
include_directories(${dir})
endforeach()
-set(LINK_FLAGS "")
-
-if(ENABLE_MONO_INTEGRATION)
- foreach(dir in ${MONO_INCLUDE_LIST})
- include_directories(${dir})
- endforeach()
- list(APPEND LINK_FLAGS ${MONO_LINK_FLAGS})
- set(JAVA_INTEROP_SOURCES ${JAVA_INTEROP_CORE_SOURCES} ${JAVA_INTEROP_MONO_SOURCES})
-else()
- set(JAVA_INTEROP_SOURCES ${JAVA_INTEROP_CORE_SOURCES})
+if(OUTPUT_DIR)
+ set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${OUTPUT_DIR}")
endif()
add_library(
- java-interop
- SHARED
- ${JAVA_INTEROP_SOURCES}
-)
-target_link_libraries(
- java-interop
- ${LINK_FLAGS}
+ java-interop-validation
+ STATIC
+ java-interop-dlfcn.cc
+ java-interop-mono.cc
+ java-interop-util.cc
+ java-interop.cc
)
diff --git a/src/java-interop/coreclr.def b/src/java-interop/coreclr.def
deleted file mode 100644
index 6eb946c9e..000000000
--- a/src/java-interop/coreclr.def
+++ /dev/null
@@ -1,20 +0,0 @@
-LIBRARY CORECLR
-
-EXPORTS
- mono_class_from_mono_type
- mono_class_get_field_from_name
- mono_class_get_name
- mono_class_get_namespace
- mono_class_is_subclass_of
- mono_class_vtable
- mono_domain_get
- mono_field_get_value
- mono_field_set_value
- mono_field_static_set_value
- mono_gc_register_bridge_callbacks
- mono_gc_wait_for_bridge_processing
- mono_object_get_class
- mono_thread_attach
- mono_thread_current
- mono_thread_get_managed_id
- mono_thread_get_name_utf8
diff --git a/src/java-interop/coreclr.lib b/src/java-interop/coreclr.lib
deleted file mode 100644
index aa421bc7b..000000000
Binary files a/src/java-interop/coreclr.lib and /dev/null differ
diff --git a/src/java-interop/java-interop-gc-bridge-mono.cc b/src/java-interop/java-interop-gc-bridge-mono.cc
deleted file mode 100644
index cebe8ece9..000000000
--- a/src/java-interop/java-interop-gc-bridge-mono.cc
+++ /dev/null
@@ -1,1399 +0,0 @@
-#define __STDC_FORMAT_MACROS
-
-#include
-#include
-#include
-#include
-
-#include "java-interop.h"
-#include "java-interop-gc-bridge.h"
-#include "java-interop-mono.h"
-#include "java-interop-util.h"
-
-#ifdef _WINDOWS
-#include
-#include
-#endif
-
-#ifdef __linux__
- #include
- #include
-#endif /* !defined (__linux__) */
-
-#if defined (ANDROID)
- #include "logger.h"
-#endif /* !defined (ANDROID) */
-
-#if defined (ANDROID) || defined (XAMARIN_ANDROID_DYLIB_MONO)
-using namespace xamarin::android;
-#endif
-
-typedef struct MonoJavaGCBridgeInfo {
- MonoClass *klass;
- MonoClassField *jniObjectReferenceControlBlock;
-} MonoJavaGCBridgeInfo;
-
-typedef struct JniObjectReferenceControlBlock {
- jobject handle;
- int handle_type;
- jobject weak_handle;
- int refs_added;
-} JniObjectReferenceControlBlock;
-
-#define NUM_GC_BRIDGE_TYPES (4)
-
-struct JavaInteropGCBridge {
-
- JavaVM *jvm;
-
- MonoClass *BridgeProcessing_type;
- MonoClassField *BridgeProcessing_field;
-
- int BridgeProcessing_vtables_count, BridgeProcessing_vtables_length;
- MonoDomain **BridgeProcessing_domains;
- MonoVTable **BridgeProcessing_vtables;
-
- int num_bridge_types;
- MonoJavaGCBridgeInfo mono_java_gc_bridge_info [NUM_GC_BRIDGE_TYPES];
-
- int gc_disabled;
-
- int gc_gref_count;
- int gc_weak_gref_count;
-
- jobject Runtime_instance;
- jmethodID Runtime_gc;
-
- jclass WeakReference_class;
- jmethodID WeakReference_init;
- jmethodID WeakReference_get;
-
- jclass GCUserPeerable_class;
- jmethodID GCUserPeerable_add;
- jmethodID GCUserPeerable_clear;
-
- FILE *gref_log, *lref_log;
- char *gref_path, *lref_path;
- int gref_log_level, lref_log_level;
- int gref_cleanup, lref_cleanup;
-
- JavaInteropMarkCrossReferencesCallback mark_cross_references;
-};
-
-static jobject
-lref_to_gref (JNIEnv *env, jobject lref)
-{
- jobject g;
- if (lref == 0)
- return 0;
- g = env->NewGlobalRef (lref);
- env->DeleteLocalRef (lref);
- return g;
-}
-
-static JNIEnv*
-ensure_jnienv (JavaInteropGCBridge *bridge)
-{
- JavaVM *jvm = bridge->jvm;
- JNIEnv *env;
- if (bridge->jvm->GetEnv ((void**)&env, JNI_VERSION_1_6) != JNI_OK || env == NULL) {
- mono_thread_attach (mono_domain_get ());
- jvm->GetEnv ((void**)&env, JNI_VERSION_1_6);
- }
- return env;
-}
-
-static int
-java_interop_gc_bridge_destroy (JavaInteropGCBridge *bridge)
-{
- if (bridge == NULL)
- return -1;
-
- JNIEnv *env = ensure_jnienv (bridge);
- if (env != NULL) {
- env->DeleteGlobalRef (bridge->Runtime_instance);
- env->DeleteGlobalRef (bridge->WeakReference_class);
- env->DeleteGlobalRef (bridge->GCUserPeerable_class);
-
- bridge->Runtime_instance = NULL;
- bridge->WeakReference_class = NULL;
-
- bridge->GCUserPeerable_class = NULL;
- }
-
- if (bridge->gref_log != NULL && bridge->gref_cleanup) {
- fclose (bridge->gref_log);
- }
- bridge->gref_log = NULL;
-
- free (bridge->gref_path);
- bridge->gref_path = NULL;
-
- if (bridge->lref_log != NULL && bridge->lref_cleanup) {
- fclose (bridge->lref_log);
- }
- bridge->lref_log = NULL;
-
- free (bridge->lref_path);
- bridge->lref_path = NULL;
-
- free (bridge->BridgeProcessing_domains);
- free (bridge->BridgeProcessing_vtables);
- bridge->BridgeProcessing_domains = NULL;
- bridge->BridgeProcessing_vtables = NULL;
- bridge->BridgeProcessing_vtables_count = 0;
- bridge->BridgeProcessing_vtables_length = 0;
-
- return 0;
-}
-
-#ifdef _WINDOWS
-static char*
-_ji_realpath_win_loop (wchar_t* wpath, DWORD len)
-{
- DWORD retval;
- char* fullpath = NULL;
- wchar_t *allocated_buffer = static_cast (xmalloc (sizeof (wchar_t)*len));
-
- while (1) {
- retval = GetFullPathNameW (wpath, len, allocated_buffer, NULL);
-
- if (retval == 0)
- break;
-
- if (retval < len && allocated_buffer [retval] == '\0') {
- fullpath = utf16_to_utf8 (allocated_buffer);
- break;
- }
-
- // other thread probably called chdir ()
- // be on the safe side and allocate more space in case it will happen again
- len = retval*2;
- allocated_buffer = static_cast (xrealloc (allocated_buffer, sizeof (wchar_t)*len));
- }
-
- free (allocated_buffer);
-
- return fullpath;
-}
-#endif
-
-static char*
-ji_realpath (const char *path)
-{
- if (path == NULL)
- return NULL;
-
-#ifndef _WINDOWS
- char *rp = realpath (path, NULL);
- if (rp == NULL) {
- return strdup (path);
- }
- return rp;
-#else
-#define BUFSIZE 512
-
- wchar_t *wpath = utf8_to_utf16 (path);
- char *fullpath = NULL;
- wchar_t buffer [BUFSIZE];
- DWORD retval = GetFullPathNameW (wpath, BUFSIZE, buffer, NULL);
-
- do {
- if (retval == 0)
- break;
-
- if (retval < BUFSIZE) {
- fullpath = utf16_to_utf8 (buffer);
- break;
- }
-
- fullpath = _ji_realpath_win_loop (wpath, retval);
- } while (0);
-
- free (wpath);
-
- return fullpath;
-#endif
-}
-
-static FILE *
-open_log_file (const char *path, FILE *alt, const char *alt_path, const char *envVar, int *cleanup, char **rpath)
-{
- path = path ? path : getenv (envVar);
- if (path == NULL)
- return NULL;
-
- *cleanup = 0;
- if (strlen (path) == 0)
- return stdout;
-
- char *rp = ji_realpath (path);
- if (rp != NULL && alt_path != NULL && strcmp (rp, alt_path) == 0) {
- free (rp);
- return alt;
- }
-
- FILE *f = fopen (path, "w");
- if (f == NULL) {
- free (rp);
- return NULL;
- }
-
- if (rpath) {
- *rpath = rp;
- } else {
- free (rp);
- }
-
- *cleanup = 1;
- return f;
-}
-
-JavaInteropGCBridge*
-java_interop_gc_bridge_new (JavaVM *jvm)
-{
- if (jvm == NULL)
- return NULL;
-
-#if defined (XAMARIN_ANDROID_DYLIB_MONO)
- if (!monodroid_dylib_mono_init (monodroid_get_dylib (), NULL)) {
- log_fatal (LOG_DEFAULT, "mono runtime initialization error: %s", dlerror ());
- exit (FATAL_EXIT_CANNOT_FIND_MONO);
- }
-#endif /* defined (XAMARIN_ANDROID_DYLIB_MONO) */
-
- JavaInteropGCBridge bridge;
- memset (&bridge, 0, sizeof (bridge));
-
- bridge.jvm = jvm;
-
- JNIEnv *env;
- if (jvm->GetEnv ((void**) &env, JNI_VERSION_1_6) != JNI_OK)
- return NULL;
-
- jclass Runtime_class = env->FindClass ("java/lang/Runtime");
- if (Runtime_class != NULL) {
- bridge.Runtime_gc = env->GetMethodID (Runtime_class, "gc", "()V");
-
- jmethodID Runtime_getRuntime = env->GetStaticMethodID (Runtime_class, "getRuntime", "()Ljava/lang/Runtime;");
- bridge.Runtime_instance = Runtime_getRuntime
- ? lref_to_gref (env, env->CallStaticObjectMethod (Runtime_class, Runtime_getRuntime))
- : NULL;
-
- env->DeleteLocalRef (Runtime_class);
- }
-
- jclass WeakReference_class = env->FindClass ("java/lang/ref/WeakReference");
- if (WeakReference_class != NULL) {
- bridge.WeakReference_init = env->GetMethodID (WeakReference_class, "", "(Ljava/lang/Object;)V");
- bridge.WeakReference_get = env->GetMethodID (WeakReference_class, "get", "()Ljava/lang/Object;");
- bridge.WeakReference_class = static_cast(lref_to_gref (env, WeakReference_class));
- }
-
- jclass GCUserPeerable_class = env->FindClass ("net/dot/jni/GCUserPeerable");
- if (GCUserPeerable_class) {
- bridge.GCUserPeerable_add = env->GetMethodID (GCUserPeerable_class, "jiAddManagedReference", "(Ljava/lang/Object;)V");
- bridge.GCUserPeerable_clear = env->GetMethodID (GCUserPeerable_class, "jiClearManagedReferences", "()V");
- bridge.GCUserPeerable_class = static_cast(lref_to_gref (env, GCUserPeerable_class));
- fflush (stdout);
- }
-
- JavaInteropGCBridge *p = static_cast(calloc (1, sizeof (JavaInteropGCBridge)));
-
- if (p == NULL || bridge.jvm == NULL ||
- bridge.Runtime_instance == NULL || bridge.Runtime_gc == NULL ||
- bridge.WeakReference_class == NULL || bridge.WeakReference_init == NULL || bridge.WeakReference_get == NULL) {
- java_interop_gc_bridge_destroy (&bridge);
- free (p);
- return NULL;
- }
-
- *p = bridge;
-
- p->gref_log = open_log_file (NULL, NULL, NULL, "JAVA_INTEROP_GREF_LOG", &p->gref_cleanup, &p->gref_path);
- p->lref_log = open_log_file (NULL, p->gref_log, p->gref_path, "JAVA_INTEROP_LREF_LOG", &p->lref_cleanup, &p->lref_path);
-
- return p;
-}
-
-int
-java_interop_gc_bridge_free (JavaInteropGCBridge *bridge)
-{
- if (bridge == NULL)
- return -1;
-
- int r = java_interop_gc_bridge_destroy (bridge);
- free (bridge);
-
- return r;
-}
-
-int
-java_interop_gc_bridge_enable (JavaInteropGCBridge *bridge, int enable)
-{
- if (!bridge)
- return -1;
-
- bridge->gc_disabled = !enable;
-
- return 0;
-}
-
-int
-java_interop_gc_bridge_set_bridge_processing_field (
- JavaInteropGCBridge *bridge,
- struct JavaInterop_System_RuntimeTypeHandle type_handle,
- char *field_name)
-{
- if (bridge == NULL || type_handle.value == NULL || field_name == NULL)
- return -1;
-
- MonoType *type = static_cast(type_handle.value);
-
- bridge->BridgeProcessing_type = mono_class_from_mono_type (type);
- bridge->BridgeProcessing_field = mono_class_get_field_from_name (bridge->BridgeProcessing_type, field_name);
-
- return 0;
-}
-
-int
-java_interop_gc_bridge_register_bridgeable_type (
- JavaInteropGCBridge *bridge,
- struct JavaInterop_System_RuntimeTypeHandle type_handle)
-{
- if (bridge == NULL || type_handle.value == NULL)
- return -1;
-
- if (bridge->num_bridge_types >= NUM_GC_BRIDGE_TYPES)
- return -1;
-
- MonoType *type = static_cast(type_handle.value);
- int i = bridge->num_bridge_types;
- MonoJavaGCBridgeInfo *info = &bridge->mono_java_gc_bridge_info [i];
-
- info->klass = mono_class_from_mono_type (type);
-
- info->jniObjectReferenceControlBlock = mono_class_get_field_from_name (info->klass, const_cast ("jniObjectReferenceControlBlock"));
-
- if (info->klass == NULL || info->jniObjectReferenceControlBlock == NULL)
- return -1;
- bridge->num_bridge_types++;
- return 0;
-}
-
-int
-java_interop_gc_bridge_get_gref_count (JavaInteropGCBridge *bridge)
-{
- if (bridge == NULL)
- return -1;
-
- return bridge->gc_gref_count;
-}
-
-int
-java_interop_gc_bridge_get_weak_gref_count (JavaInteropGCBridge *bridge)
-{
- if (bridge == NULL)
- return -1;
-
- return bridge->gc_weak_gref_count;
-}
-
-int
-java_interop_gc_bridge_gref_set_log_file (
- JavaInteropGCBridge *bridge,
- const char *gref_log_file)
-{
- if (bridge == NULL)
- return -1;
-
- if (bridge->gref_log && bridge->gref_cleanup) {
- fclose (bridge->gref_log);
- }
-
- bridge->gref_log = open_log_file (gref_log_file, bridge->lref_log, bridge->lref_path, "JAVA_INTEROP_GREF_LOG", &bridge->gref_cleanup, &bridge->gref_path);
-
- return 0;
-}
-
-FILE*
-java_interop_gc_bridge_gref_get_log_file (
- JavaInteropGCBridge *bridge)
-{
- if (bridge == NULL)
- return NULL;
-
- return bridge->gref_log;
-}
-
-int
-java_interop_gc_bridge_gref_set_log_level (
- JavaInteropGCBridge *bridge,
- int level)
-{
- if (bridge == NULL)
- return -1;
-
- bridge->gref_log_level = level;
- return 0;
-}
-
-void
-java_interop_gc_bridge_gref_log_message (
- JavaInteropGCBridge *bridge,
- int level,
- const char *message)
-{
- if (!bridge || !bridge->gref_log || bridge->gref_log_level < level)
- return;
- fprintf (bridge->gref_log, "%s", message);
- fflush (bridge->gref_log);
-}
-
-int
-java_interop_gc_bridge_lref_set_log_file (
- JavaInteropGCBridge *bridge,
- const char *lref_log_file)
-{
- if (bridge == NULL)
- return -1;
-
- if (bridge->lref_log && bridge->lref_cleanup) {
- fclose (bridge->lref_log);
- }
-
- bridge->lref_log = open_log_file (lref_log_file, bridge->gref_log, bridge->gref_path, "JAVA_INTEROP_LREF_LOG", &bridge->lref_cleanup, &bridge->lref_path);
-
- return 0;
-}
-
-FILE*
-java_interop_gc_bridge_lref_get_log_file (
- JavaInteropGCBridge *bridge)
-{
- if (bridge == NULL)
- return NULL;
-
- return bridge->lref_log;
-}
-
-int
-java_interop_gc_bridge_lref_set_log_level (
- JavaInteropGCBridge *bridge,
- int level)
-{
- if (bridge == NULL)
- return -1;
-
- bridge->lref_log_level = level;
- return 0;
-}
-
-void
-java_interop_gc_bridge_lref_log_message (
- JavaInteropGCBridge *bridge,
- int level,
- const char *message)
-{
- if (!bridge || !bridge->lref_log || bridge->lref_log_level < level)
- return;
- fprintf (bridge->lref_log, "%s", message);
- fflush (bridge->lref_log);
-}
-
-static void
-log_gref (JavaInteropGCBridge *bridge, const char *format, ...)
-{
- va_list args;
-
- if (!bridge->gref_log)
- return;
-
- va_start (args, format);
- vfprintf (bridge->gref_log, format, args);
- fflush (bridge->gref_log);
- va_end (args);
-}
-
-static char
-get_object_ref_type (JNIEnv *env, jobject handle)
-{
- if (handle == NULL)
- return 'I';
- jobjectRefType value = env->GetObjectRefType (handle);
- switch (value) {
- case JNIInvalidRefType: return 'I';
- case JNILocalRefType: return 'L';
- case JNIGlobalRefType: return 'G';
- case JNIWeakGlobalRefType: return 'W';
- default: return '*';
- }
-}
-
-static int
-gref_inc (JavaInteropGCBridge *bridge)
-{
-#if _WINDOWS
- return InterlockedIncrement ((LONG volatile*) &bridge->gc_gref_count);
-#else // !_WINDOWS
- return __sync_add_and_fetch (&bridge->gc_gref_count, 1);
-#endif // _!WINDOWS
-}
-
-static int
-gref_dec (JavaInteropGCBridge *bridge)
-{
-#if _WINDOWS
- return InterlockedDecrement ((LONG volatile*) &bridge->gc_gref_count);
-#else // !_WINDOWS
- return __sync_sub_and_fetch (&bridge->gc_gref_count, 1);
-#endif // _!WINDOWS
-}
-
-#if defined (ANDROID)
- #define WRITE_ANDROID_MESSAGE_RETURN(ret, category, format, ...) do { \
- if ((log_categories & category) == 0) \
- return ret; \
- log_info (category, format, __VA_ARGS__); \
- } while (0)
-#else /* ndef ANDROID */
- #define WRITE_ANDROID_MESSAGE_RETURN(ret, category, format, ...) do { \
- } while (0)
-#endif /* ndef ANDROID */
-
-#define WRITE_LOG_MESSAGE_RETURN(ret, category, to, from, format, ...) do { \
- WRITE_ANDROID_MESSAGE_RETURN(ret, category, format, __VA_ARGS__); \
- if (!to) \
- return ret; \
- fprintf (to, format "\n", __VA_ARGS__); \
- fprintf (to, "%s\n", from); \
- fflush (to); \
-} while (0)
-
-int
-java_interop_gc_bridge_gref_log_new (
- JavaInteropGCBridge *bridge,
- jobject curHandle,
- char curType,
- jobject newHandle,
- char newType,
- const char *thread_name,
- int64_t thread_id,
- const char *from)
-{
- if (!bridge)
- return -1;
-
- int c = gref_inc (bridge);
-
- WRITE_LOG_MESSAGE_RETURN(c, LOG_GREF, bridge->gref_log, from,
- "+g+ grefc %i gwrefc %i obj-handle %p/%c -> new-handle %p/%c from thread '%s'(%" PRId64 ")",
- c,
- bridge->gc_weak_gref_count,
- curHandle,
- curType,
- newHandle,
- newType,
- thread_name,
- thread_id);
-
- return c;
-}
-
-int
-java_interop_gc_bridge_gref_log_delete (
- JavaInteropGCBridge *bridge,
- jobject handle,
- char type,
- const char *thread_name,
- int64_t thread_id,
- const char *from)
-{
- if (!bridge)
- return -1;
-
- int c = gref_dec (bridge);
-
- WRITE_LOG_MESSAGE_RETURN(c, LOG_GREF, bridge->gref_log, from,
- "-g- grefc %i gwrefc %i handle %p/%c from thread '%s'(%" PRId64 ")",
- c,
- bridge->gc_weak_gref_count,
- handle,
- type,
- thread_name,
- thread_id);
-
- return c;
-}
-
-void
-java_interop_gc_bridge_lref_log_new (
- JavaInteropGCBridge *bridge,
- int lref_count,
- jobject curHandle,
- char curType,
- jobject newHandle,
- char newType,
- const char *thread_name,
- int64_t thread_id,
- const char *from)
-{
- if (!bridge)
- return;
-
- if (newHandle) {
- WRITE_LOG_MESSAGE_RETURN(, LOG_LREF, bridge->lref_log, from,
- "+l+ lrefc %i obj-handle %p/%c -> new-handle %p/%c from thread '%s'(%" PRId64 ")",
- lref_count,
- curHandle,
- curType,
- newHandle,
- newType,
- thread_name,
- thread_id);
- }
- else {
- WRITE_LOG_MESSAGE_RETURN(, LOG_LREF, bridge->lref_log, from,
- "+l+ lrefc %i handle %p/%c from thread '%s'(%" PRId64 ")",
- lref_count,
- curHandle,
- curType,
- thread_name,
- thread_id);
- }
-}
-
-void
-java_interop_gc_bridge_lref_log_delete (
- JavaInteropGCBridge *bridge,
- int lref_count,
- jobject handle,
- char type,
- const char *thread_name,
- int64_t thread_id,
- const char *from)
-{
- if (!bridge)
- return;
-
- WRITE_LOG_MESSAGE_RETURN(, LOG_LREF, bridge->lref_log, from,
- "-l- lrefc %i handle %p/%c from thread '%s'(%" PRId64 ")",
- lref_count,
- handle,
- type,
- thread_name,
- thread_id);
-}
-
-int
-java_interop_gc_bridge_weak_gref_log_new (
- JavaInteropGCBridge *bridge,
- jobject curHandle,
- char curType,
- jobject newHandle,
- char newType,
- const char *thread_name,
- int64_t thread_id,
- const char *from)
-{
- if (!bridge)
- return -1;
-
- int c = ++bridge->gc_weak_gref_count;
-
- WRITE_LOG_MESSAGE_RETURN(c, LOG_GREF, bridge->gref_log, from,
- "+w+ grefc %i gwrefc %i obj-handle %p/%c -> new-handle %p/%c from thread '%s'(%" PRId64 ")",
- bridge->gc_gref_count,
- bridge->gc_weak_gref_count,
- curHandle,
- curType,
- newHandle,
- newType,
- thread_name,
- thread_id);
-
- return c;
-}
-
-int
-java_interop_gc_bridge_weak_gref_log_delete (
- JavaInteropGCBridge *bridge,
- jobject handle,
- char type,
- const char *thread_name,
- int64_t thread_id,
- const char *from)
-{
- if (!bridge)
- return -1;
-
- int c = bridge->gc_weak_gref_count--;
-
- WRITE_LOG_MESSAGE_RETURN(c, LOG_GREF, bridge->gref_log, from,
- "-w- grefc %i gwrefc %i handle %p/%c from thread '%s'(%" PRId64 ")",
- bridge->gc_gref_count,
- bridge->gc_weak_gref_count,
- handle,
- type,
- thread_name,
- thread_id);
-
- return c;
-}
-
-static int
-get_gc_bridge_index (JavaInteropGCBridge *bridge, MonoClass *klass)
-{
- int i;
- int f = 0;
-
- for (i = 0; i < NUM_GC_BRIDGE_TYPES; ++i) {
- MonoClass *k = bridge->mono_java_gc_bridge_info [i].klass;
- if (k == NULL) {
- f++;
- continue;
- }
- if (klass == k || mono_class_is_subclass_of (klass, k, 0))
- return i;
- }
- return f == NUM_GC_BRIDGE_TYPES
- ? (int) -NUM_GC_BRIDGE_TYPES
- : -1;
-}
-
-static MonoJavaGCBridgeInfo *
-get_gc_bridge_info_for_class (JavaInteropGCBridge *bridge, MonoClass *klass)
-{
- int i;
-
- if (klass == NULL)
- return NULL;
-
- i = get_gc_bridge_index (bridge, klass);
- if (i < 0)
- return NULL;
- return &bridge->mono_java_gc_bridge_info [i];
-}
-
-static MonoJavaGCBridgeInfo *
-get_gc_bridge_info_for_object (JavaInteropGCBridge *bridge, MonoObject *object)
-{
- if (object == NULL)
- return NULL;
- return get_gc_bridge_info_for_class (bridge, mono_object_get_class (object));
-}
-
-static JniObjectReferenceControlBlock*
-get_gc_control_block_for_object (JavaInteropGCBridge *bridge, MonoObject *obj)
-{
- MonoJavaGCBridgeInfo *bridge_info = get_gc_bridge_info_for_object (bridge, obj);
- if (bridge_info == NULL)
- return NULL;
-
- JniObjectReferenceControlBlock *control_block;
- mono_field_get_value (obj, bridge_info->jniObjectReferenceControlBlock, &control_block);
- return control_block;
-}
-
-typedef mono_bool (*MonodroidGCTakeRefFunc) (JavaInteropGCBridge *bridge, JNIEnv *env, MonoObject *obj, const char *thread_name, int64_t thread_id);
-
-static MonodroidGCTakeRefFunc take_global_ref;
-static MonodroidGCTakeRefFunc take_weak_global_ref;
-
-static mono_bool
-take_global_ref_java (JavaInteropGCBridge *bridge, JNIEnv *env, MonoObject *obj, const char *thread_name, int64_t thread_id)
-{
- JniObjectReferenceControlBlock *control_block = get_gc_control_block_for_object (bridge, obj);
- if (control_block == NULL)
- return 0;
-
- jobject weak = control_block->weak_handle;
-
- jobject handle = env->CallObjectMethod (weak, bridge->WeakReference_get);
- log_gref (bridge, "*try_take_global_2_1 obj=%p -> wref=%p handle=%p\n", obj, weak, handle);
-
- if (handle) {
- jobject h = env->NewGlobalRef (handle);
- env->DeleteLocalRef (handle);
- handle = h;
- java_interop_gc_bridge_gref_log_new (bridge, weak, get_object_ref_type (env, weak),
- handle, get_object_ref_type (env, handle), thread_name, thread_id, "take_global_ref_java");
- }
- java_interop_gc_bridge_weak_gref_log_delete (bridge, weak, get_object_ref_type (env, weak), thread_name, thread_id, "take_global_ref_java");
- env->DeleteGlobalRef (weak);
- weak = NULL;
-
- control_block->weak_handle = weak;
- control_block->handle = handle;
- control_block->handle_type = JNIGlobalRefType;
-
- return handle != NULL;
-}
-
-static mono_bool
-take_weak_global_ref_java (JavaInteropGCBridge *bridge, JNIEnv *env, MonoObject *obj, const char *thread_name, int64_t thread_id)
-{
- JniObjectReferenceControlBlock *control_block = get_gc_control_block_for_object (bridge, obj);
- if (control_block == NULL)
- return 0;
-
- jobject handle = control_block->handle;
-
- jobject weaklocal = env->NewObject (bridge->WeakReference_class, bridge->WeakReference_init, handle);
- jobject weakglobal = env->NewGlobalRef (weaklocal);
- env->DeleteLocalRef (weaklocal);
-
- log_gref (bridge, "*take_weak_2_1 obj=%p -> wref=%p handle=%p\n", obj, weakglobal, handle);
- java_interop_gc_bridge_weak_gref_log_new (bridge, handle, get_object_ref_type (env, handle),
- weakglobal, get_object_ref_type (env, weakglobal), thread_name, thread_id, "take_weak_global_ref_2_1_compat");
-
- java_interop_gc_bridge_gref_log_delete (bridge, handle, get_object_ref_type (env, handle), thread_name, thread_id, "take_weak_global_ref_2_1_compat");
- env->DeleteGlobalRef (handle);
- control_block->handle = NULL;
- control_block->weak_handle = weakglobal;
-
- return 1;
-}
-
-static mono_bool
-take_global_ref_jni (JavaInteropGCBridge *bridge, JNIEnv *env, MonoObject *obj, const char *thread_name, int64_t thread_id)
-{
- JniObjectReferenceControlBlock *control_block = get_gc_control_block_for_object (bridge, obj);
- if (control_block == NULL)
- return 0;
-
- jobject weak = control_block->handle;
- jobject handle = env->NewGlobalRef (weak);
- log_gref (bridge, "*try_take_global obj=%p -> wref=%p handle=%p\n", obj, weak, handle);
-
- if (handle) {
- java_interop_gc_bridge_gref_log_new (bridge, weak, get_object_ref_type (env, weak),
- handle, get_object_ref_type (env, handle),
- thread_name, thread_id,
- "take_global_ref_jni");
- }
-
- java_interop_gc_bridge_weak_gref_log_delete (bridge, weak, 'W',
- thread_name, thread_id, "take_global_ref_jni");
- env->DeleteWeakGlobalRef (weak);
-
- control_block->handle = handle;
- control_block->handle_type = JNIGlobalRefType;
-
- return handle != NULL;
-}
-
-static mono_bool
-take_weak_global_ref_jni (JavaInteropGCBridge *bridge, JNIEnv *env, MonoObject *obj, const char *thread_name, int64_t thread_id)
-{
- JniObjectReferenceControlBlock *control_block = get_gc_control_block_for_object (bridge, obj);
- if (control_block == NULL)
- return 0;
-
- jobject handle = control_block->handle;
-
- log_gref (bridge, "*take_weak obj=%p; handle=%p\n", obj, handle);
-
- jobject weak = env->NewWeakGlobalRef (handle);
- java_interop_gc_bridge_weak_gref_log_new (bridge, handle, get_object_ref_type (env, handle),
- weak, get_object_ref_type (env, weak),
- thread_name, thread_id, "take_weak_global_ref_jni");
-
- java_interop_gc_bridge_gref_log_delete (bridge, handle, get_object_ref_type (env, handle),
- thread_name, thread_id, "take_weak_global_ref_jni");
- env->DeleteGlobalRef (handle);
-
- control_block->handle = weak;
- control_block->handle_type = JNIWeakGlobalRefType;
-
- return 1;
-}
-
-static jmethodID
-get_add_reference_method (JavaInteropGCBridge *bridge, JNIEnv *env, jobject obj, [[maybe_unused]] MonoClass *mclass)
-{
- if (!obj)
- return NULL;
- if (bridge->GCUserPeerable_class && env->IsInstanceOf (obj, bridge->GCUserPeerable_class)) {
- return bridge->GCUserPeerable_add;
- }
- jclass klass = env->GetObjectClass (obj);
- jmethodID add = env->GetMethodID (klass, "monodroidAddReference", "(Ljava/lang/Object;)V");
- if (!add)
- env->ExceptionClear ();
- env->DeleteLocalRef (klass);
- return add;
-}
-
-static mono_bool
-add_reference (JavaInteropGCBridge *bridge, JNIEnv *env, MonoObject *obj, JniObjectReferenceControlBlock *control_block, MonoObject *reffed_obj)
-{
- MonoClass *klass = mono_object_get_class (obj);
-
- jobject handle = control_block->handle;
-
- jmethodID add_method_id = get_add_reference_method (bridge, env, handle, klass);
- if (add_method_id) {
- JniObjectReferenceControlBlock *reffed_control_block = get_gc_control_block_for_object (bridge, reffed_obj);
- if (reffed_control_block == NULL)
- return 0;
- jobject reffed_handle = reffed_control_block->handle;
- env->CallVoidMethod (handle, add_method_id, reffed_handle);
-#if DEBUG
- if (bridge->gref_log_level > 1)
- log_gref (bridge,
- "added reference for object of class %s.%s to object of class %s.%s\n",
- mono_class_get_namespace (klass),
- mono_class_get_name (klass),
- mono_class_get_namespace (mono_object_get_class (reffed_obj)),
- mono_class_get_name (mono_object_get_class (reffed_obj)));
-#endif
- return 1;
- }
-
-#if DEBUG
- if (bridge->gref_log_level > 1)
- log_gref (bridge,
- "Missing monodroidAddReference method for object of class %s.%s\n",
- mono_class_get_namespace (klass),
- mono_class_get_name (klass));
-#endif
-
- return 0;
-}
-
-static void
-set_bridge_processing (JavaInteropGCBridge *bridge, mono_bool value)
-{
- int count = bridge->BridgeProcessing_vtables_count;
- for (int i = 0; i < count; ++i) {
- MonoVTable *v = bridge->BridgeProcessing_vtables [i];
- if (!v) {
- continue;
- }
-
- mono_field_static_set_value (v, bridge->BridgeProcessing_field, &value);
- }
-}
-
-static void
-gc_prepare_for_java_collection (JavaInteropGCBridge *bridge, JNIEnv *env, int num_sccs, MonoGCBridgeSCC **sccs, int num_xrefs, MonoGCBridgeXRef *xrefs, const char *thread_name, int64_t thread_id)
-{
- set_bridge_processing (bridge, 1);
-
- int ref_val = 1;
- /* add java refs for items on the list which reference each other */
- for (int i = 0; i < num_sccs; i++) {
- MonoGCBridgeSCC *scc = sccs [i];
-
- JniObjectReferenceControlBlock *control_block = NULL;
-
- /* start at the second item, ref j from j-1 */
- for (int j = 1; j < scc->num_objs; j++) {
- control_block = get_gc_control_block_for_object (bridge, scc->objs [j-1]);
- if (control_block != NULL && add_reference (bridge, env, scc->objs [j-1], control_block, scc->objs [j])) {
- control_block->refs_added = ref_val;
- }
- }
- /* ref the first from the last */
- if (scc->num_objs > 1) {
- control_block = get_gc_control_block_for_object (bridge, scc->objs [scc->num_objs-1]);
- if (control_block != NULL && add_reference (bridge, env, scc->objs [scc->num_objs-1], control_block, scc->objs [0])) {
- control_block->refs_added = ref_val;
- }
- }
- }
-
- /* add the cross scc refs */
- for (int i = 0; i < num_xrefs; i++) {
- JniObjectReferenceControlBlock *control_block = get_gc_control_block_for_object (bridge, sccs [xrefs [i].src_scc_index]->objs [0]);
- if (control_block != NULL && add_reference (bridge, env, sccs [xrefs [i].src_scc_index]->objs [0], control_block, sccs [xrefs [i].dst_scc_index]->objs [0])) {
- control_block->refs_added = ref_val;
- }
- }
-
- // switch to weak refs
- for (int i = 0; i < num_sccs; i++)
- for (int j = 0; j < sccs [i]->num_objs; j++)
- take_weak_global_ref (bridge, env, sccs [i]->objs [j], thread_name, thread_id);
-}
-
-static jmethodID
-get_clear_references_method (JavaInteropGCBridge *bridge, JNIEnv *env, jobject obj)
-{
- if (!obj)
- return NULL;
- if (bridge->GCUserPeerable_class && env->IsInstanceOf (obj, bridge->GCUserPeerable_class)) {
- return bridge->GCUserPeerable_clear;
- }
- jclass klass = env->GetObjectClass (obj);
- jmethodID clear = env->GetMethodID (klass, "monodroidClearReferences", "()V");
- if (!clear)
- env->ExceptionClear ();
- env->DeleteLocalRef (klass);
- return clear;
-}
-
-static void
-gc_cleanup_after_java_collection (JavaInteropGCBridge *bridge, JNIEnv *env, int num_sccs, MonoGCBridgeSCC **sccs, const char *thread_name, int64_t thread_id)
-{
- int total = 0;
- int alive = 0;
-
- for (int i = 0; i < num_sccs; i++)
- for (int j = 0; j < sccs [i]->num_objs; j++, total++)
- take_global_ref (bridge, env, sccs [i]->objs [j], thread_name, thread_id);
-
- /* clear the cross references on any remaining items */
- for (int i = 0; i < num_sccs; i++) {
- sccs [i]->is_alive = 0;
- for (int j = 0; j < sccs [i]->num_objs; j++) {
- MonoObject *obj = sccs [i]->objs [j];
-
- JniObjectReferenceControlBlock *control_block = get_gc_control_block_for_object (bridge, obj);
- if (control_block == NULL)
- continue;
-
- jobject jref = control_block->handle;
- if (jref) {
- alive++;
- if (j > 0)
- assert (sccs [i]->is_alive);
- sccs [i]->is_alive = 1;
- int refs_added = control_block->refs_added;
- if (refs_added) {
- jmethodID clear_method_id = get_clear_references_method (bridge, env, jref);
- if (clear_method_id) {
- env->CallVoidMethod (jref, clear_method_id);
- } else {
-#if DEBUG
- if (bridge->gref_log_level > 1) {
- MonoClass *klass = mono_object_get_class (obj);
- log_gref (bridge,
- "Missing monodroidClearReferences method for object of class %s.%s\n",
- mono_class_get_namespace (klass),
- mono_class_get_name (klass));
- }
-#endif
- }
- }
- } else {
- assert (!sccs [i]->is_alive);
- }
- }
- }
-#if DEBUG
- log_gref (bridge, "GC cleanup summary: %d objects tested - resurrecting %d.\n", total, alive);
-#endif
-
- set_bridge_processing (bridge, 0);
-}
-
-static void
-java_gc (JavaInteropGCBridge *bridge, JNIEnv *env)
-{
- env->CallVoidMethod (bridge->Runtime_instance, bridge->Runtime_gc);
-}
-
-int
-java_interop_gc_bridge_add_current_app_domain (JavaInteropGCBridge *bridge)
-{
- if (bridge == NULL)
- return -1;
-
- if (bridge->BridgeProcessing_type == NULL)
- return -1;
-
- MonoDomain *domain = mono_domain_get ();
- if (domain == NULL)
- return -1;
-
- int count = bridge->BridgeProcessing_vtables_count;
- for (int i = 0; i < count; ++i) {
- MonoDomain **domains = bridge->BridgeProcessing_domains;
- MonoVTable **vtables = bridge->BridgeProcessing_vtables;
- if (domains [i] == NULL) {
- domains [i] = domain;
- vtables [i] = mono_class_vtable (domain, bridge->BridgeProcessing_type);
- return 0;
- }
- }
-
- if (bridge->BridgeProcessing_vtables_count == bridge->BridgeProcessing_vtables_length) {
- int new_length = bridge->BridgeProcessing_vtables_length + 1;
- MonoDomain **new_domains = static_cast(calloc (new_length, sizeof (MonoDomain*)));
- MonoVTable **new_vtbles = static_cast(calloc (new_length, sizeof (MonoVTable*)));
- if (new_domains == NULL || new_vtbles == NULL) {
- free (new_domains);
- free (new_vtbles);
- return -1;
- }
- bridge->BridgeProcessing_vtables_length = new_length;
- memcpy (new_domains, bridge->BridgeProcessing_domains, bridge->BridgeProcessing_vtables_count);
- memcpy (new_vtbles, bridge->BridgeProcessing_vtables, bridge->BridgeProcessing_vtables_count);
- free (bridge->BridgeProcessing_domains);
- free (bridge->BridgeProcessing_vtables);
- bridge->BridgeProcessing_domains = new_domains;
- bridge->BridgeProcessing_vtables = new_vtbles;
- }
- int i = bridge->BridgeProcessing_vtables_count++;
-
- bridge->BridgeProcessing_domains [i] = domain;
- bridge->BridgeProcessing_vtables [i] = mono_class_vtable (domain, bridge->BridgeProcessing_type);
-
- return 0;
-}
-
-int
-java_interop_gc_bridge_remove_current_app_domain (JavaInteropGCBridge *bridge)
-{
- if (bridge == NULL)
- return -1;
-
- MonoDomain *domain = mono_domain_get ();
- if (domain == NULL)
- return -1;
-
- int count = bridge->BridgeProcessing_vtables_count;
- for (int i = 0; i < count; ++i) {
- if (bridge->BridgeProcessing_domains [i] == domain) {
- bridge->BridgeProcessing_domains [i] = NULL;
- bridge->BridgeProcessing_vtables [i] = NULL;
- return 0;
- }
- }
- return -1;
-}
-
-static JavaInteropGCBridge *mono_bridge;
-
-JavaInteropGCBridge*
-java_interop_gc_bridge_get_current (void)
-{
- return mono_bridge;
-}
-
-int
-java_interop_gc_bridge_set_current_once (JavaInteropGCBridge *bridge)
-{
- if (bridge == NULL)
- return -1;
- mono_bridge = bridge;
- return 0;
-}
-
-static MonoGCBridgeObjectKind
-gc_bridge_class_kind (MonoClass *klass)
-{
- int i;
- if (mono_bridge->gc_disabled)
- return MonoGCBridgeObjectKind::GC_BRIDGE_TRANSPARENT_CLASS;
-
- i = get_gc_bridge_index (mono_bridge, klass);
- if (i == -NUM_GC_BRIDGE_TYPES) {
- log_gref (mono_bridge,
- "asked if a class %s.%s is a bridge before we inited GC Bridge Types!\n",
- mono_class_get_namespace (klass),
- mono_class_get_name (klass));
- return MonoGCBridgeObjectKind::GC_BRIDGE_TRANSPARENT_CLASS;
- }
-
- if (i >= 0) {
- return MonoGCBridgeObjectKind::GC_BRIDGE_TRANSPARENT_BRIDGE_CLASS;
- }
-
- return MonoGCBridgeObjectKind::GC_BRIDGE_TRANSPARENT_CLASS;
-}
-
-static mono_bool
-gc_is_bridge_object (MonoObject *object)
-{
-
- JniObjectReferenceControlBlock *control_block = get_gc_control_block_for_object (mono_bridge, object);
- if (control_block == NULL)
- return 0;;
-
- void *handle = control_block->handle;
- if (handle == NULL) {
-#if DEBUG
- MonoClass *mclass = mono_object_get_class (object);
- log_gref (mono_bridge,
- "object of class %s.%s with null handle\n",
- mono_class_get_namespace (mclass),
- mono_class_get_name (mclass));
-#endif
- return 0;
- }
-
- return 1;
-}
-
-static char *
-get_thread_name (void)
-{
- MonoThread *thread = mono_thread_current ();
- return mono_thread_get_name_utf8 (thread);
-}
-
-static int64_t
-get_thread_id (void)
-{
- MonoThread *thread = mono_thread_current ();
- return mono_thread_get_managed_id (thread);
-}
-
-static void
-gc_cross_references (int num_sccs, MonoGCBridgeSCC **sccs, int num_xrefs, MonoGCBridgeXRef *xrefs)
-{
- if (mono_bridge->gc_disabled)
- return;
-
- JavaInteropGCBridge *bridge = mono_bridge;
-
- char *thread_name = get_thread_name ();
- int64_t thread_id = get_thread_id ();
-
-#if DEBUG
- if (bridge->gref_log_level > 1) {
- log_gref (bridge, "cross references callback invoked with %d sccs and %d xrefs.\n", num_sccs, num_xrefs);
-
- for (int i = 0; i < num_sccs; ++i) {
- log_gref (bridge, "group %d with %d objects\n", i, sccs [i]->num_objs);
- for (int j = 0; j < sccs [i]->num_objs; ++j) {
- MonoObject *obj = sccs [i]->objs [j];
- MonoClass *klass = mono_object_get_class (obj);
- log_gref (bridge,
- "\tobj %p [%s::%s]\n",
- obj,
- mono_class_get_namespace (klass),
- mono_class_get_name (klass));
- }
- }
-
- for (int i = 0; i < num_xrefs; ++i)
- log_gref (bridge, "xref [%d] %d -> %d\n", i, xrefs [i].src_scc_index, xrefs [i].dst_scc_index);
- }
-#endif
-
- JNIEnv *env = ensure_jnienv (bridge);
- if (env != NULL) {
- gc_prepare_for_java_collection (bridge, env, num_sccs, sccs, num_xrefs, xrefs, thread_name, thread_id);
- java_gc (bridge, env);
- gc_cleanup_after_java_collection (bridge, env, num_sccs, sccs, thread_name, thread_id);
- }
-
- free (thread_name);
-}
-
-static void
-managed_gc_cross_references (int num_sccs, MonoGCBridgeSCC **sccs, int num_xrefs, MonoGCBridgeXRef *xrefs)
-{
- if (mono_bridge->mark_cross_references == NULL) {
- assert (!"mono_bridge->mark_cross_references is NULL; WE SHOULD NOT BE EXECUTING");
- return;
- }
- int i;
-
- Srij_MarkCrossReferences cross_references = {};
-
- cross_references.ComponentsLen = (void*) (intptr_t) num_sccs;
- cross_references.Components = (Srij_StronglyConnectedComponent*) calloc (num_sccs, sizeof (Srij_StronglyConnectedComponent));
- for (i = 0; i < num_sccs; ++i) {
- Srij_StronglyConnectedComponent *scc = &cross_references.Components [i];
-
- scc->Count = (void*) (intptr_t) sccs [i]->num_objs;
- scc->Context = (void**) calloc (sccs [i]->num_objs, sizeof (void*));
- for (int j = 0; j < sccs [i]->num_objs; ++j) {
- MonoObject *obj = sccs [i]->objs [j];
- scc->Context [j] = get_gc_control_block_for_object (mono_bridge, obj);
- }
- }
-
- cross_references.CrossReferencesLen = (void*) (intptr_t) num_xrefs;
- cross_references.CrossReferences = (Srij_ComponentCrossReference*) calloc (num_xrefs, sizeof (Srij_ComponentCrossReference));
- for (i = 0; i < num_xrefs; ++i) {
- Srij_ComponentCrossReference *xref = &cross_references.CrossReferences [i];
- xref->SourceGroupIndex = (void*) (intptr_t) xrefs [i].src_scc_index;
- xref->DestinationGroupIndex = (void*) (intptr_t) xrefs [i].dst_scc_index;
- }
-
- mono_bridge->mark_cross_references (&cross_references);
-
- for (i = 0; i < num_sccs; ++i) {
- Srij_StronglyConnectedComponent *scc = &cross_references.Components [i];
- sccs [i]->is_alive = scc->IsAlive;
- }
-}
-
-int
-java_interop_gc_bridge_register_hooks (JavaInteropGCBridge *bridge, int weak_ref_kind)
-{
- if (bridge == NULL)
- return -1;
- if (mono_bridge != bridge)
- return -1;
-
- const char *message = NULL;
-
- MonoGCBridgeCallbacks bridge_cbs;
- memset (&bridge_cbs, 0, sizeof (bridge_cbs));
-
- switch (weak_ref_kind) {
- case JAVA_INTEROP_GC_BRIDGE_USE_WEAK_REFERENCE_KIND_JAVA:
- message = "Using java.lang.ref.WeakReference for JNI Weak References.";
- take_global_ref = take_global_ref_java;
- take_weak_global_ref = take_weak_global_ref_java;
- break;
- case JAVA_INTEROP_GC_BRIDGE_USE_WEAK_REFERENCE_KIND_JNI:
- message = "Using JNIEnv::NewWeakGlobalRef() for JNI Weak References.";
- take_global_ref = take_global_ref_jni;
- take_weak_global_ref = take_weak_global_ref_jni;
- break;
- default:
- return -1;
- }
-
- log_gref (mono_bridge, "%s\n", message);
-
- bridge_cbs.bridge_version = SGEN_BRIDGE_VERSION;
- bridge_cbs.bridge_class_kind = gc_bridge_class_kind;
- bridge_cbs.is_bridge_object = gc_is_bridge_object;
- bridge_cbs.cross_references = bridge->mark_cross_references
- ? managed_gc_cross_references
- : gc_cross_references;
-
- mono_gc_register_bridge_callbacks (&bridge_cbs);
-
- return 0;
-}
-
-int
-java_interop_gc_bridge_wait_for_bridge_processing (JavaInteropGCBridge *bridge)
-{
- if (bridge == NULL)
- return -1;
-
- mono_gc_wait_for_bridge_processing ();
- return 0;
-}
-
-int
-java_interop_gc_bridge_set_mark_cross_references (JavaInteropGCBridge *bridge, JavaInteropMarkCrossReferencesCallback markCrossReferences)
-{
- if (bridge == NULL)
- return -1;
-
- bridge->mark_cross_references = markCrossReferences;
-
- return 0;
-}
-
-int
-java_interop_gc_bridge_release_mark_cross_references_resources (JavaInteropGCBridge *bridge, Srij_MarkCrossReferences *crossReferences)
-{
- if (bridge == NULL || crossReferences == NULL)
- return -1;
-
- // leak it…
- return 0;
-}
diff --git a/src/java-interop/java-interop-gc-bridge.h b/src/java-interop/java-interop-gc-bridge.h
deleted file mode 100644
index 6715b33be..000000000
--- a/src/java-interop/java-interop-gc-bridge.h
+++ /dev/null
@@ -1,85 +0,0 @@
-#ifndef INC_JAVA_INTEROP_GC_BRIDGE_H
-#define INC_JAVA_INTEROP_GC_BRIDGE_H
-
-#include
-#include "java-interop.h"
-
-#include
-
-JAVA_INTEROP_BEGIN_DECLS
-
-typedef struct JavaInteropGCBridge JavaInteropGCBridge;
-
-typedef enum JavaInteropGCBridgeUseWeakReferenceKind {
- JAVA_INTEROP_GC_BRIDGE_USE_WEAK_REFERENCE_KIND_JAVA,
- JAVA_INTEROP_GC_BRIDGE_USE_WEAK_REFERENCE_KIND_JNI,
-} JavaInteropGCBridgeUseWeakReferenceKind;
-
-struct JavaInterop_System_RuntimeTypeHandle {
- void *value;
-};
-
-typedef struct Srij_ComponentCrossReference {
- void *SourceGroupIndex;
- void *DestinationGroupIndex;
-} Srij_ComponentCrossReference;
-
-typedef struct Srij_StronglyConnectedComponent {
- int IsAlive;
- void *Count;
- void **Context;
-} Srij_StronglyConnectedComponent;
-
-typedef struct Srij_MarkCrossReferences {
- void *ComponentsLen;
- Srij_StronglyConnectedComponent *Components;
- void* CrossReferencesLen;
- Srij_ComponentCrossReference *CrossReferences;
-} Srij_MarkCrossReferences;
-
-typedef void (*JavaInteropMarkCrossReferencesCallback) (Srij_MarkCrossReferences *crossReferences);
-
-JAVA_INTEROP_API JavaInteropGCBridge *java_interop_gc_bridge_get_current (void);
-JAVA_INTEROP_API int java_interop_gc_bridge_set_current_once (JavaInteropGCBridge *bridge);
-
-JAVA_INTEROP_API JavaInteropGCBridge *java_interop_gc_bridge_new (JavaVM *jvm);
-JAVA_INTEROP_API int java_interop_gc_bridge_free (JavaInteropGCBridge *bridge);
-
-JAVA_INTEROP_API int java_interop_gc_bridge_register_hooks (JavaInteropGCBridge *bridge, int weak_ref_kind);
-JAVA_INTEROP_API int java_interop_gc_bridge_wait_for_bridge_processing (JavaInteropGCBridge *bridge);
-
-JAVA_INTEROP_API int java_interop_gc_bridge_add_current_app_domain (JavaInteropGCBridge *bridge);
-JAVA_INTEROP_API int java_interop_gc_bridge_remove_current_app_domain (JavaInteropGCBridge *bridge);
-
-JAVA_INTEROP_API int java_interop_gc_bridge_set_bridge_processing_field (JavaInteropGCBridge *bridge, struct JavaInterop_System_RuntimeTypeHandle type_handle, char *field_name);
-
-JAVA_INTEROP_API int java_interop_gc_bridge_set_mark_cross_references (JavaInteropGCBridge *bridge, JavaInteropMarkCrossReferencesCallback markCrossReferences);
-JAVA_INTEROP_API int java_interop_gc_bridge_release_mark_cross_references_resources (JavaInteropGCBridge *bridge, Srij_MarkCrossReferences *crossReferences);
-
-JAVA_INTEROP_API int java_interop_gc_bridge_register_bridgeable_type (JavaInteropGCBridge *bridge, struct JavaInterop_System_RuntimeTypeHandle type_handle);
-JAVA_INTEROP_API int java_interop_gc_bridge_enable (JavaInteropGCBridge *bridge, int enable);
-
-JAVA_INTEROP_API int java_interop_gc_bridge_get_gref_count (JavaInteropGCBridge *bridge);
-JAVA_INTEROP_API int java_interop_gc_bridge_get_weak_gref_count (JavaInteropGCBridge *bridge);
-
-JAVA_INTEROP_API int java_interop_gc_bridge_lref_set_log_file (JavaInteropGCBridge *bridge, const char *gref_log_file);
-JAVA_INTEROP_API FILE* java_interop_gc_bridge_lref_get_log_file (JavaInteropGCBridge *bridge);
-JAVA_INTEROP_API int java_interop_gc_bridge_lref_set_log_level (JavaInteropGCBridge *bridge, int level);
-JAVA_INTEROP_API void java_interop_gc_bridge_lref_log_message (JavaInteropGCBridge *bridge, int level, const char *message);
-JAVA_INTEROP_API void java_interop_gc_bridge_lref_log_new (JavaInteropGCBridge *bridge, int lref_count, jobject curHandle, char curType, jobject newHandle, char newType, const char *thread_name, int64_t thread_id, const char *from);
-JAVA_INTEROP_API void java_interop_gc_bridge_lref_log_delete (JavaInteropGCBridge *bridge, int lref_count, jobject handle, char type, const char *thread_name, int64_t thread_id, const char *from);
-
-JAVA_INTEROP_API int java_interop_gc_bridge_gref_set_log_file (JavaInteropGCBridge *bridge, const char *gref_log_file);
-JAVA_INTEROP_API FILE* java_interop_gc_bridge_gref_get_log_file (JavaInteropGCBridge *bridge);
-JAVA_INTEROP_API int java_interop_gc_bridge_gref_set_log_level (JavaInteropGCBridge *bridge, int level);
-JAVA_INTEROP_API void java_interop_gc_bridge_gref_log_message (JavaInteropGCBridge *bridge, int level, const char *message);
-JAVA_INTEROP_API int java_interop_gc_bridge_gref_log_new (JavaInteropGCBridge *bridge, jobject curHandle, char curType, jobject newHandle, char newType, const char *thread_name, int64_t thread_id, const char *from);
-JAVA_INTEROP_API int java_interop_gc_bridge_gref_log_delete (JavaInteropGCBridge *bridge, jobject handle, char type, const char *thread_name, int64_t thread_id, const char *from);
-
-JAVA_INTEROP_API int java_interop_gc_bridge_weak_gref_log_new (JavaInteropGCBridge *bridge, jobject curHandle, char curType, jobject newHandle, char newType, const char *thread_name, int64_t thread_id, const char *from);
-JAVA_INTEROP_API int java_interop_gc_bridge_weak_gref_log_delete (JavaInteropGCBridge *bridge, jobject handle, char type, const char *thread_name, int64_t thread_id, const char *from);
-
-JAVA_INTEROP_END_DECLS
-
-#endif /* ndef INC_JAVA_INTEROP_GC_BRIDGE_H */
-
diff --git a/src/java-interop/java-interop-jvm.cc b/src/java-interop/java-interop-jvm.cc
deleted file mode 100644
index 48132f02c..000000000
--- a/src/java-interop/java-interop-jvm.cc
+++ /dev/null
@@ -1,100 +0,0 @@
-#include
-
-#include "java-interop-jvm.h"
-#include "java-interop-dlfcn.h"
-#include "java-interop-logger.h"
-#include "java-interop-util.h"
-
-using namespace microsoft::java_interop;
-
-typedef int (JNICALL *java_interop_JNI_CreateJavaVM_fptr) (JavaVM **p_vm, void **p_env, void *vm_args);
-typedef int (JNICALL *java_interop_JNI_GetCreatedJavaVMs_fptr) (JavaVM **vmBuf, int bufLen, int *nVMs);
-
-struct DylibJVM {
- void *dl_handle;
- java_interop_JNI_CreateJavaVM_fptr JNI_CreateJavaVM;
- java_interop_JNI_GetCreatedJavaVMs_fptr JNI_GetCreatedJavaVMs;
-};
-
-static struct DylibJVM *jvm;
-
-int
-java_interop_jvm_load_with_error_message (const char *path, char **error_message)
-{
- if (error_message) {
- *error_message = NULL;
- }
-
- if (jvm != NULL) {
- return JAVA_INTEROP_JVM_FAILED_ALREADY_LOADED;
- }
-
- jvm = static_cast(calloc (1, sizeof (DylibJVM)));
- if (!jvm) {
- return JAVA_INTEROP_JVM_FAILED_OOM;
- }
-
- char *error = nullptr;
- jvm->dl_handle = java_interop_lib_load (path, JAVA_INTEROP_LIB_LOAD_LOCALLY, &error);
- if (!jvm->dl_handle) {
- if (error_message) {
- *error_message = error;
- error = nullptr;
- }
- java_interop_free (error);
- free (jvm);
- jvm = NULL;
- return JAVA_INTEROP_JVM_FAILED_NOT_LOADED;
- }
-
- int symbols_missing = 0;
-
-#define LOAD_SYMBOL_CAST(symbol, Type) do { \
- error = nullptr; \
- jvm->symbol = reinterpret_cast(java_interop_lib_symbol (jvm->dl_handle, #symbol, &error)); \
- if (!jvm->symbol) { \
- log_error (LOG_DEFAULT, "Failed to load JVM symbol: %s: %s", #symbol, error); \
- symbols_missing = 1; \
- java_interop_free (error); \
- error = nullptr; \
- } \
- } while (0)
-#define LOAD_SYMBOL(symbol) LOAD_SYMBOL_CAST(symbol, java_interop_ ## symbol ## _fptr)
-
- LOAD_SYMBOL(JNI_CreateJavaVM);
- LOAD_SYMBOL(JNI_GetCreatedJavaVMs);
-
-#undef LOAD_SYMBOL_CAST
-#undef LOAD_SYMBOL
-
- if (symbols_missing) {
- java_interop_lib_close (jvm->dl_handle, nullptr);
- free (jvm);
- jvm = NULL;
- return JAVA_INTEROP_JVM_FAILED_SYMBOL_MISSING;
- }
-
- return 0;
-}
-
-int
-java_interop_jvm_load (const char *path)
-{
- return java_interop_jvm_load_with_error_message (path, NULL);
-}
-
-#define ji_return_val_if_fail(expr, val) do { if (!(expr)) return (val); } while (0)
-
-int java_interop_jvm_create (JavaVM **p_vm, void **p_env, void *vm_args)
-{
- ji_return_val_if_fail (jvm != NULL, JAVA_INTEROP_JVM_FAILED_NOT_LOADED);
-
- return (*jvm->JNI_CreateJavaVM) (p_vm, p_env, vm_args);
-}
-
-int java_interop_jvm_list (JavaVM **vmBuf, int bufLen, int *nVMs)
-{
- ji_return_val_if_fail (jvm != NULL, JAVA_INTEROP_JVM_FAILED_NOT_LOADED);
-
- return (*jvm->JNI_GetCreatedJavaVMs) (vmBuf, bufLen, nVMs);
-}
diff --git a/src/java-interop/java-interop-jvm.h b/src/java-interop/java-interop-jvm.h
deleted file mode 100644
index 1086a92fb..000000000
--- a/src/java-interop/java-interop-jvm.h
+++ /dev/null
@@ -1,24 +0,0 @@
-#ifndef INC_JAVA_INTEROP_JVM_H
-#define INC_JAVA_INTEROP_JVM_H
-
-#include
-
-#include "java-interop.h"
-
-JAVA_INTEROP_BEGIN_DECLS
-
-#define JAVA_INTEROP_JVM_FAILED (-1000)
-#define JAVA_INTEROP_JVM_FAILED_ALREADY_LOADED (JAVA_INTEROP_JVM_FAILED-1)
-#define JAVA_INTEROP_JVM_FAILED_NOT_LOADED (JAVA_INTEROP_JVM_FAILED-2)
-#define JAVA_INTEROP_JVM_FAILED_OOM (JAVA_INTEROP_JVM_FAILED-3)
-#define JAVA_INTEROP_JVM_FAILED_SYMBOL_MISSING (JAVA_INTEROP_JVM_FAILED-4)
-
-JAVA_INTEROP_API int java_interop_jvm_load (const char *path);
-JAVA_INTEROP_API int java_interop_jvm_load_with_error_message (const char *path, char **error);
-JAVA_INTEROP_API int java_interop_jvm_create (JavaVM **p_vm, void **p_env, void *vm_args);
-JAVA_INTEROP_API int java_interop_jvm_list (JavaVM **vmBuf, int bufLen, int *nVMs);
-
-JAVA_INTEROP_END_DECLS
-
-
-#endif /* ndef INC_JAVA_INTEROP_JVM_H */
diff --git a/src/java-interop/java-interop-logger.cc b/src/java-interop/java-interop-logger.cc
deleted file mode 100644
index 14fc4fe65..000000000
--- a/src/java-interop/java-interop-logger.cc
+++ /dev/null
@@ -1,98 +0,0 @@
-#include
-#include
-
-#ifndef _MSC_VER
-#include
-#endif // ndef _MSC_VER
-
-#include "java-interop-logger.h"
-
-#define LOG_VA_ARGS(_kind_,_category_,_format_) \
- do { \
- const char* _kind = (_kind_); \
- LogCategories _cat = (_category_); \
- va_list args; \
- va_start (args, _format_); \
- log_vprint (_kind, CATEGORY_NAME (_cat), (_format_), args); \
- va_end (args); \
- } while (0)
-
-// Must match the same ordering as LogCategories
-static const char* log_names[] = {
- "*none*",
- "javainterop",
- "javainterop-assembly",
- "javainterop-debug",
- "javainterop-gc",
- "javainterop-gref",
- "javainterop-lref",
- "javainterop-timing",
- "javainterop-bundle",
- "javainterop-network",
- "javainterop-netlink",
- "*error*",
-};
-
-#if defined(_MSC_VER)
-#pragma intrinsic(_BitScanForward)
-static inline unsigned long ffs (unsigned long value)
-{
- unsigned long index;
- unsigned char isNonzero = _BitScanForward (&index, value);
- return isNonzero ? (index + 1) : 0;
-}
-#elif defined(__i386__) && defined(__GNUC__)
-#define ffs(__value__) __builtin_ffs ((__value__))
-#elif defined(__x86_64__) && defined(__GNUC__)
-#define ffs(__value__) __builtin_ffsll ((__value__))
-#endif
-
-// ffs(value) returns index of lowest bit set in `value`
-#define CATEGORY_NAME(value) (value == 0 ? log_names [0] : log_names [ffs (value)])
-
-static void
-log_vprint (const char* kind, const char* tag, const char* fmt, va_list ap)
-{
- printf ("%s: [%s] ", kind, tag);
- vprintf (fmt, ap);
- putchar ('\n');
- fflush (stdout);
-}
-
-unsigned int log_categories = 0xFFFFFFFF;
-
-void
-log_error (LogCategories category, const char *format, ...)
-{
- LOG_VA_ARGS ("error", category, format);
-}
-
-void
-log_fatal (LogCategories category, const char *format, ...)
-{
- LOG_VA_ARGS ("fatal error", category, format);
-}
-
-void
-log_info_nocheck (LogCategories category, const char *format, ...)
-{
- if ((log_categories & category) == 0)
- return;
-
- LOG_VA_ARGS ("info", category, format);
-}
-
-void
-log_warn (LogCategories category, const char *format, ...)
-{
- LOG_VA_ARGS ("warning", category, format);
-}
-
-void
-log_debug_nocheck (LogCategories category, const char *format, ...)
-{
- if ((log_categories & category) == 0)
- return;
-
- LOG_VA_ARGS ("debug", category, format);
-}
diff --git a/src/java-interop/java-interop.csproj b/src/java-interop/java-interop.csproj
index 99d8d778f..4f1c20e46 100644
--- a/src/java-interop/java-interop.csproj
+++ b/src/java-interop/java-interop.csproj
@@ -1,35 +1,17 @@
-
+
$(DotNetTargetFramework)
- java-interop
- JI_DLL_EXPORT MONODEVELOP JAVA_INTEROP_DLL_EXPORT
- .
+ false
+ $(BaseIntermediateOutputPath)$(Configuration)\$(TargetFramework.ToLowerInvariant())\
$(ToolOutputFullPath)
- $(BuildToolOutputFullPath)
-
-
-
- DEBUG $(DefineConstants)
-
-
-
- 3
-
-
-
-
-
-
-
-
8.0.13
@@ -43,4 +25,4 @@
-
\ No newline at end of file
+
diff --git a/src/java-interop/java-interop.targets b/src/java-interop/java-interop.targets
index 9d35aaa47..b778afa15 100644
--- a/src/java-interop/java-interop.targets
+++ b/src/java-interop/java-interop.targets
@@ -3,25 +3,13 @@
- <_JavaInteropLibName Condition=" $([MSBuild]::IsOSPlatform ('osx')) ">libjava-interop.dylib
- <_JavaInteropLibName Condition=" $([MSBuild]::IsOSPlatform ('linux')) ">libjava-interop.so
- <_JavaInteropLibName Condition=" $([MSBuild]::IsOSPlatform ('windows')) ">java-interop.dll
+ <_JavaInteropValidationLibName Condition=" $([MSBuild]::IsOSPlatform ('windows')) ">java-interop-validation.lib
+ <_JavaInteropValidationLibName Condition=" '$(_JavaInteropValidationLibName)' == '' ">libjava-interop-validation.a
-
-
- PreserveNewest
- $(_JavaInteropLibName)
-
-
-
-
-
-
-
-
-
+ <_JavaInteropValidationSource Include="*.cc" />
+ <_JavaInteropValidationHeader Include="*.h" />
@@ -37,31 +25,19 @@
<_MonoNativePath>$(NuGetPackageRoot)microsoft.netcore.app.runtime.mono.$(NETCoreSdkRuntimeIdentifier)/$(DotNetRuntimePacksVersion)/runtimes/$(NETCoreSdkRuntimeIdentifier)/native/
<_MonoIncludePath>$(_MonoNativePath)include/mono-2.0
- <_DEnableMono>-DENABLE_MONO_INTEGRATION=ON
<_DEnableOsxArchitectures Condition=" $([MSBuild]::IsOSPlatform ('osx')) ">"-DENABLE_OSX_ARCHITECTURES=$(_CmakeOsxArch)"
<_DMonoDirs>"-DMONO_INCLUDE_LIST=$(_MonoIncludePath)"
- <_DJdkDirs>"-DJDK_INCLUDE_LIST=@(JdkIncludePath, ';')"
- <_DJni_c>"-DJNI_C_PATH=$(MSBuildThisFileDirectory)$(IntermediateOutputPath)jni.c"
- <_MonoLinkFlags Condition=" $([MSBuild]::IsOSPlatform ('windows')) " >$(MSBuildThisFileDirectory)coreclr.lib
- <_MonoLinkFlags Condition=" !$([MSBuild]::IsOSPlatform ('windows')) ">-L $(_MonoNativePath) -lcoreclr
- <_DMonoLinkFlags>"-DMONO_LINK_FLAGS=$(_MonoLinkFlags)"
- <_ExtraArgs>$([MSBuild]::Escape('$(_DJdkDirs) $(_DJni_c) $(_DEnableMono) $(_DMonoDirs) $(_DMonoLinkFlags) $(_DEnableOsxArchitectures)'))
+ <_DOutputDir>"-DOUTPUT_DIR=$(MSBuildThisFileDirectory)$(IntermediateOutputPath)"
+ <_ExtraArgs>$([MSBuild]::Escape('$(_DMonoDirs) $(_DEnableOsxArchitectures) $(_DOutputDir)'))
-
-
-
-
-
+ DependsOnTargets="GetNativeBuildCommands;_GetJavaInteropBuildInfo"
+ BeforeTargets="Build"
+ Inputs="CMakeLists.txt;$(MSBuildThisFileFullPath);java-interop.csproj;@(_JavaInteropValidationSource);@(_JavaInteropValidationHeader)"
+ Outputs="$(IntermediateOutputPath)$(_JavaInteropValidationLibName)">
<_Cmake
@@ -80,20 +56,12 @@
Targets="Cmake"
/>
-
+
-
-
-
-
-
+
-
diff --git a/tests/Java.Base-Tests/Java.Base-Tests.csproj b/tests/Java.Base-Tests/Java.Base-Tests.csproj
deleted file mode 100644
index 4bc8b63be..000000000
--- a/tests/Java.Base-Tests/Java.Base-Tests.csproj
+++ /dev/null
@@ -1,43 +0,0 @@
-
-
-
- $(DotNetTargetFramework)
- Java.BaseTests
- true
- enable
- false
-
-
-
-
-
-
- $(TestOutputFullPath)
- java.base-tests.jar
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/tests/Java.Base-Tests/Java.Base-Tests.targets b/tests/Java.Base-Tests/Java.Base-Tests.targets
deleted file mode 100644
index 8c119d541..000000000
--- a/tests/Java.Base-Tests/Java.Base-Tests.targets
+++ /dev/null
@@ -1,2 +0,0 @@
-
-
diff --git a/tests/Java.Base-Tests/Java.Base/InterfaceMethodInheritanceTests.cs b/tests/Java.Base-Tests/Java.Base/InterfaceMethodInheritanceTests.cs
deleted file mode 100644
index dc49dfd27..000000000
--- a/tests/Java.Base-Tests/Java.Base/InterfaceMethodInheritanceTests.cs
+++ /dev/null
@@ -1,26 +0,0 @@
-using System;
-
-using Java.Interop;
-
-using NUnit.Framework;
-
-namespace Java.BaseTests {
-
- [TestFixture]
- public class InterfaceMethodInheritanceTests : JavaVMFixture {
-
- [Test]
- public void InterfaceMethod ()
- {
- using var iface = global::Net.Dot.Jni.Test.HasInterfaceMethodInheritance.Create ();
- var m = iface!.M ();
- Assert.AreEqual ("HasInterfaceMethodInheritance.m", m);
- var n = iface!.N ();
- Assert.AreEqual ("HasInterfaceMethodInheritance.n", n);
- var o = iface!.O ();
- Assert.AreEqual ("HasInterfaceMethodInheritance.o", o);
- var p = iface!.P ();
- Assert.AreEqual ("HasInterfaceMethodInheritance.p", p);
- }
- }
-}
diff --git a/tests/Java.Base-Tests/Java.Base/JavaToManagedTests.cs b/tests/Java.Base-Tests/Java.Base/JavaToManagedTests.cs
deleted file mode 100644
index af5d5bc19..000000000
--- a/tests/Java.Base-Tests/Java.Base/JavaToManagedTests.cs
+++ /dev/null
@@ -1,137 +0,0 @@
-using System;
-
-using Java.Interop;
-
-using NUnit.Framework;
-
-namespace Java.BaseTests {
-
- [TestFixture]
- public class JavaToManagedTests : JavaVMFixture {
-
- [Test]
- public void InterfaceMethod ()
- {
- var invoked = false;
- var r = new MyRunnable (() => invoked = true);
- JavaInvoker.Run (r);
- Assert.IsTrue (invoked);
- r.Dispose ();
- }
-
- [Test]
- public void InterfaceInvokerMethod ()
- {
- int value = 0;
- using var c = new MyIntConsumer (v => value = v);
- using var r = JavaInvoker.CreateRunnable (c);
- r?.Run ();
- Assert.AreEqual (0, value);
- r?.Run ();
- Assert.AreEqual (1, value);
- }
- }
-
- class JavaInvoker : JavaObject {
- internal const string JniTypeName = "com/microsoft/java_base_tests/Invoker";
-
- static readonly JniPeerMembers _members = new JniPeerMembers (JniTypeName, typeof (JavaInvoker));
-
- public static unsafe void Run (Java.Lang.IRunnable r)
- {
- JniArgumentValue* args = stackalloc JniArgumentValue [1];
- args [0] = new JniArgumentValue (r);
- _members.StaticMethods.InvokeVoidMethod ("run.(Ljava/lang/Runnable;)V", args);
- }
-
- public static unsafe Java.Lang.IRunnable? CreateRunnable (Java.Util.Function.IIntConsumer c)
- {
- JniArgumentValue* args = stackalloc JniArgumentValue [1];
- args [0] = new JniArgumentValue (c);
- var _rm = _members.StaticMethods.InvokeObjectMethod ("createRunnable.(Ljava/util/function/IntConsumer;)Ljava/lang/Runnable;", args);
- return Java.Interop.JniEnvironment.Runtime.ValueManager.GetValue (ref _rm, JniObjectReferenceOptions.CopyAndDispose);
- }
- }
-
- [JniTypeSignature ("example/MyRunnable")]
- class MyRunnable : Java.Lang.Object, Java.Lang.IRunnable {
-
- Action action;
-
- public MyRunnable (Action action)
- {
- this.action = action;
- }
-
- [JniMethodSignature ("run", "()V")]
- public void Run ()
- {
- action ();
- }
-
- static Delegate GetRunHandler ()
- {
- return new _JniMarshal_PPV_V (n_Run);
- }
-
- delegate void _JniMarshal_PPV_V (IntPtr jnienv, IntPtr n_self);
-
- static void n_Run (IntPtr jnienv, IntPtr n_self)
- {
- var r_self = new JniObjectReference (n_self);
- var self = JniEnvironment.Runtime.ValueManager.GetValue (ref r_self, JniObjectReferenceOptions.CopyAndDoNotRegister);
- try {
- self!.Run ();
- } finally {
- self?.DisposeUnlessReferenced ();
- }
- }
-
- [JniAddNativeMethodRegistration]
- static void RegisterNativeMembers (JniNativeMethodRegistrationArguments args)
- {
- args.AddRegistrations (new [] { new JniNativeMethodRegistration ("n_run", "()V", new _JniMarshal_PPV_V (n_Run)) });
- }
- }
-
- [JniTypeSignature ("example/MyIntConsumer")]
- class MyIntConsumer : Java.Lang.Object, Java.Util.Function.IIntConsumer {
-
- Action action;
-
- public MyIntConsumer (Action action)
- {
- this.action = action;
- }
-
- [JniMethodSignature ("accept", "(I)V")]
- public void Accept (int value)
- {
- action (value);
- }
-
- static Delegate GetAcceptHandler ()
- {
- return new _JniMarshal_PPIV_V (n_Accept);
- }
-
- delegate void _JniMarshal_PPIV_V (IntPtr jnienv, IntPtr n_self, int value);
-
- static void n_Accept (IntPtr jnienv, IntPtr n_self, int value)
- {
- var r_self = new JniObjectReference (n_self);
- var self = JniEnvironment.Runtime.ValueManager.GetValue (ref r_self, JniObjectReferenceOptions.CopyAndDoNotRegister);
- try {
- self!.Accept (value);
- } finally {
- self?.DisposeUnlessReferenced ();
- }
- }
-
- [JniAddNativeMethodRegistration]
- static void RegisterNativeMembers (JniNativeMethodRegistrationArguments args)
- {
- args.AddRegistrations (new [] { new JniNativeMethodRegistration ("n_accept", "(I)V", new _JniMarshal_PPIV_V (n_Accept)) });
- }
- }
-}
diff --git a/tests/Java.Base-Tests/Java.Base/JavaVMFixture.Partial.cs b/tests/Java.Base-Tests/Java.Base/JavaVMFixture.Partial.cs
deleted file mode 100644
index fb22b5531..000000000
--- a/tests/Java.Base-Tests/Java.Base/JavaVMFixture.Partial.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-using System;
-using System.Reflection;
-
-using Java.Interop;
-
-namespace Java.BaseTests {
-
-public abstract partial class JavaVMFixture {
- static JavaVMFixture ()
- {
- CreateJavaVM ();
- }
- static partial void CreateJavaVM ();
- protected JavaVMFixture ()
- {
- }
-}
-
-}
\ No newline at end of file
diff --git a/tests/Java.Base-Tests/Java.Base/JavaVMFixture.cs b/tests/Java.Base-Tests/Java.Base/JavaVMFixture.cs
deleted file mode 100644
index 7864b05cd..000000000
--- a/tests/Java.Base-Tests/Java.Base/JavaVMFixture.cs
+++ /dev/null
@@ -1,31 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Diagnostics;
-using System.Linq;
-
-using Java.Interop;
-
-using Java.InteropTests;
-
-namespace Java.BaseTests {
-
- partial class JavaVMFixture {
-
- static partial void CreateJavaVM ()
- {
- var c = new TestJVM (
- jars: new[]{ "java.base-tests.jar" },
- typeMappings: new Dictionary () {
- ["java/lang/Float"] = typeof (Java.Lang.Float),
- ["example/MyIntConsumer"] = typeof (MyIntConsumer),
- ["example/MyRunnable"] = typeof (MyRunnable),
- [JavaInvoker.JniTypeName] = typeof (JavaInvoker),
- [MyQueuedSynchronizer.JniTypeName] = typeof (MyQueuedSynchronizer),
- ["example/MyQueuedSynchronizer$MyQueuedSynchronizer_MyConditionObject"] = typeof (MyQueuedSynchronizer.MyConditionObject),
- }
- );
- JniRuntime.SetCurrent (c);
- }
- }
-}
diff --git a/tests/Java.Base-Tests/Java.Base/JniRuntimeJniValueManagerContractExtras.cs b/tests/Java.Base-Tests/Java.Base/JniRuntimeJniValueManagerContractExtras.cs
deleted file mode 100644
index b28a53d7f..000000000
--- a/tests/Java.Base-Tests/Java.Base/JniRuntimeJniValueManagerContractExtras.cs
+++ /dev/null
@@ -1,32 +0,0 @@
-using System;
-
-using Java.Interop;
-
-using NUnit.Framework;
-
-namespace Java.BaseTests;
-
-[TestFixture]
-public class JniRuntimeJniValueManagerContractExtras : JavaVMFixture {
-
- [Test]
- public void CreatePeer_FloatIsNotNullableSingle ()
- {
- JniObjectReference float_ref;
-#pragma warning disable CS0618
- using (var value = new Java.Lang.Float (1.0f)) {
- float_ref = value.PeerReference.NewLocalRef ();
- }
-#pragma warning restore CS0618
- try {
- var peer = JniEnvironment.Runtime.ValueManager.CreatePeer (ref float_ref, JniObjectReferenceOptions.Copy, targetType: null);
- Assert.IsNotNull (peer, "Could not create Java.Lang.Float peer!");
- Assert.AreEqual (
- typeof (Java.Lang.Float),
- peer!.GetType (),
- $"Peer type mismatch: expected Java.Lang.Float, got {peer.GetType ()}");
- } finally {
- JniObjectReference.Dispose (ref float_ref);
- }
- }
-}
diff --git a/tests/Java.Base-Tests/Java.Base/NestedTypeTests.cs b/tests/Java.Base-Tests/Java.Base/NestedTypeTests.cs
deleted file mode 100644
index 3de95d2bc..000000000
--- a/tests/Java.Base-Tests/Java.Base/NestedTypeTests.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-using System;
-
-using Java.Interop;
-
-using NUnit.Framework;
-
-namespace Java.BaseTests {
-
- [TestFixture]
- public class NestedTypeTests : JavaVMFixture {
-
- [Test]
- public void Create_AbstractQueuedSynchronizer_ConditionObject ()
- {
- using var outer = new MyQueuedSynchronizer ();
- using var inner = new MyQueuedSynchronizer.MyConditionObject (outer);
- }
- }
-
- [JniTypeSignature (JniTypeName)]
- class MyQueuedSynchronizer : Java.Util.Concurrent.Locks.AbstractQueuedSynchronizer {
- internal const string JniTypeName = "example/MyQueuedSynchronizer";
-
- public MyQueuedSynchronizer ()
- {
- }
-
- public class MyConditionObject : Java.Util.Concurrent.Locks.AbstractQueuedSynchronizer.ConditionObject {
-
- public MyConditionObject (MyQueuedSynchronizer outer)
- : base (outer)
- {
- }
- }
- }
-}
diff --git a/tests/Java.Base-Tests/java/com/microsoft/java_base_tests/Invoker.java b/tests/Java.Base-Tests/java/com/microsoft/java_base_tests/Invoker.java
deleted file mode 100644
index 93f300285..000000000
--- a/tests/Java.Base-Tests/java/com/microsoft/java_base_tests/Invoker.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package com.microsoft.java_base_tests;
-
-import java.util.function.IntConsumer;
-
-public final class Invoker {
-
- public static void run(Runnable r) {
- r.run();
- }
-
- public static Runnable createRunnable(final IntConsumer consumer) {
- return new Runnable() {
- int value;
- public void run() {
- consumer.accept(value++);
- }
- };
- }
-}
diff --git a/tests/Java.Base-Tests/java/net/dot/jni/test/HasInterfaceMethodInheritance.java b/tests/Java.Base-Tests/java/net/dot/jni/test/HasInterfaceMethodInheritance.java
deleted file mode 100644
index ffb2824c0..000000000
--- a/tests/Java.Base-Tests/java/net/dot/jni/test/HasInterfaceMethodInheritance.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package net.dot.jni.test;
-
-public class HasInterfaceMethodInheritance implements InterfaceMethodInheritance {
- private HasInterfaceMethodInheritance() {
- }
-
- public static InterfaceMethodInheritance create() {
- return new HasInterfaceMethodInheritance();
- }
-
- public String m() {
- return "HasInterfaceMethodInheritance.m";
- }
-
- public String n() {
- return "HasInterfaceMethodInheritance.n";
- }
-
- public String o() {
- return "HasInterfaceMethodInheritance.o";
- }
-
- public String p() {
- return "HasInterfaceMethodInheritance.p";
- }
-}
diff --git a/tests/Java.Base-Tests/java/net/dot/jni/test/InterfaceMethodInheritance.java b/tests/Java.Base-Tests/java/net/dot/jni/test/InterfaceMethodInheritance.java
deleted file mode 100644
index e27d3fa50..000000000
--- a/tests/Java.Base-Tests/java/net/dot/jni/test/InterfaceMethodInheritance.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package net.dot.jni.test;
-
-/* package */ interface BaseInterface {
- String m();
-}
-
-public interface InterfaceMethodInheritance extends BaseInterface, PublicInterface {
- String n();
-}
diff --git a/tests/Java.Base-Tests/java/net/dot/jni/test/PublicInterface.java b/tests/Java.Base-Tests/java/net/dot/jni/test/PublicInterface.java
deleted file mode 100644
index 9ce0a1f98..000000000
--- a/tests/Java.Base-Tests/java/net/dot/jni/test/PublicInterface.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package net.dot.jni.test;
-
-/* package */ interface InternalInterface {
- String o();
-}
-
-public interface PublicInterface extends InternalInterface {
- String p();
-}
diff --git a/tests/Java.Interop-Tests/Java.Interop-Tests.csproj b/tests/Java.Interop-Tests/Java.Interop-Tests.csproj
index 2624d40b3..174e7bb18 100644
--- a/tests/Java.Interop-Tests/Java.Interop-Tests.csproj
+++ b/tests/Java.Interop-Tests/Java.Interop-Tests.csproj
@@ -26,7 +26,6 @@
-
diff --git a/tests/Java.Interop-Tests/Java.Interop/JniPeerMembersTests.cs b/tests/Java.Interop-Tests/Java.Interop/JniPeerMembersTests.cs
index 0cb2ac5d4..9de05c789 100644
--- a/tests/Java.Interop-Tests/Java.Interop/JniPeerMembersTests.cs
+++ b/tests/Java.Interop-Tests/Java.Interop/JniPeerMembersTests.cs
@@ -126,7 +126,7 @@ public void ReplaceInstanceMethodWithStaticMethod ()
// Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
// V [libjvm.dylib+0x4f718c] jniCheck::validate_call(JavaThread*, _jclass*, _jmethodID*, _jobject*)+0x98
// V [libjvm.dylib+0x506474] checked_jni_CallStaticObjectMethodA+0x150
- // C [libjava-interop.dylib+0x5b18] java_interop_jnienv_call_static_object_method_a+0x48
+ // C [native JNI wrapper] java_interop_jnienv_call_static_object_method_a+0x48
// C 0x000000010798a8d8
// C 0x000000010798a540
// C 0x000000010798fa94
diff --git a/tests/Java.Interop-Tests/Java.Interop/JniRuntime.JniValueManagerTests.cs b/tests/Java.Interop-Tests/Java.Interop/JniRuntime.JniValueManagerTests.cs
index b88401a36..a712105d7 100644
--- a/tests/Java.Interop-Tests/Java.Interop/JniRuntime.JniValueManagerTests.cs
+++ b/tests/Java.Interop-Tests/Java.Interop/JniRuntime.JniValueManagerTests.cs
@@ -63,6 +63,7 @@ public override IJavaPeerable PeekPeer (JniObjectReference reference)
{
return null;
}
+
}
[Test]
@@ -146,4 +147,3 @@ public unsafe void GetValue_FindBestMatchType ()
#endif // !NO_MARSHAL_MEMBER_BUILDER_SUPPORT
}
}
-
diff --git a/tests/Java.Interop-Tests/Java.Interop/JniRuntimeJniValueManagerContract.cs b/tests/Java.Interop-Tests/Java.Interop/JniRuntimeJniValueManagerContract.cs
index 25fa52bb7..706aa2b53 100644
--- a/tests/Java.Interop-Tests/Java.Interop/JniRuntimeJniValueManagerContract.cs
+++ b/tests/Java.Interop-Tests/Java.Interop/JniRuntimeJniValueManagerContract.cs
@@ -408,14 +408,8 @@ public abstract class JniRuntimeJniValueManagerContract<
}
#if !__ANDROID__
-
[TestFixture]
- public class JniRuntimeJniValueManagerContract_NoGCIntegration : JniRuntimeJniValueManagerContract {
- [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)]
- static Type ManagedValueManagerType = Type.GetType ("Java.Interop.ManagedValueManager, Java.Runtime.Environment", throwOnError:true)!;
-
- [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)]
- protected override Type ValueManagerType => ManagedValueManagerType;
+ public class JniRuntimeJniValueManagerContract_NoGCIntegration : JniRuntimeJniValueManagerContract {
}
#endif // !__ANDROID__
diff --git a/tests/Java.Interop-Tests/Java.Interop/JniRuntimeTest.cs b/tests/Java.Interop-Tests/Java.Interop/JniRuntimeTest.cs
index 48b3e1663..f5ef52768 100644
--- a/tests/Java.Interop-Tests/Java.Interop/JniRuntimeTest.cs
+++ b/tests/Java.Interop-Tests/Java.Interop/JniRuntimeTest.cs
@@ -1,7 +1,6 @@
using System;
using System.Reflection;
using System.Collections.Generic;
-using System.Linq;
using System.Threading;
using System.Diagnostics.CodeAnalysis;
@@ -32,9 +31,9 @@ public void CreateJavaVM ()
public void JDK_OnlySupportsOneVM ()
{
try {
- var second = new JreRuntimeOptions () {
+ var second = new TestJVM (new TestJVMOptions () {
JvmLibraryPath = TestJVM.GetJvmLibraryPath (),
- }.CreateJreVM ();
+ });
// If we reach here, we're in a JVM that supports > 1 VM
second.Dispose ();
Assert.Ignore ();
@@ -53,9 +52,9 @@ public void UseInvocationPointerOnNewThread ()
var t = new Thread (() => {
try {
- var second = new JreRuntimeOptions () {
+ var second = new TestJVM (new TestJVMOptions () {
InvocationPointer = InvocationPointer,
- }.CreateJreVM ();
+ });
}
catch (Exception e) {
Assert.Fail ("Expected no exception, got: {0}", e);
@@ -72,28 +71,6 @@ public void CreateJavaVMWithNullBuilder ()
Assert.Throws (() => new JavaVMWithNullBuilder ());
}
- [Test]
- public void BuiltInSimpleReferenceMap_ContainsManagedPeerByDefault ()
- {
- var types = JniRuntime.CurrentRuntime.TypeManager.GetTypes (new JniTypeSignature (ManagedPeer.JniTypeName));
- Assert.IsTrue (types.Contains (typeof (ManagedPeer)));
- }
-
-#if !__ANDROID__
- [Test]
- public void ManagedPeerNativeRegistrationFalse_RemovesManagedPeerBuiltinMapping ()
- {
- var c = JniRuntime.CurrentRuntime;
- AppContext.SetSwitch ("Java.Interop.RuntimeFeature.ManagedPeerNativeRegistration", false);
- try {
- var types = c.TypeManager.GetTypes (new JniTypeSignature (ManagedPeer.JniTypeName));
- Assert.IsEmpty (types);
- } finally {
- AppContext.SetSwitch ("Java.Interop.RuntimeFeature.ManagedPeerNativeRegistration", true);
- }
- }
-#endif // !__ANDROID__
-
class JavaVMWithNullBuilder : JniRuntime {
public JavaVMWithNullBuilder ()
: base ((JniRuntime.CreationOptions) null)
diff --git a/tests/TestJVM/TestJVM.cs b/tests/TestJVM/TestJVM.cs
index 2ff1e0715..047171d4d 100644
--- a/tests/TestJVM/TestJVM.cs
+++ b/tests/TestJVM/TestJVM.cs
@@ -1,94 +1,176 @@
+#nullable enable
+
using System;
using System.Collections.Generic;
-using System.IO;
using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
+using System.IO;
using System.Linq;
-using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
using System.Threading;
-using System.Text;
using System.Xml.Linq;
using Xamarin.Android.Tools;
-using Java.Interop;
+namespace Java.Interop {
-namespace Java.InteropTests
-{
- public class TestJVMOptions : JreRuntimeOptions {
+ struct JavaVMInitArgs {
+ public JniVersion version;
+ public int nOptions;
+ public IntPtr options;
+ public byte ignoreUnrecognized;
+ }
+
+ struct JavaVMOption {
+ public IntPtr optionString;
+ public IntPtr extraInfo;
+ }
- public TestJVMOptions (Assembly? callingAssembly = null)
+ public class TestJVMOptions : JniRuntime.CreationOptions {
+
+ internal List Options {get;} = new List ();
+ internal Dictionary? typeMappings;
+ internal NativeLibraryJvmLibraryHandler? LibraryHandler;
+
+ public ICollection JarFilePaths {get;} = new List ();
+ public IDictionary TypeMappings => typeMappings ??= new Dictionary ();
+
+ internal List ClassPath {get;} = new List ();
+ internal JdkInfo? JdkInfo {get; set;}
+
+ public TestJVMOptions ()
{
- CallingAssembly = callingAssembly ?? Assembly.GetCallingAssembly ();
+ JniVersion = JniVersion.v1_2;
}
- public ICollection JarFilePaths {get;} = new List ();
- public Assembly CallingAssembly {get; set;}
-
- internal JdkInfo? JdkInfo {get; set;}
+ public TestJVMOptions AddOption (string option)
+ {
+ if (option == null)
+ throw new ArgumentNullException (nameof (option));
+ Options.Add (option);
+ return this;
+ }
}
- public class TestJVM : JreRuntime {
+ public class TestJVM : JniRuntime {
+
+ NativeLibraryJvmLibraryHandler? LibraryHandler;
#if !__ANDROID__
public JdkInfo? JdkInfo { get; private set; }
#endif // !__ANDROID__
- public TestJVM (TestJVMOptions builder)
- : base (OverrideOptions (builder))
+ public TestJVM (TestJVMOptions options)
+ : base (CreateJVM (options))
{
+ LibraryHandler = options.LibraryHandler;
#if !__ANDROID__
- this.JdkInfo = builder.JdkInfo;
+ JdkInfo = options.JdkInfo;
#endif // !__ANDROID__
-
}
- static TestJVMOptions OverrideOptions (TestJVMOptions builder)
+ static unsafe TestJVMOptions CreateJVM (TestJVMOptions options)
{
- var dir = GetOutputDirectoryName ();
+ if (options == null)
+ throw new ArgumentNullException (nameof (options));
+ options.TypeManager ??= new TestJvmTypeManager (options.typeMappings);
+ options.ValueManager ??= new ManagedValueManager ();
+ options.ObjectReferenceManager ??= new ManagedObjectReferenceManager ();
+
+ if (options.InvocationPointer != IntPtr.Zero || options.EnvironmentPointer != IntPtr.Zero)
+ return options;
+
+ var dir = GetOutputDirectoryName ();
var info = GetJdkInfo ();
- builder.JvmLibraryPath = info.JdkJvmPath;
- builder.JdkInfo = info.JdkInfo;
- builder.JniAddNativeMethodRegistrationAttributePresent = true;
- builder.JniGlobalReferenceLogWriter = GetLogOutput ("JAVA_INTEROP_GREF_LOG", "g-", builder.CallingAssembly);
- builder.JniLocalReferenceLogWriter = GetLogOutput ("JAVA_INTEROP_LREF_LOG", "l-", builder.CallingAssembly);
+ options.JvmLibraryPath ??= info.JdkJvmPath;
+ options.JdkInfo = info.JdkInfo;
+
+ if (string.IsNullOrEmpty (options.JvmLibraryPath))
+ throw new InvalidOperationException ($"Member `{nameof (TestJVMOptions)}.{nameof (TestJVMOptions.JvmLibraryPath)}` must be set.");
+
+ foreach (var jar in options.JarFilePaths)
+ options.ClassPath.Add (Path.Combine (dir, jar));
+ options.AddOption ("-Xcheck:jni");
- foreach (var jar in builder.JarFilePaths)
- builder.ClassPath.Add (Path.Combine (dir, jar));
- builder.AddOption ("-Xcheck:jni");
- builder.TypeManager = builder.TypeManager ?? new TestJvmTypeManager (builder.TypeMappings);
+ var handler = new NativeLibraryJvmLibraryHandler ();
+ options.LibraryHandler = handler;
+ try {
+ handler.LoadJvmLibrary (options.JvmLibraryPath);
+ EnsureJavaInteropJar (options);
- return builder;
+ var args = new JavaVMInitArgs {
+ version = options.JniVersion,
+ nOptions = options.Options.Count + 1,
+ ignoreUnrecognized = 0,
+ };
+ var jvmOptions = new JavaVMOption [options.Options.Count + 1];
+ try {
+ for (int i = 0; i < options.Options.Count; ++i)
+ jvmOptions [i].optionString = Marshal.StringToHGlobalAnsi (options.Options [i]);
+ jvmOptions [options.Options.Count].optionString = Marshal.StringToHGlobalAnsi (
+ string.Format ("-Djava.class.path={0}", string.Join (Path.PathSeparator.ToString (), options.ClassPath)));
+
+ fixed (JavaVMOption* popts = jvmOptions) {
+ args.options = (IntPtr) popts;
+ int r = handler.CreateJavaVM (out var javavm, out var jnienv, ref args);
+ if (r != 0) {
+ handler.Dispose ();
+ options.LibraryHandler = null;
+ throw new NotSupportedException (
+ string.Format (
+ "The JDK supports creating at most one JVM per process, ever; " +
+ "do you have a JVM running already, or have you already created (and destroyed?) one? " +
+ "(JNI_CreateJavaVM returned {0}).",
+ r));
+ }
+ options.InvocationPointer = javavm;
+ options.EnvironmentPointer = jnienv;
+ }
+ } finally {
+ for (int i = 0; i < jvmOptions.Length; ++i)
+ Marshal.FreeHGlobal (jvmOptions [i].optionString);
+ }
+ return options;
+ } catch {
+ if (options.LibraryHandler != null) {
+ options.LibraryHandler.Dispose ();
+ options.LibraryHandler = null;
+ }
+ throw;
+ }
}
- static string GetOutputDirectoryName ()
+ static void EnsureJavaInteropJar (TestJVMOptions options)
{
- return Path.GetDirectoryName (typeof (TestJVM).Assembly.Location) ??
- Environment.CurrentDirectory;
+ if (options.ClassPath.Any (p => p.EndsWith ("java-interop.jar", StringComparison.OrdinalIgnoreCase)))
+ return;
+
+ var dir = GetOutputDirectoryName ();
+ var jar = Path.Combine (dir, "java-interop.jar");
+ if (!File.Exists (jar)) {
+ throw new FileNotFoundException ($"`java-interop.jar` is required. Please add to `TestJVMOptions.ClassPath`. Tried to find it in `{jar}`.");
+ }
+ options.ClassPath.Add (jar);
}
- static TextWriter? GetLogOutput (string envVar, string prefix, Assembly caller)
+ static string GetOutputDirectoryName ()
{
- var path = Environment.GetEnvironmentVariable (envVar);
- if (!string.IsNullOrEmpty (path))
- return null;
- path = Path.Combine (
- GetOutputDirectoryName (),
- prefix + Path.GetFileName (caller.Location) + ".txt");
- return new StreamWriter (path, append: false, encoding: new UTF8Encoding (encoderShouldEmitUTF8Identifier: false));
+ return Path.GetDirectoryName (typeof (TestJVM).Assembly.Location) ??
+ Environment.CurrentDirectory;
}
public static string? GetJvmLibraryPath (Action? logger = null) => GetJdkInfo (logger).JdkJvmPath;
static (JdkInfo? JdkInfo, string? JdkJvmPath) GetJdkInfo (Action? logger = null)
{
- var info = ReadJavaSdkDirectoryFromJdkInfoProps (logger);
- if (info.JdkJvmPath != null) {
+ var info = ReadJavaSdkDirectoryFromJdkInfoProps (logger);
+ if (info.JdkJvmPath != null)
return (JdkInfo: info.JavaSdkDirectory == null ? null : new JdkInfo (info.JavaSdkDirectory), JdkJvmPath: info.JdkJvmPath);
- }
- var jdk = JdkInfo.GetKnownSystemJdkInfos (logger)
- .FirstOrDefault ();
+
+ var jdk = JdkInfo.GetKnownSystemJdkInfos (logger).FirstOrDefault ();
return (jdk, jdk?.JdkJvmPath);
}
@@ -96,24 +178,23 @@ static string GetOutputDirectoryName ()
{
var jdkPropFile = TryProbeForJdkInfoProps (logger);
logger?.Invoke (TraceLevel.Verbose, $"TestJVM: jdkPropFile? {jdkPropFile}");
- if (!File.Exists (jdkPropFile)) {
+ if (!File.Exists (jdkPropFile))
return (null, null);
- }
logger?.Invoke (TraceLevel.Verbose, $"TestJVM: Extracting $(JdkJvmPath) from: {jdkPropFile}");
- var msbuild = XNamespace.Get ("http://schemas.microsoft.com/developer/msbuild/2003");
+ var msbuild = XNamespace.Get ("http://schemas.microsoft.com/developer/msbuild/2003");
- var jdkProps = XDocument.Load (jdkPropFile);
- var jdkJvmPath = jdkProps.Elements ()
+ var jdkProps = XDocument.Load (jdkPropFile);
+ var jdkJvmPath = jdkProps.Elements ()
.Elements (msbuild + "Choose")
.Elements (msbuild + "When")
.Elements (msbuild + "PropertyGroup")
.Elements (msbuild + "JdkJvmPath")
.FirstOrDefault ();
- if (jdkJvmPath == null) {
+ if (jdkJvmPath == null)
return (null, null);
- }
- var jdkPath = jdkProps.Elements ()
+
+ var jdkPath = jdkProps.Elements ()
.Elements (msbuild + "PropertyGroup")
.Elements (msbuild + "JavaSdkDirectory")
.FirstOrDefault ();
@@ -126,32 +207,27 @@ static string GetOutputDirectoryName ()
{
for (var probing = Path.GetDirectoryName (typeof (TestJVM).Assembly.Location); probing != null; probing = Path.GetDirectoryName (probing)) {
logger?.Invoke (TraceLevel.Verbose, $"TestJVM: probing for JdkInfo.props around {probing}");
- if (File.Exists (Path.Combine (probing, "Java.Interop.sln"))) {
- // we've hit the root of the repo checkout
+ if (File.Exists (Path.Combine (probing, "Java.Interop.sln")))
return ProbeFromRootDir (probing);
- }
var dirName = Path.GetFileName (probing);
if (dirName.StartsWith ("Test", StringComparison.OrdinalIgnoreCase)) {
- var buildName = dirName.Replace ("Test", "Build");
- if (buildName.Contains ('-')) {
- buildName = buildName.Substring (0, buildName.IndexOf ('-'));
- }
+ var buildName = dirName.Replace ("Test", "Build");
+ if (buildName.Contains ('-'))
+ buildName = buildName.Substring (0, buildName.IndexOf ('-'));
return Path.Combine (Path.GetDirectoryName (probing)!, buildName, "JdkInfo.props");
}
}
return null;
- string ProbeFromRootDir (string location)
+ static string ProbeFromRootDir (string location)
{
- var buildDebug = Path.Combine (location, "bin", "BuildDebug");
- var buildRelease = Path.Combine (location, "bin", "BuildRelease");
- if (Directory.Exists (buildDebug) && !Directory.Exists (buildRelease)) {
+ var buildDebug = Path.Combine (location, "bin", "BuildDebug");
+ var buildRelease = Path.Combine (location, "bin", "BuildRelease");
+ if (Directory.Exists (buildDebug) && !Directory.Exists (buildRelease))
return Path.Combine (buildDebug, "JdkInfo.props");
- }
- if (Directory.Exists (buildRelease) && !Directory.Exists (buildDebug)) {
+ if (Directory.Exists (buildRelease) && !Directory.Exists (buildDebug))
return Path.Combine (buildRelease, "JdkInfo.props");
- }
var dir = Directory.GetLastWriteTime (buildDebug) > Directory.GetLastWriteTime (buildRelease)
? buildDebug
: buildRelease;
@@ -160,36 +236,332 @@ string ProbeFromRootDir (string location)
}
public TestJVM (string[]? jars = null, Dictionary? typeMappings = null)
- : this (CreateOptions (jars, Assembly.GetCallingAssembly (), typeMappings))
+ : this (CreateOptions (jars, typeMappings))
{
}
- static TestJVMOptions CreateOptions (string[]? jarFiles, Assembly callingAssembly, Dictionary? typeMappings)
+ static TestJVMOptions CreateOptions (string[]? jarFiles, Dictionary? typeMappings)
{
- var o = new TestJVMOptions {
- CallingAssembly = callingAssembly,
- };
+ var options = new TestJVMOptions ();
if (typeMappings != null) {
- foreach (var e in typeMappings) {
- o.TypeMappings.Add (e.Key, e.Value);
- }
+ foreach (var e in typeMappings)
+ options.TypeMappings.Add (e.Key, e.Value);
}
if (jarFiles != null) {
- foreach (var jar in jarFiles) {
- o.JarFilePaths.Add (jar);
+ foreach (var jar in jarFiles)
+ options.JarFilePaths.Add (jar);
+ }
+ return options;
+ }
+
+ public override string? GetCurrentManagedThreadName ()
+ {
+ return Thread.CurrentThread.Name;
+ }
+
+ public override string GetCurrentManagedThreadStackTrace (int skipFrames, bool fNeedFileInfo)
+ {
+ return new StackTrace (skipFrames, fNeedFileInfo).ToString ();
+ }
+
+ protected override void Dispose (bool disposing)
+ {
+ base.Dispose (disposing);
+ LibraryHandler?.Dispose ();
+ LibraryHandler = null;
+ }
+ }
+
+ internal sealed class NativeLibraryJvmLibraryHandler : IDisposable {
+
+ IntPtr handle;
+ IntPtr create;
+
+ public void LoadJvmLibrary (string path)
+ {
+ handle = NativeLibrary.Load (path);
+ if (!NativeLibrary.TryGetExport (handle, "JNI_CreateJavaVM", out create) ||
+ !NativeLibrary.TryGetExport (handle, "JNI_GetCreatedJavaVMs", out _)) {
+ Dispose ();
+ throw new NotSupportedException ($"Library `{path}` does not export the required symbols `JNI_CreateJavaVM` or `JNI_GetCreatedJavaVMs`!");
+ }
+ }
+
+ public unsafe int CreateJavaVM (out IntPtr javavm, out IntPtr jnienv, ref JavaVMInitArgs args)
+ {
+ var createJavaVM = (delegate* unmanaged) create;
+ return createJavaVM (out javavm, out jnienv, ref args);
+ }
+
+ public void Dispose ()
+ {
+ if (handle != IntPtr.Zero)
+ NativeLibrary.Free (handle);
+ handle = IntPtr.Zero;
+ create = IntPtr.Zero;
+ }
+ }
+
+ class ManagedObjectReferenceManager : JniRuntime.JniObjectReferenceManager {
+
+ int grefCount;
+ int wgrefCount;
+
+ public override int GlobalReferenceCount => grefCount;
+ public override int WeakGlobalReferenceCount => wgrefCount;
+
+ public override JniObjectReference CreateGlobalReference (JniObjectReference reference)
+ {
+ var r = base.CreateGlobalReference (reference);
+ if (r.IsValid)
+ Interlocked.Increment (ref grefCount);
+ return r;
+ }
+
+ public override void DeleteGlobalReference (ref JniObjectReference reference)
+ {
+ if (reference.IsValid)
+ Interlocked.Decrement (ref grefCount);
+ base.DeleteGlobalReference (ref reference);
+ }
+
+ public override JniObjectReference CreateWeakGlobalReference (JniObjectReference reference)
+ {
+ var r = base.CreateWeakGlobalReference (reference);
+ if (r.IsValid)
+ Interlocked.Increment (ref wgrefCount);
+ return r;
+ }
+
+ public override void DeleteWeakGlobalReference (ref JniObjectReference reference)
+ {
+ if (reference.IsValid)
+ Interlocked.Decrement (ref wgrefCount);
+ base.DeleteWeakGlobalReference (ref reference);
+ }
+ }
+
+ public class ManagedValueManager : JniRuntime.ReflectionJniValueManager {
+
+ Dictionary>? RegisteredInstances = new Dictionary> ();
+
+ public override void WaitForGCBridgeProcessing ()
+ {
+ }
+
+ public override void CollectPeers ()
+ {
+ var registered = RegisteredInstances ?? throw new ObjectDisposedException (nameof (ManagedValueManager));
+ var peers = new List ();
+
+ lock (registered) {
+ foreach (var ps in registered.Values)
+ peers.AddRange (ps);
+ registered.Clear ();
+ }
+
+ List? exceptions = null;
+ foreach (var peer in peers) {
+ try {
+ peer.Dispose ();
+ } catch (Exception e) {
+ exceptions ??= new List ();
+ exceptions.Add (e);
}
}
- return o;
+ if (exceptions != null)
+ throw new AggregateException ("Exceptions while collecting peers.", exceptions);
+ }
+
+ public override void AddPeer (IJavaPeerable value)
+ {
+ var registered = RegisteredInstances ?? throw new ObjectDisposedException (nameof (ManagedValueManager));
+ var r = value.PeerReference;
+ if (!r.IsValid)
+ throw new ObjectDisposedException (value.GetType ().FullName);
+
+ if (r.Type != JniObjectReferenceType.Global) {
+ value.SetPeerReference (r.NewGlobalRef ());
+ JniObjectReference.Dispose (ref r, JniObjectReferenceOptions.CopyAndDispose);
+ }
+
+ int key = value.JniIdentityHashCode;
+ lock (registered) {
+ if (!registered.TryGetValue (key, out var peers)) {
+ registered.Add (key, new List { value });
+ return;
+ }
+
+ for (int i = peers.Count - 1; i >= 0; i--) {
+ var peer = peers [i];
+ if (!JniEnvironment.Types.IsSameObject (peer.PeerReference, value.PeerReference))
+ continue;
+ if (Replaceable (peer, value)) {
+ peers [i] = value;
+ } else {
+ WarnNotReplacing (key, value, peer);
+ }
+ return;
+ }
+ peers.Add (value);
+ }
+ }
+
+ static bool Replaceable (IJavaPeerable peer, IJavaPeerable value)
+ {
+ return peer.JniManagedPeerState.HasFlag (JniManagedPeerStates.Replaceable) &&
+ !value.JniManagedPeerState.HasFlag (JniManagedPeerStates.Replaceable);
+ }
+
+ void WarnNotReplacing (int key, IJavaPeerable ignoreValue, IJavaPeerable keepValue)
+ {
+ Runtime.ObjectReferenceManager.WriteGlobalReferenceLine (
+ "Warning: Not registering PeerReference={0} IdentityHashCode=0x{1} Instance={2} Instance.Type={3} Java.Type={4}; " +
+ "keeping previously registered PeerReference={5} Instance={6} Instance.Type={7} Java.Type={8}.",
+ ignoreValue.PeerReference.ToString (),
+ key.ToString ("x"),
+ RuntimeHelpers.GetHashCode (ignoreValue).ToString ("x"),
+ ignoreValue.GetType ().FullName,
+ JniEnvironment.Types.GetJniTypeNameFromInstance (ignoreValue.PeerReference),
+ keepValue.PeerReference.ToString (),
+ RuntimeHelpers.GetHashCode (keepValue).ToString ("x"),
+ keepValue.GetType ().FullName,
+ JniEnvironment.Types.GetJniTypeNameFromInstance (keepValue.PeerReference));
+ }
+
+ public override IJavaPeerable? PeekPeer (JniObjectReference reference)
+ {
+ var registered = RegisteredInstances ?? throw new ObjectDisposedException (nameof (ManagedValueManager));
+ if (!reference.IsValid)
+ return null;
+
+ int key = GetJniIdentityHashCode (reference);
+ lock (registered) {
+ if (!registered.TryGetValue (key, out var peers))
+ return null;
+
+ for (int i = peers.Count - 1; i >= 0; i--) {
+ var peer = peers [i];
+ if (JniEnvironment.Types.IsSameObject (reference, peer.PeerReference))
+ return peer;
+ }
+ if (peers.Count == 0)
+ registered.Remove (key);
+ }
+ return null;
+ }
+
+ public override void RemovePeer (IJavaPeerable value)
+ {
+ var registered = RegisteredInstances ?? throw new ObjectDisposedException (nameof (ManagedValueManager));
+ if (value == null)
+ throw new ArgumentNullException (nameof (value));
+
+ int key = value.JniIdentityHashCode;
+ lock (registered) {
+ if (!registered.TryGetValue (key, out var peers))
+ return;
+
+ for (int i = peers.Count - 1; i >= 0; i--) {
+ if (object.ReferenceEquals (value, peers [i]))
+ peers.RemoveAt (i);
+ }
+ if (peers.Count == 0)
+ registered.Remove (key);
+ }
+ }
+
+ public override void FinalizePeer (IJavaPeerable value)
+ {
+ var h = value.PeerReference;
+ var o = Runtime.ObjectReferenceManager;
+ if (!h.IsValid || h.Type == JniObjectReferenceType.Local) {
+ RemovePeer (value);
+ value.SetPeerReference (new JniObjectReference ());
+ value.Finalized ();
+ return;
+ }
+
+ RemovePeer (value);
+ if (o.LogGlobalReferenceMessages) {
+ o.WriteGlobalReferenceLine ("Finalizing PeerReference={0} IdentityHashCode=0x{1} Instance=0x{2} Instance.Type={3}",
+ h.ToString (),
+ value.JniIdentityHashCode.ToString ("x"),
+ RuntimeHelpers.GetHashCode (value).ToString ("x"),
+ value.GetType ().ToString ());
+ }
+ value.SetPeerReference (new JniObjectReference ());
+ JniObjectReference.Dispose (ref h);
+ value.Finalized ();
+ }
+
+ public override List GetSurfacedPeers ()
+ {
+ var registered = RegisteredInstances ?? throw new ObjectDisposedException (nameof (ManagedValueManager));
+ lock (registered) {
+ var peers = new List (registered.Count);
+ foreach (var e in registered) {
+ foreach (var peer in e.Value)
+ peers.Add (new JniSurfacedPeerInfo (e.Key, new WeakReference (peer)));
+ }
+ return peers;
+ }
+ }
+
+ protected override void Dispose (bool disposing)
+ {
+ RegisteredInstances = null;
+ base.Dispose (disposing);
}
}
- public class TestJvmTypeManager : JreTypeManager
- {
+ public class TestJvmTypeManager : JniRuntime.ReflectionJniTypeManager {
+
+ const DynamicallyAccessedMemberTypes MethodsAndPrivateNested = DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.NonPublicNestedTypes;
+
+ IDictionary? typeMappings;
public TestJvmTypeManager (IDictionary? typeMappings)
- : base (typeMappings)
{
+ this.typeMappings = typeMappings;
+ }
+
+ protected override IEnumerable GetTypesForSimpleReference (string jniSimpleReference)
+ {
+ foreach (var type in base.GetTypesForSimpleReference (jniSimpleReference))
+ yield return type;
+ if (typeMappings != null && typeMappings.TryGetValue (jniSimpleReference, out var target))
+ yield return target;
+ }
+
+ protected override IEnumerable GetSimpleReferences (Type type)
+ {
+ return base.GetSimpleReferences (type)
+ .Concat (CreateSimpleReferencesEnumerator (type));
+ }
+
+ IEnumerable CreateSimpleReferencesEnumerator (Type type)
+ {
+ if (typeMappings == null)
+ yield break;
+ foreach (var e in typeMappings) {
+ if (e.Value == type)
+ yield return e.Key;
+ }
+ }
+
+ public override void RegisterNativeMembers (
+ JniType nativeClass,
+ [DynamicallyAccessedMembers (MethodsAndPrivateNested)]
+ Type type,
+ ReadOnlySpan methods)
+ {
+ if (TryRegisterNativeMembers (nativeClass, type, methods) || methods.IsEmpty)
+ return;
+
+ throw new NotSupportedException (
+ $"Could not register native members for type '{type.FullName}'. " +
+ "Ensure that the type has the appropriate [JniAddNativeMethodRegistration] attribute and static registration method.");
}
}
}
-
diff --git a/tests/TestJVM/TestJVM.csproj b/tests/TestJVM/TestJVM.csproj
index 2ab635532..bccab73e1 100644
--- a/tests/TestJVM/TestJVM.csproj
+++ b/tests/TestJVM/TestJVM.csproj
@@ -6,6 +6,7 @@
false
true
..\..\product.snk
+ true
@@ -23,7 +24,6 @@
-
diff --git a/tests/generator-Tests/generator-Tests.csproj b/tests/generator-Tests/generator-Tests.csproj
index 39d09c875..91e0fb8df 100644
--- a/tests/generator-Tests/generator-Tests.csproj
+++ b/tests/generator-Tests/generator-Tests.csproj
@@ -23,6 +23,7 @@
+
diff --git a/tests/invocation-overhead/Makefile b/tests/invocation-overhead/Makefile
deleted file mode 100644
index 4fe8e0359..000000000
--- a/tests/invocation-overhead/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-CONFIGURATION = Debug
-
-all: bin/$(CONFIGURATION)/net472/invocation-overheads.exe
-
-bin/$(CONFIGURATION)/net472/invocation-overheads.exe:
- msbuild /restore
-
-clean:
- msbuild /t:Clean
-
-run:
- msbuild /t:Run /nologo /v:m
diff --git a/tests/invocation-overhead/README.md b/tests/invocation-overhead/README.md
deleted file mode 100644
index 1555f1687..000000000
--- a/tests/invocation-overhead/README.md
+++ /dev/null
@@ -1,124 +0,0 @@
-# JNI Invocation Overhead
-
-The original Java.Interop effort wanted a *type-safe* and *simple*
-binding around JNI. As such, it used `SafeHandle`s.
-
-As the Xamarin.Forms team has turned their attention to profiling
-Xamarin.Forms apps, and finding major Xamarin.Android-related
-performance issues, performance needed to be considered.
-
-For example, GC object allocation is a MAJOR concern for them;
-ideally, you could have ZERO GC ALLOCATIONS performed when
-invoking a Java method.
-
-`SafeHandle`s don't fit "nicely" in that world; every method that
-returns a `SafeHandle` ALLOCATES A NEW GC OBJECT.
-
-So...how bad is that?
-
-What's in this directory is insanity: there are four different active
-non-`SafeHandle` "strategies" for dealing with JNI:
-
- 1. Xamarin.Android JNI handling from 2011 until Xamarin.Android 6.1 (2016)
- (`XAIntPtrTiming`)
-
- This uses `IntPtr`s *everywhere*, e.g. `JNIEnv::CallObjectMethod()` returns
- an `IntPtr`.
-
- 2. "Happier Medium?" (`JIIntPtrTiming`)
-
- `IntPtr`s everywhere means it's trivial to forget that
- a JNI handle is a GREF vs. an LREF vs… What if we used the same `JNIEnv`
- invocation logic as `XAIntPtrTiming`, but instead of `IntPtr`s everywhere
- we instead had a `JniObjectReference` structure?
-
- 3. "Optimize (2)" (`JIPinvokeTiming`)
-
- (2) was slower than (1). What if we rethought the `JNIEnv`
- invocation logic and removed all the `Marshal.GetDelegateForFunctionPointer()`
- invocations with normal P/Invokes?
-
- 4. Function pointer invocation with error handling (`JIFunctionPointersTiming`)
-
-To compare these strategies, `jnienv-gen.exe` was updated so that *all* of them
-could be emitted into the same `.cs` file, into separate namespaces.
-These "core" JNI bindings could then be used with to invoke
-`java.util.Arrays.binarySearch(int[], int)`, 10,000,000 times, and compare
-the results.
-
-Historically, this benchmark also included a `SafeHandle` strategy. Result in
-2015 (commit [25de1f38][25de]):
-
-[25de]: https://github.com/xamarin/Java.Interop/commit/25de1f38bb6b3ef2d4c98d2d95923a4bd50d2ea0
-
- # SafeHandle timing: 00:00:02.7913432
- # Average Invocation: 0.00027913432ms
- # JIIntPtrTiming timing: 00:00:01.9809859
- # Average Invocation: 0.00019809859ms
-
-Basically, with a `JniObjectReference` struct-oriented approach, SafeHandles
-take ~1.4x longer to run. Rephrased: the `JniObjectReference` struct takes
-70% of the time of SafeHandles.
-
-Ouch.
-
-What about the current Xamarin.Android "all IntPtrs all the time!" approach?
-
- # SafeHandle timing: 00:00:02.8118485
- # Average Invocation: 0.00028118485ms
- # XAIntPtrTiming timing: 00:00:02.0061727
- # Average Invocation: 0.00020061727ms
-
-The performance difference is comparable -- SafeHandles take ~1.4x as long to
-run, or IntPtrs take ~70% as long as using SafeHandles.
-
-Interesting -- but probably not *that* interesting -- is that in an absolute
-sense, the `JniObjectReference` struct was *faster* than the `IntPtr` approach,
-even though `JniObjectReference` contains *both* an `IntPtr` *and* an enum --
-and is thus bigger!
-
-That doesn't make any sense.
-
-Regardless, `JniObjectReference` doesn't appear to be *slower*, and thus should
-be a viable option here.
-
----
-
-These historical results led to `JniObjectReference` becoming the stable public
-API instead of exposing `JniLocalReference` or other `SafeHandle` subclasses.
-The optional SafeHandle-backed implementation was kept for migration and
-comparison, but was never used by the active build and is no longer maintained.
-The supported representation is now the `IntPtr`-backed `JniObjectReference`
-struct.
-
-## Historical 2021 Timing Update
-
-How did the old `SafeHandle` timings compare in 2021 on Desktop Mono (macOS)?
-
- # SafeTiming timing: 00:00:09.3850449
- # Average Invocation: 0.00093850449ms
- # XAIntPtrTiming timing: 00:00:04.4930288
- # Average Invocation: 0.00044930288ms
- # JIIntPtrTiming timing: 00:00:04.5563368
- # Average Invocation: 0.00045563368ms
- # JIPinvokeTiming timing: 00:00:03.4710383
- # Average Invocation: 0.00034710383ms
-
-In an absolute sense, things are worse: 10e6 invocations in 2015 took 2-3sec.
-Now, they're taking at least 3.5sec.
-
-In a relative sense, `SafeHandles` got *worse*, and takes 2.09x longer than
-`XAIntPtrTiming`, and 2.7x longer than `JIPinvokeTiming`!
-
-What about .NET Core 3.1? After some finagling, *that* can work too!
-
- # SafeTiming timing: 00:00:05.1734443
- # Average Invocation: 0.00051734443ms
- # XAIntPtrTiming timing: 00:00:03.1048897
- # Average Invocation: 0.00031048897ms
- # JIIntPtrTiming timing: 00:00:03.4353958
- # Average Invocation: 0.00034353958ms
- # JIPinvokeTiming timing: 00:00:02.7470934
- # Average Invocation: 0.00027470934000000004ms
-
-Relative performance is a similar story: `SafeHandle`s are slowest.
diff --git a/tests/invocation-overhead/invocation-overhead.cs b/tests/invocation-overhead/invocation-overhead.cs
deleted file mode 100644
index d8f7cc586..000000000
--- a/tests/invocation-overhead/invocation-overhead.cs
+++ /dev/null
@@ -1,381 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Reflection;
-using System.Runtime.InteropServices;
-using Java.Interop;
-
-using JIIntPtrEnv = Java.Interop.JIIntPtrs.JniEnvironment;
-using PinvokeEnv = Java.Interop.JIPinvokes.JniEnvironment;
-using XAIntPtrEnv = Java.Interop.XAIntPtrs.JniEnvironment;
-using JIFuncPtrEnv = Java.Interop.JIFunctionPointers.JniEnvironment;
-
-public class XFieldInfo
-{
- public IntPtr ID;
- public bool IsStatic;
- public bool IsValid {get {return ID != IntPtr.Zero;}}
- public XFieldInfo (string name, string signature, IntPtr id, bool isStatic)
- {
- ID = id;
- IsStatic = isStatic;
- }
- public override string ToString ()
- {
- return string.Format ("{0}(0x{1})", GetType ().FullName, ID.ToString ("x"));
- }
-}
-
-public class XMethodInfo
-{
- public IntPtr ID;
- public bool IsStatic;
- public bool IsValid {get {return ID != IntPtr.Zero;}}
- public XMethodInfo (string name, string signature, IntPtr id, bool isStatic)
- {
- ID = id;
- IsStatic = isStatic;
- }
- public override string ToString ()
- {
- return string.Format ("{0}(0x{1})", GetType ().FullName, ID.ToString ("x"));
- }
-}
-
-namespace Java.Interop.JIIntPtrs {
- public class JniFieldInfo : XFieldInfo {
- public JniFieldInfo (string name, string signature, IntPtr id, bool isStatic)
- : base (name, signature, id, isStatic)
- {
- }
- }
- public class JniMethodInfo : XMethodInfo {
- public JniMethodInfo (string name, string signature, IntPtr id, bool isStatic)
- : base (name, signature, id, isStatic)
- {
- }
- }
- public struct JniObjectReference
- {
- public IntPtr Handle {get; private set;}
- public JniObjectReferenceType Type {get; private set;}
- public bool IsValid {
- get {
- return Handle != IntPtr.Zero;
- }
- }
-
- public JniObjectReference (IntPtr handle, JniObjectReferenceType type = JniObjectReferenceType.Invalid)
- {
- Handle = handle;
- Type = type;
- }
- }
- class JniEnvironmentInfo {
- public IntPtr EnvironmentPointer;
- public JniEnvironmentInvoker Invoker;
- }
- public static partial class JniEnvironment {
- internal static JniEnvironmentInfo CurrentInfo;
-
- internal static void LogCreateLocalRef (IntPtr value)
- {
- }
- public static Exception GetExceptionForLastThrowable ()
- {
- var v = JIIntPtrEnv.Exceptions.ExceptionOccurred ();
- var h = v.Handle;
- if (h == IntPtr.Zero)
- return null;
- JIIntPtrEnv.Exceptions.ExceptionClear ();
- LogCreateLocalRef (h);
- JIIntPtrEnv.References.DeleteLocalRef (h);
- return new Exception ("yada yada yada");
- }
- }
-}
-
-namespace Java.Interop.JIPinvokes {
- public class JniFieldInfo : XFieldInfo {
- public JniFieldInfo (string name, string signature, IntPtr id, bool isStatic)
- : base (name, signature, id, isStatic)
- {
- }
- }
- public class JniMethodInfo : XMethodInfo {
- public JniMethodInfo (string name, string signature, IntPtr id, bool isStatic)
- : base (name, signature, id, isStatic)
- {
- }
- }
- public struct JniObjectReference
- {
- public IntPtr Handle {get; private set;}
- public JniObjectReferenceType Type {get; private set;}
- public bool IsValid {
- get {
- return Handle != IntPtr.Zero;
- }
- }
-
- public JniObjectReference (IntPtr handle, JniObjectReferenceType type = JniObjectReferenceType.Invalid)
- {
- Handle = handle;
- Type = type;
- }
- }
- public static partial class JniEnvironment {
- public static IntPtr EnvironmentPointer;
-
- internal static void LogCreateLocalRef (IntPtr value)
- {
- }
- public static Exception GetExceptionForLastThrowable (IntPtr h)
- {
- if (h == IntPtr.Zero)
- return null;
- PinvokeEnv.Exceptions.ExceptionClear ();
- LogCreateLocalRef (h);
- var r = new JniObjectReference (h, JniObjectReferenceType.Local);
- PinvokeEnv.References.DeleteLocalRef (r.Handle);
- return new Exception ("yada yada yada");
- }
- public static Exception GetExceptionForLastThrowable ()
- {
- var v = JIIntPtrEnv.Exceptions.ExceptionOccurred ();
- var h = v.Handle;
- if (h == IntPtr.Zero)
- return null;
- PinvokeEnv.Exceptions.ExceptionClear ();
- LogCreateLocalRef (h);
- PinvokeEnv.References.DeleteLocalRef (h);
- return new Exception ("yada yada yada");
- }
- }
-}
-namespace Java.Interop.XAIntPtrs {
- public class JniFieldInfo : XFieldInfo {
- public JniFieldInfo (string name, string signature, IntPtr id, bool isStatic)
- : base (name, signature, id, isStatic)
- {
- }
- }
- public class JniMethodInfo : XMethodInfo {
- public JniMethodInfo (string name, string signature, IntPtr id, bool isStatic)
- : base (name, signature, id, isStatic)
- {
- }
- }
- public struct JniObjectReference
- {
- public IntPtr Handle {get; private set;}
- public JniObjectReferenceType Type {get; private set;}
- public bool IsValid {
- get {
- return Handle != IntPtr.Zero;
- }
- }
-
- public JniObjectReference (IntPtr handle, JniObjectReferenceType type = JniObjectReferenceType.Invalid)
- {
- Handle = handle;
- Type = type;
- }
- }
- class JniEnvironmentInfo {
- public IntPtr EnvironmentPointer;
- public JniEnvironmentInvoker Invoker;
- }
- public partial class JniEnvironment {
- internal static JniEnvironmentInfo CurrentInfo;
-
- internal static void LogCreateLocalRef (IntPtr value)
- {
- }
- public static Exception GetExceptionForLastThrowable ()
- {
- var h = XAIntPtrEnv.Exceptions.ExceptionOccurred ();
- if (h == IntPtr.Zero)
- return null;
- XAIntPtrEnv.Exceptions.ExceptionClear ();
- LogCreateLocalRef (h);
- XAIntPtrEnv.References.DeleteLocalRef (h);
- return new Exception ("yada yada yada");
- }
- }
-}
-
-namespace Java.Interop.JIFunctionPointers {
- public class JniFieldInfo : XFieldInfo {
- public JniFieldInfo (string name, string signature, IntPtr id, bool isStatic)
- : base (name, signature, id, isStatic)
- {
- }
- }
- public class JniMethodInfo : XMethodInfo {
- public JniMethodInfo (string name, string signature, IntPtr id, bool isStatic)
- : base (name, signature, id, isStatic)
- {
- }
- }
- public struct JniObjectReference
- {
- public IntPtr Handle {get; private set;}
- public JniObjectReferenceType Type {get; private set;}
- public bool IsValid {
- get {
- return Handle != IntPtr.Zero;
- }
- }
-
- public JniObjectReference (IntPtr handle, JniObjectReferenceType type = JniObjectReferenceType.Invalid)
- {
- Handle = handle;
- Type = type;
- }
- }
- public static partial class JniEnvironment {
- public static IntPtr EnvironmentPointer;
-
- internal static void LogCreateLocalRef (IntPtr value)
- {
- }
- public static Exception GetExceptionForLastThrowable (IntPtr h)
- {
- if (h == IntPtr.Zero)
- return null;
- JIFuncPtrEnv.Exceptions.ExceptionClear ();
- LogCreateLocalRef (h);
- var r = new JniObjectReference (h, JniObjectReferenceType.Local);
- JIFuncPtrEnv.References.DeleteLocalRef (r.Handle);
- return new Exception ("yada yada yada");
- }
- public static Exception GetExceptionForLastThrowable ()
- {
- var v = JIIntPtrEnv.Exceptions.ExceptionOccurred ();
- var h = v.Handle;
- if (h == IntPtr.Zero)
- return null;
- JIFuncPtrEnv.Exceptions.ExceptionClear ();
- LogCreateLocalRef (h);
- JIFuncPtrEnv.References.DeleteLocalRef (h);
- return new Exception ("yada yada yada");
- }
- }
-}
-
-class App {
-
- public static void Main ()
- {
- var path = Environment.GetEnvironmentVariable ("JI_JVM_PATH");
- if (string.IsNullOrEmpty (path)) {
- Console.Error.WriteLine ($"error: must set `JI_JVM_PATH` environment variable to path of JVM library to use.");
- return;
- }
- var runtimeOptions = new JreRuntimeOptions (){
- JvmLibraryPath = Environment.GetEnvironmentVariable ("JI_JVM_PATH"),
- };
- var GlobalRuntime = runtimeOptions.CreateJreVM ();
- IntPtr _env = global::Java.Interop.JniEnvironment.EnvironmentPointer;
-
- XAIntPtrTiming (_env);
- JIIntPtrTiming (_env);
- JIPinvokeTiming (_env);
- JIFunctionPointersTiming (_env);
-
- GlobalRuntime.Dispose ();
- }
-
- const int C = 10000000;
-
- static unsafe void JIIntPtrTiming (IntPtr _env)
- {
- JIIntPtrEnv.CurrentInfo = new Java.Interop.JIIntPtrs.JniEnvironmentInfo {
- EnvironmentPointer = _env,
- Invoker = new Java.Interop.JIIntPtrs.JniEnvironmentInvoker ((JniNativeInterfaceStruct*) Marshal.ReadIntPtr (_env)),
- };
- var Arrays_class = JIIntPtrEnv.Types._FindClass ("java/util/Arrays");
- var Arrays_binarySearch = JIIntPtrEnv.StaticMethods.GetStaticMethodID (Arrays_class, "binarySearch", "([II)I");
- var intArray = JIIntPtrEnv.Arrays.NewIntArray (3);
- fixed (int* p = new int[]{1,2,3})
- JIIntPtrEnv.Arrays.SetIntArrayRegion (intArray, 0, 3, p);
-
- var t = Stopwatch.StartNew ();
- var args = stackalloc JniArgumentValue [2];
- args [0] = new JniArgumentValue (intArray.Handle);
- args [1] = new JniArgumentValue (2);
- for (int i = 0; i < C; ++i) {
- int r = JIIntPtrEnv.StaticMethods.CallStaticIntMethod (Arrays_class, Arrays_binarySearch, args);
- }
- t.Stop ();
- Console.WriteLine ("# {0} timing: {1}", nameof (JIIntPtrTiming), t.Elapsed);
- Console.WriteLine ("#\tAverage Invocation: {0}ms", t.Elapsed.TotalMilliseconds / C);
- }
-
- static unsafe void JIPinvokeTiming (IntPtr _env)
- {
- PinvokeEnv.EnvironmentPointer = _env;
- var Arrays_class = PinvokeEnv.Types._FindClass ("java/util/Arrays");
- var Arrays_binarySearch = PinvokeEnv.StaticMethods.GetStaticMethodID (Arrays_class, "binarySearch", "([II)I");
- var intArray = PinvokeEnv.Arrays.NewIntArray (3);
- fixed (int* p = new int[]{1,2,3})
- PinvokeEnv.Arrays.SetIntArrayRegion (intArray, 0, 3, p);
-
- var t = Stopwatch.StartNew ();
- var args = stackalloc JniArgumentValue [2];
- args [0] = new JniArgumentValue (intArray.Handle);
- args [1] = new JniArgumentValue (2);
- for (int i = 0; i < C; ++i) {
- int r = PinvokeEnv.StaticMethods.CallStaticIntMethod (Arrays_class, Arrays_binarySearch, args);
- }
- t.Stop ();
- Console.WriteLine ("# {0} timing: {1}", nameof (JIPinvokeTiming), t.Elapsed);
- Console.WriteLine ("#\tAverage Invocation: {0}ms", t.Elapsed.TotalMilliseconds / C);
- }
-
- static unsafe void XAIntPtrTiming (IntPtr _env)
- {
- XAIntPtrEnv.CurrentInfo = new Java.Interop.XAIntPtrs.JniEnvironmentInfo {
- EnvironmentPointer = _env,
- Invoker = new Java.Interop.XAIntPtrs.JniEnvironmentInvoker ((JniNativeInterfaceStruct*) Marshal.ReadIntPtr (_env)),
- };
- var Arrays_class = XAIntPtrEnv.Types._FindClass ("java/util/Arrays");
- var Arrays_binarySearch = XAIntPtrEnv.StaticMethods.GetStaticMethodID (Arrays_class, "binarySearch", "([II)I");
- var intArray = XAIntPtrEnv.Arrays.NewIntArray (3);
- fixed (int* p = new int[]{1,2,3})
- XAIntPtrEnv.Arrays.SetIntArrayRegion (intArray, 0, 3, p);
-
- var t = Stopwatch.StartNew ();
- var args = stackalloc JniArgumentValue [2];
- args [0] = new JniArgumentValue (intArray);
- args [1] = new JniArgumentValue (2);
- for (int i = 0; i < C; ++i) {
- int r = XAIntPtrEnv.StaticMethods.CallStaticIntMethod (Arrays_class, Arrays_binarySearch, args);
- }
- t.Stop ();
- Console.WriteLine ("# {0} timing: {1}", nameof (XAIntPtrTiming), t.Elapsed);
- Console.WriteLine ("#\tAverage Invocation: {0}ms", t.Elapsed.TotalMilliseconds / C);
- }
-
- static unsafe void JIFunctionPointersTiming (IntPtr _env)
- {
- JIFuncPtrEnv.EnvironmentPointer = _env;
- var Arrays_class = JIFuncPtrEnv.Types._FindClass ("java/util/Arrays");
- var Arrays_binarySearch = JIFuncPtrEnv.StaticMethods.GetStaticMethodID (Arrays_class, "binarySearch", "([II)I");
- var intArray = JIFuncPtrEnv.Arrays.NewIntArray (3);
- fixed (int* p = new int[]{1,2,3})
- JIFuncPtrEnv.Arrays.SetIntArrayRegion (intArray, 0, 3, p);
-
- var t = Stopwatch.StartNew ();
- var args = stackalloc JniArgumentValue [2];
- args [0] = new JniArgumentValue (intArray.Handle);
- args [1] = new JniArgumentValue (2);
- for (int i = 0; i < C; ++i) {
- int r = JIFuncPtrEnv.StaticMethods.CallStaticIntMethod (Arrays_class, Arrays_binarySearch, args);
- }
- t.Stop ();
- Console.WriteLine ("# {0} timing: {1}", nameof (JIFunctionPointersTiming), t.Elapsed);
- Console.WriteLine ("#\tAverage Invocation: {0}ms", t.Elapsed.TotalMilliseconds / C);
- }
-}
diff --git a/tests/invocation-overhead/invocation-overhead.csproj b/tests/invocation-overhead/invocation-overhead.csproj
deleted file mode 100644
index 6b06224bc..000000000
--- a/tests/invocation-overhead/invocation-overhead.csproj
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-
- $(DotNetTargetFramework)
- Exe
- True
- True
- FEATURE_JNIENVIRONMENT_JI_INTPTRS;FEATURE_JNIENVIRONMENT_JI_PINVOKES;FEATURE_JNIENVIRONMENT_XA_INTPTRS;FEATURE_JNIENVIRONMENT_JI_FUNCTION_POINTERS
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/tests/invocation-overhead/invocation-overhead.targets b/tests/invocation-overhead/invocation-overhead.targets
deleted file mode 100644
index ada3761d5..000000000
--- a/tests/invocation-overhead/invocation-overhead.targets
+++ /dev/null
@@ -1,37 +0,0 @@
-
-
-
-
-
-
- <_NativeLibsSrc Include="$(ToolOutputFullPath)\libjava-interop.*" />
- <_NativeLibsDst Include="@(_NativeLibsSrc->'$(OutputPath)%(Filename)%(Extension)')" />
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/tests/invocation-overhead/jni-api.h b/tests/invocation-overhead/jni-api.h
deleted file mode 100644
index 012c34a29..000000000
--- a/tests/invocation-overhead/jni-api.h
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * Generated file; DO NOT EDIT!
- *
- * To make changes, edit Java.Interop/build-tools/jnienv-gen and rerun
- */
-
-#if !defined (__JAVA_INTEROP_NATIVE_H)
-#define __JAVA_INTEROP_NATIVE_H
-
-#include
-
-typedef jmethodID jstaticmethodID;
-typedef jfieldID jstaticfieldID;
-typedef jobject jglobal;
-
-#if !defined(JI_NO_VISIBILITY)
- /* VS 2010 and later have stdint.h */
- #if defined(_MSC_VER)
-
- #define JI_API_EXPORT __declspec(dllexport)
- #define JI_API_IMPORT __declspec(dllimport)
-
- #else /* defined(_MSC_VER */
-
- #define JI_API_EXPORT __attribute__ ((visibility ("default")))
- #define JI_API_IMPORT
-
- #endif /* !defined(_MSC_VER) */
-
- #if defined(JI_DLL_EXPORT)
- #define JI_API JI_API_EXPORT
- #elif defined(JI_DLL_IMPORT)
- #define JI_API JI_API_IMPORT
- #else /* !defined(JI_DLL_IMPORT) && !defined(JI_API_IMPORT) */
- #define JI_API
- #endif /* JI_DLL_EXPORT... */
-#else // JI_NO_VISIBILITY
- #define JI_API
-#endif // JI_NO_VISIBILITY
-
-JI_API jint java_interop_jnienv_get_version (JNIEnv *env);
-JI_API jclass java_interop_jnienv_define_class (JNIEnv *env, jthrowable *_thrown, const char* name, jobject loader, const jbyte* buffer, jsize bufferLength);
-JI_API jclass java_interop_jnienv_find_class (JNIEnv *env, jthrowable *_thrown, const char* classname);
-JI_API jobject java_interop_jnienv_to_reflected_method (JNIEnv *env, jthrowable *_thrown, jclass type, jmethodID method, jboolean isStatic);
-JI_API jclass java_interop_jnienv_get_superclass (JNIEnv *env, jclass type);
-JI_API jboolean java_interop_jnienv_is_assignable_from (JNIEnv *env, jclass class1, jclass class2);
-JI_API jobject java_interop_jnienv_to_reflected_field (JNIEnv *env, jthrowable *_thrown, jclass type, jfieldID field, jboolean isStatic);
-JI_API jint java_interop_jnienv_throw (JNIEnv *env, jthrowable toThrow);
-JI_API jint java_interop_jnienv_throw_new (JNIEnv *env, jclass type, const char* message);
-JI_API jthrowable java_interop_jnienv_exception_occurred (JNIEnv *env);
-JI_API void java_interop_jnienv_exception_describe (JNIEnv *env);
-JI_API void java_interop_jnienv_exception_clear (JNIEnv *env);
-JI_API void java_interop_jnienv_fatal_error (JNIEnv *env, const char* message);
-JI_API jint java_interop_jnienv_push_local_frame (JNIEnv *env, jint capacity);
-JI_API jobject java_interop_jnienv_pop_local_frame (JNIEnv *env, jobject result);
-JI_API jglobal java_interop_jnienv_new_global_ref (JNIEnv *env, jobject instance);
-JI_API void java_interop_jnienv_delete_global_ref (JNIEnv *env, jobject instance);
-JI_API void java_interop_jnienv_delete_local_ref (JNIEnv *env, jobject instance);
-JI_API jboolean java_interop_jnienv_is_same_object (JNIEnv *env, jobject object1, jobject object2);
-JI_API jobject java_interop_jnienv_new_local_ref (JNIEnv *env, jobject instance);
-JI_API jint java_interop_jnienv_ensure_local_capacity (JNIEnv *env, jint capacity);
-JI_API jobject java_interop_jnienv_alloc_object (JNIEnv *env, jthrowable *_thrown, jclass type);
-JI_API jobject java_interop_jnienv_new_object (JNIEnv *env, jthrowable *_thrown, jclass type, jmethodID method);
-JI_API jobject java_interop_jnienv_new_object_a (JNIEnv *env, jthrowable *_thrown, jclass type, jmethodID method, jvalue* args);
-JI_API jclass java_interop_jnienv_get_object_class (JNIEnv *env, jobject instance);
-JI_API jboolean java_interop_jnienv_is_instance_of (JNIEnv *env, jobject instance, jclass type);
-JI_API jmethodID java_interop_jnienv_get_method_id (JNIEnv *env, jthrowable *_thrown, jclass type, const char* name, const char* signature);
-JI_API jobject java_interop_jnienv_call_object_method (JNIEnv *env, jthrowable *_thrown, jobject instance, jmethodID method);
-JI_API jobject java_interop_jnienv_call_object_method_a (JNIEnv *env, jthrowable *_thrown, jobject instance, jmethodID method, jvalue* args);
-JI_API jboolean java_interop_jnienv_call_boolean_method (JNIEnv *env, jthrowable *_thrown, jobject instance, jmethodID method);
-JI_API jboolean java_interop_jnienv_call_boolean_method_a (JNIEnv *env, jthrowable *_thrown, jobject instance, jmethodID method, jvalue* args);
-JI_API jbyte java_interop_jnienv_call_byte_method (JNIEnv *env, jthrowable *_thrown, jobject instance, jmethodID method);
-JI_API jbyte java_interop_jnienv_call_byte_method_a (JNIEnv *env, jthrowable *_thrown, jobject instance, jmethodID method, jvalue* args);
-JI_API jchar java_interop_jnienv_call_char_method (JNIEnv *env, jthrowable *_thrown, jobject instance, jmethodID method);
-JI_API jchar java_interop_jnienv_call_char_method_a (JNIEnv *env, jthrowable *_thrown, jobject instance, jmethodID method, jvalue* args);
-JI_API jshort java_interop_jnienv_call_short_method (JNIEnv *env, jthrowable *_thrown, jobject instance, jmethodID method);
-JI_API jshort java_interop_jnienv_call_short_method_a (JNIEnv *env, jthrowable *_thrown, jobject instance, jmethodID method, jvalue* args);
-JI_API jint java_interop_jnienv_call_int_method (JNIEnv *env, jthrowable *_thrown, jobject instance, jmethodID method);
-JI_API jint java_interop_jnienv_call_int_method_a (JNIEnv *env, jthrowable *_thrown, jobject instance, jmethodID method, jvalue* args);
-JI_API jlong java_interop_jnienv_call_long_method (JNIEnv *env, jthrowable *_thrown, jobject instance, jmethodID method);
-JI_API jlong java_interop_jnienv_call_long_method_a (JNIEnv *env, jthrowable *_thrown, jobject instance, jmethodID method, jvalue* args);
-JI_API jfloat java_interop_jnienv_call_float_method (JNIEnv *env, jthrowable *_thrown, jobject instance, jmethodID method);
-JI_API jfloat java_interop_jnienv_call_float_method_a (JNIEnv *env, jthrowable *_thrown, jobject instance, jmethodID method, jvalue* args);
-JI_API jdouble java_interop_jnienv_call_double_method (JNIEnv *env, jthrowable *_thrown, jobject instance, jmethodID method);
-JI_API jdouble java_interop_jnienv_call_double_method_a (JNIEnv *env, jthrowable *_thrown, jobject instance, jmethodID method, jvalue* args);
-JI_API void java_interop_jnienv_call_void_method (JNIEnv *env, jthrowable *_thrown, jobject instance, jmethodID method);
-JI_API void java_interop_jnienv_call_void_method_a (JNIEnv *env, jthrowable *_thrown, jobject instance, jmethodID method, jvalue* args);
-JI_API jobject java_interop_jnienv_call_nonvirtual_object_method (JNIEnv *env, jthrowable *_thrown, jobject instance, jclass type, jmethodID method);
-JI_API jobject java_interop_jnienv_call_nonvirtual_object_method_a (JNIEnv *env, jthrowable *_thrown, jobject instance, jclass type, jmethodID method, jvalue* args);
-JI_API jboolean java_interop_jnienv_call_nonvirtual_boolean_method (JNIEnv *env, jthrowable *_thrown, jobject instance, jclass type, jmethodID method);
-JI_API jboolean java_interop_jnienv_call_nonvirtual_boolean_method_a (JNIEnv *env, jthrowable *_thrown, jobject instance, jclass type, jmethodID method, jvalue* args);
-JI_API jbyte java_interop_jnienv_call_nonvirtual_byte_method (JNIEnv *env, jthrowable *_thrown, jobject instance, jclass type, jmethodID method);
-JI_API jbyte java_interop_jnienv_call_nonvirtual_byte_method_a (JNIEnv *env, jthrowable *_thrown, jobject instance, jclass type, jmethodID method, jvalue* args);
-JI_API jchar java_interop_jnienv_call_nonvirtual_char_method (JNIEnv *env, jthrowable *_thrown, jobject instance, jclass type, jmethodID method);
-JI_API jchar java_interop_jnienv_call_nonvirtual_char_method_a (JNIEnv *env, jthrowable *_thrown, jobject instance, jclass type, jmethodID method, jvalue* args);
-JI_API jshort java_interop_jnienv_call_nonvirtual_short_method (JNIEnv *env, jthrowable *_thrown, jobject instance, jclass type, jmethodID method);
-JI_API jshort java_interop_jnienv_call_nonvirtual_short_method_a (JNIEnv *env, jthrowable *_thrown, jobject instance, jclass type, jmethodID method, jvalue* args);
-JI_API jint java_interop_jnienv_call_nonvirtual_int_method (JNIEnv *env, jthrowable *_thrown, jobject instance, jclass type, jmethodID method);
-JI_API jint java_interop_jnienv_call_nonvirtual_int_method_a (JNIEnv *env, jthrowable *_thrown, jobject instance, jclass type, jmethodID method, jvalue* args);
-JI_API jlong java_interop_jnienv_call_nonvirtual_long_method (JNIEnv *env, jthrowable *_thrown, jobject instance, jclass type, jmethodID method);
-JI_API jlong java_interop_jnienv_call_nonvirtual_long_method_a (JNIEnv *env, jthrowable *_thrown, jobject instance, jclass type, jmethodID method, jvalue* args);
-JI_API jfloat java_interop_jnienv_call_nonvirtual_float_method (JNIEnv *env, jthrowable *_thrown, jobject instance, jclass type, jmethodID method);
-JI_API jfloat java_interop_jnienv_call_nonvirtual_float_method_a (JNIEnv *env, jthrowable *_thrown, jobject instance, jclass type, jmethodID method, jvalue* args);
-JI_API jdouble java_interop_jnienv_call_nonvirtual_double_method (JNIEnv *env, jthrowable *_thrown, jobject instance, jclass type, jmethodID method);
-JI_API jdouble java_interop_jnienv_call_nonvirtual_double_method_a (JNIEnv *env, jthrowable *_thrown, jobject instance, jclass type, jmethodID method, jvalue* args);
-JI_API void java_interop_jnienv_call_nonvirtual_void_method (JNIEnv *env, jthrowable *_thrown, jobject instance, jclass type, jmethodID method);
-JI_API void java_interop_jnienv_call_nonvirtual_void_method_a (JNIEnv *env, jthrowable *_thrown, jobject instance, jclass type, jmethodID method, jvalue* args);
-JI_API jfieldID java_interop_jnienv_get_field_id (JNIEnv *env, jthrowable *_thrown, jclass type, const char* name, const char* signature);
-JI_API jobject java_interop_jnienv_get_object_field (JNIEnv *env, jobject instance, jfieldID field);
-JI_API jboolean java_interop_jnienv_get_boolean_field (JNIEnv *env, jobject instance, jfieldID field);
-JI_API jbyte java_interop_jnienv_get_byte_field (JNIEnv *env, jobject instance, jfieldID field);
-JI_API jchar java_interop_jnienv_get_char_field (JNIEnv *env, jobject instance, jfieldID field);
-JI_API jshort java_interop_jnienv_get_short_field (JNIEnv *env, jobject instance, jfieldID field);
-JI_API jint java_interop_jnienv_get_int_field (JNIEnv *env, jobject instance, jfieldID field);
-JI_API jlong java_interop_jnienv_get_long_field (JNIEnv *env, jobject instance, jfieldID field);
-JI_API jfloat java_interop_jnienv_get_float_field (JNIEnv *env, jobject instance, jfieldID field);
-JI_API jdouble java_interop_jnienv_get_double_field (JNIEnv *env, jobject instance, jfieldID field);
-JI_API void java_interop_jnienv_set_object_field (JNIEnv *env, jobject instance, jfieldID field, jobject value);
-JI_API void java_interop_jnienv_set_boolean_field (JNIEnv *env, jobject instance, jfieldID field, jboolean value);
-JI_API void java_interop_jnienv_set_byte_field (JNIEnv *env, jobject instance, jfieldID field, jbyte value);
-JI_API void java_interop_jnienv_set_char_field (JNIEnv *env, jobject instance, jfieldID field, jchar value);
-JI_API void java_interop_jnienv_set_short_field (JNIEnv *env, jobject instance, jfieldID field, jshort value);
-JI_API void java_interop_jnienv_set_int_field (JNIEnv *env, jobject instance, jfieldID field, jint value);
-JI_API void java_interop_jnienv_set_long_field (JNIEnv *env, jobject instance, jfieldID field, jlong value);
-JI_API void java_interop_jnienv_set_float_field (JNIEnv *env, jobject instance, jfieldID field, jfloat value);
-JI_API void java_interop_jnienv_set_double_field (JNIEnv *env, jobject instance, jfieldID field, jdouble value);
-JI_API jstaticmethodID java_interop_jnienv_get_static_method_id (JNIEnv *env, jthrowable *_thrown, jclass type, const char* name, const char* signature);
-JI_API jobject java_interop_jnienv_call_static_object_method (JNIEnv *env, jthrowable *_thrown, jclass type, jstaticmethodID method);
-JI_API jobject java_interop_jnienv_call_static_object_method_a (JNIEnv *env, jthrowable *_thrown, jclass type, jstaticmethodID method, jvalue* args);
-JI_API jboolean java_interop_jnienv_call_static_boolean_method (JNIEnv *env, jthrowable *_thrown, jclass type, jstaticmethodID method);
-JI_API jboolean java_interop_jnienv_call_static_boolean_method_a (JNIEnv *env, jthrowable *_thrown, jclass type, jstaticmethodID method, jvalue* args);
-JI_API jbyte java_interop_jnienv_call_static_byte_method (JNIEnv *env, jthrowable *_thrown, jclass type, jstaticmethodID method);
-JI_API jbyte java_interop_jnienv_call_static_byte_method_a (JNIEnv *env, jthrowable *_thrown, jclass type, jstaticmethodID method, jvalue* args);
-JI_API jchar java_interop_jnienv_call_static_char_method (JNIEnv *env, jthrowable *_thrown, jclass type, jstaticmethodID method);
-JI_API jchar java_interop_jnienv_call_static_char_method_a (JNIEnv *env, jthrowable *_thrown, jclass type, jstaticmethodID method, jvalue* args);
-JI_API jshort java_interop_jnienv_call_static_short_method (JNIEnv *env, jthrowable *_thrown, jclass type, jstaticmethodID method);
-JI_API jshort java_interop_jnienv_call_static_short_method_a (JNIEnv *env, jthrowable *_thrown, jclass type, jstaticmethodID method, jvalue* args);
-JI_API jint java_interop_jnienv_call_static_int_method (JNIEnv *env, jthrowable *_thrown, jclass type, jstaticmethodID method);
-JI_API jint java_interop_jnienv_call_static_int_method_a (JNIEnv *env, jthrowable *_thrown, jclass type, jstaticmethodID method, jvalue* args);
-JI_API jlong java_interop_jnienv_call_static_long_method (JNIEnv *env, jthrowable *_thrown, jclass type, jstaticmethodID method);
-JI_API jlong java_interop_jnienv_call_static_long_method_a (JNIEnv *env, jthrowable *_thrown, jclass type, jstaticmethodID method, jvalue* args);
-JI_API jfloat java_interop_jnienv_call_static_float_method (JNIEnv *env, jthrowable *_thrown, jclass type, jstaticmethodID method);
-JI_API jfloat java_interop_jnienv_call_static_float_method_a (JNIEnv *env, jthrowable *_thrown, jclass type, jstaticmethodID method, jvalue* args);
-JI_API jdouble java_interop_jnienv_call_static_double_method (JNIEnv *env, jthrowable *_thrown, jclass type, jstaticmethodID method);
-JI_API jdouble java_interop_jnienv_call_static_double_method_a (JNIEnv *env, jthrowable *_thrown, jclass type, jstaticmethodID method, jvalue* args);
-JI_API void java_interop_jnienv_call_static_void_method (JNIEnv *env, jthrowable *_thrown, jclass type, jstaticmethodID method);
-JI_API void java_interop_jnienv_call_static_void_method_a (JNIEnv *env, jthrowable *_thrown, jclass type, jstaticmethodID method, jvalue* args);
-JI_API jstaticfieldID java_interop_jnienv_get_static_field_id (JNIEnv *env, jthrowable *_thrown, jclass type, const char* name, const char* signature);
-JI_API jobject java_interop_jnienv_get_static_object_field (JNIEnv *env, jclass type, jstaticfieldID field);
-JI_API jboolean java_interop_jnienv_get_static_boolean_field (JNIEnv *env, jclass type, jstaticfieldID field);
-JI_API jbyte java_interop_jnienv_get_static_byte_field (JNIEnv *env, jclass type, jstaticfieldID field);
-JI_API jchar java_interop_jnienv_get_static_char_field (JNIEnv *env, jclass type, jstaticfieldID field);
-JI_API jshort java_interop_jnienv_get_static_short_field (JNIEnv *env, jclass type, jstaticfieldID field);
-JI_API jint java_interop_jnienv_get_static_int_field (JNIEnv *env, jclass type, jstaticfieldID field);
-JI_API jlong java_interop_jnienv_get_static_long_field (JNIEnv *env, jclass type, jstaticfieldID field);
-JI_API jfloat java_interop_jnienv_get_static_float_field (JNIEnv *env, jclass type, jstaticfieldID field);
-JI_API jdouble java_interop_jnienv_get_static_double_field (JNIEnv *env, jclass type, jstaticfieldID field);
-JI_API void java_interop_jnienv_set_static_object_field (JNIEnv *env, jclass type, jstaticfieldID field, jobject value);
-JI_API void java_interop_jnienv_set_static_boolean_field (JNIEnv *env, jclass type, jstaticfieldID field, jboolean value);
-JI_API void java_interop_jnienv_set_static_byte_field (JNIEnv *env, jclass type, jstaticfieldID field, jbyte value);
-JI_API void java_interop_jnienv_set_static_char_field (JNIEnv *env, jclass type, jstaticfieldID field, jchar value);
-JI_API void java_interop_jnienv_set_static_short_field (JNIEnv *env, jclass type, jstaticfieldID field, jshort value);
-JI_API void java_interop_jnienv_set_static_int_field (JNIEnv *env, jclass type, jstaticfieldID field, jint value);
-JI_API void java_interop_jnienv_set_static_long_field (JNIEnv *env, jclass type, jstaticfieldID field, jlong value);
-JI_API void java_interop_jnienv_set_static_float_field (JNIEnv *env, jclass type, jstaticfieldID field, jfloat value);
-JI_API void java_interop_jnienv_set_static_double_field (JNIEnv *env, jclass type, jstaticfieldID field, jdouble value);
-JI_API jstring java_interop_jnienv_new_string (JNIEnv *env, jthrowable *_thrown, jchar* unicodeChars, jsize length);
-JI_API jsize java_interop_jnienv_get_string_length (JNIEnv *env, jstring stringInstance);
-JI_API const jchar* java_interop_jnienv_get_string_chars (JNIEnv *env, jstring stringInstance, jboolean* isCopy);
-JI_API void java_interop_jnienv_release_string_chars (JNIEnv *env, jstring stringInstance, jchar* chars);
-JI_API jsize java_interop_jnienv_get_array_length (JNIEnv *env, jarray array);
-JI_API jobjectArray java_interop_jnienv_new_object_array (JNIEnv *env, jthrowable *_thrown, jsize length, jclass elementClass, jobject initialElement);
-JI_API jobject java_interop_jnienv_get_object_array_element (JNIEnv *env, jthrowable *_thrown, jobjectArray array, jsize index);
-JI_API void java_interop_jnienv_set_object_array_element (JNIEnv *env, jthrowable *_thrown, jobjectArray array, jsize index, jobject value);
-JI_API jbooleanArray java_interop_jnienv_new_boolean_array (JNIEnv *env, jsize length);
-JI_API jbyteArray java_interop_jnienv_new_byte_array (JNIEnv *env, jsize length);
-JI_API jcharArray java_interop_jnienv_new_char_array (JNIEnv *env, jsize length);
-JI_API jshortArray java_interop_jnienv_new_short_array (JNIEnv *env, jsize length);
-JI_API jintArray java_interop_jnienv_new_int_array (JNIEnv *env, jsize length);
-JI_API jlongArray java_interop_jnienv_new_long_array (JNIEnv *env, jsize length);
-JI_API jfloatArray java_interop_jnienv_new_float_array (JNIEnv *env, jsize length);
-JI_API jdoubleArray java_interop_jnienv_new_double_array (JNIEnv *env, jsize length);
-JI_API jboolean* java_interop_jnienv_get_boolean_array_elements (JNIEnv *env, jbooleanArray array, jboolean* isCopy);
-JI_API jbyte* java_interop_jnienv_get_byte_array_elements (JNIEnv *env, jbyteArray array, jboolean* isCopy);
-JI_API jchar* java_interop_jnienv_get_char_array_elements (JNIEnv *env, jcharArray array, jboolean* isCopy);
-JI_API jshort* java_interop_jnienv_get_short_array_elements (JNIEnv *env, jshortArray array, jboolean* isCopy);
-JI_API jint* java_interop_jnienv_get_int_array_elements (JNIEnv *env, jintArray array, jboolean* isCopy);
-JI_API jlong* java_interop_jnienv_get_long_array_elements (JNIEnv *env, jlongArray array, jboolean* isCopy);
-JI_API jfloat* java_interop_jnienv_get_float_array_elements (JNIEnv *env, jfloatArray array, jboolean* isCopy);
-JI_API jdouble* java_interop_jnienv_get_double_array_elements (JNIEnv *env, jdoubleArray array, jboolean* isCopy);
-JI_API void java_interop_jnienv_release_boolean_array_elements (JNIEnv *env, jbooleanArray array, jboolean* elements, jint mode);
-JI_API void java_interop_jnienv_release_byte_array_elements (JNIEnv *env, jbyteArray array, jbyte* elements, jint mode);
-JI_API void java_interop_jnienv_release_char_array_elements (JNIEnv *env, jcharArray array, jchar* elements, jint mode);
-JI_API void java_interop_jnienv_release_short_array_elements (JNIEnv *env, jshortArray array, jshort* elements, jint mode);
-JI_API void java_interop_jnienv_release_int_array_elements (JNIEnv *env, jintArray array, jint* elements, jint mode);
-JI_API void java_interop_jnienv_release_long_array_elements (JNIEnv *env, jlongArray array, jlong* elements, jint mode);
-JI_API void java_interop_jnienv_release_float_array_elements (JNIEnv *env, jfloatArray array, jfloat* elements, jint mode);
-JI_API void java_interop_jnienv_release_double_array_elements (JNIEnv *env, jdoubleArray array, jdouble* elements, jint mode);
-JI_API void java_interop_jnienv_get_boolean_array_region (JNIEnv *env, jthrowable *_thrown, jbooleanArray array, jsize start, jsize length, jboolean* buffer);
-JI_API void java_interop_jnienv_get_byte_array_region (JNIEnv *env, jthrowable *_thrown, jbyteArray array, jsize start, jsize length, jbyte* buffer);
-JI_API void java_interop_jnienv_get_char_array_region (JNIEnv *env, jthrowable *_thrown, jcharArray array, jsize start, jsize length, jchar* buffer);
-JI_API void java_interop_jnienv_get_short_array_region (JNIEnv *env, jthrowable *_thrown, jshortArray array, jsize start, jsize length, jshort* buffer);
-JI_API void java_interop_jnienv_get_int_array_region (JNIEnv *env, jthrowable *_thrown, jintArray array, jsize start, jsize length, jint* buffer);
-JI_API void java_interop_jnienv_get_long_array_region (JNIEnv *env, jthrowable *_thrown, jlongArray array, jsize start, jsize length, jlong* buffer);
-JI_API void java_interop_jnienv_get_float_array_region (JNIEnv *env, jthrowable *_thrown, jlongArray array, jsize start, jsize length, jfloat* buffer);
-JI_API void java_interop_jnienv_get_double_array_region (JNIEnv *env, jthrowable *_thrown, jdoubleArray array, jsize start, jsize length, jdouble* buffer);
-JI_API void java_interop_jnienv_set_boolean_array_region (JNIEnv *env, jthrowable *_thrown, jbooleanArray array, jsize start, jsize length, jboolean* buffer);
-JI_API void java_interop_jnienv_set_byte_array_region (JNIEnv *env, jthrowable *_thrown, jbyteArray array, jsize start, jsize length, jbyte* buffer);
-JI_API void java_interop_jnienv_set_char_array_region (JNIEnv *env, jthrowable *_thrown, jcharArray array, jsize start, jsize length, const jchar* buffer);
-JI_API void java_interop_jnienv_set_short_array_region (JNIEnv *env, jthrowable *_thrown, jshortArray array, jsize start, jsize length, jshort* buffer);
-JI_API void java_interop_jnienv_set_int_array_region (JNIEnv *env, jthrowable *_thrown, jintArray array, jsize start, jsize length, jint* buffer);
-JI_API void java_interop_jnienv_set_long_array_region (JNIEnv *env, jthrowable *_thrown, jlongArray array, jsize start, jsize length, jlong* buffer);
-JI_API void java_interop_jnienv_set_float_array_region (JNIEnv *env, jthrowable *_thrown, jfloatArray array, jsize start, jsize length, jfloat* buffer);
-JI_API void java_interop_jnienv_set_double_array_region (JNIEnv *env, jthrowable *_thrown, jdoubleArray array, jsize start, jsize length, jdouble* buffer);
-JI_API jint java_interop_jnienv_register_natives (JNIEnv *env, jthrowable *_thrown, jclass type, const JNINativeMethod* methods, jint numMethods);
-JI_API jint java_interop_jnienv_unregister_natives (JNIEnv *env, jclass type);
-JI_API jint java_interop_jnienv_monitor_enter (JNIEnv *env, jobject instance);
-JI_API jint java_interop_jnienv_monitor_exit (JNIEnv *env, jobject instance);
-JI_API jint java_interop_jnienv_get_java_vm (JNIEnv *env, JavaVM** vm);
-JI_API void* java_interop_jnienv_get_primitive_array_critical (JNIEnv *env, jarray array, jboolean* isCopy);
-JI_API void java_interop_jnienv_release_primitive_array_critical (JNIEnv *env, jarray array, void* carray, jint mode);
-JI_API jweak java_interop_jnienv_new_weak_global_ref (JNIEnv *env, jobject instance);
-JI_API void java_interop_jnienv_delete_weak_global_ref (JNIEnv *env, jobject instance);
-JI_API jboolean java_interop_jnienv_exception_check (JNIEnv *env);
-JI_API jobject java_interop_jnienv_new_direct_byte_buffer (JNIEnv *env, jthrowable *_thrown, void* address, jlong capacity);
-JI_API void* java_interop_jnienv_get_direct_buffer_address (JNIEnv *env, jobject buffer);
-JI_API jlong java_interop_jnienv_get_direct_buffer_capacity (JNIEnv *env, jobject buffer);
-JI_API jobjectRefType java_interop_jnienv_get_object_ref_type (JNIEnv *env, jobject instance);
-
-#endif // __JAVA_INTEROP_NATIVE_H
diff --git a/tests/invocation-overhead/jni.c b/tests/invocation-overhead/jni.c
deleted file mode 100644
index e26ea59ab..000000000
--- a/tests/invocation-overhead/jni.c
+++ /dev/null
@@ -1,1452 +0,0 @@
-/*
- * Generated file; DO NOT EDIT!
- *
- * To make changes, edit Java.Interop/build-tools/jnienv-gen and rerun
- */
-
-#include "jni-api.h"
-
-JI_API jint
-java_interop_jnienv_get_version (JNIEnv *env)
-{
- jint _r_ = (*env)->GetVersion (env);
- return _r_;
-}
-
-JI_API jclass
-java_interop_jnienv_define_class (JNIEnv *env, jthrowable *_thrown, const char* name, jobject loader, const jbyte* buffer, jsize bufferLength)
-{
- *_thrown = 0;
- jclass _r_ = (*env)->DefineClass (env, name, loader, buffer, bufferLength);
- *_thrown = (*env)->ExceptionOccurred (env);
- return _r_;
-}
-
-JI_API jclass
-java_interop_jnienv_find_class (JNIEnv *env, jthrowable *_thrown, const char* classname)
-{
- *_thrown = 0;
- jclass _r_ = (*env)->FindClass (env, classname);
- *_thrown = (*env)->ExceptionOccurred (env);
- return _r_;
-}
-
-JI_API jobject
-java_interop_jnienv_to_reflected_method (JNIEnv *env, jthrowable *_thrown, jclass type, jmethodID method, jboolean isStatic)
-{
- *_thrown = 0;
- jobject _r_ = (*env)->ToReflectedMethod (env, type, method, isStatic);
- *_thrown = (*env)->ExceptionOccurred (env);
- return _r_;
-}
-
-JI_API jclass
-java_interop_jnienv_get_superclass (JNIEnv *env, jclass type)
-{
- jclass _r_ = (*env)->GetSuperclass (env, type);
- return _r_;
-}
-
-JI_API jboolean
-java_interop_jnienv_is_assignable_from (JNIEnv *env, jclass class1, jclass class2)
-{
- jboolean _r_ = (*env)->IsAssignableFrom (env, class1, class2);
- return _r_;
-}
-
-JI_API jobject
-java_interop_jnienv_to_reflected_field (JNIEnv *env, jthrowable *_thrown, jclass type, jfieldID field, jboolean isStatic)
-{
- *_thrown = 0;
- jobject _r_ = (*env)->ToReflectedField (env, type, field, isStatic);
- *_thrown = (*env)->ExceptionOccurred (env);
- return _r_;
-}
-
-JI_API jint
-java_interop_jnienv_throw (JNIEnv *env, jthrowable toThrow)
-{
- jint _r_ = (*env)->Throw (env, toThrow);
- return _r_;
-}
-
-JI_API jint
-java_interop_jnienv_throw_new (JNIEnv *env, jclass type, const char* message)
-{
- jint _r_ = (*env)->ThrowNew (env, type, message);
- return _r_;
-}
-
-JI_API jthrowable
-java_interop_jnienv_exception_occurred (JNIEnv *env)
-{
- jthrowable _r_ = (*env)->ExceptionOccurred (env);
- return _r_;
-}
-
-JI_API void
-java_interop_jnienv_exception_describe (JNIEnv *env)
-{
- (*env)->ExceptionDescribe (env);
-}
-
-JI_API void
-java_interop_jnienv_exception_clear (JNIEnv *env)
-{
- (*env)->ExceptionClear (env);
-}
-
-JI_API void
-java_interop_jnienv_fatal_error (JNIEnv *env, const char* message)
-{
- (*env)->FatalError (env, message);
-}
-
-JI_API jint
-java_interop_jnienv_push_local_frame (JNIEnv *env, jint capacity)
-{
- jint _r_ = (*env)->PushLocalFrame (env, capacity);
- return _r_;
-}
-
-JI_API jobject
-java_interop_jnienv_pop_local_frame (JNIEnv *env, jobject result)
-{
- jobject _r_ = (*env)->PopLocalFrame (env, result);
- return _r_;
-}
-
-JI_API jglobal
-java_interop_jnienv_new_global_ref (JNIEnv *env, jobject instance)
-{
- jglobal _r_ = (*env)->NewGlobalRef (env, instance);
- return _r_;
-}
-
-JI_API void
-java_interop_jnienv_delete_global_ref (JNIEnv *env, jobject instance)
-{
- (*env)->DeleteGlobalRef (env, instance);
-}
-
-JI_API void
-java_interop_jnienv_delete_local_ref (JNIEnv *env, jobject instance)
-{
- (*env)->DeleteLocalRef (env, instance);
-}
-
-JI_API jboolean
-java_interop_jnienv_is_same_object (JNIEnv *env, jobject object1, jobject object2)
-{
- jboolean _r_ = (*env)->IsSameObject (env, object1, object2);
- return _r_;
-}
-
-JI_API jobject
-java_interop_jnienv_new_local_ref (JNIEnv *env, jobject instance)
-{
- jobject _r_ = (*env)->NewLocalRef (env, instance);
- return _r_;
-}
-
-JI_API jint
-java_interop_jnienv_ensure_local_capacity (JNIEnv *env, jint capacity)
-{
- jint _r_ = (*env)->EnsureLocalCapacity (env, capacity);
- return _r_;
-}
-
-JI_API jobject
-java_interop_jnienv_alloc_object (JNIEnv *env, jthrowable *_thrown, jclass type)
-{
- *_thrown = 0;
- jobject _r_ = (*env)->AllocObject (env, type);
- *_thrown = (*env)->ExceptionOccurred (env);
- return _r_;
-}
-
-JI_API jobject
-java_interop_jnienv_new_object (JNIEnv *env, jthrowable *_thrown, jclass type, jmethodID method)
-{
- *_thrown = 0;
- jobject _r_ = (*env)->NewObject (env, type, method);
- *_thrown = (*env)->ExceptionOccurred (env);
- return _r_;
-}
-
-JI_API jobject
-java_interop_jnienv_new_object_a (JNIEnv *env, jthrowable *_thrown, jclass type, jmethodID method, jvalue* args)
-{
- *_thrown = 0;
- jobject _r_ = (*env)->NewObjectA (env, type, method, args);
- *_thrown = (*env)->ExceptionOccurred (env);
- return _r_;
-}
-
-JI_API jclass
-java_interop_jnienv_get_object_class (JNIEnv *env, jobject instance)
-{
- jclass _r_ = (*env)->GetObjectClass (env, instance);
- return _r_;
-}
-
-JI_API jboolean
-java_interop_jnienv_is_instance_of (JNIEnv *env, jobject instance, jclass type)
-{
- jboolean _r_ = (*env)->IsInstanceOf (env, instance, type);
- return _r_;
-}
-
-JI_API jmethodID
-java_interop_jnienv_get_method_id (JNIEnv *env, jthrowable *_thrown, jclass type, const char* name, const char* signature)
-{
- *_thrown = 0;
- jmethodID _r_ = (*env)->GetMethodID (env, type, name, signature);
- *_thrown = (*env)->ExceptionOccurred (env);
- return _r_;
-}
-
-JI_API jobject
-java_interop_jnienv_call_object_method (JNIEnv *env, jthrowable *_thrown, jobject instance, jmethodID method)
-{
- *_thrown = 0;
- jobject _r_ = (*env)->CallObjectMethod (env, instance, method);
- *_thrown = (*env)->ExceptionOccurred (env);
- return _r_;
-}
-
-JI_API jobject
-java_interop_jnienv_call_object_method_a (JNIEnv *env, jthrowable *_thrown, jobject instance, jmethodID method, jvalue* args)
-{
- *_thrown = 0;
- jobject _r_ = (*env)->CallObjectMethodA (env, instance, method, args);
- *_thrown = (*env)->ExceptionOccurred (env);
- return _r_;
-}
-
-JI_API jboolean
-java_interop_jnienv_call_boolean_method (JNIEnv *env, jthrowable *_thrown, jobject instance, jmethodID method)
-{
- *_thrown = 0;
- jboolean _r_ = (*env)->CallBooleanMethod (env, instance, method);
- *_thrown = (*env)->ExceptionOccurred (env);
- return _r_;
-}
-
-JI_API jboolean
-java_interop_jnienv_call_boolean_method_a (JNIEnv *env, jthrowable *_thrown, jobject instance, jmethodID method, jvalue* args)
-{
- *_thrown = 0;
- jboolean _r_ = (*env)->CallBooleanMethodA (env, instance, method, args);
- *_thrown = (*env)->ExceptionOccurred (env);
- return _r_;
-}
-
-JI_API jbyte
-java_interop_jnienv_call_byte_method (JNIEnv *env, jthrowable *_thrown, jobject instance, jmethodID method)
-{
- *_thrown = 0;
- jbyte _r_ = (*env)->CallByteMethod (env, instance, method);
- *_thrown = (*env)->ExceptionOccurred (env);
- return _r_;
-}
-
-JI_API jbyte
-java_interop_jnienv_call_byte_method_a (JNIEnv *env, jthrowable *_thrown, jobject instance, jmethodID method, jvalue* args)
-{
- *_thrown = 0;
- jbyte _r_ = (*env)->CallByteMethodA (env, instance, method, args);
- *_thrown = (*env)->ExceptionOccurred (env);
- return _r_;
-}
-
-JI_API jchar
-java_interop_jnienv_call_char_method (JNIEnv *env, jthrowable *_thrown, jobject instance, jmethodID method)
-{
- *_thrown = 0;
- jchar _r_ = (*env)->CallCharMethod (env, instance, method);
- *_thrown = (*env)->ExceptionOccurred (env);
- return _r_;
-}
-
-JI_API jchar
-java_interop_jnienv_call_char_method_a (JNIEnv *env, jthrowable *_thrown, jobject instance, jmethodID method, jvalue* args)
-{
- *_thrown = 0;
- jchar _r_ = (*env)->CallCharMethodA (env, instance, method, args);
- *_thrown = (*env)->ExceptionOccurred (env);
- return _r_;
-}
-
-JI_API jshort
-java_interop_jnienv_call_short_method (JNIEnv *env, jthrowable *_thrown, jobject instance, jmethodID method)
-{
- *_thrown = 0;
- jshort _r_ = (*env)->CallShortMethod (env, instance, method);
- *_thrown = (*env)->ExceptionOccurred (env);
- return _r_;
-}
-
-JI_API jshort
-java_interop_jnienv_call_short_method_a (JNIEnv *env, jthrowable *_thrown, jobject instance, jmethodID method, jvalue* args)
-{
- *_thrown = 0;
- jshort _r_ = (*env)->CallShortMethodA (env, instance, method, args);
- *_thrown = (*env)->ExceptionOccurred (env);
- return _r_;
-}
-
-JI_API jint
-java_interop_jnienv_call_int_method (JNIEnv *env, jthrowable *_thrown, jobject instance, jmethodID method)
-{
- *_thrown = 0;
- jint _r_ = (*env)->CallIntMethod (env, instance, method);
- *_thrown = (*env)->ExceptionOccurred (env);
- return _r_;
-}
-
-JI_API jint
-java_interop_jnienv_call_int_method_a (JNIEnv *env, jthrowable *_thrown, jobject instance, jmethodID method, jvalue* args)
-{
- *_thrown = 0;
- jint _r_ = (*env)->CallIntMethodA (env, instance, method, args);
- *_thrown = (*env)->ExceptionOccurred (env);
- return _r_;
-}
-
-JI_API jlong
-java_interop_jnienv_call_long_method (JNIEnv *env, jthrowable *_thrown, jobject instance, jmethodID method)
-{
- *_thrown = 0;
- jlong _r_ = (*env)->CallLongMethod (env, instance, method);
- *_thrown = (*env)->ExceptionOccurred (env);
- return _r_;
-}
-
-JI_API jlong
-java_interop_jnienv_call_long_method_a (JNIEnv *env, jthrowable *_thrown, jobject instance, jmethodID method, jvalue* args)
-{
- *_thrown = 0;
- jlong _r_ = (*env)->CallLongMethodA (env, instance, method, args);
- *_thrown = (*env)->ExceptionOccurred (env);
- return _r_;
-}
-
-JI_API jfloat
-java_interop_jnienv_call_float_method (JNIEnv *env, jthrowable *_thrown, jobject instance, jmethodID method)
-{
- *_thrown = 0;
- jfloat _r_ = (*env)->CallFloatMethod (env, instance, method);
- *_thrown = (*env)->ExceptionOccurred (env);
- return _r_;
-}
-
-JI_API jfloat
-java_interop_jnienv_call_float_method_a (JNIEnv *env, jthrowable *_thrown, jobject instance, jmethodID method, jvalue* args)
-{
- *_thrown = 0;
- jfloat _r_ = (*env)->CallFloatMethodA (env, instance, method, args);
- *_thrown = (*env)->ExceptionOccurred (env);
- return _r_;
-}
-
-JI_API jdouble
-java_interop_jnienv_call_double_method (JNIEnv *env, jthrowable *_thrown, jobject instance, jmethodID method)
-{
- *_thrown = 0;
- jdouble _r_ = (*env)->CallDoubleMethod (env, instance, method);
- *_thrown = (*env)->ExceptionOccurred (env);
- return _r_;
-}
-
-JI_API jdouble
-java_interop_jnienv_call_double_method_a (JNIEnv *env, jthrowable *_thrown, jobject instance, jmethodID method, jvalue* args)
-{
- *_thrown = 0;
- jdouble _r_ = (*env)->CallDoubleMethodA (env, instance, method, args);
- *_thrown = (*env)->ExceptionOccurred (env);
- return _r_;
-}
-
-JI_API void
-java_interop_jnienv_call_void_method (JNIEnv *env, jthrowable *_thrown, jobject instance, jmethodID method)
-{
- *_thrown = 0;
- (*env)->CallVoidMethod (env, instance, method);
- *_thrown = (*env)->ExceptionOccurred (env);
-}
-
-JI_API void
-java_interop_jnienv_call_void_method_a (JNIEnv *env, jthrowable *_thrown, jobject instance, jmethodID method, jvalue* args)
-{
- *_thrown = 0;
- (*env)->CallVoidMethodA (env, instance, method, args);
- *_thrown = (*env)->ExceptionOccurred (env);
-}
-
-JI_API jobject
-java_interop_jnienv_call_nonvirtual_object_method (JNIEnv *env, jthrowable *_thrown, jobject instance, jclass type, jmethodID method)
-{
- *_thrown = 0;
- jobject _r_ = (*env)->CallNonvirtualObjectMethod (env, instance, type, method);
- *_thrown = (*env)->ExceptionOccurred (env);
- return _r_;
-}
-
-JI_API jobject
-java_interop_jnienv_call_nonvirtual_object_method_a (JNIEnv *env, jthrowable *_thrown, jobject instance, jclass type, jmethodID method, jvalue* args)
-{
- *_thrown = 0;
- jobject _r_ = (*env)->CallNonvirtualObjectMethodA (env, instance, type, method, args);
- *_thrown = (*env)->ExceptionOccurred (env);
- return _r_;
-}
-
-JI_API jboolean
-java_interop_jnienv_call_nonvirtual_boolean_method (JNIEnv *env, jthrowable *_thrown, jobject instance, jclass type, jmethodID method)
-{
- *_thrown = 0;
- jboolean _r_ = (*env)->CallNonvirtualBooleanMethod (env, instance, type, method);
- *_thrown = (*env)->ExceptionOccurred (env);
- return _r_;
-}
-
-JI_API jboolean
-java_interop_jnienv_call_nonvirtual_boolean_method_a (JNIEnv *env, jthrowable *_thrown, jobject instance, jclass type, jmethodID method, jvalue* args)
-{
- *_thrown = 0;
- jboolean _r_ = (*env)->CallNonvirtualBooleanMethodA (env, instance, type, method, args);
- *_thrown = (*env)->ExceptionOccurred (env);
- return _r_;
-}
-
-JI_API jbyte
-java_interop_jnienv_call_nonvirtual_byte_method (JNIEnv *env, jthrowable *_thrown, jobject instance, jclass type, jmethodID method)
-{
- *_thrown = 0;
- jbyte _r_ = (*env)->CallNonvirtualByteMethod (env, instance, type, method);
- *_thrown = (*env)->ExceptionOccurred (env);
- return _r_;
-}
-
-JI_API jbyte
-java_interop_jnienv_call_nonvirtual_byte_method_a (JNIEnv *env, jthrowable *_thrown, jobject instance, jclass type, jmethodID method, jvalue* args)
-{
- *_thrown = 0;
- jbyte _r_ = (*env)->CallNonvirtualByteMethodA (env, instance, type, method, args);
- *_thrown = (*env)->ExceptionOccurred (env);
- return _r_;
-}
-
-JI_API jchar
-java_interop_jnienv_call_nonvirtual_char_method (JNIEnv *env, jthrowable *_thrown, jobject instance, jclass type, jmethodID method)
-{
- *_thrown = 0;
- jchar _r_ = (*env)->CallNonvirtualCharMethod (env, instance, type, method);
- *_thrown = (*env)->ExceptionOccurred (env);
- return _r_;
-}
-
-JI_API jchar
-java_interop_jnienv_call_nonvirtual_char_method_a (JNIEnv *env, jthrowable *_thrown, jobject instance, jclass type, jmethodID method, jvalue* args)
-{
- *_thrown = 0;
- jchar _r_ = (*env)->CallNonvirtualCharMethodA (env, instance, type, method, args);
- *_thrown = (*env)->ExceptionOccurred (env);
- return _r_;
-}
-
-JI_API jshort
-java_interop_jnienv_call_nonvirtual_short_method (JNIEnv *env, jthrowable *_thrown, jobject instance, jclass type, jmethodID method)
-{
- *_thrown = 0;
- jshort _r_ = (*env)->CallNonvirtualShortMethod (env, instance, type, method);
- *_thrown = (*env)->ExceptionOccurred (env);
- return _r_;
-}
-
-JI_API jshort
-java_interop_jnienv_call_nonvirtual_short_method_a (JNIEnv *env, jthrowable *_thrown, jobject instance, jclass type, jmethodID method, jvalue* args)
-{
- *_thrown = 0;
- jshort _r_ = (*env)->CallNonvirtualShortMethodA (env, instance, type, method, args);
- *_thrown = (*env)->ExceptionOccurred (env);
- return _r_;
-}
-
-JI_API jint
-java_interop_jnienv_call_nonvirtual_int_method (JNIEnv *env, jthrowable *_thrown, jobject instance, jclass type, jmethodID method)
-{
- *_thrown = 0;
- jint _r_ = (*env)->CallNonvirtualIntMethod (env, instance, type, method);
- *_thrown = (*env)->ExceptionOccurred (env);
- return _r_;
-}
-
-JI_API jint
-java_interop_jnienv_call_nonvirtual_int_method_a (JNIEnv *env, jthrowable *_thrown, jobject instance, jclass type, jmethodID method, jvalue* args)
-{
- *_thrown = 0;
- jint _r_ = (*env)->CallNonvirtualIntMethodA (env, instance, type, method, args);
- *_thrown = (*env)->ExceptionOccurred (env);
- return _r_;
-}
-
-JI_API jlong
-java_interop_jnienv_call_nonvirtual_long_method (JNIEnv *env, jthrowable *_thrown, jobject instance, jclass type, jmethodID method)
-{
- *_thrown = 0;
- jlong _r_ = (*env)->CallNonvirtualLongMethod (env, instance, type, method);
- *_thrown = (*env)->ExceptionOccurred (env);
- return _r_;
-}
-
-JI_API jlong
-java_interop_jnienv_call_nonvirtual_long_method_a (JNIEnv *env, jthrowable *_thrown, jobject instance, jclass type, jmethodID method, jvalue* args)
-{
- *_thrown = 0;
- jlong _r_ = (*env)->CallNonvirtualLongMethodA (env, instance, type, method, args);
- *_thrown = (*env)->ExceptionOccurred (env);
- return _r_;
-}
-
-JI_API jfloat
-java_interop_jnienv_call_nonvirtual_float_method (JNIEnv *env, jthrowable *_thrown, jobject instance, jclass type, jmethodID method)
-{
- *_thrown = 0;
- jfloat _r_ = (*env)->CallNonvirtualFloatMethod (env, instance, type, method);
- *_thrown = (*env)->ExceptionOccurred (env);
- return _r_;
-}
-
-JI_API jfloat
-java_interop_jnienv_call_nonvirtual_float_method_a (JNIEnv *env, jthrowable *_thrown, jobject instance, jclass type, jmethodID method, jvalue* args)
-{
- *_thrown = 0;
- jfloat _r_ = (*env)->CallNonvirtualFloatMethodA (env, instance, type, method, args);
- *_thrown = (*env)->ExceptionOccurred (env);
- return _r_;
-}
-
-JI_API jdouble
-java_interop_jnienv_call_nonvirtual_double_method (JNIEnv *env, jthrowable *_thrown, jobject instance, jclass type, jmethodID method)
-{
- *_thrown = 0;
- jdouble _r_ = (*env)->CallNonvirtualDoubleMethod (env, instance, type, method);
- *_thrown = (*env)->ExceptionOccurred (env);
- return _r_;
-}
-
-JI_API jdouble
-java_interop_jnienv_call_nonvirtual_double_method_a (JNIEnv *env, jthrowable *_thrown, jobject instance, jclass type, jmethodID method, jvalue* args)
-{
- *_thrown = 0;
- jdouble _r_ = (*env)->CallNonvirtualDoubleMethodA (env, instance, type, method, args);
- *_thrown = (*env)->ExceptionOccurred (env);
- return _r_;
-}
-
-JI_API void
-java_interop_jnienv_call_nonvirtual_void_method (JNIEnv *env, jthrowable *_thrown, jobject instance, jclass type, jmethodID method)
-{
- *_thrown = 0;
- (*env)->CallNonvirtualVoidMethod (env, instance, type, method);
- *_thrown = (*env)->ExceptionOccurred (env);
-}
-
-JI_API void
-java_interop_jnienv_call_nonvirtual_void_method_a (JNIEnv *env, jthrowable *_thrown, jobject instance, jclass type, jmethodID method, jvalue* args)
-{
- *_thrown = 0;
- (*env)->CallNonvirtualVoidMethodA (env, instance, type, method, args);
- *_thrown = (*env)->ExceptionOccurred (env);
-}
-
-JI_API jfieldID
-java_interop_jnienv_get_field_id (JNIEnv *env, jthrowable *_thrown, jclass type, const char* name, const char* signature)
-{
- *_thrown = 0;
- jfieldID _r_ = (*env)->GetFieldID (env, type, name, signature);
- *_thrown = (*env)->ExceptionOccurred (env);
- return _r_;
-}
-
-JI_API jobject
-java_interop_jnienv_get_object_field (JNIEnv *env, jobject instance, jfieldID field)
-{
- jobject _r_ = (*env)->GetObjectField (env, instance, field);
- return _r_;
-}
-
-JI_API jboolean
-java_interop_jnienv_get_boolean_field (JNIEnv *env, jobject instance, jfieldID field)
-{
- jboolean _r_ = (*env)->GetBooleanField (env, instance, field);
- return _r_;
-}
-
-JI_API jbyte
-java_interop_jnienv_get_byte_field (JNIEnv *env, jobject instance, jfieldID field)
-{
- jbyte _r_ = (*env)->GetByteField (env, instance, field);
- return _r_;
-}
-
-JI_API jchar
-java_interop_jnienv_get_char_field (JNIEnv *env, jobject instance, jfieldID field)
-{
- jchar _r_ = (*env)->GetCharField (env, instance, field);
- return _r_;
-}
-
-JI_API jshort
-java_interop_jnienv_get_short_field (JNIEnv *env, jobject instance, jfieldID field)
-{
- jshort _r_ = (*env)->GetShortField (env, instance, field);
- return _r_;
-}
-
-JI_API jint
-java_interop_jnienv_get_int_field (JNIEnv *env, jobject instance, jfieldID field)
-{
- jint _r_ = (*env)->GetIntField (env, instance, field);
- return _r_;
-}
-
-JI_API jlong
-java_interop_jnienv_get_long_field (JNIEnv *env, jobject instance, jfieldID field)
-{
- jlong _r_ = (*env)->GetLongField (env, instance, field);
- return _r_;
-}
-
-JI_API jfloat
-java_interop_jnienv_get_float_field (JNIEnv *env, jobject instance, jfieldID field)
-{
- jfloat _r_ = (*env)->GetFloatField (env, instance, field);
- return _r_;
-}
-
-JI_API jdouble
-java_interop_jnienv_get_double_field (JNIEnv *env, jobject instance, jfieldID field)
-{
- jdouble _r_ = (*env)->GetDoubleField (env, instance, field);
- return _r_;
-}
-
-JI_API void
-java_interop_jnienv_set_object_field (JNIEnv *env, jobject instance, jfieldID field, jobject value)
-{
- (*env)->SetObjectField (env, instance, field, value);
-}
-
-JI_API void
-java_interop_jnienv_set_boolean_field (JNIEnv *env, jobject instance, jfieldID field, jboolean value)
-{
- (*env)->SetBooleanField (env, instance, field, value);
-}
-
-JI_API void
-java_interop_jnienv_set_byte_field (JNIEnv *env, jobject instance, jfieldID field, jbyte value)
-{
- (*env)->SetByteField (env, instance, field, value);
-}
-
-JI_API void
-java_interop_jnienv_set_char_field (JNIEnv *env, jobject instance, jfieldID field, jchar value)
-{
- (*env)->SetCharField (env, instance, field, value);
-}
-
-JI_API void
-java_interop_jnienv_set_short_field (JNIEnv *env, jobject instance, jfieldID field, jshort value)
-{
- (*env)->SetShortField (env, instance, field, value);
-}
-
-JI_API void
-java_interop_jnienv_set_int_field (JNIEnv *env, jobject instance, jfieldID field, jint value)
-{
- (*env)->SetIntField (env, instance, field, value);
-}
-
-JI_API void
-java_interop_jnienv_set_long_field (JNIEnv *env, jobject instance, jfieldID field, jlong value)
-{
- (*env)->SetLongField (env, instance, field, value);
-}
-
-JI_API void
-java_interop_jnienv_set_float_field (JNIEnv *env, jobject instance, jfieldID field, jfloat value)
-{
- (*env)->SetFloatField (env, instance, field, value);
-}
-
-JI_API void
-java_interop_jnienv_set_double_field (JNIEnv *env, jobject instance, jfieldID field, jdouble value)
-{
- (*env)->SetDoubleField (env, instance, field, value);
-}
-
-JI_API jstaticmethodID
-java_interop_jnienv_get_static_method_id (JNIEnv *env, jthrowable *_thrown, jclass type, const char* name, const char* signature)
-{
- *_thrown = 0;
- jstaticmethodID _r_ = (*env)->GetStaticMethodID (env, type, name, signature);
- *_thrown = (*env)->ExceptionOccurred (env);
- return _r_;
-}
-
-JI_API jobject
-java_interop_jnienv_call_static_object_method (JNIEnv *env, jthrowable *_thrown, jclass type, jstaticmethodID method)
-{
- *_thrown = 0;
- jobject _r_ = (*env)->CallStaticObjectMethod (env, type, method);
- *_thrown = (*env)->ExceptionOccurred (env);
- return _r_;
-}
-
-JI_API jobject
-java_interop_jnienv_call_static_object_method_a (JNIEnv *env, jthrowable *_thrown, jclass type, jstaticmethodID method, jvalue* args)
-{
- *_thrown = 0;
- jobject _r_ = (*env)->CallStaticObjectMethodA (env, type, method, args);
- *_thrown = (*env)->ExceptionOccurred (env);
- return _r_;
-}
-
-JI_API jboolean
-java_interop_jnienv_call_static_boolean_method (JNIEnv *env, jthrowable *_thrown, jclass type, jstaticmethodID method)
-{
- *_thrown = 0;
- jboolean _r_ = (*env)->CallStaticBooleanMethod (env, type, method);
- *_thrown = (*env)->ExceptionOccurred (env);
- return _r_;
-}
-
-JI_API jboolean
-java_interop_jnienv_call_static_boolean_method_a (JNIEnv *env, jthrowable *_thrown, jclass type, jstaticmethodID method, jvalue* args)
-{
- *_thrown = 0;
- jboolean _r_ = (*env)->CallStaticBooleanMethodA (env, type, method, args);
- *_thrown = (*env)->ExceptionOccurred (env);
- return _r_;
-}
-
-JI_API jbyte
-java_interop_jnienv_call_static_byte_method (JNIEnv *env, jthrowable *_thrown, jclass type, jstaticmethodID method)
-{
- *_thrown = 0;
- jbyte _r_ = (*env)->CallStaticByteMethod (env, type, method);
- *_thrown = (*env)->ExceptionOccurred (env);
- return _r_;
-}
-
-JI_API jbyte
-java_interop_jnienv_call_static_byte_method_a (JNIEnv *env, jthrowable *_thrown, jclass type, jstaticmethodID method, jvalue* args)
-{
- *_thrown = 0;
- jbyte _r_ = (*env)->CallStaticByteMethodA (env, type, method, args);
- *_thrown = (*env)->ExceptionOccurred (env);
- return _r_;
-}
-
-JI_API jchar
-java_interop_jnienv_call_static_char_method (JNIEnv *env, jthrowable *_thrown, jclass type, jstaticmethodID method)
-{
- *_thrown = 0;
- jchar _r_ = (*env)->CallStaticCharMethod (env, type, method);
- *_thrown = (*env)->ExceptionOccurred (env);
- return _r_;
-}
-
-JI_API jchar
-java_interop_jnienv_call_static_char_method_a (JNIEnv *env, jthrowable *_thrown, jclass type, jstaticmethodID method, jvalue* args)
-{
- *_thrown = 0;
- jchar _r_ = (*env)->CallStaticCharMethodA (env, type, method, args);
- *_thrown = (*env)->ExceptionOccurred (env);
- return _r_;
-}
-
-JI_API jshort
-java_interop_jnienv_call_static_short_method (JNIEnv *env, jthrowable *_thrown, jclass type, jstaticmethodID method)
-{
- *_thrown = 0;
- jshort _r_ = (*env)->CallStaticShortMethod (env, type, method);
- *_thrown = (*env)->ExceptionOccurred (env);
- return _r_;
-}
-
-JI_API jshort
-java_interop_jnienv_call_static_short_method_a (JNIEnv *env, jthrowable *_thrown, jclass type, jstaticmethodID method, jvalue* args)
-{
- *_thrown = 0;
- jshort _r_ = (*env)->CallStaticShortMethodA (env, type, method, args);
- *_thrown = (*env)->ExceptionOccurred (env);
- return _r_;
-}
-
-JI_API jint
-java_interop_jnienv_call_static_int_method (JNIEnv *env, jthrowable *_thrown, jclass type, jstaticmethodID method)
-{
- *_thrown = 0;
- jint _r_ = (*env)->CallStaticIntMethod (env, type, method);
- *_thrown = (*env)->ExceptionOccurred (env);
- return _r_;
-}
-
-JI_API jint
-java_interop_jnienv_call_static_int_method_a (JNIEnv *env, jthrowable *_thrown, jclass type, jstaticmethodID method, jvalue* args)
-{
- *_thrown = 0;
- jint _r_ = (*env)->CallStaticIntMethodA (env, type, method, args);
- *_thrown = (*env)->ExceptionOccurred (env);
- return _r_;
-}
-
-JI_API jlong
-java_interop_jnienv_call_static_long_method (JNIEnv *env, jthrowable *_thrown, jclass type, jstaticmethodID method)
-{
- *_thrown = 0;
- jlong _r_ = (*env)->CallStaticLongMethod (env, type, method);
- *_thrown = (*env)->ExceptionOccurred (env);
- return _r_;
-}
-
-JI_API jlong
-java_interop_jnienv_call_static_long_method_a (JNIEnv *env, jthrowable *_thrown, jclass type, jstaticmethodID method, jvalue* args)
-{
- *_thrown = 0;
- jlong _r_ = (*env)->CallStaticLongMethodA (env, type, method, args);
- *_thrown = (*env)->ExceptionOccurred (env);
- return _r_;
-}
-
-JI_API jfloat
-java_interop_jnienv_call_static_float_method (JNIEnv *env, jthrowable *_thrown, jclass type, jstaticmethodID method)
-{
- *_thrown = 0;
- jfloat _r_ = (*env)->CallStaticFloatMethod (env, type, method);
- *_thrown = (*env)->ExceptionOccurred (env);
- return _r_;
-}
-
-JI_API jfloat
-java_interop_jnienv_call_static_float_method_a (JNIEnv *env, jthrowable *_thrown, jclass type, jstaticmethodID method, jvalue* args)
-{
- *_thrown = 0;
- jfloat _r_ = (*env)->CallStaticFloatMethodA (env, type, method, args);
- *_thrown = (*env)->ExceptionOccurred (env);
- return _r_;
-}
-
-JI_API jdouble
-java_interop_jnienv_call_static_double_method (JNIEnv *env, jthrowable *_thrown, jclass type, jstaticmethodID method)
-{
- *_thrown = 0;
- jdouble _r_ = (*env)->CallStaticDoubleMethod (env, type, method);
- *_thrown = (*env)->ExceptionOccurred (env);
- return _r_;
-}
-
-JI_API jdouble
-java_interop_jnienv_call_static_double_method_a (JNIEnv *env, jthrowable *_thrown, jclass type, jstaticmethodID method, jvalue* args)
-{
- *_thrown = 0;
- jdouble _r_ = (*env)->CallStaticDoubleMethodA (env, type, method, args);
- *_thrown = (*env)->ExceptionOccurred (env);
- return _r_;
-}
-
-JI_API void
-java_interop_jnienv_call_static_void_method (JNIEnv *env, jthrowable *_thrown, jclass type, jstaticmethodID method)
-{
- *_thrown = 0;
- (*env)->CallStaticVoidMethod (env, type, method);
- *_thrown = (*env)->ExceptionOccurred (env);
-}
-
-JI_API void
-java_interop_jnienv_call_static_void_method_a (JNIEnv *env, jthrowable *_thrown, jclass type, jstaticmethodID method, jvalue* args)
-{
- *_thrown = 0;
- (*env)->CallStaticVoidMethodA (env, type, method, args);
- *_thrown = (*env)->ExceptionOccurred (env);
-}
-
-JI_API jstaticfieldID
-java_interop_jnienv_get_static_field_id (JNIEnv *env, jthrowable *_thrown, jclass type, const char* name, const char* signature)
-{
- *_thrown = 0;
- jstaticfieldID _r_ = (*env)->GetStaticFieldID (env, type, name, signature);
- *_thrown = (*env)->ExceptionOccurred (env);
- return _r_;
-}
-
-JI_API jobject
-java_interop_jnienv_get_static_object_field (JNIEnv *env, jclass type, jstaticfieldID field)
-{
- jobject _r_ = (*env)->GetStaticObjectField (env, type, field);
- return _r_;
-}
-
-JI_API jboolean
-java_interop_jnienv_get_static_boolean_field (JNIEnv *env, jclass type, jstaticfieldID field)
-{
- jboolean _r_ = (*env)->GetStaticBooleanField (env, type, field);
- return _r_;
-}
-
-JI_API jbyte
-java_interop_jnienv_get_static_byte_field (JNIEnv *env, jclass type, jstaticfieldID field)
-{
- jbyte _r_ = (*env)->GetStaticByteField (env, type, field);
- return _r_;
-}
-
-JI_API jchar
-java_interop_jnienv_get_static_char_field (JNIEnv *env, jclass type, jstaticfieldID field)
-{
- jchar _r_ = (*env)->GetStaticCharField (env, type, field);
- return _r_;
-}
-
-JI_API jshort
-java_interop_jnienv_get_static_short_field (JNIEnv *env, jclass type, jstaticfieldID field)
-{
- jshort _r_ = (*env)->GetStaticShortField (env, type, field);
- return _r_;
-}
-
-JI_API jint
-java_interop_jnienv_get_static_int_field (JNIEnv *env, jclass type, jstaticfieldID field)
-{
- jint _r_ = (*env)->GetStaticIntField (env, type, field);
- return _r_;
-}
-
-JI_API jlong
-java_interop_jnienv_get_static_long_field (JNIEnv *env, jclass type, jstaticfieldID field)
-{
- jlong _r_ = (*env)->GetStaticLongField (env, type, field);
- return _r_;
-}
-
-JI_API jfloat
-java_interop_jnienv_get_static_float_field (JNIEnv *env, jclass type, jstaticfieldID field)
-{
- jfloat _r_ = (*env)->GetStaticFloatField (env, type, field);
- return _r_;
-}
-
-JI_API jdouble
-java_interop_jnienv_get_static_double_field (JNIEnv *env, jclass type, jstaticfieldID field)
-{
- jdouble _r_ = (*env)->GetStaticDoubleField (env, type, field);
- return _r_;
-}
-
-JI_API void
-java_interop_jnienv_set_static_object_field (JNIEnv *env, jclass type, jstaticfieldID field, jobject value)
-{
- (*env)->SetStaticObjectField (env, type, field, value);
-}
-
-JI_API void
-java_interop_jnienv_set_static_boolean_field (JNIEnv *env, jclass type, jstaticfieldID field, jboolean value)
-{
- (*env)->SetStaticBooleanField (env, type, field, value);
-}
-
-JI_API void
-java_interop_jnienv_set_static_byte_field (JNIEnv *env, jclass type, jstaticfieldID field, jbyte value)
-{
- (*env)->SetStaticByteField (env, type, field, value);
-}
-
-JI_API void
-java_interop_jnienv_set_static_char_field (JNIEnv *env, jclass type, jstaticfieldID field, jchar value)
-{
- (*env)->SetStaticCharField (env, type, field, value);
-}
-
-JI_API void
-java_interop_jnienv_set_static_short_field (JNIEnv *env, jclass type, jstaticfieldID field, jshort value)
-{
- (*env)->SetStaticShortField (env, type, field, value);
-}
-
-JI_API void
-java_interop_jnienv_set_static_int_field (JNIEnv *env, jclass type, jstaticfieldID field, jint value)
-{
- (*env)->SetStaticIntField (env, type, field, value);
-}
-
-JI_API void
-java_interop_jnienv_set_static_long_field (JNIEnv *env, jclass type, jstaticfieldID field, jlong value)
-{
- (*env)->SetStaticLongField (env, type, field, value);
-}
-
-JI_API void
-java_interop_jnienv_set_static_float_field (JNIEnv *env, jclass type, jstaticfieldID field, jfloat value)
-{
- (*env)->SetStaticFloatField (env, type, field, value);
-}
-
-JI_API void
-java_interop_jnienv_set_static_double_field (JNIEnv *env, jclass type, jstaticfieldID field, jdouble value)
-{
- (*env)->SetStaticDoubleField (env, type, field, value);
-}
-
-JI_API jstring
-java_interop_jnienv_new_string (JNIEnv *env, jthrowable *_thrown, jchar* unicodeChars, jsize length)
-{
- *_thrown = 0;
- jstring _r_ = (*env)->NewString (env, unicodeChars, length);
- *_thrown = (*env)->ExceptionOccurred (env);
- return _r_;
-}
-
-JI_API jsize
-java_interop_jnienv_get_string_length (JNIEnv *env, jstring stringInstance)
-{
- jsize _r_ = (*env)->GetStringLength (env, stringInstance);
- return _r_;
-}
-
-JI_API const jchar*
-java_interop_jnienv_get_string_chars (JNIEnv *env, jstring stringInstance, jboolean* isCopy)
-{
- const jchar* _r_ = (*env)->GetStringChars (env, stringInstance, isCopy);
- return _r_;
-}
-
-JI_API void
-java_interop_jnienv_release_string_chars (JNIEnv *env, jstring stringInstance, jchar* chars)
-{
- (*env)->ReleaseStringChars (env, stringInstance, chars);
-}
-
-JI_API jsize
-java_interop_jnienv_get_array_length (JNIEnv *env, jarray array)
-{
- jsize _r_ = (*env)->GetArrayLength (env, array);
- return _r_;
-}
-
-JI_API jobjectArray
-java_interop_jnienv_new_object_array (JNIEnv *env, jthrowable *_thrown, jsize length, jclass elementClass, jobject initialElement)
-{
- *_thrown = 0;
- jobjectArray _r_ = (*env)->NewObjectArray (env, length, elementClass, initialElement);
- *_thrown = (*env)->ExceptionOccurred (env);
- return _r_;
-}
-
-JI_API jobject
-java_interop_jnienv_get_object_array_element (JNIEnv *env, jthrowable *_thrown, jobjectArray array, jsize index)
-{
- *_thrown = 0;
- jobject _r_ = (*env)->GetObjectArrayElement (env, array, index);
- *_thrown = (*env)->ExceptionOccurred (env);
- return _r_;
-}
-
-JI_API void
-java_interop_jnienv_set_object_array_element (JNIEnv *env, jthrowable *_thrown, jobjectArray array, jsize index, jobject value)
-{
- *_thrown = 0;
- (*env)->SetObjectArrayElement (env, array, index, value);
- *_thrown = (*env)->ExceptionOccurred (env);
-}
-
-JI_API jbooleanArray
-java_interop_jnienv_new_boolean_array (JNIEnv *env, jsize length)
-{
- jbooleanArray _r_ = (*env)->NewBooleanArray (env, length);
- return _r_;
-}
-
-JI_API jbyteArray
-java_interop_jnienv_new_byte_array (JNIEnv *env, jsize length)
-{
- jbyteArray _r_ = (*env)->NewByteArray (env, length);
- return _r_;
-}
-
-JI_API jcharArray
-java_interop_jnienv_new_char_array (JNIEnv *env, jsize length)
-{
- jcharArray _r_ = (*env)->NewCharArray (env, length);
- return _r_;
-}
-
-JI_API jshortArray
-java_interop_jnienv_new_short_array (JNIEnv *env, jsize length)
-{
- jshortArray _r_ = (*env)->NewShortArray (env, length);
- return _r_;
-}
-
-JI_API jintArray
-java_interop_jnienv_new_int_array (JNIEnv *env, jsize length)
-{
- jintArray _r_ = (*env)->NewIntArray (env, length);
- return _r_;
-}
-
-JI_API jlongArray
-java_interop_jnienv_new_long_array (JNIEnv *env, jsize length)
-{
- jlongArray _r_ = (*env)->NewLongArray (env, length);
- return _r_;
-}
-
-JI_API jfloatArray
-java_interop_jnienv_new_float_array (JNIEnv *env, jsize length)
-{
- jfloatArray _r_ = (*env)->NewFloatArray (env, length);
- return _r_;
-}
-
-JI_API jdoubleArray
-java_interop_jnienv_new_double_array (JNIEnv *env, jsize length)
-{
- jdoubleArray _r_ = (*env)->NewDoubleArray (env, length);
- return _r_;
-}
-
-JI_API jboolean*
-java_interop_jnienv_get_boolean_array_elements (JNIEnv *env, jbooleanArray array, jboolean* isCopy)
-{
- jboolean* _r_ = (*env)->GetBooleanArrayElements (env, array, isCopy);
- return _r_;
-}
-
-JI_API jbyte*
-java_interop_jnienv_get_byte_array_elements (JNIEnv *env, jbyteArray array, jboolean* isCopy)
-{
- jbyte* _r_ = (*env)->GetByteArrayElements (env, array, isCopy);
- return _r_;
-}
-
-JI_API jchar*
-java_interop_jnienv_get_char_array_elements (JNIEnv *env, jcharArray array, jboolean* isCopy)
-{
- jchar* _r_ = (*env)->GetCharArrayElements (env, array, isCopy);
- return _r_;
-}
-
-JI_API jshort*
-java_interop_jnienv_get_short_array_elements (JNIEnv *env, jshortArray array, jboolean* isCopy)
-{
- jshort* _r_ = (*env)->GetShortArrayElements (env, array, isCopy);
- return _r_;
-}
-
-JI_API jint*
-java_interop_jnienv_get_int_array_elements (JNIEnv *env, jintArray array, jboolean* isCopy)
-{
- jint* _r_ = (*env)->GetIntArrayElements (env, array, isCopy);
- return _r_;
-}
-
-JI_API jlong*
-java_interop_jnienv_get_long_array_elements (JNIEnv *env, jlongArray array, jboolean* isCopy)
-{
- jlong* _r_ = (*env)->GetLongArrayElements (env, array, isCopy);
- return _r_;
-}
-
-JI_API jfloat*
-java_interop_jnienv_get_float_array_elements (JNIEnv *env, jfloatArray array, jboolean* isCopy)
-{
- jfloat* _r_ = (*env)->GetFloatArrayElements (env, array, isCopy);
- return _r_;
-}
-
-JI_API jdouble*
-java_interop_jnienv_get_double_array_elements (JNIEnv *env, jdoubleArray array, jboolean* isCopy)
-{
- jdouble* _r_ = (*env)->GetDoubleArrayElements (env, array, isCopy);
- return _r_;
-}
-
-JI_API void
-java_interop_jnienv_release_boolean_array_elements (JNIEnv *env, jbooleanArray array, jboolean* elements, jint mode)
-{
- (*env)->ReleaseBooleanArrayElements (env, array, elements, mode);
-}
-
-JI_API void
-java_interop_jnienv_release_byte_array_elements (JNIEnv *env, jbyteArray array, jbyte* elements, jint mode)
-{
- (*env)->ReleaseByteArrayElements (env, array, elements, mode);
-}
-
-JI_API void
-java_interop_jnienv_release_char_array_elements (JNIEnv *env, jcharArray array, jchar* elements, jint mode)
-{
- (*env)->ReleaseCharArrayElements (env, array, elements, mode);
-}
-
-JI_API void
-java_interop_jnienv_release_short_array_elements (JNIEnv *env, jshortArray array, jshort* elements, jint mode)
-{
- (*env)->ReleaseShortArrayElements (env, array, elements, mode);
-}
-
-JI_API void
-java_interop_jnienv_release_int_array_elements (JNIEnv *env, jintArray array, jint* elements, jint mode)
-{
- (*env)->ReleaseIntArrayElements (env, array, elements, mode);
-}
-
-JI_API void
-java_interop_jnienv_release_long_array_elements (JNIEnv *env, jlongArray array, jlong* elements, jint mode)
-{
- (*env)->ReleaseLongArrayElements (env, array, elements, mode);
-}
-
-JI_API void
-java_interop_jnienv_release_float_array_elements (JNIEnv *env, jfloatArray array, jfloat* elements, jint mode)
-{
- (*env)->ReleaseFloatArrayElements (env, array, elements, mode);
-}
-
-JI_API void
-java_interop_jnienv_release_double_array_elements (JNIEnv *env, jdoubleArray array, jdouble* elements, jint mode)
-{
- (*env)->ReleaseDoubleArrayElements (env, array, elements, mode);
-}
-
-JI_API void
-java_interop_jnienv_get_boolean_array_region (JNIEnv *env, jthrowable *_thrown, jbooleanArray array, jsize start, jsize length, jboolean* buffer)
-{
- *_thrown = 0;
- (*env)->GetBooleanArrayRegion (env, array, start, length, buffer);
- *_thrown = (*env)->ExceptionOccurred (env);
-}
-
-JI_API void
-java_interop_jnienv_get_byte_array_region (JNIEnv *env, jthrowable *_thrown, jbyteArray array, jsize start, jsize length, jbyte* buffer)
-{
- *_thrown = 0;
- (*env)->GetByteArrayRegion (env, array, start, length, buffer);
- *_thrown = (*env)->ExceptionOccurred (env);
-}
-
-JI_API void
-java_interop_jnienv_get_char_array_region (JNIEnv *env, jthrowable *_thrown, jcharArray array, jsize start, jsize length, jchar* buffer)
-{
- *_thrown = 0;
- (*env)->GetCharArrayRegion (env, array, start, length, buffer);
- *_thrown = (*env)->ExceptionOccurred (env);
-}
-
-JI_API void
-java_interop_jnienv_get_short_array_region (JNIEnv *env, jthrowable *_thrown, jshortArray array, jsize start, jsize length, jshort* buffer)
-{
- *_thrown = 0;
- (*env)->GetShortArrayRegion (env, array, start, length, buffer);
- *_thrown = (*env)->ExceptionOccurred (env);
-}
-
-JI_API void
-java_interop_jnienv_get_int_array_region (JNIEnv *env, jthrowable *_thrown, jintArray array, jsize start, jsize length, jint* buffer)
-{
- *_thrown = 0;
- (*env)->GetIntArrayRegion (env, array, start, length, buffer);
- *_thrown = (*env)->ExceptionOccurred (env);
-}
-
-JI_API void
-java_interop_jnienv_get_long_array_region (JNIEnv *env, jthrowable *_thrown, jlongArray array, jsize start, jsize length, jlong* buffer)
-{
- *_thrown = 0;
- (*env)->GetLongArrayRegion (env, array, start, length, buffer);
- *_thrown = (*env)->ExceptionOccurred (env);
-}
-
-JI_API void
-java_interop_jnienv_get_float_array_region (JNIEnv *env, jthrowable *_thrown, jlongArray array, jsize start, jsize length, jfloat* buffer)
-{
- *_thrown = 0;
- (*env)->GetFloatArrayRegion (env, array, start, length, buffer);
- *_thrown = (*env)->ExceptionOccurred (env);
-}
-
-JI_API void
-java_interop_jnienv_get_double_array_region (JNIEnv *env, jthrowable *_thrown, jdoubleArray array, jsize start, jsize length, jdouble* buffer)
-{
- *_thrown = 0;
- (*env)->GetDoubleArrayRegion (env, array, start, length, buffer);
- *_thrown = (*env)->ExceptionOccurred (env);
-}
-
-JI_API void
-java_interop_jnienv_set_boolean_array_region (JNIEnv *env, jthrowable *_thrown, jbooleanArray array, jsize start, jsize length, jboolean* buffer)
-{
- *_thrown = 0;
- (*env)->SetBooleanArrayRegion (env, array, start, length, buffer);
- *_thrown = (*env)->ExceptionOccurred (env);
-}
-
-JI_API void
-java_interop_jnienv_set_byte_array_region (JNIEnv *env, jthrowable *_thrown, jbyteArray array, jsize start, jsize length, jbyte* buffer)
-{
- *_thrown = 0;
- (*env)->SetByteArrayRegion (env, array, start, length, buffer);
- *_thrown = (*env)->ExceptionOccurred (env);
-}
-
-JI_API void
-java_interop_jnienv_set_char_array_region (JNIEnv *env, jthrowable *_thrown, jcharArray array, jsize start, jsize length, const jchar* buffer)
-{
- *_thrown = 0;
- (*env)->SetCharArrayRegion (env, array, start, length, buffer);
- *_thrown = (*env)->ExceptionOccurred (env);
-}
-
-JI_API void
-java_interop_jnienv_set_short_array_region (JNIEnv *env, jthrowable *_thrown, jshortArray array, jsize start, jsize length, jshort* buffer)
-{
- *_thrown = 0;
- (*env)->SetShortArrayRegion (env, array, start, length, buffer);
- *_thrown = (*env)->ExceptionOccurred (env);
-}
-
-JI_API void
-java_interop_jnienv_set_int_array_region (JNIEnv *env, jthrowable *_thrown, jintArray array, jsize start, jsize length, jint* buffer)
-{
- *_thrown = 0;
- (*env)->SetIntArrayRegion (env, array, start, length, buffer);
- *_thrown = (*env)->ExceptionOccurred (env);
-}
-
-JI_API void
-java_interop_jnienv_set_long_array_region (JNIEnv *env, jthrowable *_thrown, jlongArray array, jsize start, jsize length, jlong* buffer)
-{
- *_thrown = 0;
- (*env)->SetLongArrayRegion (env, array, start, length, buffer);
- *_thrown = (*env)->ExceptionOccurred (env);
-}
-
-JI_API void
-java_interop_jnienv_set_float_array_region (JNIEnv *env, jthrowable *_thrown, jfloatArray array, jsize start, jsize length, jfloat* buffer)
-{
- *_thrown = 0;
- (*env)->SetFloatArrayRegion (env, array, start, length, buffer);
- *_thrown = (*env)->ExceptionOccurred (env);
-}
-
-JI_API void
-java_interop_jnienv_set_double_array_region (JNIEnv *env, jthrowable *_thrown, jdoubleArray array, jsize start, jsize length, jdouble* buffer)
-{
- *_thrown = 0;
- (*env)->SetDoubleArrayRegion (env, array, start, length, buffer);
- *_thrown = (*env)->ExceptionOccurred (env);
-}
-
-JI_API jint
-java_interop_jnienv_register_natives (JNIEnv *env, jthrowable *_thrown, jclass type, const JNINativeMethod* methods, jint numMethods)
-{
- *_thrown = 0;
- jint _r_ = (*env)->RegisterNatives (env, type, methods, numMethods);
- *_thrown = (*env)->ExceptionOccurred (env);
- return _r_;
-}
-
-JI_API jint
-java_interop_jnienv_unregister_natives (JNIEnv *env, jclass type)
-{
- jint _r_ = (*env)->UnregisterNatives (env, type);
- return _r_;
-}
-
-JI_API jint
-java_interop_jnienv_monitor_enter (JNIEnv *env, jobject instance)
-{
- jint _r_ = (*env)->MonitorEnter (env, instance);
- return _r_;
-}
-
-JI_API jint
-java_interop_jnienv_monitor_exit (JNIEnv *env, jobject instance)
-{
- jint _r_ = (*env)->MonitorExit (env, instance);
- return _r_;
-}
-
-JI_API jint
-java_interop_jnienv_get_java_vm (JNIEnv *env, JavaVM** vm)
-{
- jint _r_ = (*env)->GetJavaVM (env, vm);
- return _r_;
-}
-
-JI_API void*
-java_interop_jnienv_get_primitive_array_critical (JNIEnv *env, jarray array, jboolean* isCopy)
-{
- void* _r_ = (*env)->GetPrimitiveArrayCritical (env, array, isCopy);
- return _r_;
-}
-
-JI_API void
-java_interop_jnienv_release_primitive_array_critical (JNIEnv *env, jarray array, void* carray, jint mode)
-{
- (*env)->ReleasePrimitiveArrayCritical (env, array, carray, mode);
-}
-
-JI_API jweak
-java_interop_jnienv_new_weak_global_ref (JNIEnv *env, jobject instance)
-{
- jweak _r_ = (*env)->NewWeakGlobalRef (env, instance);
- return _r_;
-}
-
-JI_API void
-java_interop_jnienv_delete_weak_global_ref (JNIEnv *env, jobject instance)
-{
- (*env)->DeleteWeakGlobalRef (env, instance);
-}
-
-JI_API jboolean
-java_interop_jnienv_exception_check (JNIEnv *env)
-{
- jboolean _r_ = (*env)->ExceptionCheck (env);
- return _r_;
-}
-
-JI_API jobject
-java_interop_jnienv_new_direct_byte_buffer (JNIEnv *env, jthrowable *_thrown, void* address, jlong capacity)
-{
- *_thrown = 0;
- jobject _r_ = (*env)->NewDirectByteBuffer (env, address, capacity);
- *_thrown = (*env)->ExceptionOccurred (env);
- return _r_;
-}
-
-JI_API void*
-java_interop_jnienv_get_direct_buffer_address (JNIEnv *env, jobject buffer)
-{
- void* _r_ = (*env)->GetDirectBufferAddress (env, buffer);
- return _r_;
-}
-
-JI_API jlong
-java_interop_jnienv_get_direct_buffer_capacity (JNIEnv *env, jobject buffer)
-{
- jlong _r_ = (*env)->GetDirectBufferCapacity (env, buffer);
- return _r_;
-}
-
-JI_API jobjectRefType
-java_interop_jnienv_get_object_ref_type (JNIEnv *env, jobject instance)
-{
- jobjectRefType _r_ = (*env)->GetObjectRefType (env, instance);
- return _r_;
-}
diff --git a/tests/invocation-overhead/jni.cs b/tests/invocation-overhead/jni.cs
deleted file mode 100644
index 7f8a432bb..000000000
--- a/tests/invocation-overhead/jni.cs
+++ /dev/null
@@ -1,17245 +0,0 @@
-// Generated file; DO NOT EDIT!
-//
-// To make changes, edit monodroid/tools/jnienv-gen-interop and rerun
-#nullable enable
-
-#if !FEATURE_JNIENVIRONMENT_JI_INTPTRS && !FEATURE_JNIENVIRONMENT_JI_PINVOKES && !FEATURE_JNIENVIRONMENT_XA_INTPTRS && !FEATURE_JNIENVIRONMENT_JI_FUNCTION_POINTERS
-#define FEATURE_JNIENVIRONMENT_JI_PINVOKES
-#endif // !FEATURE_JNIENVIRONMENT_JI_INTPTRS && !FEATURE_JNIENVIRONMENT_JI_PINVOKES && !FEATURE_JNIENVIRONMENT_XA_INTPTRS && !FEATURE_JNIENVIRONMENT_JI_FUNCTION_POINTERS
-
-#if FEATURE_JNIENVIRONMENT_JI_INTPTRS && (FEATURE_JNIENVIRONMENT_JI_PINVOKES || FEATURE_JNIENVIRONMENT_XA_INTPTRS || FEATURE_JNIENVIRONMENT_JI_FUNCTION_POINTERS)
-#define _NAMESPACE_PER_HANDLE
-#endif // FEATURE_JNIENVIRONMENT_JI_INTPTRS && (FEATURE_JNIENVIRONMENT_JI_PINVOKES || FEATURE_JNIENVIRONMENT_XA_INTPTRS || FEATURE_JNIENVIRONMENT_JI_FUNCTION_POINTERS)
-#if FEATURE_JNIENVIRONMENT_JI_PINVOKES && (FEATURE_JNIENVIRONMENT_XA_INTPTRS || FEATURE_JNIENVIRONMENT_JI_FUNCTION_POINTERS)
-#define _NAMESPACE_PER_HANDLE
-#endif // FEATURE_JNIENVIRONMENT_JI_PINVOKES && (FEATURE_JNIENVIRONMENT_XA_INTPTRS || FEATURE_JNIENVIRONMENT_JI_FUNCTION_POINTERS)
-#if FEATURE_JNIENVIRONMENT_XA_INTPTRS && FEATURE_JNIENVIRONMENT_JI_FUNCTION_POINTERS
-#define _NAMESPACE_PER_HANDLE
-#endif // FEATURE_JNIENVIRONMENT_XA_INTPTRS && FEATURE_JNIENVIRONMENT_JI_FUNCTION_POINTERS
-
-using System;
-using System.Linq;
-using System.Runtime.ExceptionServices;
-using System.Runtime.InteropServices;
-using System.Threading;
-
-using Java.Interop;
-
-using JNIEnvPtr = System.IntPtr;
-
-#if FEATURE_JNIENVIRONMENT_JI_INTPTRS || FEATURE_JNIENVIRONMENT_JI_PINVOKES || FEATURE_JNIENVIRONMENT_JI_FUNCTION_POINTERS
- using jinstanceFieldID = System.IntPtr;
- using jstaticFieldID = System.IntPtr;
- using jinstanceMethodID = System.IntPtr;
- using jstaticMethodID = System.IntPtr;
- using jobject = System.IntPtr;
-#endif // FEATURE_JNIENVIRONMENT_JI_INTPTRS || FEATURE_JNIENVIRONMENT_JI_PINVOKES || FEATURE_JNIENVIRONMENT_JI_FUNCTION_POINTERS
-
-namespace Java.Interop {
-#pragma warning disable 0649 // Field is assigned to, and will always have its default value `null`; ignore as it'll be set in native code.
-#pragma warning disable 0169 // Field never used; ignore since these fields make the structure have the right layout.
-
-#if FEATURE_JNIENVIRONMENT_JI_INTPTRS || FEATURE_JNIENVIRONMENT_XA_INTPTRS
- [StructLayout (LayoutKind.Sequential)]
- partial struct JniNativeInterfaceStruct {
-
- private IntPtr reserved0; // void*
- private IntPtr reserved1; // void*
- private IntPtr reserved2; // void*
- private IntPtr reserved3; // void*
- public IntPtr GetVersion; // jint (*GetVersion)(JNIEnv*);
- public IntPtr DefineClass; // jclass (*DefineClass)(JNIEnv*, const char, jobject, const jbyte*, jsize);
- public IntPtr FindClass; // jclass (*FindClass)(JNIEnv*, const char*);
- public IntPtr FromReflectedMethod; // jmethodID (*FromReflectedMethod)(JNIEnv*, jobject);
- public IntPtr FromReflectedField; // jfieldID (*FromReflectedField)(JNIEnv*, jobject);
- public IntPtr ToReflectedMethod; // jobject (*ToReflectedMethod)(JNIEnv*, jclass, jmethodID, jboolean);
- public IntPtr GetSuperclass; // jclass (*GetSuperclass)(JNIEnv*, jclass);
- public IntPtr IsAssignableFrom; // jboolean (*IsAssignableFrom)(JNIEnv*, jclass, jclass);
- public IntPtr ToReflectedField; // jobject (*ToReflectedField)(JNIEnv*, jclass, jfieldID, jboolean);
- public IntPtr Throw; // jint (*Throw)(JNIEnv*, jthrowable);
- public IntPtr ThrowNew; // jint (*ThrowNew)(JNIEnv*, jclass, const char*);
- public IntPtr ExceptionOccurred; // jthrowable (*ExceptionOccurred)(JNIEnv*);
- public IntPtr ExceptionDescribe; // void (*ExceptionDescribe)(JNIEnv*);
- public IntPtr ExceptionClear; // void (*ExceptionClear)(JNIEnv*);
- public IntPtr FatalError; // void (*FatalError)(JNIEnv*, const char*);
- public IntPtr PushLocalFrame; // jint (*PushLocalFrame)(JNIEnv*, jint);
- public IntPtr PopLocalFrame; // jobject (*PopLocalFrame)(JNIEnv*, jobject);
- public IntPtr NewGlobalRef; // jobject (*NewGlobalRef)(JNIEnv*, jobject);
- public IntPtr DeleteGlobalRef; // void (*DeleteGlobalRef)(JNIEnv*, jobject);
- public IntPtr DeleteLocalRef; // void (*DeleteLocalRef)(JNIEnv*, jobject);
- public IntPtr IsSameObject; // jboolean (*IsSameObject)(JNIEnv*, jobject, jobject);
- public IntPtr NewLocalRef; // jobject (*NewLocalRef)(JNIEnv*, jobject);
- public IntPtr EnsureLocalCapacity; // jint (*EnsureLocalCapacity)(JNIEnv*, jint);
- public IntPtr AllocObject; // jobject (*AllocObject)(JNIEnv*, jclass);
- public IntPtr NewObject; // jobject (*NewObject)(JNIEnv*, jclass, jmethodID, ...);
- public IntPtr NewObjectV; // jobject (*NewObjectV)(JNIEnv*, jclass, jmethodID, va_list);
- public IntPtr NewObjectA; // jobject (*NewObjectA)(JNIEnv*, jclass, jmethodID, jvalue*);
- public IntPtr GetObjectClass; // jclass (*GetObjectClass)(JNIEnv*, jobject);
- public IntPtr IsInstanceOf; // jboolean (*IsInstanceOf)(JNIEnv*, jobject, jclass);
- public IntPtr GetMethodID; // jmethodID (*GetMethodID)(JNIEnv*, jclass, const char*, const char*);
- public IntPtr CallObjectMethod; // jobject (*CallObjectMethod)(JNIEnv*, jobject, jmethodID, ...);
- public IntPtr CallObjectMethodV; // jobject (*CallObjectMethodV)(JNIEnv*, jobject, jmethodID, va_list);
- public IntPtr CallObjectMethodA; // jobject (*CallObjectMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
- public IntPtr CallBooleanMethod; // jboolean (*CallBooleanMethod)(JNIEnv*, jobject, jmethodID, ...);
- public IntPtr CallBooleanMethodV; // jboolean (*CallBooleanMethodV)(JNIEnv*, jobject, jmethodID, va_list);
- public IntPtr CallBooleanMethodA; // jboolean (*CallBooleanMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
- public IntPtr CallByteMethod; // jbyte (*CallByteMethod)(JNIEnv*, jobject, jmethodID, ...);
- public IntPtr CallByteMethodV; // jbyte (*CallByteMethodV)(JNIEnv*, jobject, jmethodID, va_list);
- public IntPtr CallByteMethodA; // jbyte (*CallByteMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
- public IntPtr CallCharMethod; // jchar (*CallCharMethod)(JNIEnv*, jobject, jmethodID, ...);
- public IntPtr CallCharMethodV; // jchar (*CallCharMethodV)(JNIEnv*, jobject, jmethodID, va_list);
- public IntPtr CallCharMethodA; // jchar (*CallCharMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
- public IntPtr CallShortMethod; // jshort (*CallShortMethod)(JNIEnv*, jobject, jmethodID, ...);
- public IntPtr CallShortMethodV; // jshort (*CallShortMethodV)(JNIEnv*, jobject, jmethodID, va_list);
- public IntPtr CallShortMethodA; // jshort (*CallShortMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
- public IntPtr CallIntMethod; // jint (*CallIntMethod)(JNIEnv*, jobject, jmethodID, ...);
- public IntPtr CallIntMethodV; // jint (*CallIntMethodV)(JNIEnv*, jobject, jmethodID, va_list);
- public IntPtr CallIntMethodA; // jint (*CallIntMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
- public IntPtr CallLongMethod; // jlong (*CallLongMethod)(JNIEnv*, jobject, jmethodID, ...);
- public IntPtr CallLongMethodV; // jlong (*CallLongMethodV)(JNIEnv*, jobject, jmethodID, va_list);
- public IntPtr CallLongMethodA; // jlong (*CallLongMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
- public IntPtr CallFloatMethod; // jfloat (*CallFloatMethod)(JNIEnv*, jobject, jmethodID, ...);
- public IntPtr CallFloatMethodV; // jfloat (*CallFloatMethodV)(JNIEnv*, jobject, jmethodID, va_list);
- public IntPtr CallFloatMethodA; // jfloat (*CallFloatMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
- public IntPtr CallDoubleMethod; // jdouble (*CallDoubleMethod)(JNIEnv*, jobject, jmethodID, ...);
- public IntPtr CallDoubleMethodV; // jdouble (*CallDoubleMethodV)(JNIEnv*, jobject, jmethodID, va_list);
- public IntPtr CallDoubleMethodA; // jdouble (*CallDoubleMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
- public IntPtr CallVoidMethod; // void (*CallVoidMethod)(JNIEnv*, jobject, jmethodID, ...);
- public IntPtr CallVoidMethodV; // void (*CallVoidMethodV)(JNIEnv*, jobject, jmethodID, va_list);
- public IntPtr CallVoidMethodA; // void (*CallVoidMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
- public IntPtr CallNonvirtualObjectMethod; // jobject (*CallNonvirtualObjectMethod)(JNIEnv*, jobject, jclass, jmethodID, ...);
- public IntPtr CallNonvirtualObjectMethodV; // jobject (*CallNonvirtualObjectMethodV)(JNIEnv*, jobject, jclass, jmethodID, va_list);
- public IntPtr CallNonvirtualObjectMethodA; // jobject (*CallNonvirtualObjectMethodA)(JNIEnv*, jobject, jclass, jmethodID, jvalue*);
- public IntPtr CallNonvirtualBooleanMethod; // jboolean (*CallNonvirtualBooleanMethod)(JNIEnv*, jobject, jclass, jmethodID, ...);
- public IntPtr CallNonvirtualBooleanMethodV; // jboolean (*CallNonvirtualBooleanMethodV)(JNIEnv*, jobject, jclass, jmethodID, va_list);
- public IntPtr CallNonvirtualBooleanMethodA; // jboolean (*CallNonvirtualBooleanMethodA)(JNIEnv*, jobject, jclass, jmethodID, jvalue*);
- public IntPtr CallNonvirtualByteMethod; // jbyte (*CallNonvirtualByteMethod)(JNIEnv*, jobject, jclass, jmethodID, ...);
- public IntPtr CallNonvirtualByteMethodV; // jbyte (*CallNonvirtualByteMethodV)(JNIEnv*, jobject, jclass, jmethodID, va_list);
- public IntPtr CallNonvirtualByteMethodA; // jbyte (*CallNonvirtualByteMethodA)(JNIEnv*, jobject, jclass, jmethodID, jvalue*);
- public IntPtr CallNonvirtualCharMethod; // jchar (*CallNonvirtualCharMethod)(JNIEnv*, jobject, jclass, jmethodID, ...);
- public IntPtr CallNonvirtualCharMethodV; // jchar (*CallNonvirtualCharMethodV)(JNIEnv*, jobject, jclass, jmethodID, va_list);
- public IntPtr CallNonvirtualCharMethodA; // jchar (*CallNonvirtualCharMethodA)(JNIEnv*, jobject, jclass, jmethodID, jvalue*);
- public IntPtr CallNonvirtualShortMethod; // jshort (*CallNonvirtualShortMethod)(JNIEnv*, jobject, jclass, jmethodID, ...);
- public IntPtr CallNonvirtualShortMethodV; // jshort (*CallNonvirtualShortMethodV)(JNIEnv*, jobject, jclass, jmethodID, va_list);
- public IntPtr CallNonvirtualShortMethodA; // jshort (*CallNonvirtualShortMethodA)(JNIEnv*, jobject, jclass, jmethodID, jvalue*);
- public IntPtr CallNonvirtualIntMethod; // jint (*CallNonvirtualIntMethod)(JNIEnv*, jobject, jclass, jmethodID, ...);
- public IntPtr CallNonvirtualIntMethodV; // jint (*CallNonvirtualIntMethodV)(JNIEnv*, jobject, jclass, jmethodID, va_list);
- public IntPtr CallNonvirtualIntMethodA; // jint (*CallNonvirtualIntMethodA)(JNIEnv*, jobject, jclass, jmethodID, jvalue*);
- public IntPtr CallNonvirtualLongMethod; // jlong (*CallNonvirtualLongMethod)(JNIEnv*, jobject, jclass, jmethodID, ...);
- public IntPtr CallNonvirtualLongMethodV; // jlong (*CallNonvirtualLongMethodV)(JNIEnv*, jobject, jclass, jmethodID, va_list);
- public IntPtr CallNonvirtualLongMethodA; // jlong (*CallNonvirtualLongMethodA)(JNIEnv*, jobject, jclass, jmethodID, jvalue*);
- public IntPtr CallNonvirtualFloatMethod; // jfloat (*CallNonvirtualFloatMethod)(JNIEnv*, jobject, jclass, jmethodID, ...);
- public IntPtr CallNonvirtualFloatMethodV; // jfloat (*CallNonvirtualFloatMethodV)(JNIEnv*, jobject, jclass, jmethodID, va_list);
- public IntPtr CallNonvirtualFloatMethodA; // jfloat (*CallNonvirtualFloatMethodA)(JNIEnv*, jobject, jclass, jmethodID, jvalue*);
- public IntPtr CallNonvirtualDoubleMethod; // jdouble (*CallNonvirtualDoubleMethod)(JNIEnv*, jobject, jclass, jmethodID, ...);
- public IntPtr CallNonvirtualDoubleMethodV; // jdouble (*CallNonvirtualDoubleMethodV)(JNIEnv*, jobject, jclass, jmethodID, va_list);
- public IntPtr CallNonvirtualDoubleMethodA; // jdouble (*CallNonvirtualDoubleMethodA)(JNIEnv*, jobject, jclass, jmethodID, jvalue*);
- public IntPtr CallNonvirtualVoidMethod; // void (*CallNonvirtualVoidMethod)(JNIEnv*, jobject, jclass, jmethodID, ...);
- public IntPtr CallNonvirtualVoidMethodV; // void (*CallNonvirtualVoidMethodV)(JNIEnv*, jobject, jclass, jmethodID, va_list);
- public IntPtr CallNonvirtualVoidMethodA; // void (*CallNonvirtualVoidMethodA)(JNIEnv*, jobject, jclass, jmethodID, jvalue*);
- public IntPtr GetFieldID; // jfieldID (*GetFieldID)(JNIEnv*, jclass, const char*, const char*);
- public IntPtr GetObjectField; // jobject (*GetObjectField)(JNIEnv*, jobject, jfieldID);
- public IntPtr GetBooleanField; // jboolean (*GetBooleanField)(JNIEnv*, jobject, jfieldID);
- public IntPtr GetByteField; // jbyte (*GetByteField)(JNIEnv*, jobject, jfieldID);
- public IntPtr GetCharField; // jchar (*GetCharField)(JNIEnv*, jobject, jfieldID);
- public IntPtr GetShortField; // jshort (*GetShortField)(JNIEnv*, jobject, jfieldID);
- public IntPtr GetIntField; // jint (*GetIntField)(JNIEnv*, jobject, jfieldID);
- public IntPtr GetLongField; // jlong (*GetLongField)(JNIEnv*, jobject, jfieldID);
- public IntPtr GetFloatField; // jfloat (*GetFloatField)(JNIEnv*, jobject, jfieldID);
- public IntPtr GetDoubleField; // jdouble (*GetDoubleField)(JNIEnv*, jobject, jfieldID);
- public IntPtr SetObjectField; // void (*SetObjectField)(JNIEnv*, jobject, jfieldID, jobject);
- public IntPtr SetBooleanField; // void (*SetBooleanField)(JNIEnv*, jobject, jfieldID, jboolean);
- public IntPtr SetByteField; // void (*SetByteField)(JNIEnv*, jobject, jfieldID, jbyte);
- public IntPtr SetCharField; // void (*SetCharField)(JNIEnv*, jobject, jfieldID, jchar);
- public IntPtr SetShortField; // void (*SetShortField)(JNIEnv*, jobject, jfieldID, jshort);
- public IntPtr SetIntField; // void (*SetIntField)(JNIEnv*, jobject, jfieldID, jint);
- public IntPtr SetLongField; // void (*SetLongField)(JNIEnv*, jobject, jfieldID, jlong);
- public IntPtr SetFloatField; // void (*SetFloatField)(JNIEnv*, jobject, jfieldID, jfloat);
- public IntPtr SetDoubleField; // void (*SetDoubleField)(JNIEnv*, jobject, jfieldID, jdouble);
- public IntPtr GetStaticMethodID; // jmethodID (*GetStaticMethodID)(JNIEnv*, jclass, const char*, const char*);
- public IntPtr CallStaticObjectMethod; // jobject (*CallStaticObjectMethod)(JNIEnv*, jclass, jmethodID, ...);
- public IntPtr CallStaticObjectMethodV; // jobject (*CallStaticObjectMethodV)(JNIEnv*, jclass, jmethodID, va_list);
- public IntPtr CallStaticObjectMethodA; // jobject (*CallStaticObjectMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);
- public IntPtr CallStaticBooleanMethod; // jboolean (*CallStaticBooleanMethod)(JNIEnv*, jclass, jmethodID, ...);
- public IntPtr CallStaticBooleanMethodV; // jboolean (*CallStaticBooleanMethodV)(JNIEnv*, jclass, jmethodID, va_list);
- public IntPtr CallStaticBooleanMethodA; // jboolean (*CallStaticBooleanMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);
- public IntPtr CallStaticByteMethod; // jbyte (*CallStaticByteMethod)(JNIEnv*, jclass, jmethodID, ...);
- public IntPtr CallStaticByteMethodV; // jbyte (*CallStaticByteMethodV)(JNIEnv*, jclass, jmethodID, va_list);
- public IntPtr CallStaticByteMethodA; // jbyte (*CallStaticByteMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);
- public IntPtr CallStaticCharMethod; // jchar (*CallStaticCharMethod)(JNIEnv*, jclass, jmethodID, ...);
- public IntPtr CallStaticCharMethodV; // jchar (*CallStaticCharMethodV)(JNIEnv*, jclass, jmethodID, va_list);
- public IntPtr CallStaticCharMethodA; // jchar (*CallStaticCharMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);
- public IntPtr CallStaticShortMethod; // jshort (*CallStaticShortMethod)(JNIEnv*, jclass, jmethodID, ...);
- public IntPtr CallStaticShortMethodV; // jshort (*CallStaticShortMethodV)(JNIEnv*, jclass, jmethodID, va_list);
- public IntPtr CallStaticShortMethodA; // jshort (*CallStaticShortMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);
- public IntPtr CallStaticIntMethod; // jint (*CallStaticIntMethod)(JNIEnv*, jclass, jmethodID, ...);
- public IntPtr CallStaticIntMethodV; // jint (*CallStaticIntMethodV)(JNIEnv*, jclass, jmethodID, va_list);
- public IntPtr CallStaticIntMethodA; // jint (*CallStaticIntMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);
- public IntPtr CallStaticLongMethod; // jlong (*CallStaticLongMethod)(JNIEnv*, jclass, jmethodID, ...);
- public IntPtr CallStaticLongMethodV; // jlong (*CallStaticLongMethodV)(JNIEnv*, jclass, jmethodID, va_list);
- public IntPtr CallStaticLongMethodA; // jlong (*CallStaticLongMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);
- public IntPtr CallStaticFloatMethod; // jfloat (*CallStaticFloatMethod)(JNIEnv*, jclass, jmethodID, ...);
- public IntPtr CallStaticFloatMethodV; // jfloat (*CallStaticFloatMethodV)(JNIEnv*, jclass, jmethodID, va_list);
- public IntPtr CallStaticFloatMethodA; // jfloat (*CallStaticFloatMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);
- public IntPtr CallStaticDoubleMethod; // jdouble (*CallStaticDoubleMethod)(JNIEnv*, jclass, jmethodID, ...);
- public IntPtr CallStaticDoubleMethodV; // jdouble (*CallStaticDoubleMethodV)(JNIEnv*, jclass, jmethodID, va_list);
- public IntPtr CallStaticDoubleMethodA; // jdouble (*CallStaticDoubleMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);
- public IntPtr CallStaticVoidMethod; // void (*CallStaticVoidMethod)(JNIEnv*, jclass, jmethodID, ...);
- public IntPtr CallStaticVoidMethodV; // void (*CallStaticVoidMethodV)(JNIEnv*, jclass, jmethodID, va_list);
- public IntPtr CallStaticVoidMethodA; // void (*CallStaticVoidMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);
- public IntPtr GetStaticFieldID; // jstaticfieldID (*GetStaticFieldID)(JNIEnv*, jclass, const char*, const char*);
- public IntPtr GetStaticObjectField; // jobject (*GetStaticObjectField)(JNIEnv*, jclass, jfieldID);
- public IntPtr GetStaticBooleanField; // jboolean (*GetStaticBooleanField)(JNIEnv*, jclass, jfieldID);
- public IntPtr GetStaticByteField; // jbyte (*GetStaticByteField)(JNIEnv*, jclass, jfieldID);
- public IntPtr GetStaticCharField; // jchar (*GetStaticCharField)(JNIEnv*, jclass, jfieldID);
- public IntPtr GetStaticShortField; // jshort (*GetStaticShortField)(JNIEnv*, jclass, jfieldID);
- public IntPtr GetStaticIntField; // jint (*GetStaticIntField)(JNIEnv*, jclass, jfieldID);
- public IntPtr GetStaticLongField; // jlong (*GetStaticLongField)(JNIEnv*, jclass, jfieldID);
- public IntPtr GetStaticFloatField; // jfloat (*GetStaticFloatField)(JNIEnv*, jclass, jfieldID);
- public IntPtr GetStaticDoubleField; // jdouble (*GetStaticDoubleField)(JNIEnv*, jclass, jfieldID);
- public IntPtr SetStaticObjectField; // void (*SetStaticObjectField)(JNIEnv*, jclass, jfieldID, jobject);
- public IntPtr SetStaticBooleanField; // void (*SetStaticBooleanField)(JNIEnv*, jclass, jfieldID, jboolean);
- public IntPtr SetStaticByteField; // void (*SetStaticByteField)(JNIEnv*, jclass, jfieldID, jbyte);
- public IntPtr SetStaticCharField; // void (*SetStaticCharField)(JNIEnv*, jclass, jfieldID, jchar);
- public IntPtr SetStaticShortField; // void (*SetStaticShortField)(JNIEnv*, jclass, jfieldID, jshort);
- public IntPtr SetStaticIntField; // void (*SetStaticIntField)(JNIEnv*, jclass, jfieldID, jint);
- public IntPtr SetStaticLongField; // void (*SetStaticLongField)(JNIEnv*, jclass, jfieldID, jlong);
- public IntPtr SetStaticFloatField; // void (*SetStaticFloatField)(JNIEnv*, jclass, jfieldID, jfloat);
- public IntPtr SetStaticDoubleField; // void (*SetStaticDoubleField)(JNIEnv*, jclass, jfieldID, jdouble);
- public IntPtr NewString; // jstring (*NewString)(JNIEnv*, const jchar*, jsize);
- public IntPtr GetStringLength; // jsize (*GetStringLength)(JNIEnv*, jstring);
- public IntPtr GetStringChars; // const jchar* (*GetStringChars)(JNIEnv*, jstring, jboolean*);
- public IntPtr ReleaseStringChars; // void (*ReleaseStringChars)(JNIEnv*, jstring, const jchar*);
- public IntPtr NewStringUTF; // jstring (*NewStringUTF)(JNIEnv*, const char*);
- public IntPtr GetStringUTFLength; // jsize (*GetStringUTFLength)(JNIEnv*, jstring);
- public IntPtr GetStringUTFChars; // const char* (*GetStringUTFChars)(JNIEnv*, jstring, jboolean*);
- public IntPtr ReleaseStringUTFChars; // void (*ReleaseStringUTFChars)(JNIEnv*, jstring, const char*);
- public IntPtr GetArrayLength; // jsize (*GetArrayLength)(JNIEnv*, jarray);
- public IntPtr NewObjectArray; // jobjectArray (*NewObjectArray)(JNIEnv*, jsize, jclass, jobject);
- public IntPtr GetObjectArrayElement; // jobject (*GetObjectArrayElement)(JNIEnv*, jobjectArray, jsize);
- public IntPtr SetObjectArrayElement; // void (*SetObjectArrayElement)(JNIEnv*, jobjectArray, jsize, jobject);
- public IntPtr NewBooleanArray; // jbooleanArray (*NewBooleanArray)(JNIEnv*, jsize);
- public IntPtr NewByteArray; // jbyteArray (*NewByteArray)(JNIEnv*, jsize);
- public IntPtr NewCharArray; // jcharArray (*NewCharArray)(JNIEnv*, jsize);
- public IntPtr NewShortArray; // jshortArray (*NewShortArray)(JNIEnv*, jsize);
- public IntPtr NewIntArray; // jintArray (*NewIntArray)(JNIEnv*, jsize);
- public IntPtr NewLongArray; // jlongArray (*NewLongArray)(JNIEnv*, jsize);
- public IntPtr NewFloatArray; // jfloatArray (*NewFloatArray)(JNIEnv*, jsize);
- public IntPtr NewDoubleArray; // jdoubleArray (*NewDoubleArray)(JNIEnv*, jsize);
- public IntPtr GetBooleanArrayElements; // jboolean* (*GetBooleanArrayElements)(JNIEnv*, jbooleanArray, jboolean*);
- public IntPtr GetByteArrayElements; // jbyte* (*GetByteArrayElements)(JNIEnv*, jbyteArray, jboolean*);
- public IntPtr GetCharArrayElements; // jchar* (*GetCharArrayElements)(JNIEnv*, jcharArray, jboolean*);
- public IntPtr GetShortArrayElements; // jshort* (*GetShortArrayElements)(JNIEnv*, jshortArray, jboolean*);
- public IntPtr GetIntArrayElements; // jint* (*GetIntArrayElements)(JNIEnv*, jintArray, jboolean*);
- public IntPtr GetLongArrayElements; // jlong* (*GetLongArrayElements)(JNIEnv*, jlongArray, jboolean*);
- public IntPtr GetFloatArrayElements; // jfloat* (*GetFloatArrayElements)(JNIEnv*, jfloatArray, jboolean*);
- public IntPtr GetDoubleArrayElements; // jdouble* (*GetDoubleArrayElements)(JNIEnv*, jdoubleArray, jboolean*);
- public IntPtr ReleaseBooleanArrayElements; // void (*ReleaseBooleanArrayElements)(JNIEnv*, jbooleanArray, jboolean*, jint);
- public IntPtr ReleaseByteArrayElements; // void (*ReleaseByteArrayElements)(JNIEnv*, jbyteArray, jbyte*, jint);
- public IntPtr ReleaseCharArrayElements; // void (*ReleaseCharArrayElements)(JNIEnv*, jcharArray, jchar*, jint);
- public IntPtr ReleaseShortArrayElements; // void (*ReleaseShortArrayElements)(JNIEnv*, jshortArray, jshort*, jint);
- public IntPtr ReleaseIntArrayElements; // void (*ReleaseIntArrayElements)(JNIEnv*, jintArray, jint*, jint);
- public IntPtr ReleaseLongArrayElements; // void (*ReleaseLongArrayElements)(JNIEnv*, jlongArray, jlong*, jint);
- public IntPtr ReleaseFloatArrayElements; // void (*ReleaseFloatArrayElements)(JNIEnv*, jfloatArray, jfloat*, jint);
- public IntPtr ReleaseDoubleArrayElements; // void (*ReleaseDoubleArrayElements)(JNIEnv*, jdoubleArray, jdouble*, jint);
- public IntPtr GetBooleanArrayRegion; // void (*GetBooleanArrayRegion)(JNIEnv*, jbooleanArray, jsize, jsize, jboolean*);
- public IntPtr GetByteArrayRegion; // void (*GetByteArrayRegion)(JNIEnv*, jbyteArray, jsize, jsize, jbyte*);
- public IntPtr GetCharArrayRegion; // void (*GetCharArrayRegion)(JNIEnv*, jcharArray, jsize, jsize, jchar*);
- public IntPtr GetShortArrayRegion; // void (*GetShortArrayRegion)(JNIEnv*, jshortArray, jsize, jsize, jshort*);
- public IntPtr GetIntArrayRegion; // void (*GetIntArrayRegion)(JNIEnv*, jintArray, jsize, jsize, jint*);
- public IntPtr GetLongArrayRegion; // void (*GetLongArrayRegion)(JNIEnv*, jlongArray, jsize, jsize, jlong*);
- public IntPtr GetFloatArrayRegion; // void (*GetFloatArrayRegion)(JNIEnv*, jfloatArray, jsize, jsize, jfloat*);
- public IntPtr GetDoubleArrayRegion; // void (*GetDoubleArrayRegion)(JNIEnv*, jdoubleArray, jsize, jsize, jdouble*);
- public IntPtr SetBooleanArrayRegion; // void (*SetBooleanArrayRegion)(JNIEnv*, jbooleanArray, jsize, jsize, const jboolean*);
- public IntPtr SetByteArrayRegion; // void (*SetByteArrayRegion)(JNIEnv*, jbyteArray, jsize, jsize, const jbyte*);
- public IntPtr SetCharArrayRegion; // void (*SetCharArrayRegion)(JNIEnv*, jcharArray, jsize, jsize, const jchar*);
- public IntPtr SetShortArrayRegion; // void (*SetShortArrayRegion)(JNIEnv*, jshortArray, jsize, jsize, const jshort*);
- public IntPtr SetIntArrayRegion; // void (*SetIntArrayRegion)(JNIEnv*, jintArray, jsize, jsize, const jint*);
- public IntPtr SetLongArrayRegion; // void (*SetLongArrayRegion)(JNIEnv*, jlongArray, jsize, jsize, const jlong*);
- public IntPtr SetFloatArrayRegion; // void (*SetFloatArrayRegion)(JNIEnv*, jfloatArray, jsize, jsize, const jfloat*);
- public IntPtr SetDoubleArrayRegion; // void (*SetDoubleArrayRegion)(JNIEnv*, jdoubleArray, jsize, jsize, const jdouble*);
- public IntPtr RegisterNatives; // jint (*RegisterNatives)(JNIEnv*, jclass, const JNINativeMethod*, jint);
- public IntPtr UnregisterNatives; // jint (*UnregisterNatives)(JNIEnv*, jclass);
- public IntPtr MonitorEnter; // jint (*MonitorEnter)(JNIEnv*, jobject);
- public IntPtr MonitorExit; // jint (*MonitorExit)(JNIEnv*, jobject);
- public IntPtr GetJavaVM; // jint (*GetJavaVM)(JNIEnv*, JavaVM**);
- public IntPtr GetStringRegion; // void (*GetStringRegion)(JNIEnv*, jstring, jsize, jsize, jchar*);
- public IntPtr GetStringUTFRegion; // void (*GetStringUTFRegion)(JNIEnv*, jstring, jsize, jsize, char*);
- public IntPtr GetPrimitiveArrayCritical; // void* (*GetPrimitiveArrayCritical)(JNIEnv*, jarray, jboolean*);
- public IntPtr ReleasePrimitiveArrayCritical; // void (*ReleasePrimitiveArrayCritical)(JNIEnv*, jarray, void*, jint);
- public IntPtr GetStringCritical; // const jchar* (*GetStringCritical)(JNIEnv*, jstring, jboolean*);
- public IntPtr ReleaseStringCritical; // void (*ReleaseStringCritical)(JNIEnv*, jstring, const jchar*);
- public IntPtr NewWeakGlobalRef; // jweak (*NewWeakGlobalRef)(JNIEnv*, jobject);
- public IntPtr DeleteWeakGlobalRef; // void (*DeleteWeakGlobalRef)(JNIEnv*, jweak);
- public IntPtr ExceptionCheck; // jboolean (*ExceptionCheck)(JNIEnv*);
- public IntPtr NewDirectByteBuffer; // jobject (*NewDirectByteBuffer)(JNIEnv*, void*, jlong);
- public IntPtr GetDirectBufferAddress; // void* (*GetDirectBufferAddress)(JNIEnv*, jobject);
- public IntPtr GetDirectBufferCapacity; // jlong (*GetDirectBufferCapacity)(JNIEnv*, jobject);
- public IntPtr GetObjectRefType; // jobjectRefType (*GetObjectRefType)(JNIEnv*, jobject);
- }
-#endif // FEATURE_JNIENVIRONMENT_JI_INTPTRS || FEATURE_JNIENVIRONMENT_XA_INTPTRS
-
-#if FEATURE_JNIENVIRONMENT_JI_FUNCTION_POINTERS
- [StructLayout (LayoutKind.Sequential)]
- unsafe partial struct JNIEnv {
- private IntPtr reserved0; // void*
- private IntPtr reserved1; // void*
- private IntPtr reserved2; // void*
- private IntPtr reserved3; // void*
- public delegate* unmanaged GetVersion;
- public delegate* unmanaged DefineClass;
- public delegate* unmanaged FindClass;
- public delegate* unmanaged FromReflectedMethod;
- public delegate* unmanaged FromReflectedField;
- public delegate* unmanaged ToReflectedMethod;
- public delegate* unmanaged GetSuperclass;
- public delegate* unmanaged IsAssignableFrom;
- public delegate* unmanaged ToReflectedField;
- public delegate* unmanaged Throw;
- public delegate* unmanaged ThrowNew;
- public delegate* unmanaged ExceptionOccurred;
- public delegate* unmanaged ExceptionDescribe;
- public delegate* unmanaged ExceptionClear;
- public delegate* unmanaged FatalError;
- public delegate* unmanaged PushLocalFrame;
- public delegate* unmanaged PopLocalFrame;
- public delegate* unmanaged NewGlobalRef;
- public delegate* unmanaged DeleteGlobalRef;
- public delegate* unmanaged DeleteLocalRef;
- public delegate* unmanaged IsSameObject;
- public delegate* unmanaged NewLocalRef;
- public delegate* unmanaged EnsureLocalCapacity;
- public delegate* unmanaged AllocObject;
- public delegate* unmanaged NewObject;
- public IntPtr NewObjectV; // jobject (*NewObjectV)(JNIEnv*, jclass, jmethodID, va_list);
- public delegate* unmanaged NewObjectA;
- public delegate* unmanaged GetObjectClass;
- public delegate* unmanaged IsInstanceOf;
- public delegate* unmanaged GetMethodID;
- public delegate* unmanaged CallObjectMethod;
- public IntPtr CallObjectMethodV; // jobject (*CallObjectMethodV)(JNIEnv*, jobject, jmethodID, va_list);
- public delegate* unmanaged CallObjectMethodA;
- public delegate* unmanaged CallBooleanMethod;
- public IntPtr CallBooleanMethodV; // jboolean (*CallBooleanMethodV)(JNIEnv*, jobject, jmethodID, va_list);
- public delegate* unmanaged CallBooleanMethodA;
- public delegate* unmanaged CallByteMethod;
- public IntPtr CallByteMethodV; // jbyte (*CallByteMethodV)(JNIEnv*, jobject, jmethodID, va_list);
- public delegate* unmanaged CallByteMethodA;
- public delegate* unmanaged CallCharMethod;
- public IntPtr CallCharMethodV; // jchar (*CallCharMethodV)(JNIEnv*, jobject, jmethodID, va_list);
- public delegate* unmanaged CallCharMethodA;
- public delegate* unmanaged CallShortMethod;
- public IntPtr CallShortMethodV; // jshort (*CallShortMethodV)(JNIEnv*, jobject, jmethodID, va_list);
- public delegate* unmanaged CallShortMethodA;
- public delegate* unmanaged CallIntMethod;
- public IntPtr CallIntMethodV; // jint (*CallIntMethodV)(JNIEnv*, jobject, jmethodID, va_list);
- public delegate* unmanaged CallIntMethodA;
- public delegate* unmanaged CallLongMethod;
- public IntPtr CallLongMethodV; // jlong (*CallLongMethodV)(JNIEnv*, jobject, jmethodID, va_list);
- public delegate* unmanaged CallLongMethodA;
- public delegate* unmanaged CallFloatMethod;
- public IntPtr CallFloatMethodV; // jfloat (*CallFloatMethodV)(JNIEnv*, jobject, jmethodID, va_list);
- public delegate* unmanaged CallFloatMethodA;
- public delegate* unmanaged CallDoubleMethod;
- public IntPtr CallDoubleMethodV; // jdouble (*CallDoubleMethodV)(JNIEnv*, jobject, jmethodID, va_list);
- public delegate* unmanaged CallDoubleMethodA;
- public delegate* unmanaged CallVoidMethod;
- public IntPtr CallVoidMethodV; // void (*CallVoidMethodV)(JNIEnv*, jobject, jmethodID, va_list);
- public delegate* unmanaged CallVoidMethodA;
- public delegate* unmanaged CallNonvirtualObjectMethod;
- public IntPtr CallNonvirtualObjectMethodV; // jobject (*CallNonvirtualObjectMethodV)(JNIEnv*, jobject, jclass, jmethodID, va_list);
- public delegate* unmanaged CallNonvirtualObjectMethodA;
- public delegate* unmanaged CallNonvirtualBooleanMethod;
- public IntPtr CallNonvirtualBooleanMethodV; // jboolean (*CallNonvirtualBooleanMethodV)(JNIEnv*, jobject, jclass, jmethodID, va_list);
- public delegate* unmanaged CallNonvirtualBooleanMethodA;
- public delegate* unmanaged CallNonvirtualByteMethod;
- public IntPtr CallNonvirtualByteMethodV; // jbyte (*CallNonvirtualByteMethodV)(JNIEnv*, jobject, jclass, jmethodID, va_list);
- public delegate* unmanaged CallNonvirtualByteMethodA;
- public delegate* unmanaged CallNonvirtualCharMethod;
- public IntPtr CallNonvirtualCharMethodV; // jchar (*CallNonvirtualCharMethodV)(JNIEnv*, jobject, jclass, jmethodID, va_list);
- public delegate* unmanaged CallNonvirtualCharMethodA;
- public delegate* unmanaged CallNonvirtualShortMethod;
- public IntPtr CallNonvirtualShortMethodV; // jshort (*CallNonvirtualShortMethodV)(JNIEnv*, jobject, jclass, jmethodID, va_list);
- public delegate* unmanaged CallNonvirtualShortMethodA;
- public delegate* unmanaged CallNonvirtualIntMethod;
- public IntPtr CallNonvirtualIntMethodV; // jint (*CallNonvirtualIntMethodV)(JNIEnv*, jobject, jclass, jmethodID, va_list);
- public delegate* unmanaged CallNonvirtualIntMethodA;
- public delegate* unmanaged CallNonvirtualLongMethod;
- public IntPtr CallNonvirtualLongMethodV; // jlong (*CallNonvirtualLongMethodV)(JNIEnv*, jobject, jclass, jmethodID, va_list);
- public delegate* unmanaged CallNonvirtualLongMethodA;
- public delegate* unmanaged CallNonvirtualFloatMethod;
- public IntPtr CallNonvirtualFloatMethodV; // jfloat (*CallNonvirtualFloatMethodV)(JNIEnv*, jobject, jclass, jmethodID, va_list);
- public delegate* unmanaged CallNonvirtualFloatMethodA;
- public delegate* unmanaged CallNonvirtualDoubleMethod;
- public IntPtr CallNonvirtualDoubleMethodV; // jdouble (*CallNonvirtualDoubleMethodV)(JNIEnv*, jobject, jclass, jmethodID, va_list);
- public delegate* unmanaged CallNonvirtualDoubleMethodA;
- public delegate* unmanaged CallNonvirtualVoidMethod;
- public IntPtr CallNonvirtualVoidMethodV; // void (*CallNonvirtualVoidMethodV)(JNIEnv*, jobject, jclass, jmethodID, va_list);
- public delegate* unmanaged CallNonvirtualVoidMethodA;
- public delegate* unmanaged GetFieldID;
- public delegate* unmanaged GetObjectField;
- public delegate* unmanaged GetBooleanField;
- public delegate* unmanaged GetByteField;
- public delegate* unmanaged GetCharField;
- public delegate* unmanaged GetShortField;
- public delegate* unmanaged GetIntField;
- public delegate* unmanaged GetLongField;
- public delegate* unmanaged GetFloatField;
- public delegate* unmanaged GetDoubleField;
- public delegate* unmanaged SetObjectField;
- public delegate* unmanaged SetBooleanField;
- public delegate* unmanaged SetByteField;
- public delegate* unmanaged SetCharField;
- public delegate* unmanaged SetShortField;
- public delegate* unmanaged SetIntField;
- public delegate* unmanaged SetLongField;
- public delegate* unmanaged SetFloatField;
- public delegate* unmanaged SetDoubleField;
- public delegate* unmanaged GetStaticMethodID;
- public delegate* unmanaged CallStaticObjectMethod;
- public IntPtr CallStaticObjectMethodV; // jobject (*CallStaticObjectMethodV)(JNIEnv*, jclass, jmethodID, va_list);
- public delegate* unmanaged CallStaticObjectMethodA;
- public delegate* unmanaged CallStaticBooleanMethod;
- public IntPtr CallStaticBooleanMethodV; // jboolean (*CallStaticBooleanMethodV)(JNIEnv*, jclass, jmethodID, va_list);
- public delegate* unmanaged CallStaticBooleanMethodA;
- public delegate* unmanaged CallStaticByteMethod;
- public IntPtr CallStaticByteMethodV; // jbyte (*CallStaticByteMethodV)(JNIEnv*, jclass, jmethodID, va_list);
- public delegate* unmanaged CallStaticByteMethodA;
- public delegate* unmanaged CallStaticCharMethod;
- public IntPtr CallStaticCharMethodV; // jchar (*CallStaticCharMethodV)(JNIEnv*, jclass, jmethodID, va_list);
- public delegate* unmanaged CallStaticCharMethodA;
- public delegate* unmanaged CallStaticShortMethod;
- public IntPtr CallStaticShortMethodV; // jshort (*CallStaticShortMethodV)(JNIEnv*, jclass, jmethodID, va_list);
- public delegate* unmanaged CallStaticShortMethodA;
- public delegate* unmanaged CallStaticIntMethod;
- public IntPtr CallStaticIntMethodV; // jint (*CallStaticIntMethodV)(JNIEnv*, jclass, jmethodID, va_list);
- public delegate* unmanaged CallStaticIntMethodA;
- public delegate* unmanaged CallStaticLongMethod;
- public IntPtr CallStaticLongMethodV; // jlong (*CallStaticLongMethodV)(JNIEnv*, jclass, jmethodID, va_list);
- public delegate* unmanaged CallStaticLongMethodA;
- public delegate* unmanaged CallStaticFloatMethod;
- public IntPtr CallStaticFloatMethodV; // jfloat (*CallStaticFloatMethodV)(JNIEnv*, jclass, jmethodID, va_list);
- public delegate* unmanaged CallStaticFloatMethodA;
- public delegate* unmanaged CallStaticDoubleMethod;
- public IntPtr CallStaticDoubleMethodV; // jdouble (*CallStaticDoubleMethodV)(JNIEnv*, jclass, jmethodID, va_list);
- public delegate* unmanaged CallStaticDoubleMethodA;
- public delegate* unmanaged CallStaticVoidMethod;
- public IntPtr CallStaticVoidMethodV; // void (*CallStaticVoidMethodV)(JNIEnv*, jclass, jmethodID, va_list);
- public delegate* unmanaged CallStaticVoidMethodA;
- public delegate* unmanaged GetStaticFieldID;
- public delegate* unmanaged GetStaticObjectField;
- public delegate* unmanaged GetStaticBooleanField;
- public delegate* unmanaged GetStaticByteField;
- public delegate* unmanaged GetStaticCharField;
- public delegate* unmanaged GetStaticShortField;
- public delegate* unmanaged GetStaticIntField;
- public delegate* unmanaged GetStaticLongField;
- public delegate* unmanaged GetStaticFloatField;
- public delegate* unmanaged GetStaticDoubleField;
- public delegate* unmanaged SetStaticObjectField;
- public delegate* unmanaged SetStaticBooleanField;
- public delegate* unmanaged SetStaticByteField;
- public delegate* unmanaged SetStaticCharField;
- public delegate* unmanaged SetStaticShortField;
- public delegate* unmanaged SetStaticIntField;
- public delegate* unmanaged SetStaticLongField;
- public delegate* unmanaged SetStaticFloatField;
- public delegate* unmanaged SetStaticDoubleField;
- public delegate* unmanaged NewString;
- public delegate* unmanaged GetStringLength;
- public delegate* unmanaged GetStringChars;
- public delegate* unmanaged ReleaseStringChars;
- public delegate* unmanaged NewStringUTF;
- public delegate* unmanaged GetStringUTFLength;
- public delegate* unmanaged GetStringUTFChars;
- public delegate* unmanaged ReleaseStringUTFChars;
- public delegate* unmanaged GetArrayLength;
- public delegate* unmanaged NewObjectArray;
- public delegate* unmanaged GetObjectArrayElement;
- public delegate* unmanaged SetObjectArrayElement;
- public delegate* unmanaged NewBooleanArray;
- public delegate* unmanaged NewByteArray;
- public delegate* unmanaged NewCharArray;
- public delegate* unmanaged NewShortArray;
- public delegate* unmanaged NewIntArray;
- public delegate* unmanaged NewLongArray;
- public delegate* unmanaged NewFloatArray;
- public delegate* unmanaged NewDoubleArray;
- public delegate* unmanaged GetBooleanArrayElements;
- public delegate* unmanaged GetByteArrayElements;
- public delegate* unmanaged GetCharArrayElements;
- public delegate* unmanaged GetShortArrayElements;
- public delegate* unmanaged GetIntArrayElements;
- public delegate* unmanaged GetLongArrayElements;
- public delegate* unmanaged GetFloatArrayElements;
- public delegate* unmanaged GetDoubleArrayElements;
- public delegate* unmanaged ReleaseBooleanArrayElements;
- public delegate* unmanaged ReleaseByteArrayElements;
- public delegate* unmanaged ReleaseCharArrayElements;
- public delegate* unmanaged ReleaseShortArrayElements;
- public delegate* unmanaged ReleaseIntArrayElements;
- public delegate* unmanaged ReleaseLongArrayElements;
- public delegate* unmanaged ReleaseFloatArrayElements;
- public delegate* unmanaged ReleaseDoubleArrayElements;
- public delegate* unmanaged GetBooleanArrayRegion;
- public delegate* unmanaged GetByteArrayRegion;
- public delegate* unmanaged GetCharArrayRegion;
- public delegate* unmanaged GetShortArrayRegion;
- public delegate* unmanaged GetIntArrayRegion;
- public delegate* unmanaged GetLongArrayRegion;
- public delegate* unmanaged GetFloatArrayRegion;
- public delegate* unmanaged GetDoubleArrayRegion;
- public delegate* unmanaged SetBooleanArrayRegion;
- public delegate* unmanaged SetByteArrayRegion;
- public delegate* unmanaged SetCharArrayRegion;
- public delegate* unmanaged SetShortArrayRegion;
- public delegate* unmanaged SetIntArrayRegion;
- public delegate* unmanaged SetLongArrayRegion;
- public delegate* unmanaged SetFloatArrayRegion;
- public delegate* unmanaged SetDoubleArrayRegion;
- public delegate* unmanaged RegisterNatives;
- public delegate* unmanaged UnregisterNatives;
- public delegate* unmanaged MonitorEnter;
- public delegate* unmanaged MonitorExit;
- public delegate* unmanaged GetJavaVM;
- public delegate* unmanaged GetStringRegion;
- public delegate* unmanaged GetStringUTFRegion;
- public delegate* unmanaged GetPrimitiveArrayCritical;
- public delegate* unmanaged ReleasePrimitiveArrayCritical;
- public delegate* unmanaged GetStringCritical;
- public delegate* unmanaged ReleaseStringCritical;
- public delegate* unmanaged NewWeakGlobalRef;
- public delegate* unmanaged DeleteWeakGlobalRef;
- public delegate* unmanaged ExceptionCheck;
- public delegate* unmanaged NewDirectByteBuffer;
- public delegate* unmanaged GetDirectBufferAddress;
- public delegate* unmanaged