Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RISC-V] FP structs larger than 16 bytes in interops #107386

Open
tomeksowi opened this issue Sep 5, 2024 · 5 comments
Open

[RISC-V] FP structs larger than 16 bytes in interops #107386

tomeksowi opened this issue Sep 5, 2024 · 5 comments
Labels
arch-riscv Related to the RISC-V architecture area-System.Runtime.InteropServices
Milestone

Comments

@tomeksowi
Copy link
Contributor

tomeksowi commented Sep 5, 2024

.NET currently supports passing/returning structs according to hardware floating-point calling convention up to 16 bytes for reasons stated in #107286 (comment)

Native ABI does not limit size of FP structs so this won't work:

struct Empty {}
struct S { double; Empty; long; }

[DllImport("SomeLib")]
public static extern void func(S s);

.NET will pass S according to integer calling convention (by implicit reference) and the native side will expect it in two registers, fa0 and a0.

Such structs are acheivable via empty structs, which are undefined in C, which ABI .NET interops follow. However, it would be nice to throw an exception if FP structs > 16 bytes appear in interops. (Things like struct { _Alignas(16) double; long; } are legal in C and .NET users may use empty structs to match the layout.)

@dotnet-policy-service dotnet-policy-service bot added the untriaged New issue has not been triaged by the area owner label Sep 5, 2024
Copy link
Contributor

Tagging subscribers to this area: @dotnet/interop-contrib
See info in area-owners.md if you want to be subscribed.

@am11 am11 added the arch-riscv Related to the RISC-V architecture label Sep 5, 2024
@am11
Copy link
Member

am11 commented Sep 5, 2024

.NET will pass S according to integer calling convention (by implicit reference) and the native side will expect it in two registers, fa0 and a0.

Can we use custom marshalling to handle the specific layout and calling conventions required by the native side?

Alternatively, a wrapper function on the native side that can handle the conversion between the .NET calling convention and the native calling convention? That wrapper would take the struct as passed by .NET, unpack it, and then repack it according to the native ABI expectations.

@tomeksowi
Copy link
Contributor Author

Can we use custom marshalling to handle the specific layout and calling conventions required by the native side?

Alternatively, a wrapper function on the native side that can handle the conversion between the .NET calling convention and the native calling convention? That wrapper would take the struct as passed by .NET, unpack it, and then repack it according to the native ABI expectations.

I think it's not worth it, it's a corner-case achievable only by extra padding and the user has an easy (and cheaper performance-wise) way out of explicitly passing by ref.

@AaronRobinsonMSFT
Copy link
Member

However, it would be nice to throw an exception if FP structs > 16 bytes appear in interops.

@tomeksowi Is this issue for support or for an exception? It isn't clear based on title and the above comment in the description.

@tomeksowi
Copy link
Contributor Author

@tomeksowi Is this issue for support or for an exception?

Exception first, we can leave it open for visibility if anyone really needs it supported.

@agocke agocke added this to the Future milestone Sep 11, 2024
@agocke agocke removed the untriaged New issue has not been triaged by the area owner label Sep 11, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
arch-riscv Related to the RISC-V architecture area-System.Runtime.InteropServices
Projects
Status: No status
Development

No branches or pull requests

4 participants