nodejs / node

Node.js JavaScript runtime ✨🐢🚀✨
https://nodejs.org
Other
106.37k stars 28.98k forks source link

Support native syscall API #51189

Closed skadisch closed 1 month ago

skadisch commented 8 months ago

What is the problem this feature will solve?

If you want to use any syscalls, you need native addons. As a consequence, you need builds for every architecture. Also bundling a single JS file / minification / packing a single executable gets quite hard once addons are involved.

Also, see #39436

What is the feature you are proposing to solve the problem?

Providing a syscall API in Node itself would completely remove the need for architecture specific builds and one could generate "run-everywhere" JS files.

The hard part in solving this is probably the buffer / pointer handling. Syscalls require pointers and sometimes also data structures with pointers. Pointers are 64-bit wide on most modern platforms, hence APIs would use BigInt. In order to provide a syscall API, one would also need APIs to retrieve memory addresses of ArrayBuffers.

But then asynchronicity enters the game (because we want an async syscall API, right?), which means the garbage collector may not collect buffers that are referenced in the currently running syscalls. That also includes indirectly referenced buffers (e.g. a pointer in a data structure given to the kernel). While this could probably be done in JS itself, it still poses a high risk, as it could cause all sorts of strange behaviours if the kernel writes into memory that is reused during the syscall due to garbage collection.

The "nice" approach would probably be to explicitly lock and unlock the buffers, obtaining a memory address in the process.

On the other hand, there are cases where the kernel provides buffers to the userspace (e.g. mmap). In order to utilize this, we would need an API to instantiate a buffer based on the memory address and size.

Syscall numbers and ABI are architecture dependent, but could probably easily be handeled in JS if we know the architecture and platform (which we should?).

So in my eyes we would need something like:

This is of course mainly with Linux in mind, not sure about Windows.

What alternatives have you considered?

If node addons could be loaded via "data:" URLs, you could probably also get very far in creating "run-everywhere" JS files.

aduh95 commented 8 months ago

I think https://github.com/nodejs/node/issues/39436#issuecomment-894861190 still stands.

  • ArrayBuffer.lock() -> returns { memoryAddress: BigInt, unlock: () => void }
  • ArrayBuffer.fromPointer() - takes address and size as BigInts

Note that ArrayBuffer is not implemented by us, any change on this API would need to come from a TC39 proposal and implemented by V8.

axkibe commented 8 months ago

It already exists: https://github.com/node-ffi-napi/node-ffi-napi

just use the FFI against libc to get the C syscalls.

github-actions[bot] commented 2 months ago

There has been no activity on this feature request for 5 months. To help maintain relevant open issues, please add the https://github.com/nodejs/node/labels/never-stale label or close this issue if it should be closed. If not, the issue will be automatically closed 6 months after the last non-automated comment. For more information on how the project manages feature requests, please consult the feature request management document.

github-actions[bot] commented 1 month ago

There has been no activity on this feature request and it is being closed. If you feel closing this issue is not the right thing to do, please leave a comment.

For more information on how the project manages feature requests, please consult the feature request management document.