From 3d6fa64f19e74924813ece5e5fbd53023342bac8 Mon Sep 17 00:00:00 2001 From: Aapo Alasuutari Date: Mon, 20 Jun 2022 14:06:04 +0300 Subject: feat(ext/ffi): Callbacks (#14663) This commit adds support for unstable FFI callbacks. A callback is registered using the `Deno.UnsafeCallback` API. The backing memory for the callback can be disposed of using `Deno.UnsafeCallback#close`. It is not safe to pass the callback after calling close. Callbacks from other than the isolate thread are not supported. Co-authored-by: Divy Srivastava Co-authored-by: Bert Belder --- cli/dts/lib.deno.unstable.d.ts | 94 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 91 insertions(+), 3 deletions(-) (limited to 'cli/dts') diff --git a/cli/dts/lib.deno.unstable.d.ts b/cli/dts/lib.deno.unstable.d.ts index 7ebd80422..3482d1c80 100644 --- a/cli/dts/lib.deno.unstable.d.ts +++ b/cli/dts/lib.deno.unstable.d.ts @@ -346,9 +346,14 @@ declare namespace Deno { | "f64" | "pointer"; + type NativeParameterType = + | NativeType + | NativeCallbackType; + /** A foreign function as defined by its parameter and result types */ export interface ForeignFunction< - Parameters extends readonly NativeType[] = readonly NativeType[], + Parameters extends readonly NativeParameterType[] = + readonly NativeParameterType[], Result extends NativeType = NativeType, NonBlocking extends boolean = boolean, > { @@ -391,11 +396,17 @@ declare namespace Deno { type StaticForeignFunctionParameter = T extends "void" ? void : T extends StaticNativeNumberType | StaticNativeBigIntType ? number | bigint - : T extends "pointer" ? Deno.UnsafePointer | Deno.TypedArray | null + : T extends "pointer" ? UnsafePointer | TypedArray | null + : T extends NativeCallbackType< + infer U extends readonly NativeType[], + infer V extends NativeParameterType + > ? UnsafeCallback | UnsafePointer | null : unknown; /** Infers a foreign function parameter list. */ - type StaticForeignFunctionParameters = [ + type StaticForeignFunctionParameters< + T extends readonly NativeParameterType[], + > = [ ...{ [K in keyof T]: StaticForeignFunctionParameter; }, @@ -513,6 +524,83 @@ declare namespace Deno { >; } + export interface UnsafeCallbackDefinition< + Parameters extends readonly NativeType[] = readonly NativeType[], + Result extends NativeParameterType = NativeParameterType, + > { + parameters: Parameters; + result: Result; + } + + interface NativeCallbackType< + Parameters extends readonly NativeType[] = readonly NativeType[], + Result extends NativeParameterType = NativeParameterType, + > { + readonly function: UnsafeCallbackDefinition; + } + + type UnsafeCallbackParameters = T extends [] + ? [] + : T extends + readonly [infer U extends NativeType, ...(infer V extends NativeType[])] + ? [ + UnsafeCallbackParameter, + ...UnsafeCallbackParameters, + ] + : never; + + type UnsafeCallbackParameter = T extends + StaticNativeBigIntType ? bigint + : T extends StaticNativeNumberType ? number + : T extends "pointer" ? UnsafePointer + : never; + + type UnsafeCallbackResult = T extends "void" + ? void + : T extends StaticNativeBigIntType ? number | bigint + : T extends StaticNativeNumberType ? number + : T extends "pointer" ? UnsafePointer | TypedArray | null + : T extends NativeCallbackType< + infer U extends readonly NativeType[], + infer V extends NativeParameterType + > ? UnsafeCallback | UnsafePointer | null + : never; + + type UnsafeCallbackFunction< + Parameters extends readonly NativeType[] = readonly NativeType[], + Result extends NativeParameterType = NativeParameterType, + > = Result extends NativeParameterType + ? Parameters extends readonly [] ? () => UnsafeCallbackResult + : Parameters extends readonly NativeType[] ? ( + ...args: UnsafeCallbackParameters + ) => UnsafeCallbackResult + : never + : never; + + /** + * **UNSTABLE**: Unsafe and new API, beware! + * + * An unsafe function pointer for passing JavaScript functions + * as C function pointers to ffi calls. + * + * The function pointer remains valid until the `close()` method is called. + */ + export class UnsafeCallback< + Parameters extends readonly NativeType[] = readonly NativeType[], + Result extends NativeParameterType = NativeParameterType, + > { + constructor( + definition: UnsafeCallbackDefinition, + callback: UnsafeCallbackFunction, + ); + + pointer: UnsafePointer; + definition: UnsafeCallbackDefinition; + callback: UnsafeCallbackFunction; + + close(): void; + } + /** A dynamic library resource */ export interface DynamicLibrary { /** All of the registered library along with functions for calling them */ -- cgit v1.2.3