From 57fcf8f9bacce688bed4cfe5c38bc5dff5e71ae0 Mon Sep 17 00:00:00 2001 From: u9g Date: Thu, 2 Mar 2023 15:24:43 -0500 Subject: [PATCH] Remake typings for FFI dlopen/linkSymbols + introduce Pointer type (#2227) * Give dlopen & linkSymbols typings for exported functions * Fix lookup table * Fully change over to Pointer + fix examples * add back header for typings * Fix tsc errors * Run formatter on ffi.d.ts * Revert args/return type change * Add type tests for ffi --------- Co-authored-by: Colin McDonnell --- packages/bun-types/bun.lockb | Bin 37964 -> 38313 bytes packages/bun-types/ffi.d.ts | 149 ++++++++++++++++++++----- packages/bun-types/package.json | 5 +- packages/bun-types/tests/ffi.test-d.ts | 96 ++++++++++++++++ 4 files changed, 222 insertions(+), 28 deletions(-) create mode 100644 packages/bun-types/tests/ffi.test-d.ts diff --git a/packages/bun-types/bun.lockb b/packages/bun-types/bun.lockb index b95880249521c7aff3daa54c2cd32222bec8afb9..e764f6a0c88d5603b03975e180f1499b520f9e17 100755 GIT binary patch delta 7111 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 LeCfkz7d`cNd7@P6 delta 6571 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 Qp0YnBvMZAY-}Cc-1AC#dod5s; diff --git a/packages/bun-types/ffi.d.ts b/packages/bun-types/ffi.d.ts index 19337fab1c..3e7e91534e 100644 --- a/packages/bun-types/ffi.d.ts +++ b/packages/bun-types/ffi.d.ts @@ -345,6 +345,74 @@ declare module "bun:ffi" { */ u64_fast = 16, } + + type UNTYPED = never; + export type Pointer = number & {}; + + interface FFITypeToType { + [FFIType.char]: number; + [FFIType.int8_t]: number; + [FFIType.i8]: number; + [FFIType.uint8_t]: number; + [FFIType.u8]: number; + [FFIType.int16_t]: number; + [FFIType.i16]: number; + [FFIType.uint16_t]: number; + [FFIType.u16]: number; + [FFIType.int32_t]: number; + [FFIType.i32]: number; + [FFIType.int]: number; + [FFIType.uint32_t]: number; + [FFIType.u32]: number; + [FFIType.int64_t]: UNTYPED; + [FFIType.i64]: UNTYPED; + [FFIType.uint64_t]: UNTYPED; + [FFIType.u64]: UNTYPED; + [FFIType.double]: UNTYPED; + [FFIType.f64]: UNTYPED; + [FFIType.float]: UNTYPED; + [FFIType.f32]: UNTYPED; + [FFIType.bool]: boolean; + [FFIType.ptr]: Pointer; + [FFIType.pointer]: Pointer; + [FFIType.void]: UNTYPED; + [FFIType.cstring]: CString; + [FFIType.i64_fast]: number | bigint; + [FFIType.u64_fast]: number | bigint; + } + interface FFITypeStringToType { + ["char"]: FFIType.char; + ["int8_t"]: FFIType.int8_t; + ["i8"]: FFIType.i8; + ["uint8_t"]: FFIType.uint8_t; + ["u8"]: FFIType.u8; + ["int16_t"]: FFIType.int16_t; + ["i16"]: FFIType.i16; + ["uint16_t"]: FFIType.uint16_t; + ["u16"]: FFIType.u16; + ["int32_t"]: FFIType.int32_t; + ["i32"]: FFIType.i32; + ["int"]: FFIType.int; + ["uint32_t"]: FFIType.uint32_t; + ["u32"]: FFIType.u32; + ["int64_t"]: FFIType.int64_t; + ["i64"]: FFIType.i64; + ["uint64_t"]: FFIType.uint64_t; + ["u64"]: FFIType.u64; + ["double"]: FFIType.double; + ["f64"]: FFIType.f64; + ["float"]: FFIType.float; + ["f32"]: FFIType.f32; + ["bool"]: FFIType.bool; + ["ptr"]: FFIType.ptr; + ["pointer"]: FFIType.pointer; + ["void"]: FFIType.void; + ["cstring"]: FFIType.cstring; + ["function"]: FFIType.pointer; // for now + ["usize"]: FFIType.uint64_t; // for now + ["callback"]: FFIType.pointer; // for now + } + export type FFITypeOrString = | FFIType | "char" @@ -388,12 +456,16 @@ declare module "bun:ffi" { * * @example * From JavaScript: - * ```js - * const lib = dlopen('add', { - * // FFIType can be used or you can pass string labels. - * args: [FFIType.i32, "i32"], - * returns: "i32", - * }); + * ```ts + * import { dlopen, FFIType, suffix } from "bun:ffi" + * + * const lib = dlopen(`adder.${suffix}`, { + * add: { + * // FFIType can be used or you can pass string labels. + * args: [FFIType.i32, "i32"], + * returns: "i32", + * }, + * }) * lib.symbols.add(1, 2) * ``` * In C: @@ -413,7 +485,9 @@ declare module "bun:ffi" { * * @example * From JavaScript: - * ```js + * ```ts + * import { dlopen, CString } from "bun:ffi" + * * const lib = dlopen('z', { * version: { * returns: "ptr", @@ -470,16 +544,8 @@ declare module "bun:ffi" { // */ // export function callback(ffi: FFIFunction, cb: Function): number; - export interface Library { - symbols: Record< - string, - CallableFunction & { - /** - * The function without a wrapper - */ - native: CallableFunction; - } - >; + export interface Library>> { + symbols: ConvertFns; /** * `dlclose` the library, unloading the symbols and freeing allocated memory. @@ -491,6 +557,32 @@ declare module "bun:ffi" { close(): void; } + type ToFFIType = T extends FFIType + ? T + : T extends string + ? FFITypeStringToType[T] + : never; + + type _Narrow = [U] extends [T] ? U : Extract; + type Narrow = + | _Narrow + | _Narrow + | _Narrow + | _Narrow + | _Narrow + | _Narrow + | _Narrow + | (T extends object ? { [K in keyof T]: Narrow } : never) + | Extract<{} | null | undefined, T>; + + type ConvertFns> = { + [K in keyof Fns]: ( + ...args: Fns[K]["args"] extends infer A extends FFITypeOrString[] + ? { [L in keyof A]: FFITypeToType[ToFFIType] } + : never + ) => FFITypeToType[ToFFIType>]; + }; + /** * Open a library using `"bun:ffi"` * @@ -518,7 +610,10 @@ declare module "bun:ffi" { * goes to Fabrice Bellard and TinyCC maintainers for making this possible. * */ - export function dlopen(name: string, symbols: Symbols): Library; + export function dlopen>>( + name: string, + symbols: Fns, + ): Library; /** * Turn a native library's function pointer into a JavaScript function @@ -548,7 +643,7 @@ declare module "bun:ffi" { * */ export function CFunction( - fn: FFIFunction & { ptr: number | bigint }, + fn: FFIFunction & { ptr: Pointer }, ): CallableFunction & { /** * Free the memory allocated by the wrapping function @@ -608,7 +703,9 @@ declare module "bun:ffi" { * goes to Fabrice Bellard and TinyCC maintainers for making this possible. * */ - export function linkSymbols(symbols: Symbols): Library; + export function linkSymbols>>( + symbols: Fns, + ): Library; /** * Read a pointer as a {@link Buffer} @@ -626,7 +723,7 @@ declare module "bun:ffi" { * */ export function toBuffer( - ptr: number, + ptr: Pointer, byteOffset?: number, byteLength?: number, ): Buffer; @@ -646,7 +743,7 @@ declare module "bun:ffi" { * undefined behavior. Use with care! */ export function toArrayBuffer( - ptr: number, + ptr: Pointer, byteOffset?: number, byteLength?: number, ): ArrayBuffer; @@ -681,7 +778,7 @@ declare module "bun:ffi" { export function ptr( view: TypedArray | ArrayBufferLike | DataView, byteOffset?: number, - ): number; + ): Pointer; /** * Get a string from a UTF-8 encoded C string @@ -734,7 +831,7 @@ declare module "bun:ffi" { * reading beyond the bounds of the pointer will crash the program or cause * undefined behavior. Use with care! */ - constructor(ptr: number, byteOffset?: number, byteLength?: number); + constructor(ptr: Pointer, byteOffset?: number, byteLength?: number); /** * The ptr to the C string @@ -743,7 +840,7 @@ declare module "bun:ffi" { * is safe to continue using this instance after the `ptr` has been * freed. */ - ptr: number; + ptr: Pointer; byteOffset?: number; byteLength?: number; @@ -772,7 +869,7 @@ declare module "bun:ffi" { * * Becomes `null` once {@link JSCallback.prototype.close} is called */ - readonly ptr: number | null; + readonly ptr: Pointer | null; /** * Can the callback be called from a different thread? diff --git a/packages/bun-types/package.json b/packages/bun-types/package.json index ada826752a..2dbf1839d7 100644 --- a/packages/bun-types/package.json +++ b/packages/bun-types/package.json @@ -10,8 +10,9 @@ "fmt": "prettier --write './**/*.{ts,tsx,js,jsx}'" }, "devDependencies": { - "tsd": "^0.22.0", - "prettier": "^2.4.1" + "conditional-type-checks": "^1.0.6", + "prettier": "^2.4.1", + "tsd": "^0.22.0" }, "tsd": { "directory": "tests" diff --git a/packages/bun-types/tests/ffi.test-d.ts b/packages/bun-types/tests/ffi.test-d.ts new file mode 100644 index 0000000000..1057361342 --- /dev/null +++ b/packages/bun-types/tests/ffi.test-d.ts @@ -0,0 +1,96 @@ +import { dlopen, FFIType, suffix, CString, Pointer } from "bun:ffi"; +import * as tsd from "tsd"; +import * as tc from "conditional-type-checks"; + +// `suffix` is either "dylib", "so", or "dll" depending on the platform +// you don't have to use "suffix", it's just there for convenience +const path = `libsqlite3.${suffix}`; + +const lib = dlopen( + path, // a library name or file path + { + sqlite3_libversion: { + // no arguments, returns a string + args: [], + returns: FFIType.cstring, + }, + add: { + args: [FFIType.i32, FFIType.i32], + returns: FFIType.i32, + }, + allArgs: { + args: [ + FFIType.char, // string + FFIType.int8_t, + FFIType.i8, + FFIType.uint8_t, + FFIType.u8, + FFIType.int16_t, + FFIType.i16, + FFIType.uint16_t, + FFIType.u16, + FFIType.int32_t, + FFIType.i32, + FFIType.int, + FFIType.uint32_t, + FFIType.u32, + FFIType.int64_t, + FFIType.i64, + FFIType.uint64_t, + FFIType.u64, + FFIType.double, + FFIType.f64, + FFIType.float, + FFIType.f32, + FFIType.bool, + FFIType.ptr, + FFIType.pointer, + FFIType.void, + FFIType.cstring, + FFIType.i64_fast, + FFIType.u64_fast, + ], + returns: FFIType.void, + }, + }, +); + +tsd.expectType(lib.symbols.sqlite3_libversion()); +tsd.expectType(lib.symbols.add(1, 2)); + +tc.assert< + tc.IsExact< + typeof lib["symbols"]["allArgs"], + [ + number, + number, + number, + number, + number, + number, + number, + number, + number, + number, + number, + number, + number, + number, + never, + never, + never, + never, + never, + never, + never, + never, + boolean, + Pointer, + Pointer, + never, + CString, + number | bigint, + number | bigint, + ] + > +>;