koffi 2.16.1 → 3.0.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +2 -2
- package/README.md +8 -8
- package/build/koffi/darwin_arm64/koffi.node +0 -0
- package/build/koffi/darwin_x64/koffi.node +0 -0
- package/build/koffi/freebsd_arm64/koffi.node +0 -0
- package/build/koffi/freebsd_ia32/koffi.node +0 -0
- package/build/koffi/freebsd_x64/koffi.node +0 -0
- package/build/koffi/linux_arm64/koffi.node +0 -0
- package/build/koffi/linux_ia32/koffi.node +0 -0
- package/build/koffi/linux_x64/koffi.node +0 -0
- package/build/koffi/musl_arm64/koffi.node +0 -0
- package/build/koffi/musl_x64/koffi.node +0 -0
- package/build/koffi/openbsd_ia32/koffi.node +0 -0
- package/build/koffi/openbsd_x64/koffi.node +0 -0
- package/build/koffi/win32_ia32/koffi.node +0 -0
- package/build/koffi/win32_x64/koffi.node +0 -0
- package/doc/benchmarks.md +33 -33
- package/doc/benchmarks.xlsx +0 -0
- package/doc/contribute.md +37 -25
- package/doc/index.md +8 -8
- package/doc/variables.md +1 -1
- package/index.d.ts +11 -9
- package/index.js +1 -634
- package/indirect.js +1 -533
- package/lib/native/base/base.cc +63 -85
- package/lib/native/base/base.hh +178 -151
- package/package.json +3 -4
- package/src/build.js +1178 -0
- package/src/koffi/CMakeLists.txt +97 -34
- package/src/koffi/index.js +359 -0
- package/src/koffi/indirect.js +216 -0
- package/src/koffi/src/{abi_arm32.cc → abi/arm32.cc} +279 -275
- package/src/koffi/src/{abi_arm32_asm.S → abi/arm32_asm.S} +2 -5
- package/src/koffi/src/abi/arm64.cc +1511 -0
- package/src/koffi/src/{abi_arm64_asm.S → abi/arm64_asm.S} +44 -23
- package/src/koffi/src/{abi_arm64_asm.asm → abi/arm64_asm.asm} +32 -25
- package/src/koffi/src/{abi_loong64_asm.S → abi/loong64_asm.S} +1 -5
- package/src/koffi/src/{abi_riscv64.cc → abi/riscv64.cc} +279 -273
- package/src/koffi/src/{abi_riscv64_asm.S → abi/riscv64_asm.S} +1 -4
- package/src/koffi/src/abi/x64sysv.cc +1456 -0
- package/src/koffi/src/{abi_x64_sysv_asm.S → abi/x64sysv_asm.S} +30 -33
- package/src/koffi/src/abi/x64win.cc +1121 -0
- package/src/koffi/src/{abi_x64_win_asm.S → abi/x64win_asm.S} +8 -12
- package/src/koffi/src/{abi_x64_win_asm.asm → abi/x64win_asm.asm} +11 -14
- package/src/koffi/src/abi/x86.cc +1233 -0
- package/src/koffi/src/{abi_x86_asm.S → abi/x86_asm.S} +49 -25
- package/src/koffi/src/{abi_x86_asm.asm → abi/x86_asm.asm} +11 -14
- package/src/koffi/src/call.cc +458 -598
- package/src/koffi/src/call.hh +61 -82
- package/src/koffi/src/ffi.cc +595 -309
- package/src/koffi/src/ffi.hh +103 -89
- package/src/koffi/src/parser.cc +0 -4
- package/src/koffi/src/primitives.inc +39 -0
- package/src/koffi/{tools/write_trampolines.js → src/trampolines.js} +1 -1
- package/src/koffi/src/util.cc +503 -446
- package/src/koffi/src/util.hh +269 -57
- package/src/koffi/src/uv.cc +2 -2
- package/src/koffi/src/uv.def +3 -0
- package/src/koffi/src/win32.hh +30 -1
- package/vendor/node-addon-api/napi-inl.h +4 -0
- package/vendor/node-addon-api/napi.h +1 -0
- package/build/koffi/linux_armhf/koffi.node +0 -0
- package/build/koffi/linux_loong64/koffi.node +0 -0
- package/build/koffi/linux_riscv64d/koffi.node +0 -0
- package/build/koffi/win32_arm64/koffi.exp +0 -0
- package/build/koffi/win32_arm64/koffi.lib +0 -0
- package/build/koffi/win32_arm64/koffi.node +0 -0
- package/doc/platforms.md +0 -36
- package/src/cnoke/LICENSE.txt +0 -22
- package/src/cnoke/README.md +0 -99
- package/src/cnoke/assets/FindCNoke.cmake +0 -127
- package/src/cnoke/assets/toolchains.json +0 -126
- package/src/cnoke/assets/win_delay_hook.c +0 -36
- package/src/cnoke/cnoke.js +0 -170
- package/src/cnoke/package.json +0 -24
- package/src/cnoke/src/builder.js +0 -511
- package/src/cnoke/src/index.js +0 -10
- package/src/cnoke/src/tools.js +0 -407
- package/src/koffi/src/abi_arm64.cc +0 -1295
- package/src/koffi/src/abi_x64_sysv.cc +0 -939
- package/src/koffi/src/abi_x64_win.cc +0 -715
- package/src/koffi/src/abi_x86.cc +0 -860
- package/src/koffi/src/init.js +0 -105
- /package/src/koffi/src/{abi_loong64.cc → abi/loong64.cc} +0 -0
package/src/koffi/src/util.hh
CHANGED
|
@@ -10,14 +10,36 @@
|
|
|
10
10
|
|
|
11
11
|
namespace K {
|
|
12
12
|
|
|
13
|
+
#if defined(_MSC_VER)
|
|
14
|
+
#define FORCE_INLINE __forceinline
|
|
15
|
+
#else
|
|
16
|
+
#define FORCE_INLINE __attribute__((always_inline)) inline
|
|
17
|
+
#endif
|
|
18
|
+
#if defined(UNITY_BUILD)
|
|
19
|
+
#define INLINE_UNITY FORCE_INLINE
|
|
20
|
+
#else
|
|
21
|
+
#define INLINE_UNITY
|
|
22
|
+
#endif
|
|
23
|
+
|
|
24
|
+
#if defined(__GNUC__) || defined(__clang__)
|
|
25
|
+
#if __has_attribute(musttail) && __has_attribute(preserve_none)
|
|
26
|
+
#define MUST_TAIL __attribute__((musttail))
|
|
27
|
+
#define PRESERVE_NONE __attribute__((preserve_none))
|
|
28
|
+
#elif __has_attribute(musttail) && !defined(__clang__)
|
|
29
|
+
// GCC regalloc seems better, so the generated code is not too bad even without preserve_none
|
|
30
|
+
#define MUST_TAIL __attribute__((musttail))
|
|
31
|
+
#define PRESERVE_NONE
|
|
32
|
+
#endif
|
|
33
|
+
#endif
|
|
34
|
+
|
|
13
35
|
extern const napi_type_tag TypeInfoMarker;
|
|
14
36
|
extern const napi_type_tag CastMarker;
|
|
15
|
-
extern const napi_type_tag
|
|
37
|
+
extern const napi_type_tag UnionClassMarker;
|
|
16
38
|
|
|
17
|
-
class
|
|
39
|
+
class UnionClass: public Napi::ObjectWrap<UnionClass> {
|
|
40
|
+
InstanceData *instance;
|
|
18
41
|
const TypeInfo *type;
|
|
19
42
|
|
|
20
|
-
Napi::Reference<Napi::Symbol> active_symbol;
|
|
21
43
|
Size active_idx = -1;
|
|
22
44
|
|
|
23
45
|
HeapArray<uint8_t> raw;
|
|
@@ -25,7 +47,9 @@ class MagicUnion: public Napi::ObjectWrap<MagicUnion> {
|
|
|
25
47
|
public:
|
|
26
48
|
static Napi::Function InitClass(Napi::Env env, const TypeInfo *type);
|
|
27
49
|
|
|
28
|
-
|
|
50
|
+
UnionClass(const Napi::CallbackInfo &info);
|
|
51
|
+
|
|
52
|
+
void Finalize(Napi::BasicEnv env) override;
|
|
29
53
|
|
|
30
54
|
const TypeInfo *GetType() { return type; }
|
|
31
55
|
const RecordMember *GetMember() const { return (active_idx >= 0) ? &type->members[active_idx] : nullptr; }
|
|
@@ -48,21 +72,21 @@ void ThrowError(Napi::Env env, const char *msg, Args... args)
|
|
|
48
72
|
err.ThrowAsJavaScriptException();
|
|
49
73
|
}
|
|
50
74
|
|
|
51
|
-
static
|
|
75
|
+
static FORCE_INLINE bool IsInteger(const TypeInfo *type)
|
|
52
76
|
{
|
|
53
77
|
bool integer = ((int)type->primitive >= (int)PrimitiveKind::Int8 &&
|
|
54
78
|
(int)type->primitive <= (int)PrimitiveKind::UInt64);
|
|
55
79
|
return integer;
|
|
56
80
|
}
|
|
57
81
|
|
|
58
|
-
static
|
|
82
|
+
static FORCE_INLINE bool IsFloat(const TypeInfo *type)
|
|
59
83
|
{
|
|
60
84
|
bool fp = (type->primitive == PrimitiveKind::Float32 ||
|
|
61
85
|
type->primitive == PrimitiveKind::Float64);
|
|
62
86
|
return fp;
|
|
63
87
|
}
|
|
64
88
|
|
|
65
|
-
static
|
|
89
|
+
static FORCE_INLINE bool IsRegularSize(Size size, Size max)
|
|
66
90
|
{
|
|
67
91
|
bool regular = (size <= max && !(size & (size - 1)));
|
|
68
92
|
return regular;
|
|
@@ -82,65 +106,235 @@ bool CanPassType(const TypeInfo *type, int directions);
|
|
|
82
106
|
bool CanReturnType(const TypeInfo *type);
|
|
83
107
|
bool CanStoreType(const TypeInfo *type);
|
|
84
108
|
|
|
109
|
+
static FORCE_INLINE napi_valuetype GetKindOf(napi_env env, napi_value value)
|
|
110
|
+
{
|
|
111
|
+
napi_valuetype kind = napi_undefined;
|
|
112
|
+
napi_typeof(env, value, &kind);
|
|
113
|
+
|
|
114
|
+
return kind;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
static FORCE_INLINE napi_valuetype GetKindOf(Napi::Value value)
|
|
118
|
+
{
|
|
119
|
+
return GetKindOf(value.Env(), value);
|
|
120
|
+
}
|
|
121
|
+
|
|
85
122
|
// Can be slow, only use for error messages
|
|
86
|
-
const char *GetValueType(const InstanceData *instance,
|
|
123
|
+
const char *GetValueType(const InstanceData *instance, napi_value value);
|
|
87
124
|
|
|
88
|
-
void SetValueTag(
|
|
89
|
-
bool CheckValueTag(
|
|
125
|
+
void SetValueTag(napi_env env, napi_value value, const void *marker);
|
|
126
|
+
bool CheckValueTag(napi_env env, napi_value value, const void *marker);
|
|
90
127
|
|
|
91
|
-
static
|
|
128
|
+
static FORCE_INLINE bool IsNullOrUndefined(napi_valuetype kind)
|
|
92
129
|
{
|
|
93
|
-
return
|
|
130
|
+
return kind == napi_null || kind == napi_undefined;
|
|
94
131
|
}
|
|
95
132
|
|
|
96
|
-
static
|
|
133
|
+
static FORCE_INLINE bool IsNullOrUndefined(napi_env env, napi_value value)
|
|
97
134
|
{
|
|
98
|
-
|
|
135
|
+
napi_valuetype kind = GetKindOf(env, value);
|
|
136
|
+
return IsNullOrUndefined(kind);
|
|
99
137
|
}
|
|
100
138
|
|
|
101
|
-
static
|
|
139
|
+
static FORCE_INLINE bool IsArray(napi_env env, napi_value value)
|
|
102
140
|
{
|
|
103
|
-
|
|
141
|
+
bool array = false;
|
|
142
|
+
napi_is_array(env, value, &array);
|
|
143
|
+
|
|
144
|
+
return array;
|
|
104
145
|
}
|
|
105
146
|
|
|
106
|
-
static
|
|
147
|
+
static FORCE_INLINE bool IsObject(napi_env env, napi_value value)
|
|
107
148
|
{
|
|
108
|
-
if (value
|
|
109
|
-
|
|
110
|
-
|
|
149
|
+
if (GetKindOf(env, value) != napi_object)
|
|
150
|
+
return false;
|
|
151
|
+
if (IsArray(env, value))
|
|
152
|
+
return false;
|
|
111
153
|
|
|
112
|
-
|
|
113
|
-
|
|
154
|
+
return true;
|
|
155
|
+
}
|
|
114
156
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
157
|
+
static FORCE_INLINE bool IsTypedArray(napi_env env, napi_value value)
|
|
158
|
+
{
|
|
159
|
+
bool typedarray = false;
|
|
160
|
+
napi_is_typedarray(env, value, &typedarray);
|
|
161
|
+
return typedarray;
|
|
162
|
+
}
|
|
118
163
|
|
|
119
|
-
|
|
120
|
-
|
|
164
|
+
static FORCE_INLINE bool IsArrayBuffer(napi_env env, napi_value value)
|
|
165
|
+
{
|
|
166
|
+
bool arraybuffer = false;
|
|
167
|
+
napi_is_arraybuffer(env, value, &arraybuffer);
|
|
168
|
+
return arraybuffer;
|
|
169
|
+
}
|
|
121
170
|
|
|
122
|
-
|
|
171
|
+
static FORCE_INLINE bool IsBuffer(napi_env env, napi_value value)
|
|
172
|
+
{
|
|
173
|
+
bool buffer = false;
|
|
174
|
+
napi_is_buffer(env, value, &buffer);
|
|
175
|
+
return buffer;
|
|
123
176
|
}
|
|
124
177
|
|
|
125
|
-
|
|
178
|
+
static FORCE_INLINE napi_value GetReferenceValue(napi_env env, napi_ref ref)
|
|
179
|
+
{
|
|
180
|
+
napi_value value;
|
|
126
181
|
|
|
127
|
-
|
|
128
|
-
|
|
182
|
+
napi_status status = napi_get_reference_value(env, ref, &value);
|
|
183
|
+
K_ASSERT(status == napi_ok);
|
|
184
|
+
|
|
185
|
+
return value;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
static FORCE_INLINE uint32_t GetArrayLength(napi_env env, napi_value array)
|
|
129
189
|
{
|
|
130
|
-
|
|
190
|
+
uint32_t length = 0;
|
|
131
191
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
192
|
+
napi_status status = napi_get_array_length(env, array, &length);
|
|
193
|
+
K_ASSERT(status == napi_ok);
|
|
194
|
+
|
|
195
|
+
return length;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
template <typename T>
|
|
199
|
+
static FORCE_INLINE bool TryNumber(napi_env env, napi_value value, T *out_value)
|
|
200
|
+
{
|
|
201
|
+
T v;
|
|
202
|
+
napi_status status;
|
|
203
|
+
|
|
204
|
+
// Assume number first
|
|
205
|
+
if constexpr (std::is_same_v<T, double>) {
|
|
206
|
+
status = napi_get_value_double(env, value, &v);
|
|
207
|
+
} else if constexpr (std::is_same_v<T, float>) {
|
|
208
|
+
double d;
|
|
209
|
+
status = napi_get_value_double(env, value, &d);
|
|
210
|
+
v = (float)d;
|
|
211
|
+
} else {
|
|
212
|
+
int64_t i64;
|
|
213
|
+
status = napi_get_value_int64(env, value, &i64);
|
|
214
|
+
v = (T)i64;
|
|
215
|
+
}
|
|
216
|
+
if (status == napi_ok) [[likely]] {
|
|
217
|
+
*out_value = v;
|
|
218
|
+
return true;
|
|
219
|
+
}
|
|
136
220
|
|
|
221
|
+
// Maybe a BigInt?
|
|
222
|
+
if constexpr (std::is_signed_v<T>) {
|
|
223
|
+
int64_t i64;
|
|
137
224
|
bool lossless;
|
|
138
|
-
|
|
225
|
+
status = napi_get_value_bigint_int64(env, value, &i64, &lossless);
|
|
226
|
+
v = (T)i64;
|
|
227
|
+
} else {
|
|
228
|
+
uint64_t u64;
|
|
229
|
+
bool lossless;
|
|
230
|
+
status = napi_get_value_bigint_uint64(env, value, &u64, &lossless);
|
|
231
|
+
v = (T)u64;
|
|
232
|
+
}
|
|
233
|
+
if (status == napi_ok) {
|
|
234
|
+
*out_value = v;
|
|
235
|
+
return true;
|
|
139
236
|
}
|
|
140
237
|
|
|
141
|
-
|
|
238
|
+
return false;
|
|
142
239
|
}
|
|
143
240
|
|
|
241
|
+
static FORCE_INLINE bool TryPointer(napi_env env, napi_value value, void **out_ptr)
|
|
242
|
+
{
|
|
243
|
+
if (uintptr_t ptr = 0; TryNumber(env, value, &ptr)) {
|
|
244
|
+
*out_ptr = (void *)ptr;
|
|
245
|
+
return true;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
napi_valuetype kind = GetKindOf(env, value);
|
|
249
|
+
|
|
250
|
+
if (IsNullOrUndefined(kind)) {
|
|
251
|
+
*out_ptr = nullptr;
|
|
252
|
+
return true;
|
|
253
|
+
} else if (IsTypedArray(env, value)) {
|
|
254
|
+
napi_get_typedarray_info(env, value, nullptr, nullptr, out_ptr, nullptr, nullptr);
|
|
255
|
+
return true;
|
|
256
|
+
} else if (kind == napi_external) {
|
|
257
|
+
Napi::External<void> external = Napi::External<void>(env, value);
|
|
258
|
+
|
|
259
|
+
*out_ptr = (void *)external.Data();
|
|
260
|
+
return true;
|
|
261
|
+
} else if (IsArrayBuffer(env, value)) {
|
|
262
|
+
Napi::ArrayBuffer buffer = Napi::ArrayBuffer(env, value);
|
|
263
|
+
|
|
264
|
+
*out_ptr = (void *)buffer.Data();
|
|
265
|
+
return true;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
return false;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
static FORCE_INLINE bool TryPointer(napi_env env, napi_value value, void **out_ptr, bool *out_external)
|
|
272
|
+
{
|
|
273
|
+
if (uintptr_t ptr = 0; TryNumber(env, value, &ptr)) {
|
|
274
|
+
*out_ptr = (void *)ptr;
|
|
275
|
+
*out_external = false;
|
|
276
|
+
|
|
277
|
+
return true;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
napi_valuetype kind = GetKindOf(env, value);
|
|
281
|
+
|
|
282
|
+
if (IsNullOrUndefined(kind)) {
|
|
283
|
+
*out_ptr = nullptr;
|
|
284
|
+
*out_external = false;
|
|
285
|
+
|
|
286
|
+
return true;
|
|
287
|
+
} else if (IsTypedArray(env, value)) {
|
|
288
|
+
napi_get_typedarray_info(env, value, nullptr, nullptr, out_ptr, nullptr, nullptr);
|
|
289
|
+
*out_external = false;
|
|
290
|
+
|
|
291
|
+
return true;
|
|
292
|
+
} else if (kind == napi_external) {
|
|
293
|
+
Napi::External<void> external = Napi::External<void>(env, value);
|
|
294
|
+
|
|
295
|
+
*out_ptr = (void *)external.Data();
|
|
296
|
+
*out_external = true;
|
|
297
|
+
|
|
298
|
+
return true;
|
|
299
|
+
} else if (IsArrayBuffer(env, value)) {
|
|
300
|
+
Napi::ArrayBuffer buffer = Napi::ArrayBuffer(env, value);
|
|
301
|
+
|
|
302
|
+
*out_ptr = (void *)buffer.Data();
|
|
303
|
+
*out_external = false;
|
|
304
|
+
|
|
305
|
+
return true;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
return false;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
static FORCE_INLINE bool TryBuffer(napi_env env, napi_value value, Span<uint8_t> *out_buffer)
|
|
312
|
+
{
|
|
313
|
+
// Before somewhere around Node 20.12, napi_get_buffer_info() would assert/crash
|
|
314
|
+
// when used with something it did not support, instead of returning napi_invalid_arg.
|
|
315
|
+
// So we need to call napi_is_buffer(), at least for now.
|
|
316
|
+
|
|
317
|
+
if (IsBuffer(env, value)) {
|
|
318
|
+
void *ptr = nullptr;
|
|
319
|
+
size_t length = 0;
|
|
320
|
+
|
|
321
|
+
// Assume it works
|
|
322
|
+
napi_get_buffer_info(env, value, &ptr, &length);
|
|
323
|
+
|
|
324
|
+
*out_buffer = MakeSpan((uint8_t *)ptr, (Size)length);
|
|
325
|
+
return true;
|
|
326
|
+
} else if (IsArrayBuffer(env, value)) {
|
|
327
|
+
Napi::ArrayBuffer buffer = Napi::ArrayBuffer(env, value);
|
|
328
|
+
|
|
329
|
+
*out_buffer = MakeSpan((uint8_t *)buffer.Data(), (Size)buffer.ByteLength());
|
|
330
|
+
return true;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
return false;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
int GetTypedArrayType(const TypeInfo *type);
|
|
337
|
+
|
|
144
338
|
template <typename T>
|
|
145
339
|
Size NullTerminatedLength(const T *ptr)
|
|
146
340
|
{
|
|
@@ -165,10 +359,10 @@ static inline Napi::String MakeStringFromUTF32(Napi::Env env, const char32_t *pt
|
|
|
165
359
|
{ return MakeStringFromUTF32(env, ptr, NullTerminatedLength(ptr)); }
|
|
166
360
|
|
|
167
361
|
Napi::Object DecodeObject(Napi::Env env, const uint8_t *origin, const TypeInfo *type);
|
|
168
|
-
void DecodeObject(Napi::
|
|
169
|
-
Napi::Value DecodeArray(Napi::Env env, const uint8_t *origin, const TypeInfo *type, uint32_t len);
|
|
362
|
+
void DecodeObject(Napi::Env env, napi_value obj, const uint8_t *origin, const TypeInfo *type);
|
|
170
363
|
Napi::Value DecodeArray(Napi::Env env, const uint8_t *origin, const TypeInfo *type);
|
|
171
|
-
|
|
364
|
+
Napi::Value DecodeArray(Napi::Env env, const uint8_t *origin, const TypeInfo *type, uint32_t len);
|
|
365
|
+
void DecodeElements(Napi::Env env, napi_value array, const uint8_t *origin, const TypeInfo *ref, uint32_t len);
|
|
172
366
|
void DecodeBuffer(Span<uint8_t> buffer, const uint8_t *origin, const TypeInfo *ref);
|
|
173
367
|
|
|
174
368
|
Napi::Value Decode(Napi::Value value, Size offset, const TypeInfo *type, const Size *len = nullptr);
|
|
@@ -177,29 +371,44 @@ Napi::Value Decode(Napi::Env env, const uint8_t *ptr, const TypeInfo *type, cons
|
|
|
177
371
|
bool Encode(Napi::Value ref, Size offset, Napi::Value value, const TypeInfo *type, const Size *len = nullptr);
|
|
178
372
|
bool Encode(Napi::Env env, uint8_t *ptr, Napi::Value value, const TypeInfo *type, const Size *len = nullptr);
|
|
179
373
|
|
|
180
|
-
static
|
|
181
|
-
{
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
}
|
|
188
|
-
|
|
374
|
+
static FORCE_INLINE Napi::Value NewInt(Napi::Env env, int8_t i)
|
|
375
|
+
{ napi_value value; napi_create_int32(env, (int32_t)i, &value); return Napi::Value(env, value); }
|
|
376
|
+
static FORCE_INLINE Napi::Value NewInt(Napi::Env env, uint8_t i)
|
|
377
|
+
{ napi_value value; napi_create_uint32(env, (uint32_t)i, &value); return Napi::Value(env, value); }
|
|
378
|
+
static FORCE_INLINE Napi::Value NewInt(Napi::Env env, int16_t i)
|
|
379
|
+
{ napi_value value; napi_create_int32(env, (int32_t)i, &value); return Napi::Value(env, value); }
|
|
380
|
+
static FORCE_INLINE Napi::Value NewInt(Napi::Env env, uint16_t i)
|
|
381
|
+
{ napi_value value; napi_create_uint32(env, (uint32_t)i, &value); return Napi::Value(env, value); }
|
|
382
|
+
static FORCE_INLINE Napi::Value NewInt(Napi::Env env, int32_t i)
|
|
383
|
+
{ napi_value value; napi_create_int32(env, i, &value); return Napi::Value(env, value); }
|
|
384
|
+
static FORCE_INLINE Napi::Value NewInt(Napi::Env env, uint32_t i)
|
|
385
|
+
{ napi_value value; napi_create_uint32(env, i, &value); return Napi::Value(env, value); }
|
|
189
386
|
|
|
190
|
-
|
|
387
|
+
template <typename T>
|
|
388
|
+
static FORCE_INLINE Napi::Value NewInt(Napi::Env env, T i)
|
|
191
389
|
{
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
390
|
+
static_assert(sizeof(T) == 8);
|
|
391
|
+
|
|
392
|
+
if constexpr (std::is_signed_v<T>) {
|
|
393
|
+
if (i <= 9007199254740992ll && i >= -9007199254740992ll) {
|
|
394
|
+
napi_value value;
|
|
395
|
+
napi_create_int64(env, (int64_t)i, &value);
|
|
396
|
+
return Napi::Value(env, value);
|
|
397
|
+
}
|
|
195
398
|
} else {
|
|
196
|
-
|
|
399
|
+
if (i <= 9007199254740992ull) {
|
|
400
|
+
napi_value value;
|
|
401
|
+
napi_create_int64(env, (int64_t)i, &value);
|
|
402
|
+
return Napi::Value(env, value);
|
|
403
|
+
}
|
|
197
404
|
}
|
|
405
|
+
|
|
406
|
+
return Napi::BigInt::New(env, i);
|
|
198
407
|
}
|
|
199
408
|
|
|
200
|
-
static
|
|
409
|
+
static FORCE_INLINE Napi::Array GetOwnPropertyNames(napi_env env, napi_value obj)
|
|
201
410
|
{
|
|
202
|
-
|
|
411
|
+
K_ASSERT(IsObject(env, obj));
|
|
203
412
|
|
|
204
413
|
napi_value result;
|
|
205
414
|
napi_status status = napi_get_all_property_names(env, obj, napi_key_own_only,
|
|
@@ -212,6 +421,9 @@ static inline Napi::Array GetOwnPropertyNames(Napi::Object obj)
|
|
|
212
421
|
|
|
213
422
|
Napi::Function WrapFunction(Napi::Env env, const FunctionInfo *func);
|
|
214
423
|
|
|
424
|
+
Napi::Value INLINE_UNITY WrapPointer(Napi::Env env, const TypeInfo *ref, void *ptr);
|
|
425
|
+
Napi::Value INLINE_UNITY WrapCallback(Napi::Env env, const TypeInfo *ref, void *ptr);
|
|
426
|
+
|
|
215
427
|
bool DetectCallConvention(Span<const char> name, CallConvention *out_convention);
|
|
216
428
|
|
|
217
429
|
int AnalyseFlat(const TypeInfo *type, FunctionRef<void(const TypeInfo *type, int offset, int count)> func);
|
package/src/koffi/src/uv.cc
CHANGED
|
@@ -143,7 +143,7 @@ void PollHandle::OnPoll(uv_poll_t *h, int status, int events)
|
|
|
143
143
|
obj.Set("writable", !!(events & UV_WRITABLE));
|
|
144
144
|
obj.Set("disconnect", !!(events & UV_DISCONNECT));
|
|
145
145
|
|
|
146
|
-
napi_value args[] = {
|
|
146
|
+
napi_value args[] = { NewInt(env, (int32_t)status), obj };
|
|
147
147
|
poll->callback.Call(poll->Value(), K_LEN(args), args);
|
|
148
148
|
}
|
|
149
149
|
|
|
@@ -171,7 +171,7 @@ Napi::Value Poll(const Napi::CallbackInfo &info)
|
|
|
171
171
|
int fd = info[0].As<Napi::Number>().Int32Value();
|
|
172
172
|
|
|
173
173
|
Napi::Function ctor = PollHandle::Define(env);
|
|
174
|
-
Napi::Object inst = ctor.New({
|
|
174
|
+
Napi::Object inst = ctor.New({ NewInt(env, (int32_t)fd) });
|
|
175
175
|
Napi::Function start = inst.Get("start").As<Napi::Function>();
|
|
176
176
|
|
|
177
177
|
if (env.IsExceptionPending()) [[unlikely]]
|
package/src/koffi/src/uv.def
CHANGED
package/src/koffi/src/win32.hh
CHANGED
|
@@ -49,7 +49,7 @@ struct PE_NT_HEADERS {
|
|
|
49
49
|
// ... OptionalHeader;
|
|
50
50
|
};
|
|
51
51
|
|
|
52
|
-
#if _WIN64
|
|
52
|
+
#if defined(_WIN64)
|
|
53
53
|
|
|
54
54
|
struct TEB {
|
|
55
55
|
void *ExceptionList;
|
|
@@ -107,6 +107,35 @@ static inline TEB *GetTEB()
|
|
|
107
107
|
return teb;
|
|
108
108
|
}
|
|
109
109
|
|
|
110
|
+
#if defined(_WIN64)
|
|
111
|
+
#define ADJUST_TEB(Teb, Low, High) \
|
|
112
|
+
K_DEFER_C(base = (Teb)->StackBase, \
|
|
113
|
+
limit = (Teb)->StackLimit, \
|
|
114
|
+
dealloc = (Teb)->DeallocationStack) { \
|
|
115
|
+
(Teb)->StackBase = base; \
|
|
116
|
+
(Teb)->StackLimit = limit; \
|
|
117
|
+
(Teb)->DeallocationStack = dealloc; \
|
|
118
|
+
}; \
|
|
119
|
+
(Teb)->StackBase = (High); \
|
|
120
|
+
(Teb)->StackLimit = (Low); \
|
|
121
|
+
(Teb)->DeallocationStack = (Low);
|
|
122
|
+
#else
|
|
123
|
+
#define ADJUST_TEB(Teb, Low, High) \
|
|
124
|
+
K_DEFER_C(base = (Teb)->StackBase, \
|
|
125
|
+
limit = (Teb)->StackLimit, \
|
|
126
|
+
dealloc = (Teb)->DeallocationStack, \
|
|
127
|
+
seh = (Teb)->ExceptionList) { \
|
|
128
|
+
(Teb)->StackBase = base; \
|
|
129
|
+
(Teb)->StackLimit = limit; \
|
|
130
|
+
(Teb)->DeallocationStack = dealloc; \
|
|
131
|
+
(Teb)->ExceptionList = seh; \
|
|
132
|
+
}; \
|
|
133
|
+
(Teb)->StackBase = (High); \
|
|
134
|
+
(Teb)->StackLimit = (Low); \
|
|
135
|
+
(Teb)->DeallocationStack = (Low); \
|
|
136
|
+
(Teb)->ExceptionList = (High) - K_SIZE(SehFrame);
|
|
137
|
+
#endif
|
|
138
|
+
|
|
110
139
|
extern const HashMap<int, const char *> WindowsMachineNames;
|
|
111
140
|
|
|
112
141
|
void *LoadWindowsLibrary(Napi::Env env, Span<const char> path); // Returns HANDLE
|
|
@@ -4094,6 +4094,10 @@ inline const Value CallbackInfo::operator[](size_t index) const {
|
|
|
4094
4094
|
return index < _argc ? Value(_env, _argv[index]) : Env().Undefined();
|
|
4095
4095
|
}
|
|
4096
4096
|
|
|
4097
|
+
inline napi_value *CallbackInfo::First() const {
|
|
4098
|
+
return _argv;
|
|
4099
|
+
}
|
|
4100
|
+
|
|
4097
4101
|
inline Value CallbackInfo::This() const {
|
|
4098
4102
|
if (_this == nullptr) {
|
|
4099
4103
|
return Env().Undefined();
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/doc/platforms.md
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
# Node.js
|
|
2
|
-
|
|
3
|
-
Koffi requires a recent [Node.js](https://nodejs.org/) version with [N-API](https://nodejs.org/api/n-api.html) version 8 support:
|
|
4
|
-
|
|
5
|
-
- Node < 12.22.0 is not supported
|
|
6
|
-
- _Node 12.x_: Node 12.22.0 or newer
|
|
7
|
-
- _Node 14.x_: Node 14.17.0 or newer
|
|
8
|
-
- _Node 15.x_: Node 15.12.0 or newer
|
|
9
|
-
- Node 16.0.0 or later versions
|
|
10
|
-
|
|
11
|
-
Use [NVM](https://github.com/nvm-sh/nvm) to install more recent Node versions on older Linux distributions.
|
|
12
|
-
|
|
13
|
-
# Supported platforms
|
|
14
|
-
|
|
15
|
-
The following combinations of OS and architectures __are officially supported and tested__ at the moment:
|
|
16
|
-
|
|
17
|
-
ISA / OS | Windows | Linux (glibc) | Linux (musl) | macOS | FreeBSD | OpenBSD
|
|
18
|
-
------------------ | ----------- | ------------- | ------------ | ----------- | ----------- | --------
|
|
19
|
-
x86 (IA32) [^1] | ✅ Yes | ✅ Yes | 🟨 Probably | ⬜️ *N/A* | ✅ Yes | ✅ Yes
|
|
20
|
-
x86_64 (AMD64) | ✅ Yes | ✅ Yes | ✅ Yes | ✅ Yes | ✅ Yes | ✅ Yes
|
|
21
|
-
ARM32 LE [^2] | ⬜️ *N/A* | ✅ Yes | 🟨 Probably | ⬜️ *N/A* | 🟨 Probably | 🟨 Probably
|
|
22
|
-
ARM64 (AArch64) LE | ✅ Yes | ✅ Yes | ✅ Yes | ✅ Yes | ✅ Yes | 🟨 Probably
|
|
23
|
-
RISC-V 64 [^3] | ⬜️ *N/A* | ✅ Yes | 🟨 Probably | ⬜️ *N/A* | 🟨 Probably | 🟨 Probably
|
|
24
|
-
LoongArch64 | ⬜️ *N/A* | ✅ Yes | 🟨 Probably | ⬜️ *N/A* | 🟨 Probably | 🟨 Probably
|
|
25
|
-
|
|
26
|
-
<div class="legend">✅ Yes | 🟨 Probably | ⬜️ Not applicable</div>
|
|
27
|
-
|
|
28
|
-
[^1]: The following call conventions are supported for forward calls: cdecl, stdcall, MS fastcall, thiscall. Only cdecl and stdcall can be used for C to JS callbacks.
|
|
29
|
-
[^2]: The prebuilt binary uses the hard float ABI and expects a VFP coprocessor. Build from source to use Koffi with a different ABI (softfp, soft).
|
|
30
|
-
[^3]: The prebuilt binary uses the LP64D (double-precision float) ABI. The LP64 ABI is supported in theory if you build Koffi from source (untested), the LP64F ABI is not supported.
|
|
31
|
-
|
|
32
|
-
For all fully supported platforms (green check marks), a prebuilt binary is included in the NPM package which means you can install Koffi without a C++ compiler.
|
|
33
|
-
|
|
34
|
-
<style>
|
|
35
|
-
table td:not(:first-child) { text-align: center; }
|
|
36
|
-
</style>
|
package/src/cnoke/LICENSE.txt
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (C) 2025 Niels Martignène <niels.martignene@protonmail.com>
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
6
|
-
this software and associated documentation files (the “Software”), to deal in
|
|
7
|
-
the Software without restriction, including without limitation the rights to use,
|
|
8
|
-
copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
|
9
|
-
Software, and to permit persons to whom the Software is furnished to do so,
|
|
10
|
-
subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
|
|
16
|
-
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|
17
|
-
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
18
|
-
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
19
|
-
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
20
|
-
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
21
|
-
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
22
|
-
OTHER DEALINGS IN THE SOFTWARE.
|