[mono][wasm] Respect [Un]SupportedOSPlatform in the Mono pinvoke generator#131022
Conversation
The Mono wasm pinvoke collector analyzed every P/Invoke and callback in every
referenced assembly without consulting platform attributes. A Windows-only
method with non-blittable parameters (e.g. a gdi32 P/Invoke taking HandleRef /
object) therefore produced spurious WASM0060/WASM0062/WASM0001 diagnostics when
building for the browser, even though the method is never usable there.
The CoreCLR pinvoke collector already skips such methods via an
IsUnsupportedOnPlatform / EvaluatePlatformAttributes check driven by TargetOS.
Mirror that into the Mono collector: thread TargetOS through
ManagedToNativeGenerator -> PInvokeTableGenerator -> PInvokeCollector and skip
pinvokes/callbacks whose method, declaring type, or assembly is unsupported on
the target OS (UnsupportedOSPlatform matching the target, or a SupportedOSPlatform
list that does not include it).
Adds a Wasm.Build.Tests regression that builds a browser app containing a
[SupportedOSPlatform("windows")] non-blittable pinvoke and asserts none of
WASM0001/WASM0060/WASM0062 are emitted.
Fixes #110870
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 62dcd5b3-7227-426b-a072-8812e9c4382d
|
Azure Pipelines: Successfully started running 3 pipeline(s). 13 pipeline(s) were filtered out due to trigger conditions. There may be pipelines that require an authorized user to comment /azp run to run. |
|
Tagging subscribers to 'arch-wasm': @lewing, @pavelsavara |
There was a problem hiding this comment.
Pull request overview
This PR updates the Mono WASM P/Invoke collection/generation step to respect [SupportedOSPlatform] / [UnsupportedOSPlatform] attributes, so platform-specific (e.g., Windows-only) P/Invokes and callbacks are skipped when building for browser/WASI targets and don’t emit irrelevant non-blittable/signature diagnostics.
Changes:
- Thread
TargetOSthrough the MonoManagedToNativeGenerator→PInvokeTableGenerator→PInvokeCollectorpipeline and validate supported target values (browser,wasi). - Add platform-attribute evaluation to the Mono
PInvokeCollectorand skip unsupported P/Invokes/callbacks (mirroring the CoreCLR collector behavior). - Add a WASM build test asset + regression test asserting Windows-only non-blittable P/Invokes don’t produce
WASM0001/WASM0060/WASM0062when targetingbrowser.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| src/tasks/WasmAppBuilder/mono/PInvokeTableGenerator.cs | Passes targetOS into the Mono PInvokeCollector so platform filtering can occur during scan. |
| src/tasks/WasmAppBuilder/mono/PInvokeCollector.cs | Implements platform attribute evaluation/caching and skips unsupported P/Invokes and callbacks. |
| src/tasks/WasmAppBuilder/mono/ManagedToNativeGenerator.cs | Introduces/validates TargetOS and forwards it into PInvokeTableGenerator. |
| src/mono/wasm/Wasm.Build.Tests/PInvokeTableGeneratorTests.cs | Adds a regression test asserting the diagnostics are not emitted for a Windows-only P/Invoke. |
| src/mono/wasm/testassets/EntryPoints/PInvoke/UnsupportedOSPlatform.cs | Adds a Windows-only, intentionally non-blittable P/Invoke sample used by the new test. |
| src/mono/wasm/build/WasmApp.Common.targets | Passes $(TargetOS) into ManagedToNativeGenerator so the task can apply platform filtering. |
|
Workflow state for the Holistic Review Orchestrator. {
"version": 5,
"last_dispatched_commit": "22b820636a25ef95f0c7eb94f127c69c25dd0e45",
"last_dispatched_base_ref": "main",
"last_dispatched_base_sha": "13c03a4a9a854291f77636b1e15038e65919e68b",
"last_reviewed_commit": "22b820636a25ef95f0c7eb94f127c69c25dd0e45",
"last_reviewed_base_ref": "main",
"last_reviewed_base_sha": "13c03a4a9a854291f77636b1e15038e65919e68b",
"last_recorded_worker_run_id": "29689450331",
"review_attempt_commit": "",
"review_attempt_base_ref": "",
"review_attempt_count": 0,
"max_review_attempts": 5,
"review_history_format": "holistic-review-disclosure-v1",
"review_history": [
{
"commit": "22b820636a25ef95f0c7eb94f127c69c25dd0e45",
"review_id": 4730871164
}
]
} |
There was a problem hiding this comment.
Holistic Review
Motivation: When building a browser/wasm app, the wasm P/Invoke collector analyzes every DllImport method regardless of platform. A Windows-only P/Invoke (e.g. GDI/USER32 with non-blittable parameters) that can never be reached on the browser was still being analyzed, producing spurious WASM0060/WASM0062/WASM0001 diagnostics and build failures (#110870).
Approach: The ManagedToNativeGenerator MSBuild task now accepts a TargetOS property (defaulting to browser, validated against browser/wasi), threaded through PInvokeTableGenerator into PInvokeCollector. The collector skips P/Invoke methods and callbacks that are unsupported on the target OS, determined by walking SupportedOSPlatform/UnsupportedOSPlatform attributes at method → declaring-type (recursively through nesting) → assembly scope, with per-type and per-assembly caches. WasmApp.Common.targets passes TargetOS to the task. A regression test asset and a [Theory] test assert the diagnostics are no longer emitted.
Summary: This is a clean, well-targeted fix. The platform-attribute resolution correctly mirrors runtime precedence (explicit method result wins over type; SupportedOSPlatform present-but-not-listing-target implies unsupported), caching is keyed appropriately, and the new TargetOS plumbing matches the already-existing pattern in the coreclr sibling (src/tasks/WasmAppBuilder/coreclr/ManagedToNativeGenerator.cs), keeping the two variants consistent. The try/catch around attribute inspection preserves the collector's prior tolerance of unresolvable attribute assemblies. The regression test uses the established CopyTestAsset/ReplaceFile/BuildProject helpers and the correct native-mono category. I found no correctness or design concerns; behavior for the default browser target is unchanged for platform-agnostic P/Invokes. Non-blocking observation: EvaluatePlatformAttributes compares the platform name by exact string equality, so a version-qualified attribute value would not match browser/wasi—harmless in practice since those targets are not version-qualified.
Detailed Findings
No actionable issues. LGTM.
Note
This review was generated by this repository's Holistic Review agentic workflow to complement the built-in Copilot review.
Generated by Holistic Review · 62 AIC · ⌖ 10.4 AIC · ⊞ 10K
|
/backport to release/10.0 |
|
Started backporting to |
|
@lewing backporting to git am output$ git am --3way --empty=keep --ignore-whitespace --keep-non-patch changes.patch
Applying: [wasm] Respect [Un]SupportedOSPlatform in the Mono pinvoke generator
Using index info to reconstruct a base tree...
M src/mono/wasm/Wasm.Build.Tests/PInvokeTableGeneratorTests.cs
M src/mono/wasm/build/WasmApp.Common.targets
A src/tasks/WasmAppBuilder/mono/ManagedToNativeGenerator.cs
A src/tasks/WasmAppBuilder/mono/PInvokeCollector.cs
A src/tasks/WasmAppBuilder/mono/PInvokeTableGenerator.cs
Falling back to patching base and 3-way merge...
Auto-merging src/mono/wasm/Wasm.Build.Tests/PInvokeTableGeneratorTests.cs
Auto-merging src/mono/wasm/build/WasmApp.Common.targets
Auto-merging src/tasks/WasmAppBuilder/ManagedToNativeGenerator.cs
CONFLICT (content): Merge conflict in src/tasks/WasmAppBuilder/ManagedToNativeGenerator.cs
Auto-merging src/tasks/WasmAppBuilder/PInvokeCollector.cs
Auto-merging src/tasks/WasmAppBuilder/PInvokeTableGenerator.cs
error: Failed to merge in the changes.
hint: Use 'git am --show-current-patch=diff' to see the failed patch
hint: When you have resolved this problem, run "git am --continue".
hint: If you prefer to skip this patch, run "git am --skip" instead.
hint: To restore the original branch and stop patching, run "git am --abort".
hint: Disable this message with "git config set advice.mergeConflict false"
Patch failed at 0001 [wasm] Respect [Un]SupportedOSPlatform in the Mono pinvoke generator
Error: The process '/usr/bin/git' failed with exit code 128 |
Summary
Fixes #110870. Building a browser-wasm app that references a Windows-only P/Invoke with non-blittable parameters (e.g. the gdi32
GetCharABCWidthsFloat, which takesHandleRef/object) emits spurious diagnostics on the Mono wasm backend:Root cause
The Mono pinvoke collector (
src/tasks/WasmAppBuilder/mono/PInvokeCollector.cs) analyzed every P/Invoke and callback in every referenced assembly, without consulting[SupportedOSPlatform]/[UnsupportedOSPlatform]. So a method that is only usable on Windows still had its (non-blittable) signature analyzed when targeting the browser, producing the warnings.The CoreCLR collector already handles this — it skips a method up front via
IsUnsupportedOnPlatform/EvaluatePlatformAttributes, driven by aTargetOS. That check was never ported to the Mono collector, so #110870 still reproduces on Mono while it's fixed on CoreCLR.Fix
Mirror the CoreCLR platform check into the Mono generator:
TargetOSthroughManagedToNativeGenerator→PInvokeTableGenerator→PInvokeCollector(the shared<ManagedToNativeGenerator>invocation now passesTargetOS="$(TargetOS)"; the Mono task gets aTargetOSproperty defaulting tobrowser, mirroring CoreCLR).[UnsupportedOSPlatform(target)], or a[SupportedOSPlatform(...)]list that doesn't include the target.Only affects the Mono wasm build task; CoreCLR is unchanged.
Test
Adds
PInvokeTableGeneratorTests.UnsupportedOSPlatformPInvokeIsSkipped: builds a browser app containing a[SupportedOSPlatform("windows")]non-blittable pinvoke and asserts none ofWASM0001/WASM0060/WASM0062are emitted.Verification
Built the Mono wasm build task and ran a repro (browser app with a
[SupportedOSPlatform("windows")]gdi32-style pinvoke takingHandleRef/object), plus the new WBT test:WASM0060+WASM0062+WASM0001(matching the report).Note
This pull request was authored with GitHub Copilot.