Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Java.Interop.Tools.Expressions] Add Java.Interop.Tools.Expressions
Fixes: #616 Context: #14 Context: ff4053c Context: da5d1b8 Context: 4787e01 Context: 41ba348 Remember `jnimarshalmethod-gen` (176240d)? And it's crazy idea to use the System.Linq.Expressions-based custom marshaling infrastructure (ff4053c, da5d1b8) to generate JNI marshal methods at build/packaging time. And how we had to back burner it because it depended upon System.Reflection.Emit being able to write assemblies to disk, which is a feature that never made it to .NET Core, and is still lacking as of .NET 7? Add `src/Java.Interop.Tools.Expressions`, which contains code which uses Mono.Cecil to compile `Expression<T>` expressions to IL. Then update jnimarshalmethod-gen to use it! Testing this puppy: % mkdir _x % dotnet bin/Debug-net7.0/jnimarshalmethod-gen.dll \ bin/TestDebug-net7.0/Java.Interop.Export-Tests.dll \ -v --keeptemp \ --jvm /Library/Java/JavaVirtualMachines/microsoft-11.jdk/Contents/Home/lib/jli/libjli.dylib \ -o _x \ -L bin/TestDebug-net7.0 \ -L /usr/local/share/dotnet/shared/Microsoft.NETCore.App/7.0.0 First param is assembly to process; `Java.Interop.Export-Tests.dll` is handy because that's what the `run-test-jnimarshal` target in `Makefile` processes. `-v` is verbose output, `--keeptemp` is keep temporary files (and may be vestigial). `--jvm PATH` is the path to the JVM library to load+use. `-o DIR` is where to place output files; this will create `_x/Java.Interop.Export-Tests.dll`. `-L DIR` adds `DIR` to library resolution paths; this adds `bin/TestDebug/net7.0` (dependencies of `Java.Interop.Export-Tests.dll`) and `Microsoft.NETCore.App/7.0.0-rc.1.22422.12` (net7 libs). What does that *do*? % ikdasm bin/TestDebug-net7.0/Java.Interop.Export-Tests.dll > beg.il % ikdasm _x/Java.Interop.Export-Tests.dll > end.il % git diff --no-index beg.il end.il is a ~2KB diff which shows, paraphrasing greatly: public partial class ExportTest { partial class __<$>_jni_marshal_methods { static IntPtr funcIJavaObject (IntPtr jnienv, IntPtr this) => … // … [JniAddNativeMethodRegistration] static void __RegisterNativeMembers (JniNativeMethodRegistrationArguments args) => … } } internal delegate long _JniMarshal_PP_J (IntPtr jnienv, IntPtr self); // … wherein `ExportTest._<$>_jni_marshal_methods` and the `_JniMarshal*` delegate types are added to the assembly. This also unblocks the desire stated in 4787e01: > For `Java.Base`, @jonpryor wants to support the custom marshaling > infrastructure introduced in 77a6bf8. This would allow types to > participate in JNI marshal method ("connector method") generation > *at runtime*, allowing specialization based on the current set of > types and assemblies. One-off tests: ensure that the generated assembly can be decompiled: % ikdasm bin/TestDebug-net7.0/Java.Interop.Tools.Expressions-Tests-ExpressionAssemblyBuilderTests.dll % monodis bin/TestDebug-net7.0/Java.Interop.Tools.Expressions-Tests-ExpressionAssemblyBuilderTests.dll % ikdasm _x/Java.Interop.Export-Tests.dll % monodis _x/Java.Interop.Export-Tests.dll Re-enable most of `Java.Interop.Export-Tests.dll` for .NET 7; see 41ba348, which disabled those tests. TODO: we should be able to use `jnimarshalmethod-gen` output as part of the unit tests, a'la c8f3e51. Unfortunately, `dotnet test` doesn't like the updated assembly. Why? # sanity test: tests run! % % dotnet test bin/TestDebug-net7.0/Java.Interop.Export-Tests.dll … Passed! - Failed: 0, Passed: 17, Skipped: 0, Total: 17, Duration: 110 ms - Java.Interop.Export-Tests.dll (net7.0) # backup! % cp bin/TestDebug-net7.0/Java.Interop.Export-Tests.dll . # …previous jnimarshalmethod-gen.dll invocation… # replace the test assembly % \cp _x/Java.Interop.Export-Tests.dll bin/TestDebug-net7.0 # run tests for updated assembly % dotnet test bin/TestDebug-net7.0/Java.Interop.Export-Tests.dll … No test is available in …/bin/TestDebug-net7.0/Java.Interop.Export-Tests.dll. Make sure that test discoverer & executors are registered and platform & framework version settings are appropriate and try again. Additionally, path to test adapters can be specified using /TestAdapterPath command. Example /TestAdapterPath:<pathToCustomAdapters>. Huh? Assembly diff: https://gist.github.com/jonpryor/b8233444f2e51043732bea922f6afc81
- Loading branch information