[wasm][coreCLR] Make the call-helpers marshalling check per-P/Invoke and raise it to a warning
- Dominant language
- C#
- Stars
- 18.3k
- Forks
- 5.6k
- PR merge metrics
- PR metrics pending
Description
Requested by @jkotas in https://github.com/dotnet/runtime/pull/131877#discussion_r3925493223.
The generated wasm call helpers describe every P/Invoke with the signature the type system reports. That is what native code sees only when the module opts out of runtime marshalling — otherwise `[MarshalAs]` and the built-in rules for reference types can change what actually crosses the boundary, and the helpers would disagree with the runtime.
#131877 reports this per *module*, as a message:
```
'System.IO.Compression' declares P/Invokes without [assembly: DisableRuntimeMarshalling];
the generated helpers assume its signatures cross to native unmarshalled.
```
Two things to improve:
1. **Make it per-P/Invoke and marshalling-aware.** `Marshaller.IsMarshallingRequired(MethodSignature, ParameterMetadata[], ModuleDesc)` answers the real question, and the `ParameterMetadata` overload also sees `[MarshalAs]`, which the module-level check cannot. Note `IsMarshallingRequired(MethodDesc)` is not usable directly — it returns true for anything `UnmanagedCallersOnly`.
2. **Raise it to a warning once it is precise.** It is a message today because it names whole framework assemblies, which ship prebuilt in the runtime pack — a warning there would fail builds under `TreatWarningsAsErrors` that no user could fix. Over the browser framework closure it currently fires for four: `System.IO.Compression`, `System.Net.Primitives`, `System.Net.WebSockets`, `System.Runtime.InteropServices.JavaScript`. All four are `[LibraryImport]`-only, so their generated stubs already use blittable signatures and a per-P/Invoke check should stop reporting them without any change on their side.
> [!NOTE]
> This issue was drafted with GitHub Copilot.
Contributor guide
Assessment
This issue has not been assessed yet.