Skip to content

Commit 25037b3

Browse files
committed
pre-implement node core ffi
nodejs/node#46905
1 parent a9b3d6a commit 25037b3

File tree

3 files changed

+149
-0
lines changed

3 files changed

+149
-0
lines changed

lib/node/index.js

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
Copyright (c) Anthony Beaumont
3+
This source code is licensed under the MIT License
4+
found in the LICENSE file in the root directory of this source tree.
5+
*/
6+
7+
/*
8+
⚠️ Experimental and not yet tested
9+
Based on https://github.com/nodejs/node/pull/46905
10+
*/
11+
12+
import * as deno from "./types/deno.js";
13+
14+
export * from "./open.js";
15+
export const types = Object.assign(Object.create(null), {
16+
//node/lib/ffi.js | These are not exported
17+
"void": "void",
18+
"char": "char",
19+
"signed char": "char",
20+
"unsigned char": "uchar",
21+
"short": "short",
22+
"short int": "short",
23+
"signed short": "short",
24+
"signed short int": "short",
25+
"unsigned short": "ushort",
26+
"unsigned short int": "ushort",
27+
"int": "int",
28+
"signed": "int",
29+
"signed int": "int",
30+
"unsigned": "uint",
31+
"unsigned int": "uint",
32+
"long": "long",
33+
"long int": "long",
34+
"signed long": "long",
35+
"signed long int": "long",
36+
"unsigned long": "ulong",
37+
"unsigned long int": "ulong",
38+
"float": "float",
39+
"double": "double",
40+
"pointer": "pointer",
41+
...deno.types,
42+
});

lib/node/open.js

+82
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/*
2+
Copyright (c) Anthony Beaumont
3+
This source code is licensed under the MIT License
4+
found in the LICENSE file in the root directory of this source tree.
5+
*/
6+
7+
/*
8+
⚠️ Experimental and not yet tested
9+
Based on https://github.com/nodejs/node/pull/46905
10+
*/
11+
12+
import { platform } from "node:process";
13+
import { getNativeFunction } from "node:ffi";
14+
import { Failure } from "@xan105/error";
15+
import { asBoolean, asArray } from "@xan105/is/opt";
16+
import {
17+
shouldObj,
18+
shouldObjWithinObj,
19+
shouldStringNotEmpty
20+
} from "@xan105/is/assert";
21+
22+
function load(path, option = {}){
23+
24+
shouldStringNotEmpty(path);
25+
shouldObj(option);
26+
27+
const options = {
28+
ignoreLoadingFail: asBoolean(option.ignoreLoadingFail) ?? false,
29+
ignoreMissingSymbol: asBoolean(option.ignoreMissingSymbol) ?? false
30+
};
31+
32+
const ext = {
33+
"win32": ".dll",
34+
"darwin": ".dylib",
35+
}[platform] ?? ".so";
36+
37+
if (path.indexOf(ext) === -1) path += ext;
38+
39+
const handle = function(symbol, result, parameters){
40+
try{
41+
return getNativeFunction(path, symbol, result, parameters);
42+
}catch(err){
43+
if(err.code === "ERR_FFI_LIBRARY_LOAD_FAILED" && options.ignoreLoadingFail)
44+
return undefined;
45+
else if (err.code === "ERR_FFI_SYMBOL_NOT_FOUND" && options.ignoreMissingSymbol)
46+
return undefined;
47+
48+
throw new Failure(err.message, {
49+
code: "ERR_FFI",
50+
cause: err,
51+
info: { lib: path, symbol }
52+
});
53+
}
54+
};
55+
56+
return handle;
57+
}
58+
59+
function dlopen(path, symbols, option){
60+
61+
shouldObjWithinObj(symbols);
62+
63+
const lib = Object.create(null);
64+
const handle = load(path, option);
65+
66+
for (const [name, definition] of Object.entries(symbols)){
67+
68+
if (name === "__proto__") continue; //not allowed
69+
70+
const parameters = asArray(definition.parameters) ?? [];
71+
const result = definition.result || "void";
72+
const nonblocking = asBoolean(definition.nonblocking) ?? false;
73+
const symbol = definition.symbol || name;
74+
75+
const fn = handle(symbol, result, parameters);
76+
if(typeof fn === "function") lib[name] = fn;
77+
}
78+
79+
return lib;
80+
}
81+
82+
export { load, dlopen }

lib/node/types/deno.js

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*
2+
Copyright (c) Anthony Beaumont
3+
This source code is licensed under the MIT License
4+
found in the LICENSE file in the root directory of this source tree.
5+
*/
6+
7+
/*
8+
⚠️ Experimental and not yet tested
9+
Based on https://github.com/nodejs/node/pull/46905
10+
*/
11+
12+
export const types = Object.assign(Object.create(null), {
13+
i8 : "char",
14+
u8 : "char",
15+
i16 : "short",
16+
u16 : "ushort",
17+
i32 : "int",
18+
u32 : "uint",
19+
i64 : "long",
20+
u64 : "ulong",
21+
//usize : koffi.types.size_t,
22+
f32 : "float",
23+
f64 : "double",
24+
"function" : "pointer"
25+
});

0 commit comments

Comments
 (0)