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

Support native syscall API #51189

Open
skadisch opened this issue Dec 16, 2023 · 2 comments
Open

Support native syscall API #51189

skadisch opened this issue Dec 16, 2023 · 2 comments
Labels
feature request Issues that request new features to be added to Node.js.

Comments

@skadisch
Copy link

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:

  • os.syscall() - takes an array of BigInts, returns Promise of BigInt
  • os.syscallSync() - takes an array of BigInts, returns BigInt
  • ArrayBuffer.lock() -> returns { memoryAddress: BigInt, unlock: () => void }
  • ArrayBuffer.fromPointer() - takes address and size as BigInts

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.

@skadisch skadisch added the feature request Issues that request new features to be added to Node.js. label Dec 16, 2023
@aduh95
Copy link
Contributor

aduh95 commented Dec 17, 2023

I think #39436 (comment) 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
Copy link
Contributor

axkibe commented Dec 24, 2023

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

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature request Issues that request new features to be added to Node.js.
Projects
Status: Pending Triage
Development

No branches or pull requests

3 participants