Skip to content

Commit f73de52

Browse files
committed
fixup! fixup! fixup! src,lib: initial ffi implementation
1 parent f24a9d3 commit f73de52

12 files changed

Lines changed: 124 additions & 134 deletions

File tree

benchmark/ffi/getpid.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ const common = require('../common.js');
44
const ffi = require('node:ffi');
55

66
const bench = common.createBenchmark(main, {
7-
n: [1e7]
8-
})
7+
n: [1e7],
8+
});
99

1010
const getpid = ffi.getNativeFunction(null, 'uv_os_getpid', 'int', []);
1111

doc/api/ffi.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ added: REPLACEME
109109
* `func` {string} The function name inside the shared library.
110110
* `retType` {string} The return value's type.
111111
* `argTypes` {Array} The types of the arguments.
112-
* Returns: {function} A JavaScript wrapper for the native function.
112+
* Returns: {Function} A JavaScript wrapper for the native function.
113113

114114
Retrieves a native function from a given shared library (i.e. `.so`, `.dylib`,
115115
or `.dll`), and returns a JavaScript wrapper function. The wrapper function does

lib/ffi.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ const {
1515
getLibrary,
1616
types,
1717
sizes,
18-
charIsSigned
18+
charIsSigned,
1919
} = internalBinding('ffi');
2020

2121
const {
@@ -131,7 +131,7 @@ const writers = {
131131
double(offset, value) {
132132
callBufferDV.setFloat64(offset, value, true);
133133
return offset + 8;
134-
}
134+
},
135135
};
136136
writers.pointer = writers.uint64_t;
137137

@@ -154,7 +154,7 @@ const readers = {
154154
uint64_t: (offset) => callBufferDV.getBigUint64(offset, true),
155155
float: (offset) => callBufferDV.getFloat32(offset, true),
156156
double: (offset) => callBufferDV.getFloat64(offset, true),
157-
void: () => undefined
157+
void: () => undefined,
158158
};
159159
readers.pointer = readers.uint64_t;
160160

