denoland / deno

A modern runtime for JavaScript and TypeScript.
https://deno.com
MIT License
98.19k stars 5.41k forks source link

Proper FFI support #5551

Closed buckle2000 closed 4 years ago

buckle2000 commented 4 years ago

To interface with code from other languages easily, deno need to have proper foreign function interface (FFI) support, not plugin support with proprietary format.

Prior Art

Python ctypes: On every dynamic call, infer foreign function argument type from types of objects; provide special wrapper types for C types and structs. Argument types are dynamic on every call. node-ffi (unofficial package): Like LuaJIT, declare first, then call. LuaJIT FFI: Turn C declarations into functions. cgo: Turn C declarations into functions. Rust: extern "C" for C ABI.

Implementation

We can create the functionality by exposing dlopen, dlsym... from libdl (or rust) and and ffi_* from libffi as ops, and make rest part of the standard library . This approach was taken by node-ffi. It doesn't leak v8 details.

Runtime API

Each function has one op related to it.

C:          void *dlopen(const char *file, int mode); |
Typescript: function Deno.dlopenSync(path?: string, options?: DlopenOptions): Promise<SharedObject>
Capability: ffi=path (can run code)

C:          int dlclose(void *handle); |
Typescript: Deno.close ?
Capability: None/ffi (can run code too), but current Deno.close requres no permission

C:          void *dlsym(void *restrict handle, const char *restrict name); |
Typescript: TODO
Capability: None?

C:          char *dlerror(void); |
Typescript: TODO
Capability: None?

C:          ffi_status ffi_prep_cif(ffi_cif *cif, ffi_abi abi, unsigned int nargs,ffi_type *rtype, ffi_type **atypes); |
Typescript: TODO
Capability: None

C:          ffi_status ffi_prep_cif_var(ffi_cif *cif, ffi_abi abi, unsigned int nfixedargs, unsigned int ntotalargs, ffi_type *rtype, ffi_type **atypes); |
Typescript: TODO
Capability: None

C:          void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue); |
Typescript: TODO
Capability: ffi

C:          ffi_status ffi_get_struct_offsets (ffi_abi abi, ffi_type *struct_type, size_t *offsets); |
Typescript: TODO
Capability: None
buckle2000 commented 4 years ago

Closing in favor of #5566