koffi 2.2.2-beta.3 → 2.2.2-beta.5

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 (35) hide show
  1. package/package.json +1 -1
  2. package/src/koffi/build/2.2.2-beta.5/koffi_darwin_arm64.tar.gz +0 -0
  3. package/src/koffi/build/2.2.2-beta.5/koffi_darwin_x64.tar.gz +0 -0
  4. package/src/koffi/build/2.2.2-beta.5/koffi_freebsd_arm64.tar.gz +0 -0
  5. package/src/koffi/build/2.2.2-beta.5/koffi_freebsd_ia32.tar.gz +0 -0
  6. package/src/koffi/build/2.2.2-beta.5/koffi_freebsd_x64.tar.gz +0 -0
  7. package/src/koffi/build/2.2.2-beta.5/koffi_linux_arm32hf.tar.gz +0 -0
  8. package/src/koffi/build/2.2.2-beta.5/koffi_linux_arm64.tar.gz +0 -0
  9. package/src/koffi/build/2.2.2-beta.5/koffi_linux_ia32.tar.gz +0 -0
  10. package/src/koffi/build/2.2.2-beta.5/koffi_linux_riscv64hf64.tar.gz +0 -0
  11. package/src/koffi/build/2.2.2-beta.5/koffi_linux_x64.tar.gz +0 -0
  12. package/src/koffi/build/2.2.2-beta.5/koffi_openbsd_ia32.tar.gz +0 -0
  13. package/src/koffi/build/2.2.2-beta.5/koffi_openbsd_x64.tar.gz +0 -0
  14. package/src/koffi/build/2.2.2-beta.5/koffi_win32_arm64.tar.gz +0 -0
  15. package/src/koffi/build/2.2.2-beta.5/koffi_win32_ia32.tar.gz +0 -0
  16. package/src/koffi/build/2.2.2-beta.5/koffi_win32_x64.tar.gz +0 -0
  17. package/src/koffi/src/ffi.cc +7 -1
  18. package/src/koffi/src/index.js +3 -2
  19. package/src/koffi/test/callbacks.js +17 -12
  20. package/src/koffi/test/misc.c +15 -8
  21. package/src/koffi/build/2.2.2-beta.3/koffi_darwin_arm64.tar.gz +0 -0
  22. package/src/koffi/build/2.2.2-beta.3/koffi_darwin_x64.tar.gz +0 -0
  23. package/src/koffi/build/2.2.2-beta.3/koffi_freebsd_arm64.tar.gz +0 -0
  24. package/src/koffi/build/2.2.2-beta.3/koffi_freebsd_ia32.tar.gz +0 -0
  25. package/src/koffi/build/2.2.2-beta.3/koffi_freebsd_x64.tar.gz +0 -0
  26. package/src/koffi/build/2.2.2-beta.3/koffi_linux_arm32hf.tar.gz +0 -0
  27. package/src/koffi/build/2.2.2-beta.3/koffi_linux_arm64.tar.gz +0 -0
  28. package/src/koffi/build/2.2.2-beta.3/koffi_linux_ia32.tar.gz +0 -0
  29. package/src/koffi/build/2.2.2-beta.3/koffi_linux_riscv64hf64.tar.gz +0 -0
  30. package/src/koffi/build/2.2.2-beta.3/koffi_linux_x64.tar.gz +0 -0
  31. package/src/koffi/build/2.2.2-beta.3/koffi_openbsd_ia32.tar.gz +0 -0
  32. package/src/koffi/build/2.2.2-beta.3/koffi_openbsd_x64.tar.gz +0 -0
  33. package/src/koffi/build/2.2.2-beta.3/koffi_win32_arm64.tar.gz +0 -0
  34. package/src/koffi/build/2.2.2-beta.3/koffi_win32_ia32.tar.gz +0 -0
  35. package/src/koffi/build/2.2.2-beta.3/koffi_win32_x64.tar.gz +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "koffi",
3
- "version": "2.2.2-beta.3",
3
+ "version": "2.2.2-beta.5",
4
4
  "stable": "2.2.1",
5
5
  "description": "Fast and simple C FFI (foreign function interface) for Node.js",
6
6
  "keywords": [
@@ -1891,7 +1891,9 @@ extern "C" void RelayCallback(Size idx, uint8_t *own_sp, uint8_t *caller_sp, Bac
1891
1891
  if (RG_LIKELY(exec_call)) {
1892
1892
  exec_call->RelaySafe(idx, own_sp, caller_sp, out_reg);
1893
1893
  } else {
1894
- Napi::Env env = shared.trampolines[idx].func.Env();
1894
+ TrampolineInfo *trampoline = &shared.trampolines[idx];
1895
+
1896
+ Napi::Env env = trampoline->func.Env();
1895
1897
  InstanceData *instance = env.GetInstanceData<InstanceData>();
1896
1898
 
1897
1899
  InstanceMemory *mem = AllocateMemory(instance, instance->async_stack_size, instance->async_heap_size);
@@ -1900,6 +1902,10 @@ extern "C" void RelayCallback(Size idx, uint8_t *own_sp, uint8_t *caller_sp, Bac
1900
1902
  return;
1901
1903
  }
1902
1904
 
1905
+ // Avoid triggering the "use callback beyond FFI" check
1906
+ RG_DEFER_C(generation = trampoline->generation) { trampoline->generation = generation; };
1907
+ trampoline->generation = -1;
1908
+
1903
1909
  CallData call(env, instance, mem);
1904
1910
  call.RelaySafe(idx, own_sp, caller_sp, out_reg);
1905
1911
  }
@@ -1,5 +1,3 @@
1
- #!/usr/bin/env node
2
-
3
1
  // This program is free software: you can redistribute it and/or modify
4
2
  // it under the terms of the GNU Affero General Public License as published by
5
3
  // the Free Software Foundation, either version 3 of the License, or
@@ -15,6 +13,9 @@
15
13
 
16
14
  'use strict';
17
15
 
16
+ if (process.versions.napi == null || process.versions.napi < 8)
17
+ throw new Error('This platform does not support N-API 8');
18
+
18
19
  const util = require('util');
19
20
 
20
21
  let filename = __dirname + '/../build/koffi.node';
@@ -73,9 +73,10 @@ async function test() {
73
73
  const ApplyStd = lib.func('int ApplyStd(int a, int b, int c, ApplyCallback *func)');
74
74
  const ApplyMany = lib.func('int ApplyMany(int x, IntCallback **funcs, int length)');
75
75
  const ApplyStruct = lib.func('int ApplyStruct(int x, StructCallbacks callbacks)');
76
- const SetCallback = lib.func('void SetCallback(IntCallback *func)');
77
- const CallCallback = lib.func('int CallCallback(int x)');
78
- const CallFromThread = lib.func('int CallFromThread(int x)');
76
+ const SetIndirect = lib.func('void SetIndirect(IntCallback *func)');
77
+ const CallIndirect = lib.func('int CallIndirect(int x)');
78
+ const CallIndirectThreaded = lib.func('int CallIndirectThreaded(int x)');
79
+ const CallDirectThreaded = lib.func('int CallDirectThreaded(IntCallback *func, int x)');
79
80
  const MakeVectors = lib.func('int MakeVectors(int len, VectorCallback *func)');
80
81
  const CallQSort = lib.func('void CallQSort(_Inout_ void *base, size_t nmemb, size_t size, SortCallback *cb)');
81
82
  const CallMeChar = lib.func('int CallMeChar(CharCallback *func)');
@@ -164,12 +165,12 @@ async function test() {
164
165
 
165
166
  // Persistent callback
166
167
  {
167
- SetCallback(x => -x);
168
- assert.throws(() => CallCallback(27), { message: /non-registered callback/ });
168
+ SetIndirect(x => -x);
169
+ assert.throws(() => CallIndirect(27), { message: /non-registered callback/ });
169
170
 
170
171
  let cb = koffi.register(x => -x, koffi.pointer(IntCallback));
171
- SetCallback(cb);
172
- assert.equal(CallCallback(27), -27);
172
+ SetIndirect(cb);
173
+ assert.equal(CallIndirect(27), -27);
173
174
 
174
175
  assert.equal(koffi.unregister(cb), null);
175
176
  assert.throws(() => koffi.unregister(cb));
@@ -185,8 +186,8 @@ async function test() {
185
186
  let mult = new Multiplier(5);
186
187
  let cb = koffi.register(mult, mult.multiply, 'IntCallback *');
187
188
 
188
- SetCallback(cb);
189
- assert.equal(CallCallback(42), 5 * 42);
189
+ SetIndirect(cb);
190
+ assert.equal(CallIndirect(42), 5 * 42);
190
191
 
191
192
  assert.equal(koffi.unregister(cb), null);
192
193
  assert.throws(() => koffi.unregister(cb));
@@ -262,12 +263,16 @@ async function test() {
262
263
  assert.equal(ret, 97 + 2 * 98);
263
264
  }
264
265
 
265
- // Use callback from secondary thread
266
+ // Use temporary callback from secondary thread
267
+ for (let i = 0; i < 128; i++)
268
+ assert.equal(await util.promisify(CallDirectThreaded.async)(x => -x - 2, 27), -29);
269
+
270
+ // Use registered callback from secondary thread
266
271
  for (let i = 0; i < 128; i++) {
267
272
  let cb = koffi.register(x => -x - 2, koffi.pointer(IntCallback));
268
273
 
269
- SetCallback(cb);
270
- assert.equal(await util.promisify(CallFromThread.async)(27), -29);
274
+ SetIndirect(cb);
275
+ assert.equal(await util.promisify(CallIndirectThreaded.async)(27), -29);
271
276
 
272
277
  koffi.unregister(cb);
273
278
  }
@@ -669,19 +669,19 @@ EXPORT int ApplyStruct(int x, StructCallbacks callbacks)
669
669
 
670
670
  static IntCallback *callback;
671
671
 
672
- EXPORT void SetCallback(IntCallback *cb)
672
+ EXPORT void SetIndirect(IntCallback *cb)
673
673
  {
674
674
  callback = cb;
675
675
  }
676
676
 
677
- EXPORT int CallCallback(int x)
677
+ EXPORT int CallIndirect(int x)
678
678
  {
679
679
  return callback(x);
680
680
  }
681
681
 
682
682
  #ifdef _WIN32
683
683
 
684
- static DWORD WINAPI CallFromThreadFunc(void *udata)
684
+ static DWORD WINAPI CallIndirectThreadedFunc(void *udata)
685
685
  {
686
686
  int *ptr = (int *)udata;
687
687
  *ptr = callback(*ptr);
@@ -689,22 +689,23 @@ static DWORD WINAPI CallFromThreadFunc(void *udata)
689
689
  return 0;
690
690
  }
691
691
 
692
- EXPORT int CallFromThread(int x)
692
+ EXPORT int CallIndirectThreaded(int x)
693
693
  {
694
- HANDLE h = CreateThread(NULL, 0, CallFromThreadFunc, &x, 0, NULL);
694
+ HANDLE h = CreateThread(NULL, 0, CallIndirectThreadedFunc, &x, 0, NULL);
695
695
  if (!h) {
696
696
  perror("CreateThread");
697
697
  exit(1);
698
698
  }
699
699
 
700
700
  WaitForSingleObject(h, INFINITE);
701
+ CloseHandle(h);
701
702
 
702
703
  return x;
703
704
  }
704
705
 
705
706
  #else
706
707
 
707
- static void *CallFromThreadFunc(void *udata)
708
+ static void *CallIndirectThreadedFunc(void *udata)
708
709
  {
709
710
  int *ptr = (int *)udata;
710
711
  *ptr = callback(*ptr);
@@ -712,11 +713,11 @@ static void *CallFromThreadFunc(void *udata)
712
713
  return NULL;
713
714
  }
714
715
 
715
- EXPORT int CallFromThread(int x)
716
+ EXPORT int CallIndirectThreaded(int x)
716
717
  {
717
718
  pthread_t thread;
718
719
 
719
- if (pthread_create(&thread, NULL, CallFromThreadFunc, &x)) {
720
+ if (pthread_create(&thread, NULL, CallIndirectThreadedFunc, &x)) {
720
721
  perror("pthread_create");
721
722
  exit(1);
722
723
  }
@@ -728,6 +729,12 @@ EXPORT int CallFromThread(int x)
728
729
 
729
730
  #endif
730
731
 
732
+ EXPORT int CallDirectThreaded(IntCallback *func, int x)
733
+ {
734
+ callback = func;
735
+ return CallIndirectThreaded(x);
736
+ }
737
+
731
738
  EXPORT void ReverseBytes(void *p, int len)
732
739
  {
733
740
  uint8_t *bytes = (uint8_t *)p;