@@ -235,5 +235,5 @@ function sizeof(typ) {
235235
module.exports = {
236236
getBufferPointer,
237237
getNativeFunction,
238-
sizeof
238+
sizeof,
239239
};

src/base_object_types.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ namespace node {
2020
V(http_parser_binding_data, http_parser::BindingData) \
2121
V(ffi_binding_data, ffi::FfiBindingData)
2222

23-
2423
// List of (non-binding) BaseObjects that are serializable in the snapshot.
2524
// The first argument should match what the type passes to
2625
// SET_OBJECT_ID(), the second argument should match the C++ class

src/node_ffi.cc

Lines changed: 87 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22
#include "env-inl.h"
33
#include "ffi.h"
44
#include "node_binding.h"
5+
#include "node_external_reference.h"
6+
#include "util-inl.h"
57
#include "v8-array-buffer.h"
8+
#include "v8-fast-api-calls.h"
69
#include "v8-function-callback.h"
710
#include "v8-primitive.h"
8-
#include "util-inl.h"
9-
#include "node_external_reference.h"
10-
#include "v8-fast-api-calls.h"
1111
#include "v8-template.h"
1212

1313
using v8::Array;
@@ -25,13 +25,12 @@ namespace ffi {
2525

2626
static bool lossless = false;
2727

28-
#define ReturnBigInt(isolate, ptr) args.GetReturnValue()\
29-
.Set(BigInt::NewFromUnsigned(isolate, (uint64_t)ptr))
28+
#define ReturnBigInt(isolate, ptr) \
29+
args.GetReturnValue().Set(BigInt::NewFromUnsigned(isolate, (uint64_t)ptr))
3030

3131
void GetLibrary(const FunctionCallbackInfo<Value>& args) {
3232
Environment* env = Environment::GetCurrent(args);
33-
THROW_IF_INSUFFICIENT_PERMISSIONS(
34-
env, permission::PermissionScope::kFfi, "");
33+
THROW_IF_INSUFFICIENT_PERMISSIONS(env, permission::PermissionScope::kFfi, "");
3534

3635
bool isNull = true;
3736
std::string fname = "";
@@ -42,9 +41,9 @@ void GetLibrary(const FunctionCallbackInfo<Value>& args) {
4241
isNull = false;
4342
}
4443

45-
std::map<std::string, binding::DLib *> libraries =
46-
Realm::GetBindingData<FfiBindingData>(args)->libraries;
47-
binding::DLib * lib = nullptr;
44+
std::map<std::string, binding::DLib*> libraries =
45+
Realm::GetBindingData<FfiBindingData>(args)->libraries;
46+
binding::DLib* lib = nullptr;
4847
if (libraries[fname] != nullptr) {
4948
lib = libraries[fname];
5049
} else {
@@ -61,12 +60,11 @@ void GetLibrary(const FunctionCallbackInfo<Value>& args) {
6160

6261
void GetSymbol(const FunctionCallbackInfo<Value>& args) {
6362
Environment* env = Environment::GetCurrent(args);
64-
THROW_IF_INSUFFICIENT_PERMISSIONS(
65-
env, permission::PermissionScope::kFfi, "");
63+
THROW_IF_INSUFFICIENT_PERMISSIONS(env, permission::PermissionScope::kFfi, "");
6664

6765
CHECK(args[0]->IsBigInt());
68-
binding::DLib * lib = (binding::DLib *)args[0].As<BigInt>()
69-
->Uint64Value(&lossless);
66+
binding::DLib* lib =
67+
(binding::DLib*)args[0].As<BigInt>()->Uint64Value(&lossless);
7068
CHECK(args[1]->IsString());
7169
node::Utf8Value symName(env->isolate(), args[1]);
7270
void* symbol = lib->GetSymbolAddress(symName.ToString().c_str());
@@ -75,8 +73,7 @@ void GetSymbol(const FunctionCallbackInfo<Value>& args) {
7573

7674
void GetBufferPointer(const FunctionCallbackInfo<Value>& args) {
7775
Environment* env = Environment::GetCurrent(args);
78-
THROW_IF_INSUFFICIENT_PERMISSIONS(
79-
env, permission::PermissionScope::kFfi, "");
76+
THROW_IF_INSUFFICIENT_PERMISSIONS(env, permission::PermissionScope::kFfi, "");
8077

8178
CHECK(args[0]->IsArrayBuffer() || args[0]->IsSharedArrayBuffer());
8279
void* data = args[0].As<ArrayBuffer>()->Data();
@@ -88,27 +85,26 @@ void SetCallBuffer(const FunctionCallbackInfo<Value>& args) {
8885
CHECK(args[0]->IsArrayBuffer());
8986
Local<ArrayBuffer> ab = args[0].As<ArrayBuffer>();
9087

91-
void * callBuffer = ab->Data();
88+
void* callBuffer = ab->Data();
9289
Realm::GetBindingData<FfiBindingData>(args)->callBuffer = callBuffer;
9390
ReturnBigInt(args.GetIsolate(), callBuffer);
9491
}
9592

96-
FfiSignature::FfiSignature(
97-
Environment* env,
98-
Local<Object> object,
99-
Local<BigInt> fn,
100-
Local<BigInt> retType,
101-
Local<Array> argTypes) : BaseObject(env, object) {
93+
FfiSignature::FfiSignature(Environment* env,
94+
Local<Object> object,
95+
Local<BigInt> fn,
96+
Local<BigInt> retType,
97+
Local<Array> argTypes)
98+
: BaseObject(env, object) {
10299
Local<Context> context = env->context();
103100

104101
cif_ = reinterpret_cast<ffi_cif*>(malloc(sizeof(ffi_cif)));
105-
fn_ = (void (*)()) fn->Uint64Value(&lossless);
102+
fn_ = (void (*)())fn->Uint64Value(&lossless);
106103
uint32_t argc = argTypes->Length();
107-
argvTypes_ =
108-
reinterpret_cast<ffi_type**>(malloc(sizeof(ffi_type *) * argc));
104+
argvTypes_ = reinterpret_cast<ffi_type**>(malloc(sizeof(ffi_type*) * argc));
109105

110-
ffi_type * retTyp =
111-
reinterpret_cast<ffi_type*>(retType->Uint64Value(&lossless));
106+
ffi_type* retTyp =
107+
reinterpret_cast<ffi_type*>(retType->Uint64Value(&lossless));
112108
for (uint32_t i = 0; i < argc; i++) {
113109
Local<Value> val = argTypes->Get(context, i).ToLocalChecked();
114110
CHECK(val->IsBigInt());
@@ -125,58 +121,54 @@ FfiSignature::~FfiSignature() {
125121
}
126122

127123
void FfiSignature::New(const FunctionCallbackInfo<Value>& args) {
128-
Isolate * isolate = args.GetIsolate();
129-
Environment * env = Environment::GetCurrent(isolate);
124+
Isolate* isolate = args.GetIsolate();
125+
Environment* env = Environment::GetCurrent(isolate);
130126

131-
THROW_IF_INSUFFICIENT_PERMISSIONS(
132-
env, permission::PermissionScope::kFfi, "");
127+
THROW_IF_INSUFFICIENT_PERMISSIONS(env, permission::PermissionScope::kFfi, "");
133128

134129
CHECK(args.IsConstructCall());
135130
CHECK(args[0]->IsBigInt());
136131
CHECK(args[1]->IsBigInt());
137132
CHECK(args[2]->IsArray());
138133

139-
FfiSignature* sig = new FfiSignature(
140-
env,
141-
args.This(),
142-
args[0].As<BigInt>(),
143-
args[1].As<BigInt>(),
144-
args[2].As<Array>());
145-
146-
args.This()->Set(
147-
env->context(),
148-
OneByteString(isolate, "pointer"),
149-
BigInt::NewFromUnsigned(isolate, (uint64_t)sig)).Check();
134+
FfiSignature* sig = new FfiSignature(env,
135+
args.This(),
136+
args[0].As<BigInt>(),
137+
args[1].As<BigInt>(),
138+
args[2].As<Array>());
139+
140+
args.This()
141+
->Set(env->context(),
142+
OneByteString(isolate, "pointer"),
143+
BigInt::NewFromUnsigned(isolate, (uint64_t)sig))
144+
.Check();
150145
}
151146

152-
void MakeCall(const FunctionCallbackInfo<Value> &args) {
153-
Isolate * isolate = args.GetIsolate();
154-
Environment * env = Environment::GetCurrent(isolate);
155-
THROW_IF_INSUFFICIENT_PERMISSIONS(
156-
env, permission::PermissionScope::kFfi, "");
147+
void MakeCall(const FunctionCallbackInfo<Value>& args) {
148+
Isolate* isolate = args.GetIsolate();
149+
Environment* env = Environment::GetCurrent(isolate);
150+
THROW_IF_INSUFFICIENT_PERMISSIONS(env, permission::PermissionScope::kFfi, "");
157151

158152
char* callBuffer = reinterpret_cast<char*>(
159153
Realm::GetBindingData<FfiBindingData>(args)->callBuffer);
160-
FfiSignature * sig = *reinterpret_cast<FfiSignature **>(callBuffer);
154+
FfiSignature* sig = *reinterpret_cast<FfiSignature**>(callBuffer);
161155
char* rvalue = callBuffer + sizeof(char*);
162156
char** avalues = reinterpret_cast<char**>(rvalue + sizeof(char*));
163-
ffi_call(
164-
sig->cif_,
165-
sig->fn_,
166-
reinterpret_cast<void*>(rvalue),
167-
reinterpret_cast<void**>(avalues));
157+
ffi_call(sig->cif_,
158+
sig->fn_,
159+
reinterpret_cast<void*>(rvalue),
160+
reinterpret_cast<void**>(avalues));
168161
}
169162

170-
void Initialize(
171-
Local<Object> target,
172-
Local<Value> unused,
173-
Local<Context> context,
174-
void* priv) {
175-
Environment * env = Environment::GetCurrent(context);
163+
void Initialize(Local<Object> target,
164+
Local<Value> unused,
165+
Local<Context> context,
166+
void* priv) {
167+
Environment* env = Environment::GetCurrent(context);
176168
Isolate* isolate = context->GetIsolate();
177169
Realm* realm = Realm::GetCurrent(context);
178170
FfiBindingData* const binding_data =
179-
realm->AddBindingData<FfiBindingData>(context, target);
171+
realm->AddBindingData<FfiBindingData>(context, target);
180172
if (binding_data == nullptr) return;
181173

182174
SetMethod(context, target, "setCallBuffer", SetCallBuffer);
@@ -186,16 +178,19 @@ void Initialize(
186178
SetMethod(context, target, "getLibrary", GetLibrary);
187179

188180
Local<FunctionTemplate> tmpl =
189-
NewFunctionTemplate(isolate, FfiSignature::New);
190-
tmpl->InstanceTemplate()
191-
->SetInternalFieldCount(FfiSignature::kInternalFieldCount);
181+
NewFunctionTemplate(isolate, FfiSignature::New);
182+
tmpl->InstanceTemplate()->SetInternalFieldCount(
183+
FfiSignature::kInternalFieldCount);
192184
tmpl->Inherit(BaseObject::GetConstructorTemplate(env));
193185
SetConstructorFunction(context, target, "FfiSignature", tmpl);
194186

195187
Local<Object> types = Object::New(isolate);
196-
#define NODE_FFI_SET_TYPE_CONSTANT(name, typ) types->Set(context, \
197-
OneByteString(isolate, #name), \
198-
BigInt::NewFromUnsigned(isolate, (uint64_t)&typ)).Check();
188+
#define NODE_FFI_SET_TYPE_CONSTANT(name, typ) \
189+
types \
190+
->Set(context, \
191+
OneByteString(isolate, #name), \
192+
BigInt::NewFromUnsigned(isolate, (uint64_t)&typ)) \
193+
.Check();
199194
NODE_FFI_SET_TYPE_CONSTANT(void, ffi_type_void);
200195
NODE_FFI_SET_TYPE_CONSTANT(uint8, ffi_type_uint8);
201196
NODE_FFI_SET_TYPE_CONSTANT(int8, ffi_type_sint8);
@@ -220,39 +215,42 @@ void Initialize(
220215
target->Set(context, OneByteString(isolate, "types"), types).Check();
221216

222217
Local<Object> sizes = Object::New(isolate);
223-
#define NODE_FFI_SET_SIZE_CONSTANT(typ) sizes->Set(context, \
224-
OneByteString(isolate, #typ), \
225-
Number::New(isolate, sizeof(typ))).Check();
218+
#define NODE_FFI_SET_SIZE_CONSTANT(typ) \
219+
sizes \
220+
->Set(context, \
221+
OneByteString(isolate, #typ), \
222+
Number::New(isolate, sizeof(typ))) \
223+
.Check();
226224
NODE_FFI_SET_SIZE_CONSTANT(char);
227225
NODE_FFI_SET_SIZE_CONSTANT(signed char);
228226
NODE_FFI_SET_SIZE_CONSTANT(unsigned char);
229-
NODE_FFI_SET_SIZE_CONSTANT(short); // NOLINT(runtime/int)
230-
NODE_FFI_SET_SIZE_CONSTANT(short int); // NOLINT(runtime/int)
231-
NODE_FFI_SET_SIZE_CONSTANT(signed short); // NOLINT(runtime/int)
232-
NODE_FFI_SET_SIZE_CONSTANT(signed short int); // NOLINT(runtime/int)
233-
NODE_FFI_SET_SIZE_CONSTANT(unsigned short); // NOLINT(runtime/int)
227+
NODE_FFI_SET_SIZE_CONSTANT(short); // NOLINT(runtime/int)
228+
NODE_FFI_SET_SIZE_CONSTANT(short int); // NOLINT(runtime/int)
229+
NODE_FFI_SET_SIZE_CONSTANT(signed short); // NOLINT(runtime/int)
230+
NODE_FFI_SET_SIZE_CONSTANT(signed short int); // NOLINT(runtime/int)
231+
NODE_FFI_SET_SIZE_CONSTANT(unsigned short); // NOLINT(runtime/int)
234232
NODE_FFI_SET_SIZE_CONSTANT(unsigned short int); // NOLINT(runtime/int)
235233
NODE_FFI_SET_SIZE_CONSTANT(int);
236234
NODE_FFI_SET_SIZE_CONSTANT(signed);
237235
NODE_FFI_SET_SIZE_CONSTANT(signed int);
238236
NODE_FFI_SET_SIZE_CONSTANT(unsigned);
239237
NODE_FFI_SET_SIZE_CONSTANT(unsigned int);
240-
NODE_FFI_SET_SIZE_CONSTANT(long); // NOLINT(runtime/int)
241-
NODE_FFI_SET_SIZE_CONSTANT(long int); // NOLINT(runtime/int)
242-
NODE_FFI_SET_SIZE_CONSTANT(signed long); // NOLINT(runtime/int)
243-
NODE_FFI_SET_SIZE_CONSTANT(signed long int); // NOLINT(runtime/int)
244-
NODE_FFI_SET_SIZE_CONSTANT(unsigned long); // NOLINT(runtime/int)
245-
NODE_FFI_SET_SIZE_CONSTANT(unsigned long int); // NOLINT(runtime/int)
246-
NODE_FFI_SET_SIZE_CONSTANT(long long); // NOLINT(runtime/int)
247-
NODE_FFI_SET_SIZE_CONSTANT(long long int); // NOLINT(runtime/int)
248-
NODE_FFI_SET_SIZE_CONSTANT(signed long long); // NOLINT(runtime/int)
249-
NODE_FFI_SET_SIZE_CONSTANT(signed long long int); // NOLINT(runtime/int)
250-
NODE_FFI_SET_SIZE_CONSTANT(unsigned long long); // NOLINT(runtime/int)
238+
NODE_FFI_SET_SIZE_CONSTANT(long); // NOLINT(runtime/int)
239+
NODE_FFI_SET_SIZE_CONSTANT(long int); // NOLINT(runtime/int)
240+
NODE_FFI_SET_SIZE_CONSTANT(signed long); // NOLINT(runtime/int)
241+
NODE_FFI_SET_SIZE_CONSTANT(signed long int); // NOLINT(runtime/int)
242+
NODE_FFI_SET_SIZE_CONSTANT(unsigned long); // NOLINT(runtime/int)
243+
NODE_FFI_SET_SIZE_CONSTANT(unsigned long int); // NOLINT(runtime/int)
244+
NODE_FFI_SET_SIZE_CONSTANT(long long); // NOLINT(runtime/int)
245+
NODE_FFI_SET_SIZE_CONSTANT(long long int); // NOLINT(runtime/int)
246+
NODE_FFI_SET_SIZE_CONSTANT(signed long long); // NOLINT(runtime/int)
247+
NODE_FFI_SET_SIZE_CONSTANT(signed long long int); // NOLINT(runtime/int)
248+
NODE_FFI_SET_SIZE_CONSTANT(unsigned long long); // NOLINT(runtime/int)
251249
NODE_FFI_SET_SIZE_CONSTANT(unsigned long long int); // NOLINT(runtime/int)
252250
NODE_FFI_SET_SIZE_CONSTANT(float);
253251
NODE_FFI_SET_SIZE_CONSTANT(double);
254252
// NODE_FFI_SET_SIZE_CONSTANT(long double);
255-
NODE_FFI_SET_SIZE_CONSTANT(char *);
253+
NODE_FFI_SET_SIZE_CONSTANT(char*);
256254
NODE_FFI_SET_SIZE_CONSTANT(uint8_t);
257255
NODE_FFI_SET_SIZE_CONSTANT(int8_t);
258256
NODE_FFI_SET_SIZE_CONSTANT(uint16_t);
@@ -265,10 +263,8 @@ void Initialize(
265263

266264
char test_char = -1;
267265
Local<Boolean> charIsSigned = Boolean::New(isolate, test_char < 0);
268-
target->Set(
269-
context,
270-
OneByteString(isolate, "charIsSigned"),
271-
charIsSigned).Check();
266+
target->Set(context, OneByteString(isolate, "charIsSigned"), charIsSigned)
267+
.Check();
272268
}
273269

274270
void RegisterExternalReferences(ExternalReferenceRegistry* registry) {

0 commit comments

Comments
 (0)