koffi 2.3.21-beta.3 → 2.3.21-beta.4
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/build/2.3.21-beta.4/koffi_darwin_arm64/koffi.node +0 -0
- package/build/2.3.21-beta.4/koffi_darwin_x64/koffi.node +0 -0
- package/build/2.3.21-beta.4/koffi_freebsd_arm64/koffi.node +0 -0
- package/build/2.3.21-beta.4/koffi_freebsd_ia32/koffi.node +0 -0
- package/build/{2.3.21-beta.3 → 2.3.21-beta.4}/koffi_freebsd_x64/koffi.node +0 -0
- package/build/2.3.21-beta.4/koffi_linux_arm32hf/koffi.node +0 -0
- package/build/{2.3.21-beta.3 → 2.3.21-beta.4}/koffi_linux_arm64/koffi.node +0 -0
- package/build/2.3.21-beta.4/koffi_linux_ia32/koffi.node +0 -0
- package/build/2.3.21-beta.4/koffi_linux_riscv64hf64/koffi.node +0 -0
- package/build/2.3.21-beta.4/koffi_linux_x64/koffi.node +0 -0
- package/build/2.3.21-beta.4/koffi_openbsd_ia32/koffi.node +0 -0
- package/build/{2.3.21-beta.3 → 2.3.21-beta.4}/koffi_openbsd_x64/koffi.node +0 -0
- package/build/2.3.21-beta.4/koffi_win32_arm64/koffi.node +0 -0
- package/build/{2.3.21-beta.3 → 2.3.21-beta.4}/koffi_win32_ia32/koffi.node +0 -0
- package/build/{2.3.21-beta.3 → 2.3.21-beta.4}/koffi_win32_x64/koffi.node +0 -0
- package/package.json +1 -1
- package/src/koffi/src/ffi.cc +8 -86
- package/src/koffi/src/ffi.hh +4 -0
- package/src/koffi/src/util.cc +74 -3
- package/src/koffi/src/util.hh +4 -0
- package/build/2.3.21-beta.3/koffi_darwin_arm64/koffi.node +0 -0
- package/build/2.3.21-beta.3/koffi_darwin_x64/koffi.node +0 -0
- package/build/2.3.21-beta.3/koffi_freebsd_arm64/koffi.node +0 -0
- package/build/2.3.21-beta.3/koffi_freebsd_ia32/koffi.node +0 -0
- package/build/2.3.21-beta.3/koffi_linux_arm32hf/koffi.node +0 -0
- package/build/2.3.21-beta.3/koffi_linux_ia32/koffi.node +0 -0
- package/build/2.3.21-beta.3/koffi_linux_riscv64hf64/koffi.node +0 -0
- package/build/2.3.21-beta.3/koffi_linux_x64/koffi.node +0 -0
- package/build/2.3.21-beta.3/koffi_openbsd_ia32/koffi.node +0 -0
- package/build/2.3.21-beta.3/koffi_win32_arm64/koffi.node +0 -0
- /package/build/{2.3.21-beta.3 → 2.3.21-beta.4}/koffi_win32_arm64/koffi.exp +0 -0
- /package/build/{2.3.21-beta.3 → 2.3.21-beta.4}/koffi_win32_arm64/koffi.lib +0 -0
- /package/build/{2.3.21-beta.3 → 2.3.21-beta.4}/koffi_win32_ia32/koffi.exp +0 -0
- /package/build/{2.3.21-beta.3 → 2.3.21-beta.4}/koffi_win32_ia32/koffi.lib +0 -0
- /package/build/{2.3.21-beta.3 → 2.3.21-beta.4}/koffi_win32_x64/koffi.exp +0 -0
- /package/build/{2.3.21-beta.3 → 2.3.21-beta.4}/koffi_win32_x64/koffi.lib +0 -0
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
package/src/koffi/src/ffi.cc
CHANGED
|
@@ -204,14 +204,6 @@ static inline bool CheckAlignment(int64_t align)
|
|
|
204
204
|
return valid;
|
|
205
205
|
}
|
|
206
206
|
|
|
207
|
-
static inline Napi::External<TypeInfo> WrapType(Napi::Env env, InstanceData *instance, const TypeInfo *type)
|
|
208
|
-
{
|
|
209
|
-
Napi::External<TypeInfo> external = Napi::External<TypeInfo>::New(env, (TypeInfo *)type);
|
|
210
|
-
SetValueTag(instance, external, &TypeInfoMarker);
|
|
211
|
-
|
|
212
|
-
return external;
|
|
213
|
-
}
|
|
214
|
-
|
|
215
207
|
static Napi::Value CreateStructType(const Napi::CallbackInfo &info, bool pad)
|
|
216
208
|
{
|
|
217
209
|
Napi::Env env = info.Env();
|
|
@@ -1279,7 +1271,7 @@ static Napi::Value TranslateNormalCall(const FunctionInfo *func, void *native,
|
|
|
1279
1271
|
return call.Complete(func);
|
|
1280
1272
|
}
|
|
1281
1273
|
|
|
1282
|
-
|
|
1274
|
+
Napi::Value TranslateNormalCall(const Napi::CallbackInfo &info)
|
|
1283
1275
|
{
|
|
1284
1276
|
FunctionInfo *func = (FunctionInfo *)info.Data();
|
|
1285
1277
|
return TranslateNormalCall(func, func->native, info);
|
|
@@ -1360,7 +1352,7 @@ static Napi::Value TranslateVariadicCall(const FunctionInfo *func, void *native,
|
|
|
1360
1352
|
return call.Complete(©);
|
|
1361
1353
|
}
|
|
1362
1354
|
|
|
1363
|
-
|
|
1355
|
+
Napi::Value TranslateVariadicCall(const Napi::CallbackInfo &info)
|
|
1364
1356
|
{
|
|
1365
1357
|
FunctionInfo *func = (FunctionInfo *)info.Data();
|
|
1366
1358
|
return TranslateVariadicCall(func, func->native, info);
|
|
@@ -1458,7 +1450,7 @@ static Napi::Value TranslateAsyncCall(const FunctionInfo *func, void *native,
|
|
|
1458
1450
|
return env.Undefined();
|
|
1459
1451
|
}
|
|
1460
1452
|
|
|
1461
|
-
|
|
1453
|
+
Napi::Value TranslateAsyncCall(const Napi::CallbackInfo &info)
|
|
1462
1454
|
{
|
|
1463
1455
|
FunctionInfo *func = (FunctionInfo *)info.Data();
|
|
1464
1456
|
return TranslateAsyncCall(func, func->native, info);
|
|
@@ -1533,41 +1525,7 @@ static Napi::Value FindLibraryFunction(const Napi::CallbackInfo &info, CallConve
|
|
|
1533
1525
|
return env.Null();
|
|
1534
1526
|
}
|
|
1535
1527
|
|
|
1536
|
-
Napi::Function wrapper;
|
|
1537
|
-
if (func->variadic) {
|
|
1538
|
-
Napi::Function::Callback call = TranslateVariadicCall;
|
|
1539
|
-
wrapper = Napi::Function::New(env, call, func->name, (void *)func->Ref());
|
|
1540
|
-
} else {
|
|
1541
|
-
Napi::Function::Callback call = TranslateNormalCall;
|
|
1542
|
-
wrapper = Napi::Function::New(env, call, func->name, (void *)func->Ref());
|
|
1543
|
-
}
|
|
1544
|
-
wrapper.AddFinalizer([](Napi::Env, FunctionInfo *func) { func->Unref(); }, func);
|
|
1545
|
-
|
|
1546
|
-
if (!func->variadic) {
|
|
1547
|
-
Napi::Function::Callback call = TranslateAsyncCall;
|
|
1548
|
-
Napi::Function async = Napi::Function::New(env, call, func->name, (void *)func->Ref());
|
|
1549
|
-
|
|
1550
|
-
async.AddFinalizer([](Napi::Env, FunctionInfo *func) { func->Unref(); }, func);
|
|
1551
|
-
wrapper.Set("async", async);
|
|
1552
|
-
}
|
|
1553
|
-
|
|
1554
|
-
// Create info object
|
|
1555
|
-
{
|
|
1556
|
-
Napi::Object meta = Napi::Object::New(env);
|
|
1557
|
-
Napi::Array arguments = Napi::Array::New(env, func->parameters.len);
|
|
1558
|
-
|
|
1559
|
-
meta.Set("name", Napi::String::New(env, func->name));
|
|
1560
|
-
meta.Set("arguments", arguments);
|
|
1561
|
-
meta.Set("result", WrapType(env, instance, func->ret.type));
|
|
1562
|
-
|
|
1563
|
-
for (Size i = 0; i < func->parameters.len; i++) {
|
|
1564
|
-
const ParameterInfo ¶m = func->parameters[i];
|
|
1565
|
-
arguments.Set((uint32_t)i, WrapType(env, instance, param.type));
|
|
1566
|
-
}
|
|
1567
|
-
|
|
1568
|
-
wrapper.Set("info", meta);
|
|
1569
|
-
}
|
|
1570
|
-
|
|
1528
|
+
Napi::Function wrapper = WrapFunction(env, func);
|
|
1571
1529
|
return wrapper;
|
|
1572
1530
|
}
|
|
1573
1531
|
|
|
@@ -2120,50 +2078,15 @@ static Napi::Value CallPointerSync(const Napi::CallbackInfo &info)
|
|
|
2120
2078
|
const TypeInfo *type = ResolveType(info[1]);
|
|
2121
2079
|
if (RG_UNLIKELY(!type))
|
|
2122
2080
|
return env.Null();
|
|
2123
|
-
if (RG_UNLIKELY(type->primitive != PrimitiveKind::
|
|
2124
|
-
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for type, expected function
|
|
2081
|
+
if (RG_UNLIKELY(type->primitive != PrimitiveKind::Prototype)) {
|
|
2082
|
+
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for type, expected function type", GetValueType(instance, info[1]));
|
|
2125
2083
|
return env.Null();
|
|
2126
2084
|
}
|
|
2127
2085
|
|
|
2128
2086
|
const FunctionInfo *proto = type->ref.proto;
|
|
2087
|
+
RG_ASSERT(!proto->variadic);
|
|
2129
2088
|
|
|
2130
|
-
|
|
2131
|
-
return TranslateVariadicCall(proto, ptr, info);
|
|
2132
|
-
} else {
|
|
2133
|
-
return TranslateNormalCall(proto, ptr, info);
|
|
2134
|
-
}
|
|
2135
|
-
}
|
|
2136
|
-
|
|
2137
|
-
static Napi::Value CallPointerAsync(const Napi::CallbackInfo &info)
|
|
2138
|
-
{
|
|
2139
|
-
Napi::Env env = info.Env();
|
|
2140
|
-
InstanceData *instance = env.GetInstanceData<InstanceData>();
|
|
2141
|
-
|
|
2142
|
-
if (RG_UNLIKELY(info.Length() < 2)) {
|
|
2143
|
-
ThrowError<Napi::TypeError>(env, "Expected 2 or more arguments, got %1", info.Length());
|
|
2144
|
-
return env.Null();
|
|
2145
|
-
}
|
|
2146
|
-
|
|
2147
|
-
void *ptr = nullptr;
|
|
2148
|
-
if (RG_UNLIKELY(!GetExternalPointer(env, info[0], &ptr)))
|
|
2149
|
-
return env.Null();
|
|
2150
|
-
|
|
2151
|
-
const TypeInfo *type = ResolveType(info[1]);
|
|
2152
|
-
if (RG_UNLIKELY(!type))
|
|
2153
|
-
return env.Null();
|
|
2154
|
-
if (RG_UNLIKELY(type->primitive != PrimitiveKind::Callback)) {
|
|
2155
|
-
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for type, expected function pointer type", GetValueType(instance, info[1]));
|
|
2156
|
-
return env.Null();
|
|
2157
|
-
}
|
|
2158
|
-
|
|
2159
|
-
const FunctionInfo *proto = type->ref.proto;
|
|
2160
|
-
|
|
2161
|
-
if (RG_UNLIKELY(proto->variadic)) {
|
|
2162
|
-
ThrowError<Napi::TypeError>(env, "Cannot call variadic function asynchronously");
|
|
2163
|
-
return env.Null();
|
|
2164
|
-
}
|
|
2165
|
-
|
|
2166
|
-
return TranslateAsyncCall(proto, ptr, info);
|
|
2089
|
+
return TranslateNormalCall(proto, ptr, info);
|
|
2167
2090
|
}
|
|
2168
2091
|
|
|
2169
2092
|
extern "C" void RelayCallback(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegisters *out_reg)
|
|
@@ -2233,7 +2156,6 @@ static void SetExports(Napi::Env env, Func func)
|
|
|
2233
2156
|
func("decode", Napi::Function::New(env, DecodeValue));
|
|
2234
2157
|
func("address", Napi::Function::New(env, GetPointerAddress));
|
|
2235
2158
|
func("call", Napi::Function::New(env, CallPointerSync));
|
|
2236
|
-
func("callAsync", Napi::Function::New(env, CallPointerAsync));
|
|
2237
2159
|
|
|
2238
2160
|
func("errno", Napi::Function::New(env, GetOrSetErrNo));
|
|
2239
2161
|
|
package/src/koffi/src/ffi.hh
CHANGED
|
@@ -336,4 +336,8 @@ RG_STATIC_ASSERT(MaxTrampolines <= INT16_MAX);
|
|
|
336
336
|
|
|
337
337
|
extern SharedData shared;
|
|
338
338
|
|
|
339
|
+
Napi::Value TranslateNormalCall(const Napi::CallbackInfo &info);
|
|
340
|
+
Napi::Value TranslateVariadicCall(const Napi::CallbackInfo &info);
|
|
341
|
+
Napi::Value TranslateAsyncCall(const Napi::CallbackInfo &info);
|
|
342
|
+
|
|
339
343
|
}
|
package/src/koffi/src/util.cc
CHANGED
|
@@ -345,6 +345,14 @@ const TypeInfo *MakeArrayType(InstanceData *instance, const TypeInfo *ref, Size
|
|
|
345
345
|
return MakeArrayType(instance, ref, len, hint, false);
|
|
346
346
|
}
|
|
347
347
|
|
|
348
|
+
Napi::External<TypeInfo> WrapType(Napi::Env env, InstanceData *instance, const TypeInfo *type)
|
|
349
|
+
{
|
|
350
|
+
Napi::External<TypeInfo> external = Napi::External<TypeInfo>::New(env, (TypeInfo *)type);
|
|
351
|
+
SetValueTag(instance, external, &TypeInfoMarker);
|
|
352
|
+
|
|
353
|
+
return external;
|
|
354
|
+
}
|
|
355
|
+
|
|
348
356
|
bool CanPassType(const TypeInfo *type, int directions)
|
|
349
357
|
{
|
|
350
358
|
if (directions & 2) {
|
|
@@ -1041,7 +1049,8 @@ Napi::Value Decode(Napi::Env env, const uint8_t *ptr, const TypeInfo *type, cons
|
|
|
1041
1049
|
InstanceData *instance = env.GetInstanceData<InstanceData>();
|
|
1042
1050
|
|
|
1043
1051
|
if (len && type->primitive != PrimitiveKind::String &&
|
|
1044
|
-
type->primitive != PrimitiveKind::String16
|
|
1052
|
+
type->primitive != PrimitiveKind::String16 &&
|
|
1053
|
+
type->primitive != PrimitiveKind::Prototype) {
|
|
1045
1054
|
if (*len >= 0) {
|
|
1046
1055
|
type = MakeArrayType(instance, type, *len);
|
|
1047
1056
|
} else {
|
|
@@ -1144,8 +1153,28 @@ Napi::Value Decode(Napi::Env env, const uint8_t *ptr, const TypeInfo *type, cons
|
|
|
1144
1153
|
} break;
|
|
1145
1154
|
|
|
1146
1155
|
case PrimitiveKind::Prototype: {
|
|
1147
|
-
|
|
1148
|
-
|
|
1156
|
+
const FunctionInfo *proto = type->ref.proto;
|
|
1157
|
+
RG_ASSERT(!proto->variadic);
|
|
1158
|
+
RG_ASSERT(!proto->lib);
|
|
1159
|
+
|
|
1160
|
+
FunctionInfo *func = new FunctionInfo();
|
|
1161
|
+
RG_DEFER { func->Unref(); };
|
|
1162
|
+
|
|
1163
|
+
memcpy((void *)func, proto, RG_SIZE(*proto));
|
|
1164
|
+
memset((void *)&func->parameters, 0, RG_SIZE(func->parameters));
|
|
1165
|
+
func->parameters = proto->parameters;
|
|
1166
|
+
|
|
1167
|
+
func->name = "<anonymous>";
|
|
1168
|
+
func->native = (void *)ptr;
|
|
1169
|
+
|
|
1170
|
+
// Fix back parameter offset
|
|
1171
|
+
for (ParameterInfo ¶m: func->parameters) {
|
|
1172
|
+
param.offset -= 2;
|
|
1173
|
+
}
|
|
1174
|
+
func->required_parameters -= 2;
|
|
1175
|
+
|
|
1176
|
+
Napi::Function wrapper = WrapFunction(env, func);
|
|
1177
|
+
return wrapper;
|
|
1149
1178
|
} break;
|
|
1150
1179
|
}
|
|
1151
1180
|
|
|
@@ -1155,6 +1184,48 @@ Napi::Value Decode(Napi::Env env, const uint8_t *ptr, const TypeInfo *type, cons
|
|
|
1155
1184
|
return env.Null();
|
|
1156
1185
|
}
|
|
1157
1186
|
|
|
1187
|
+
Napi::Function WrapFunction(Napi::Env env, const FunctionInfo *func)
|
|
1188
|
+
{
|
|
1189
|
+
InstanceData *instance = env.GetInstanceData<InstanceData>();
|
|
1190
|
+
|
|
1191
|
+
Napi::Function wrapper;
|
|
1192
|
+
if (func->variadic) {
|
|
1193
|
+
Napi::Function::Callback call = TranslateVariadicCall;
|
|
1194
|
+
wrapper = Napi::Function::New(env, call, func->name, (void *)func->Ref());
|
|
1195
|
+
} else {
|
|
1196
|
+
Napi::Function::Callback call = TranslateNormalCall;
|
|
1197
|
+
wrapper = Napi::Function::New(env, call, func->name, (void *)func->Ref());
|
|
1198
|
+
}
|
|
1199
|
+
wrapper.AddFinalizer([](Napi::Env, FunctionInfo *func) { func->Unref(); }, (FunctionInfo *)func);
|
|
1200
|
+
|
|
1201
|
+
if (!func->variadic) {
|
|
1202
|
+
Napi::Function::Callback call = TranslateAsyncCall;
|
|
1203
|
+
Napi::Function async = Napi::Function::New(env, call, func->name, (void *)func->Ref());
|
|
1204
|
+
|
|
1205
|
+
async.AddFinalizer([](Napi::Env, FunctionInfo *func) { func->Unref(); }, (FunctionInfo *)func);
|
|
1206
|
+
wrapper.Set("async", async);
|
|
1207
|
+
}
|
|
1208
|
+
|
|
1209
|
+
// Create info object
|
|
1210
|
+
{
|
|
1211
|
+
Napi::Object meta = Napi::Object::New(env);
|
|
1212
|
+
Napi::Array arguments = Napi::Array::New(env, func->parameters.len);
|
|
1213
|
+
|
|
1214
|
+
meta.Set("name", Napi::String::New(env, func->name));
|
|
1215
|
+
meta.Set("arguments", arguments);
|
|
1216
|
+
meta.Set("result", WrapType(env, instance, func->ret.type));
|
|
1217
|
+
|
|
1218
|
+
for (Size i = 0; i < func->parameters.len; i++) {
|
|
1219
|
+
const ParameterInfo ¶m = func->parameters[i];
|
|
1220
|
+
arguments.Set((uint32_t)i, WrapType(env, instance, param.type));
|
|
1221
|
+
}
|
|
1222
|
+
|
|
1223
|
+
wrapper.Set("info", meta);
|
|
1224
|
+
}
|
|
1225
|
+
|
|
1226
|
+
return wrapper;
|
|
1227
|
+
}
|
|
1228
|
+
|
|
1158
1229
|
static int AnalyseFlatRec(const TypeInfo *type, int offset, int count, FunctionRef<void(const TypeInfo *type, int offset, int count)> func)
|
|
1159
1230
|
{
|
|
1160
1231
|
if (type->primitive == PrimitiveKind::Record) {
|
package/src/koffi/src/util.hh
CHANGED
|
@@ -93,6 +93,8 @@ const TypeInfo *MakePointerType(InstanceData *instance, const TypeInfo *ref, int
|
|
|
93
93
|
const TypeInfo *MakeArrayType(InstanceData *instance, const TypeInfo *ref, Size len);
|
|
94
94
|
const TypeInfo *MakeArrayType(InstanceData *instance, const TypeInfo *ref, Size len, ArrayHint hint);
|
|
95
95
|
|
|
96
|
+
Napi::External<TypeInfo> WrapType(Napi::Env env, InstanceData *instance, const TypeInfo *type);
|
|
97
|
+
|
|
96
98
|
bool CanPassType(const TypeInfo *type, int directions);
|
|
97
99
|
bool CanReturnType(const TypeInfo *type);
|
|
98
100
|
bool CanStoreType(const TypeInfo *type);
|
|
@@ -185,6 +187,8 @@ static inline Napi::Value NewBigInt(Napi::Env env, uint64_t value)
|
|
|
185
187
|
}
|
|
186
188
|
}
|
|
187
189
|
|
|
190
|
+
Napi::Function WrapFunction(Napi::Env env, const FunctionInfo *func);
|
|
191
|
+
|
|
188
192
|
int AnalyseFlat(const TypeInfo *type, FunctionRef<void(const TypeInfo *type, int offset, int count)> func);
|
|
189
193
|
|
|
190
194
|
void DumpMemory(const char *type, Span<const uint8_t> bytes);
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|