11#include " node_ffi.h"
22#include " env-inl.h"
3+ #include " env.h"
34#include " ffi.h"
45#include " node_binding.h"
6+ #include " util.h"
57#include " v8-array-buffer.h"
68#include " v8-function-callback.h"
79#include " v8-primitive.h"
810#include " util-inl.h"
911#include " node_external_reference.h"
12+ #include " v8-fast-api-calls.h"
13+ #include " v8-template.h"
1014
1115using v8::Context;
1216using v8::ArrayBuffer;
@@ -15,6 +19,10 @@ using v8::Number;
1519using v8::Array;
1620using v8::Isolate;
1721using v8::String;
22+ using v8::FunctionCallbackInfo;
23+ using v8::FunctionTemplate;
24+ using v8::FastApiCallbackOptions;
25+ using v8::CFunction;
1826
1927namespace node {
2028namespace ffi {
@@ -24,7 +32,7 @@ static bool lossless = false;
2432#define ReturnBigInt (isolate, ptr ) args.GetReturnValue()\
2533 .Set(BigInt::NewFromUnsigned(isolate, (uint64_t )ptr))
2634
27- void GetLibrary (const v8:: FunctionCallbackInfo<Value>& args) {
35+ void GetLibrary (const FunctionCallbackInfo<Value>& args) {
2836 Environment* env = Environment::GetCurrent (args);
2937
3038 bool isNull = true ;
@@ -56,7 +64,7 @@ void GetLibrary(const v8::FunctionCallbackInfo<Value>& args) {
5664 ReturnBigInt (env->isolate (), lib);
5765}
5866
59- void GetSymbol (const v8:: FunctionCallbackInfo<Value>& args) {
67+ void GetSymbol (const FunctionCallbackInfo<Value>& args) {
6068 Environment* env = Environment::GetCurrent (args);
6169 CHECK (args[0 ]->IsBigInt ());
6270 binding::DLib * lib = (binding::DLib *)args[0 ].As <BigInt>()
@@ -67,14 +75,14 @@ void GetSymbol(const v8::FunctionCallbackInfo<Value>& args) {
6775 ReturnBigInt (env->isolate (), symbol);
6876}
6977
70- void GetBufferPointer (const v8:: FunctionCallbackInfo<Value>& args) {
78+ void GetBufferPointer (const FunctionCallbackInfo<Value>& args) {
7179 CHECK (args[0 ]->IsArrayBuffer ());
7280 void * data = args[0 ].As <ArrayBuffer>()->Data ();
7381
7482 ReturnBigInt (args.GetIsolate (), data);
7583}
7684
77- void SetCallBuffer (const v8:: FunctionCallbackInfo<Value>& args) {
85+ void SetCallBuffer (const FunctionCallbackInfo<Value>& args) {
7886 CHECK (args[0 ]->IsArrayBuffer ());
7987 Local<ArrayBuffer> ab = args[0 ].As <ArrayBuffer>();
8088
@@ -83,53 +91,67 @@ void SetCallBuffer(const v8::FunctionCallbackInfo<Value>& args) {
8391 ReturnBigInt (args.GetIsolate (), callBuffer);
8492}
8593
86- void AddSignature (const v8::FunctionCallbackInfo<Value>& args) {
87- Isolate * isolate = args.GetIsolate ();
88- Local<Context> context = isolate->GetCurrentContext ();
89-
90- CHECK (args[0 ]->IsBigInt ());
91- void (* fnPtr)() = (void (*)()) args[0 ].As <BigInt>()->Uint64Value (&lossless);
92-
93- CHECK (args[1 ]->IsBigInt ());
94- ffi_type * retType =
95- reinterpret_cast <ffi_type*>(args[1 ].As <BigInt>()->Uint64Value (&lossless));
94+ FfiSignature::FfiSignature (
95+ Environment* env,
96+ Local<Object> object,
97+ Local<BigInt> fn,
98+ Local<BigInt> retType,
99+ Local<Array> argTypes) : BaseObject(env, object) {
100+ Local<Context> context = env->context ();
96101
97- CHECK (args[2 ]->IsArray ());
98- Local<Array> arguments = args[2 ].As <Array>();
99-
100- uint32_t argc = arguments->Length ();
101- ffi_type** argv =
102+ cif_ = reinterpret_cast <ffi_cif*>(malloc (sizeof (ffi_cif)));
103+ fn_ = (void (*)()) fn->Uint64Value (&lossless);
104+ uint32_t argc = argTypes->Length ();
105+ argvTypes_ =
102106 reinterpret_cast <ffi_type**>(malloc (sizeof (ffi_type *) * argc));
107+
108+ ffi_type * retTyp =
109+ reinterpret_cast <ffi_type*>(retType->Uint64Value (&lossless));
103110 for (uint32_t i = 0 ; i < argc; i++) {
104- Local<Value> val = arguments ->Get (context, i).ToLocalChecked ();
111+ Local<Value> val = argTypes ->Get (context, i).ToLocalChecked ();
105112 CHECK (val->IsBigInt ());
106113 uint64_t arg = val.As <BigInt>()->Uint64Value (&lossless);
107- argv [i] = reinterpret_cast <ffi_type*>(arg);
114+ argvTypes_ [i] = reinterpret_cast <ffi_type*>(arg);
108115 }
109116
110- // TODO(bengl) throw all of this into FfiSignature constructor, and destruct
111- // accordingly
112- ffi_cif * cif = reinterpret_cast <ffi_cif*>(malloc (sizeof (ffi_cif)));
113- ffi_prep_cif (cif, FFI_DEFAULT_ABI, argc, retType, argv);
117+ ffi_prep_cif (cif_, FFI_DEFAULT_ABI, argc, retTyp, argvTypes_);
118+ }
114119
115- FfiSignature* sig = new FfiSignature ();
116- sig-> cif = cif ;
117- sig-> argvTypes = argv ;
118- sig-> fn = fnPtr;
120+ FfiSignature::~ FfiSignature () {
121+ free (cif_) ;
122+ free (argvTypes_) ;
123+ }
119124
120- Local<BigInt> sigPtr = BigInt::NewFromUnsigned (isolate, ( uint64_t )sig);
121- args. GetReturnValue (). Set (sigPtr);
125+ void FfiSignature::MemoryInfo (MemoryTracker* tracker) const {
126+ // TODO(bengl)
122127}
123128
124- void MakeCall (const v8::FunctionCallbackInfo<Value> &args) {
129+ void FfiSignature::New (const FunctionCallbackInfo<Value>& args) {
130+ CHECK (args.IsConstructCall ());
131+ CHECK (args[0 ]->IsBigInt ());
132+ CHECK (args[1 ]->IsBigInt ());
133+ CHECK (args[2 ]->IsArray ());
134+ Isolate * isolate = args.GetIsolate ();
135+ Environment * env = Environment::GetCurrent (isolate);
136+
137+ FfiSignature* sig = new FfiSignature (
138+ env, args.This (), args[0 ].As <BigInt>(), args[1 ].As <BigInt>(), args[2 ].As <Array>());
139+
140+ args.This ()->Set (
141+ env->context (),
142+ OneByteString (isolate, " pointer" ),
143+ BigInt::NewFromUnsigned (isolate, (uint64_t )sig)).Check ();
144+ }
145+
146+ void MakeCall (const FunctionCallbackInfo<Value> &args) {
125147 char * callBuffer = reinterpret_cast <char *>(
126148 Realm::GetBindingData<FfiBindingData>(args)->callBuffer );
127149 FfiSignature * sig = *reinterpret_cast <FfiSignature **>(callBuffer);
128150 char * rvalue = callBuffer + sizeof (char *);
129151 char ** avalues = reinterpret_cast <char **>(rvalue + sizeof (char *));
130152 ffi_call (
131- sig->cif ,
132- sig->fn ,
153+ sig->cif_ ,
154+ sig->fn_ ,
133155 reinterpret_cast <void *>(rvalue),
134156 reinterpret_cast <void **>(avalues));
135157}
@@ -143,6 +165,7 @@ void Initialize(
143165 Local<Value> unused,
144166 Local<Context> context,
145167 void * priv) {
168+ Environment * env = Environment::GetCurrent (context);
146169 Isolate* isolate = context->GetIsolate ();
147170 Realm* realm = Realm::GetCurrent (context);
148171 FfiBindingData* const binding_data =
@@ -151,11 +174,15 @@ void Initialize(
151174
152175 SetMethod (context, target, " setCallBuffer" , SetCallBuffer);
153176 SetMethod (context, target, " getBufferPointer" , GetBufferPointer);
154- SetMethod (context, target, " addSignature" , AddSignature);
155177 SetMethod (context, target, " makeCall" , MakeCall);
156178 SetMethod (context, target, " getSymbol" , GetSymbol);
157179 SetMethod (context, target, " getLibrary" , GetLibrary);
158180
181+ Local<FunctionTemplate> tmpl = NewFunctionTemplate (isolate, FfiSignature::New);
182+ tmpl->InstanceTemplate ()->SetInternalFieldCount (FfiSignature::kInternalFieldCount );
183+ tmpl->Inherit (BaseObject::GetConstructorTemplate (env));
184+ SetConstructorFunction (context, target, " FfiSignature" , tmpl);
185+
159186 Local<Object> types = Object::New (isolate);
160187#define NODE_FFI_SET_TYPE_CONSTANT (name, typ ) types->Set (context, \
161188 OneByteString (isolate, #name), \
@@ -231,7 +258,7 @@ void Initialize(
231258void RegisterExternalReferences (ExternalReferenceRegistry* registry) {
232259 registry->Register (SetCallBuffer);
233260 registry->Register (GetBufferPointer);
234- registry->Register (AddSignature );
261+ registry->Register (FfiSignature::New );
235262 registry->Register (MakeCall);
236263 registry->Register (GetSymbol);
237264 registry->Register (GetLibrary);
0 commit comments