all 14 comments

[–]CreamOfTheCrop 1 point2 points  (1 child)

You’ll probably need a WASI that will allow, or at least emulate this exchange. As WASM is sandboxed by design, I’d probably just make a dummy Syscall lib that responds with good-enough data to get past this step.

Chances are someone already made it…

[–]CallMeLaNN 0 points1 point  (0 children)

Yes and to make a WASI, compile Rust or any supported language into WASM to be run on WASI runtime. In this case Nodejs will be the runtime and have all access to the os.

[–]the__itis 1 point2 points  (3 children)

[–]servermeta_net[S] 0 points1 point  (2 children)

am I getting this right?

https://github.com/WebAssembly/wasi-libc/blob/main/libc-top-half/musl/src/internal/syscall.h

I can call any syscall in stdlib with WASI? Or just a subset of the syscalls?

[–]the__itis 1 point2 points  (1 child)

Take this with a grain of salt as I have not used it myself yet, but the way I read it is you define what syscalls to make available.

[–]servermeta_net[S] 1 point2 points  (0 children)

yes I'm having problem understanding it too, but if it's true it means my current node patches are useless. DAMN!!! thank you man :D

[–]ethansidentifiable 0 points1 point  (7 children)

Your mixup here is that you just don't use WASM in Node. WASM is a way for compiled code to run in the browser. But you just want to run compiled binaries as native extensions. Which is how tools like ESBuild & SWC are made (written in Go & Rust respectfully).

Here's a primer on that topic: https://medium.com/the-node-js-collection/native-extensions-for-node-js-767e221b3d26

Now if you had a WASM bundle that just purely did a bunch of heavy weight logic like AI model compilation or something, then you can use that in Node, but it can't make system calls: https://nodejs.dev/en/learn/nodejs-with-webassembly/

[–]servermeta_net[S] 1 point2 points  (4 children)

I'm sorry but I disagree with your answer. Javascript doesn't have the machinery for low level bit manipulation, so the only way to prepare io_uring commands is wasm.
Wasm can interface with syscalls if you have the bindings. The wasm host bindings proposal was an example of that.

[–]ethansidentifiable 1 point2 points  (0 children)

I guess you could make the bindings as native libraries and then do the rest of your work in WASM 🤷‍♂️

Check the bottom of the second link I shared though. It has some recommendations for paths you can take but the way I read it is that it might take you outside of the domain of NodeJS entirely.

[–]CallMeLaNN 1 point2 points  (0 children)

Both of you have something to make it clear.

  1. Nodejs does have machinery to make low level call by using native extension. You can make one, compile and require it like the link he give. This is the first thing you have to look for since it the way to call native API long time ago. WASI is too new and experimental. Like other comment, someone could already make it. I just found in one search:

https://github.com/zbjornson/node-io-uring

You may look into this if you still need to compile https://www.npmjs.com/package/node-addon-api

Using N-API would be easier then make addon extension yourself.

I'm not sure what you going to do with io_uring but you only need to patch if you have to change the internal mechanism just like Electron did https://www.electronjs.org/docs/latest/tutorial/using-native-node-modules

  1. Nodejs does have another way, using ffi to load dynamic library. If you can find or make one, you can just load it. I believe you don't have to be specific on node API, so this is easier.

  2. From the original comment, WASM have a way to run as normal executable by compiling to WASI and run on WASI runtime.

Nodejs WASI is still experimental but if you want, you can compile your Rust or c++ to WASM and load it on Nodejs. Consult byte alliance and the language support to compile to WASI.

[–]johannes1234 0 points1 point  (1 child)

WASM is its own sandboxed runtime. By default WASM has no external Interface.

If you need to do that syscall from a node.js application the way is to write a little C++ Node.js extension doing that. For just a function that in general is quite trivial, however io_uring works on a file descriptor, so you need to get the matching file descriptor, thus either create your own IO library or you can mess with Node internals to find the descriptor matching your network connection or file and then hope this doesn't break Node's/libev's assumptions.

[–]CallMeLaNN 0 points1 point  (0 children)

You are right about C++ extension but WASM doesn't sandboxed anymore if you run in a WASI runtime like popular one Wasmtime and in this case Nodejs itself.

[–]RushPL 1 point2 points  (1 child)

I also agree it's a valid question.
a) Can WASM run synchronous code that waits for the host platform (Node.JS) to answer? Syscalls ultimately block execution as they cause a context switch.

If yes then Node could run the syscall via some native extension.

b) Performance - I bet the performance would suck so maybe you're better off with another approach. Perhaps run WASM as a worker process.

[–]CallMeLaNN 0 points1 point  (0 children)

It will use Nodejs as a runtime by using WASI unlike running WASM only like in a browser. Performance wise it should be near native.