aboutsummaryrefslogtreecommitdiff
path: root/src/javascript/jsc/ffi.exports.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/javascript/jsc/ffi.exports.js')
-rw-r--r--src/javascript/jsc/ffi.exports.js53
1 files changed, 53 insertions, 0 deletions
diff --git a/src/javascript/jsc/ffi.exports.js b/src/javascript/jsc/ffi.exports.js
index 1aa9eee51..1617ffc52 100644
--- a/src/javascript/jsc/ffi.exports.js
+++ b/src/javascript/jsc/ffi.exports.js
@@ -6,6 +6,7 @@ export const toArrayBuffer = globalThis.Bun.FFI.toArrayBuffer;
export const viewSource = globalThis.Bun.FFI.viewSource;
const BunCString = globalThis.Bun.FFI.CString;
+const nativeLinkSymbols = globalThis.Bun.FFI.linkSymbols;
export class CString extends String {
constructor(ptr, byteOffset, byteLength) {
@@ -262,6 +263,58 @@ export function dlopen(path, options) {
return result;
}
+export function linkSymbols(options) {
+ const result = nativeLinkSymbols(options);
+
+ for (let key in result.symbols) {
+ var symbol = result.symbols[key];
+ if (
+ options[key]?.args?.length ||
+ FFIType[options[key]?.returns] === FFIType.cstring
+ ) {
+ result.symbols[key] = FFIBuilder(
+ options[key].args ?? [],
+ options[key].returns ?? FFIType.void,
+ symbol,
+ key
+ );
+ } else {
+ // consistentcy
+ result.symbols[key].native = result.symbols[key];
+ }
+ }
+
+ return result;
+}
+
+var cFunctionI = 0;
+var cFunctionRegistry;
+function onCloseCFunction(close) {
+ close();
+}
+export function CFunction(options) {
+ const identifier = `CFunction${cFunctionI++}`;
+ var result = linkSymbols({
+ [identifier]: options,
+ });
+ var hasClosed = false;
+ var close = result.close;
+ result.symbols[identifier].close = () => {
+ if (hasClosed || !close) return;
+ hasClosed = true;
+ close();
+ close = undefined;
+ };
+
+ cFunctionRegistry ||= new FinalizationRegistry(onCloseCFunction);
+ cFunctionRegistry.register(
+ result.symbols[identifier],
+ result.symbols[identifier].close
+ );
+
+ return result.symbols[identifier];
+}
+
export function callback(options, cb) {
return nativeCallback(options, cb);
}