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.
Files changed (36) hide show
  1. package/build/2.3.21-beta.4/koffi_darwin_arm64/koffi.node +0 -0
  2. package/build/2.3.21-beta.4/koffi_darwin_x64/koffi.node +0 -0
  3. package/build/2.3.21-beta.4/koffi_freebsd_arm64/koffi.node +0 -0
  4. package/build/2.3.21-beta.4/koffi_freebsd_ia32/koffi.node +0 -0
  5. package/build/{2.3.21-beta.3 → 2.3.21-beta.4}/koffi_freebsd_x64/koffi.node +0 -0
  6. package/build/2.3.21-beta.4/koffi_linux_arm32hf/koffi.node +0 -0
  7. package/build/{2.3.21-beta.3 → 2.3.21-beta.4}/koffi_linux_arm64/koffi.node +0 -0
  8. package/build/2.3.21-beta.4/koffi_linux_ia32/koffi.node +0 -0
  9. package/build/2.3.21-beta.4/koffi_linux_riscv64hf64/koffi.node +0 -0
  10. package/build/2.3.21-beta.4/koffi_linux_x64/koffi.node +0 -0
  11. package/build/2.3.21-beta.4/koffi_openbsd_ia32/koffi.node +0 -0
  12. package/build/{2.3.21-beta.3 → 2.3.21-beta.4}/koffi_openbsd_x64/koffi.node +0 -0
  13. package/build/2.3.21-beta.4/koffi_win32_arm64/koffi.node +0 -0
  14. package/build/{2.3.21-beta.3 → 2.3.21-beta.4}/koffi_win32_ia32/koffi.node +0 -0
  15. package/build/{2.3.21-beta.3 → 2.3.21-beta.4}/koffi_win32_x64/koffi.node +0 -0
  16. package/package.json +1 -1
  17. package/src/koffi/src/ffi.cc +8 -86
  18. package/src/koffi/src/ffi.hh +4 -0
  19. package/src/koffi/src/util.cc +74 -3
  20. package/src/koffi/src/util.hh +4 -0
  21. package/build/2.3.21-beta.3/koffi_darwin_arm64/koffi.node +0 -0
  22. package/build/2.3.21-beta.3/koffi_darwin_x64/koffi.node +0 -0
  23. package/build/2.3.21-beta.3/koffi_freebsd_arm64/koffi.node +0 -0
  24. package/build/2.3.21-beta.3/koffi_freebsd_ia32/koffi.node +0 -0
  25. package/build/2.3.21-beta.3/koffi_linux_arm32hf/koffi.node +0 -0
  26. package/build/2.3.21-beta.3/koffi_linux_ia32/koffi.node +0 -0
  27. package/build/2.3.21-beta.3/koffi_linux_riscv64hf64/koffi.node +0 -0
  28. package/build/2.3.21-beta.3/koffi_linux_x64/koffi.node +0 -0
  29. package/build/2.3.21-beta.3/koffi_openbsd_ia32/koffi.node +0 -0
  30. package/build/2.3.21-beta.3/koffi_win32_arm64/koffi.node +0 -0
  31. /package/build/{2.3.21-beta.3 → 2.3.21-beta.4}/koffi_win32_arm64/koffi.exp +0 -0
  32. /package/build/{2.3.21-beta.3 → 2.3.21-beta.4}/koffi_win32_arm64/koffi.lib +0 -0
  33. /package/build/{2.3.21-beta.3 → 2.3.21-beta.4}/koffi_win32_ia32/koffi.exp +0 -0
  34. /package/build/{2.3.21-beta.3 → 2.3.21-beta.4}/koffi_win32_ia32/koffi.lib +0 -0
  35. /package/build/{2.3.21-beta.3 → 2.3.21-beta.4}/koffi_win32_x64/koffi.exp +0 -0
  36. /package/build/{2.3.21-beta.3 → 2.3.21-beta.4}/koffi_win32_x64/koffi.lib +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "koffi",
3
- "version": "2.3.21-beta.3",
3
+ "version": "2.3.21-beta.4",
4
4
  "stable": "2.3.20",
5
5
  "description": "Fast and simple C FFI (foreign function interface) for Node.js",
6
6
  "keywords": [
@@ -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
- static Napi::Value TranslateNormalCall(const Napi::CallbackInfo &info)
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(&copy);
1361
1353
  }
1362
1354
 
1363
- static Napi::Value TranslateVariadicCall(const Napi::CallbackInfo &info)
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
- static Napi::Value TranslateAsyncCall(const Napi::CallbackInfo &info)
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 &param = 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::Callback)) {
2124
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for type, expected function pointer type", GetValueType(instance, info[1]));
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
- if (proto->variadic) {
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
 
@@ -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
  }
@@ -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
- ThrowError<Napi::TypeError>(env, "Cannot decode value of type %1", type->name);
1148
- return env.Null();
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 &param: 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 &param = 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) {
@@ -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);