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

[wasi] Add new RID for WASI #77780

Closed
pavelsavara opened this issue Nov 2, 2022 · 14 comments · Fixed by #78376
Closed

[wasi] Add new RID for WASI #77780

pavelsavara opened this issue Nov 2, 2022 · 14 comments · Fixed by #78376
Assignees
Labels
Milestone

Comments

@pavelsavara pavelsavara added this to the 8.0.0 milestone Nov 2, 2022
@pavelsavara pavelsavara self-assigned this Nov 2, 2022
@ghost
Copy link

ghost commented Nov 2, 2022

Tagging subscribers to this area: @directhex
See info in area-owners.md if you want to be subscribed.

Issue Details

The initial proposal is wasi-wasm

https://learn.microsoft.com/en-us/dotnet/core/rid-catalog

Author: pavelsavara
Assignees: pavelsavara
Labels:

arch-wasm, area-Infrastructure-mono

Milestone: 8.0.0

@pavelsavara
Copy link
Member Author

cc @lewing @radical @SteveSandersonMS what are the considerations for naming RID ?
Does it matter which WASM runtime we are targeting ? (wasmtime, wasmer, ...)
Does it matter if we want to support WASI on browser in the future ? (our own JS shim or wasmer-js)
Does it matter which features are enabled on the runtime ? (SIMD, threads, FS, network)
Do engine specific extra APIs matter ? (cloudflare's API)

Also for some reason the browser wasm is not really RID. I'm confused about it, could you please help me understand ? And do the same reasons apply here too ?

@marek-safar
Copy link
Contributor

I think wasi-wasm RID makes sense, and it'd also serve as a parent for any future wasi extension RIDs (e.g. wasmer-wasm). What you need is

<RuntimeGroup Include="browser">
<Parent>any</Parent>
<Architectures>wasm</Architectures>
</RuntimeGroup>
for wasi.

We probably also want to add OperatingSystem property for WASI detection at the same time.

@SteveSandersonMS
Copy link
Member

Does it matter which WASM runtime we are targeting ? (wasmtime, wasmer, ...)

In most cases we should target the WASI spec, not a particular runtime implementation.

There will be a few edge cases where we want to take account of the practical realities of different runtimes rather than just the spec. For example, sock_accept is in the WASI spec now and wasmtime supports it, but some other runtimes might still not do because it's relatively new. So if possible we'd want applications only to end up with a sock_accept import if the developer is doing something that requires it, rather than always depending on that import (as that could prohibit the use of other runtimes).

Does it matter if we want to support WASI on browser in the future ? (our own JS shim or wasmer-js)

In theory we shouldn't have to do anything to enable this. If a developer chooses to load their WASI-compliant module in a browser, then as long as they supply WASI-compliant import implementations, it should just work. And that does match up with what I've experienced: I've been able to run both ASP.NET Core and Blazor inside the browser after compiling them using dotnet-wasi-sdk and supplying a minimal JS WASI shim.

Does it matter which features are enabled on the runtime ? (SIMD, threads, FS, network)

Ideally in the long run we'd support as much as can be supported. For features that map to specific standard runtime features, such as FS and SIMD, we'd ideally want to emit binaries that naturally work with the standard.

For other features where there isn't a standard WASI API (e.g., threads today) we could choose to wait longer to see if a standard emerges, or we could choose to have an experimental-level implementation that lines up with the functionality on a particular runtime. I'd deprioritize things that aren't standardized though.

Do engine specific extra APIs matter ? (cloudflare's API)

We'd want to support defining arbitrary wasm imports/exports so that people can integrate with these 3rd-party APIs. I already have half of an implementation of doing this from C# by enhancing the existing pinvoke generator :)

Further out, we should look into creating a C# source generator for WIT/WITX so that any API defined as WIT/WITX can be used to generate C# bindings that builds on our support for arbitrary wasm imports/exports.

What do you think? Does that all sound reasonable?

@pavelsavara
Copy link
Member Author

Does it matter if we want to support WASI on browser in the future ?

WASI-compliant module in a browser, then as long as they supply WASI-compliant import implementations, it should just work.

It would be impractical to implement sock_accept on top of fetch and then create managed HttpMessageHandler on top of it. I imagine that dealing directly with the underlying JS is way to go.
Also the (the new) JS interop would be good to have available there.

Such build of the runtime would have not only WASI imports, but also those dotnet specific JS interop imports.

Does it matter which features are enabled on the runtime ? (SIMD, threads, FS, network)

Ideally in the long run we'd support as much as can be supported.

The problem is that you need to compile for specific feature set.
If your .wasm contains instructions which are not supported in the current engine, it will fail to load whole .wasm. Not just the offending function.
See https://web.dev/webassembly-feature-detection/

@SteveSandersonMS
Copy link
Member

SteveSandersonMS commented Nov 2, 2022

It would be impractical to implement sock_accept on top of fetch

Yeah, sock_accept is the opposite direction - it's for inbound networking (TCP listeners), not for outbound networking. I wasn't suggesting anything about implementing sock_accept on top of anything else. When running in a browser there isn't any possible implementation of sock_accept, but it's not something people would expect to work.

I imagine that dealing directly with the underlying JS is way to go.

Running in the browser is a bit of a niche so I wouldn't focus on that much. In general we should be prioritizing native interop (like mapping pinvoke to a webassembly import), not JS interop.

Totally reasonable for our JS interop mechanism to work if you happen to be in a browser, but that's a small fraction of the use cases for WASI.

If your .wasm contains instructions which are not supported in the current engine, it will fail to load whole .wasm. Not just the offending function.

Absolutely. In terms of wasm features (like bulk memory etc), we would have to expose build flags to control the kind of binary output we produce.

@SteveSandersonMS
Copy link
Member

Running in the browser is a bit of a niche

Oh I just realised that's a bit contradictory to our other goal of being able to standardize on this kind of build for browser-wasm too. Perhaps that's what you were referring to, in which case sorry for the confusing response!

@pavelsavara
Copy link
Member Author

Yes, I'm thinking that having alternative to emscripten is good long term goal. Also I think that dotnet specific WASI/JS shim would be worth it.

Regarding sock_accept , sorry, yes it's the other direction. I wanted to express that none of socks is available on the browser and it's not practical to try to polyfill for it. All you have is subset of HTTP and WS.

Regarding exposing build flags for SIMD etc. It would mean that the developer would have to have WASI-SDK installed on his machine and his CI, same way as we deploy emscripten in workload today.

The other option is to have as many folders in the runtime pack as many combinations of the supported targets there are.
So that most of the time, people are not forced to recompile it. This was also Blazor requirement I think.

@pavelsavara
Copy link
Member Author

pavelsavara commented Nov 3, 2022

  • wasi-wasm - vanilla by the spec
  • wasmtime-wasm - with engine specific APIs (like networking quirks)
  • wasmtime-wasm-threads - engine specific threads API and threads enabled in mono
  • wasmtime-wasm-all - engine specific APIs and extended instructions. Maximum set what the engine could offer. Threads, SIMD
  • wasmer-wasm - another engine
  • browser-wasm - with JS interop
  • browser-wasm-all - JS interop, threads, SIMD
  • nodeJS-wasm - JS interop on different engine. Maybe local FS access?

Am I thinking about it right ?

@pavelsavara
Copy link
Member Author

browser-wasm will clash with existing emscripten target. Do we need to solve it now ?

@marek-safar
Copy link
Contributor

I think we would probably solve the different OS/runner (e.g. wasmtime) combinations with property flags than with exposing another RID.

About browser-wasm I can imagine that we migrate this under the hood to wasi+js when the time comes and introduce some legacy compatibility name.

Do we need to solve it now ?

No

@pavelsavara
Copy link
Member Author

I think we would probably solve the different OS/runner (e.g. wasmtime) combinations with property flags than with exposing another RID.

Is there some prior attempt on this ?

I don't know how that would impact behavior in runtime pack nuget.
Would we have multiple nugets ? Or multiple folders in the same nuget ?
Since we want to pack all runtime DLLs into .wasm file for each combination of target flags, it could be quite large nuget file.

@marek-safar
Copy link
Contributor

Is there some prior attempt on this ?

.net7 experimental threading support is the prior art we have

Or multiple folders in the same nuget ?

This is likely and I can imagine that we don't duplicate files that are same

@ghost ghost added the in-pr There is an active PR which will close this issue when it is merged label Nov 15, 2022
@ghost ghost removed the in-pr There is an active PR which will close this issue when it is merged label Nov 16, 2022
@ghost ghost locked as resolved and limited conversation to collaborators Dec 16, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants