Repository navigation
[bgen] Share native-object block invocation code. Fixes #6792 - #27178
rolfbjarne wants to merge 1 commit into
Conversation
Generate a common INativeObject-based invoker for void block delegates with a single native-object reference parameter. Keep delegate-specific factories, native-to-managed bridges, and UserDelegateType metadata, while sharing the invocation method, native invoker delegate, and invoker field. Preserve null-to-zero conversion, GC.KeepAlive, and block ownership through TrampolineBlockBase. Apply the same optimization to compatible rgen callbacks. Keep non-nullable rgen parameters specialized so their argument validation and parameter names remain unchanged, and give the rgen helper distinct names for assemblies using both generators. Add generator regressions covering NSObject, native-object and protocol callbacks, nested delegate discovery, unchanged specialized signatures, and compilation of the emitted shared invokers. This reduces the duplication described in #6792 without introducing public API. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 207a8109-973e-4c0e-9413-e5849518dba7
There was a problem hiding this comment.
🟡 Changes recommended
Sharing void callbacks with a single model-typed parameter bypasses GenerateArgumentChecks, suppressing the existing BI1106 warning for invalid parameter types.
1 open issue
What changed in this PR
Reduces generated block-invocation duplication in bgen and rgen, addressing #6792 by sharing compatible native-object invokers while retaining delegate-specific bridges and factories.
Changes:
- Shares invocation code, native delegates, and invoker fields for compatible callbacks.
- Keeps non-nullable rgen callbacks specialized and uses distinct helper names for each generator.
- Adds regression tests for shared and specialized signatures, nested callbacks, metadata, and emitted-code compilation.
| File | Description |
|---|---|
tests/rgen/Microsoft.Macios.Generator.Tests/Emitters/TrampolineEmitterTests.cs |
Tests rgen sharing eligibility and generated helper compilation. |
tests/bgen/tests/shared-native-object-trampolines.cs |
Adds callback fixtures covering shared, specialized, and nested cases. |
tests/bgen/BGenTests.cs |
Verifies shared invocation, lifetime handling, factories, and metadata. |
src/rgen/Microsoft.Macios.Generator/Emitters/TrampolineEmitter.cs |
Emits a shared invoker for compatible nullable native-object callbacks. |
src/bgen/Generator.cs |
Emits a shared native-object invoker and reuses it across compatible callbacks. |
Review effort: Balanced
| return !type.IsByRef && !type.IsValueType && !HasBindAsAttribute (parameter) && | ||
| (TypeManager.IsWrappedType (type) || TypeCache.INativeObject.IsAssignableFrom (type)); |
✅ API diff for current PR / commitNET (empty diffs)✅ API diff vs stableNET (empty diffs)ℹ️ Generator diffGenerator Diff: vsdrops (html) vsdrops (raw diff) gist (raw diff) - Please review changes) Pipeline on Agent |
🔥 [CI Build #82e8cd8] Test results 🔥Test results❌ Tests failed on VSTS: test results 2 tests crashed, 3 tests failed, 207 tests passed. Failures❌ dotnettests tests (macOS)1 tests failed, 0 tests passed.Failed tests
Html Report (VSDrops) Download ❌ fsharp tests🔥 Failed catastrophically on VSTS: test results - fsharp (no summary found). Html Report (VSDrops) Download ❌ windows tests🔥 Failed catastrophically on VSTS: test results - windows (no summary found). Html Report (VSDrops) Download ❌ Tests on macOS Sonoma (14) tests1 tests failed, 4 tests passed.Failed tests
Html Report (VSDrops) Download ❌ Tests on macOS Sequoia (15) tests1 tests failed, 4 tests passed.Failed tests
Html Report (VSDrops) Download Successes✅ assembly-processing: All 1 tests passed. Html Report (VSDrops) Download macOS tests✅ Tests on macOS Tahoe (26): All 5 tests passed. Html Report (VSDrops) Download Linux Build VerificationPipeline on Agent |
|

Generate a common INativeObject-based invoker for void block delegates with a single native-object reference parameter. Keep delegate-specific factories, native-to-managed bridges, and UserDelegateType metadata, while sharing the invocation method, native invoker delegate, and invoker field. Preserve null-to-zero conversion, GC.KeepAlive, and block ownership through TrampolineBlockBase.
Apply the same optimization to compatible rgen callbacks. Keep non-nullable rgen parameters specialized so their argument validation and parameter names remain unchanged, and give the rgen helper distinct names for assemblies using both generators.
Add generator regressions covering NSObject, native-object and protocol callbacks, nested delegate discovery, unchanged specialized signatures, and compilation of the emitted shared invokers. This reduces the duplication described in #6792 without introducing public API.
For the iOS and macOS builds measured before rebasing, 312 iOS and 167 macOS invokers share one invocation implementation per generator. The managed assembly sizes decreased by 48,640 bytes and 25,600 bytes, respectively; these are not measurements of linked or AOT-compiled application sizes.
🤖 Pull request created by Copilot
Fixes #6792