Skip to content

Commit

Permalink
calling conventions
Browse files Browse the repository at this point in the history
  • Loading branch information
xan105 committed Dec 23, 2023
1 parent a6e94fd commit 81cc46b
Show file tree
Hide file tree
Showing 9 changed files with 53 additions and 32 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ This is a class wrapper to the FFI library's callback function(s) inspired by De
##### Constructor
`(definition: { result: unknown, parameters: unknown[] }, callback?: Function | null)`
`(definition: { result: unknown, parameters: unknown[], abi?: string }, callback?: Function | null)`
##### Properties
Expand Down
11 changes: 10 additions & 1 deletion lib/ffi-napi/helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,15 @@ import { asArray, asBoolean } from "@xan105/is/opt";
import { isWindows, isFunction } from "@xan105/is";
import { errorLookup } from "@xan105/error";
import { GetLastError } from "./util/win32.js";
import { conventions } from "./util/abi.js";

const StructType = ref_struct(ref);

class Callback{

#parameters;
#result;
#abi;
#ref = null;
#pointer = null;

Expand All @@ -28,13 +30,20 @@ class Callback{
shouldObj(definition);
this.#parameters = asArray(definition.parameters) ?? [];
this.#result = definition.result || "void";
this.#abi = conventions.includes(definition.abi) ? definition.abi :
{"cdecl": "ms_cdecl"}[definition.abi] ?? "default_abi";

if(isFunction(callback)) this.register(callback);
}

register(callback = ()=>{}){
if(this.#ref && this.#pointer) this.close();
this.#pointer = ffi.Callback(this.#result, this.#parameters, callback);
this.#pointer = ffi.Callback(
this.#result,
this.#parameters,
ffi["FFI_" + this.#abi.toUpperCase()],
callback
);

// Make an extra reference to the callback pointer to avoid GC
this.#ref = callback;
Expand Down
12 changes: 1 addition & 11 deletions lib/ffi-napi/open.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,13 @@ import {
shouldObjWithinObj,
shouldStringNotEmpty
} from "@xan105/is/assert";
import { conventions } from "./util/abi.js";

function load(path, option = {}){

shouldStringNotEmpty(path);
shouldObj(option);

const conventions = [
"ms_cdecl",
"stdcall",
"fastcall",
"thiscall",
"win64",
"unix64",
"sysv",
"vfp"
];

const options = {
ignoreLoadingFail: asBoolean(option.ignoreLoadingFail) ?? false,
ignoreMissingSymbol: asBoolean(option.ignoreMissingSymbol) ?? false,
Expand Down
16 changes: 16 additions & 0 deletions lib/ffi-napi/util/abi.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/*
Copyright (c) Anthony Beaumont
This source code is licensed under the MIT License
found in the LICENSE file in the root directory of this source tree.
*/

export const conventions = [
"ms_cdecl",
"stdcall",
"fastcall",
"thiscall",
"win64",
"unix64",
"sysv",
"vfp"
];
4 changes: 3 additions & 1 deletion lib/koffi/helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { asArray, asBoolean } from "@xan105/is/opt";
import { isWindows, isFunction } from "@xan105/is";
import { errorLookup } from "@xan105/error";
import { GetLastError } from "./util/win32.js";
import { conventions } from "./util/abi.js";

class Callback{

Expand All @@ -23,8 +24,9 @@ class Callback{
shouldObj(definition);
const parameters = asArray(definition.parameters) ?? [];
const result = definition.result || "void";
const abi = conventions.includes(definition.abi) ? definition.abi : "cdecl";

const cb = koffi.proto(randomUUID(), result, parameters);
const cb = koffi.proto("__" + abi, randomUUID(), result, parameters);
this.#ref = koffi.pointer(cb);

if(isFunction(callback)) this.register(callback);
Expand Down
14 changes: 3 additions & 11 deletions lib/koffi/open.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,26 +14,18 @@ import {
shouldObjWithinObj,
shouldStringNotEmpty
} from "@xan105/is/assert";
import { conventions } from "./util/abi.js";

function load(path, option = {}){

shouldStringNotEmpty(path);
shouldObj(option);

const conventions = [
"cdecl",
"stdcall",
"fastcall",
"thiscall"
];

const options = {
ignoreLoadingFail: asBoolean(option.ignoreLoadingFail) ?? false,
ignoreMissingSymbol: asBoolean(option.ignoreMissingSymbol) ?? false,
lazy: asBoolean(option.lazy) ?? false,
abi: conventions.includes(option.abi) ?
option.abi :
{"ms_cdecl": "cdecl"}[option.abi] ?? "func"
abi: conventions.includes(option.abi) ? option.abi : "cdecl"
};

const ext = {
Expand All @@ -47,7 +39,7 @@ function load(path, option = {}){
const handle = function(symbol, result, parameters){
try{
if (err) throw err;
return dylib[options.abi](symbol, result, parameters);
return dylib.func("__" + options.abi, symbol, result, parameters);
}catch(err){
if (
options.ignoreMissingSymbol &&
Expand Down
12 changes: 12 additions & 0 deletions lib/koffi/util/abi.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/*
Copyright (c) Anthony Beaumont
This source code is licensed under the MIT License
found in the LICENSE file in the root directory of this source tree.
*/

export const conventions = [
"cdecl",
"stdcall",
"fastcall",
"thiscall"
];
10 changes: 5 additions & 5 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@
"@typescript-eslint/parser": "^6.13.1",
"eslint": "^8.54.0",
"ffi-napi": "^4.0.3",
"koffi": "^2.6.10",
"koffi": "^2.7.0",
"typescript": "^5.2.2"
},
"dependencies": {
Expand All @@ -81,7 +81,7 @@
},
"peerDependencies": {
"ffi-napi": "^4.0.3",
"koffi": "^2.6.10"
"koffi": "^2.7.0"
},
"peerDependenciesMeta": {
"ffi-napi": {
Expand Down

0 comments on commit 81cc46b

Please sign in to comment.