forked from nodejs/node
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathnode_ffi.h
More file actions
160 lines (134 loc) Β· 5.4 KB
/
node_ffi.h
File metadata and controls
160 lines (134 loc) Β· 5.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
#pragma once
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
#include "base_object.h"
#include "ffi.h"
#include "uv.h"
#include <cstdint>
#include <memory>
#include <string>
#include <thread>
#include <unordered_map>
#include <vector>
namespace node::ffi {
class DynamicLibrary;
struct FFIFunction;
struct FFIFunction {
bool closed;
void* ptr;
ffi_cif cif;
std::vector<ffi_type*> args;
ffi_type* return_type;
std::vector<std::string> arg_type_names;
std::string return_type_name;
};
struct FFIFunctionInfo {
std::shared_ptr<FFIFunction> fn;
v8::Global<v8::Function> self;
std::shared_ptr<v8::BackingStore> sb_backing;
// Keep the owning DynamicLibrary alive while the generated function is alive.
v8::Global<v8::Object> library;
};
struct FFICallback {
DynamicLibrary* owner;
Environment* env;
std::thread::id thread_id;
v8::Global<v8::Function> fn;
ffi_closure* closure;
void* ptr;
ffi_cif cif;
std::vector<ffi_type*> args;
ffi_type* return_type;
~FFICallback() {
if (!fn.IsEmpty()) {
fn.Reset();
}
if (closure != nullptr) {
ffi_closure_free(closure);
closure = nullptr;
}
}
};
struct ResolvedFunction {
std::string name;
std::shared_ptr<FFIFunction> fn;
bool should_cache_symbol;
bool should_cache_function;
};
class DynamicLibrary : public BaseObject {
public:
DynamicLibrary(Environment* env, v8::Local<v8::Object> object);
~DynamicLibrary() override;
void MemoryInfo(MemoryTracker* tracker) const override;
static v8::Local<v8::FunctionTemplate> GetConstructorTemplate(
Environment* env);
static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
static void Close(const v8::FunctionCallbackInfo<v8::Value>& args);
static void InvokeFunction(const v8::FunctionCallbackInfo<v8::Value>& args);
static void InvokeFunctionSB(const v8::FunctionCallbackInfo<v8::Value>& args);
static void InvokeCallback(ffi_cif* cif,
void* ret,
void** args,
void* user_data);
static void GetPath(const v8::FunctionCallbackInfo<v8::Value>& args);
static void GetFunction(const v8::FunctionCallbackInfo<v8::Value>& args);
static void GetFunctions(const v8::FunctionCallbackInfo<v8::Value>& args);
static void GetSymbol(const v8::FunctionCallbackInfo<v8::Value>& args);
static void GetSymbols(const v8::FunctionCallbackInfo<v8::Value>& args);
static void RegisterCallback(const v8::FunctionCallbackInfo<v8::Value>& args);
static void UnregisterCallback(
const v8::FunctionCallbackInfo<v8::Value>& args);
static void RefCallback(const v8::FunctionCallbackInfo<v8::Value>& args);
static void UnrefCallback(const v8::FunctionCallbackInfo<v8::Value>& args);
SET_MEMORY_INFO_NAME(DynamicLibrary)
SET_SELF_SIZE(DynamicLibrary)
private:
void Close();
v8::Maybe<void*> ResolveSymbol(Environment* env, const std::string& name);
struct PreparedFunction {
std::shared_ptr<FFIFunction> fn;
bool should_cache_symbol;
bool should_cache_function;
};
v8::Maybe<PreparedFunction> PrepareFunction(Environment* env,
const std::string& name,
v8::Local<v8::Object> signature);
v8::MaybeLocal<v8::Function> CreateFunction(
Environment* env,
const std::string& name,
const std::shared_ptr<FFIFunction>& fn);
static void CleanupFunctionInfo(
const v8::WeakCallbackInfo<FFIFunctionInfo>& data);
uv_lib_t lib_;
void* handle_;
std::string path_;
std::unordered_map<std::string, void*> symbols_;
std::unordered_map<std::string, std::shared_ptr<FFIFunction>> functions_;
std::unordered_map<void*, std::unique_ptr<FFICallback>> callbacks_;
};
void GetInt8(const v8::FunctionCallbackInfo<v8::Value>& args);
void GetUint8(const v8::FunctionCallbackInfo<v8::Value>& args);
void GetInt16(const v8::FunctionCallbackInfo<v8::Value>& args);
void GetUint16(const v8::FunctionCallbackInfo<v8::Value>& args);
void GetInt32(const v8::FunctionCallbackInfo<v8::Value>& args);
void GetUint32(const v8::FunctionCallbackInfo<v8::Value>& args);
void GetInt64(const v8::FunctionCallbackInfo<v8::Value>& args);
void GetUint64(const v8::FunctionCallbackInfo<v8::Value>& args);
void GetFloat32(const v8::FunctionCallbackInfo<v8::Value>& args);
void GetFloat64(const v8::FunctionCallbackInfo<v8::Value>& args);
void SetInt8(const v8::FunctionCallbackInfo<v8::Value>& args);
void SetUint8(const v8::FunctionCallbackInfo<v8::Value>& args);
void SetInt16(const v8::FunctionCallbackInfo<v8::Value>& args);
void SetUint16(const v8::FunctionCallbackInfo<v8::Value>& args);
void SetInt32(const v8::FunctionCallbackInfo<v8::Value>& args);
void SetUint32(const v8::FunctionCallbackInfo<v8::Value>& args);
void SetInt64(const v8::FunctionCallbackInfo<v8::Value>& args);
void SetUint64(const v8::FunctionCallbackInfo<v8::Value>& args);
void SetFloat32(const v8::FunctionCallbackInfo<v8::Value>& args);
void SetFloat64(const v8::FunctionCallbackInfo<v8::Value>& args);
void ToString(const v8::FunctionCallbackInfo<v8::Value>& args);
void ToBuffer(const v8::FunctionCallbackInfo<v8::Value>& args);
void ToArrayBuffer(const v8::FunctionCallbackInfo<v8::Value>& args);
void ExportBytes(const v8::FunctionCallbackInfo<v8::Value>& args);
void GetRawPointer(const v8::FunctionCallbackInfo<v8::Value>& args);
} // namespace node::ffi
#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS