koffi 2.2.2-beta.5 → 2.2.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.
Files changed (60) hide show
  1. package/ChangeLog.md +14 -0
  2. package/doc/callbacks.md +10 -3
  3. package/doc/contribute.md +1 -1
  4. package/package.json +2 -2
  5. package/src/koffi/build/2.2.2/koffi_darwin_arm64.tar.gz +0 -0
  6. package/src/koffi/build/2.2.2/koffi_darwin_x64.tar.gz +0 -0
  7. package/src/koffi/build/2.2.2/koffi_freebsd_arm64.tar.gz +0 -0
  8. package/src/koffi/build/2.2.2/koffi_freebsd_ia32.tar.gz +0 -0
  9. package/src/koffi/build/2.2.2/koffi_freebsd_x64.tar.gz +0 -0
  10. package/src/koffi/build/2.2.2/koffi_linux_arm32hf.tar.gz +0 -0
  11. package/src/koffi/build/2.2.2/koffi_linux_arm64.tar.gz +0 -0
  12. package/src/koffi/build/2.2.2/koffi_linux_ia32.tar.gz +0 -0
  13. package/src/koffi/build/2.2.2/koffi_linux_riscv64hf64.tar.gz +0 -0
  14. package/src/koffi/build/2.2.2/koffi_linux_x64.tar.gz +0 -0
  15. package/src/koffi/build/2.2.2/koffi_openbsd_ia32.tar.gz +0 -0
  16. package/src/koffi/build/2.2.2/koffi_openbsd_x64.tar.gz +0 -0
  17. package/src/koffi/build/2.2.2/koffi_win32_arm64.tar.gz +0 -0
  18. package/src/koffi/build/2.2.2/koffi_win32_ia32.tar.gz +0 -0
  19. package/src/koffi/build/2.2.2/koffi_win32_x64.tar.gz +0 -0
  20. package/src/koffi/src/abi_arm32.cc +3 -70
  21. package/src/koffi/src/abi_arm32_fwd.S +6054 -97
  22. package/src/koffi/src/abi_arm64.cc +3 -70
  23. package/src/koffi/src/abi_arm64_fwd.S +6050 -93
  24. package/src/koffi/src/abi_arm64_fwd.asm +8082 -141
  25. package/src/koffi/src/abi_riscv64.cc +3 -70
  26. package/src/koffi/src/abi_riscv64_fwd.S +6044 -87
  27. package/src/koffi/src/abi_trampolines.inc +2065 -0
  28. package/src/koffi/src/abi_x64_sysv.cc +3 -70
  29. package/src/koffi/src/abi_x64_sysv_fwd.S +6048 -91
  30. package/src/koffi/src/abi_x64_win.cc +4 -71
  31. package/src/koffi/src/abi_x64_win_fwd.asm +8018 -77
  32. package/src/koffi/src/abi_x86.cc +4 -71
  33. package/src/koffi/src/abi_x86_fwd.S +6056 -99
  34. package/src/koffi/src/abi_x86_fwd.asm +8027 -86
  35. package/src/koffi/src/call.cc +23 -16
  36. package/src/koffi/src/call.hh +2 -4
  37. package/src/koffi/src/ffi.cc +35 -33
  38. package/src/koffi/src/ffi.hh +16 -5
  39. package/src/koffi/test/callbacks.js +11 -10
  40. package/src/koffi/test/misc.c +30 -17
  41. package/src/koffi/{qemu → tools}/qemu/.gitkeep +0 -0
  42. package/src/koffi/{qemu → tools}/qemu.js +4 -1
  43. package/src/koffi/{qemu → tools}/registry/machines.json +0 -0
  44. package/src/koffi/{qemu → tools}/registry/sha256sum.txt +0 -0
  45. package/src/koffi/tools/write_trampolines.py +138 -0
  46. package/src/koffi/build/2.2.2-beta.5/koffi_darwin_arm64.tar.gz +0 -0
  47. package/src/koffi/build/2.2.2-beta.5/koffi_darwin_x64.tar.gz +0 -0
  48. package/src/koffi/build/2.2.2-beta.5/koffi_freebsd_arm64.tar.gz +0 -0
  49. package/src/koffi/build/2.2.2-beta.5/koffi_freebsd_ia32.tar.gz +0 -0
  50. package/src/koffi/build/2.2.2-beta.5/koffi_freebsd_x64.tar.gz +0 -0
  51. package/src/koffi/build/2.2.2-beta.5/koffi_linux_arm32hf.tar.gz +0 -0
  52. package/src/koffi/build/2.2.2-beta.5/koffi_linux_arm64.tar.gz +0 -0
  53. package/src/koffi/build/2.2.2-beta.5/koffi_linux_ia32.tar.gz +0 -0
  54. package/src/koffi/build/2.2.2-beta.5/koffi_linux_riscv64hf64.tar.gz +0 -0
  55. package/src/koffi/build/2.2.2-beta.5/koffi_linux_x64.tar.gz +0 -0
  56. package/src/koffi/build/2.2.2-beta.5/koffi_openbsd_ia32.tar.gz +0 -0
  57. package/src/koffi/build/2.2.2-beta.5/koffi_openbsd_x64.tar.gz +0 -0
  58. package/src/koffi/build/2.2.2-beta.5/koffi_win32_arm64.tar.gz +0 -0
  59. package/src/koffi/build/2.2.2-beta.5/koffi_win32_ia32.tar.gz +0 -0
  60. package/src/koffi/build/2.2.2-beta.5/koffi_win32_x64.tar.gz +0 -0
package/ChangeLog.md CHANGED
@@ -2,6 +2,20 @@
2
2
 
3
3
  ## History
4
4
 
5
+ ### Koffi 2.2.2
6
+
7
+ **Main fixes:**
8
+
9
+ - Support transparent [asynchronous callbacks](callbacks.md#asynchronous-callbacks)
10
+ - Expand from a maximum of 16+16 to 1024 callbacks running in parallel
11
+
12
+ **Other fixes:**
13
+
14
+ - Fix bundler support by removing shebang from index.js
15
+ - Fix bugs when loading Koffi multiples times in same process (context aware module)
16
+ - Check N-API version when module is loaded
17
+ - Optimize callback unregistration
18
+
5
19
  ### Koffi 2.2.1
6
20
 
7
21
  **Main fixes:**
package/doc/callbacks.md CHANGED
@@ -77,7 +77,7 @@ console.log(ret);
77
77
 
78
78
  Use registered callbacks when the function needs to be called at a later time (e.g. log handler, event handler, `fopencookie/funopen`). Call `koffi.register(func, type)` to register a callback function, with two arguments: the JS function, and the callback type.
79
79
 
80
- When you are done, call `koffi.unregister()` (with the value returned by `koffi.register()`) to release the slot. A maximum of 16 registered callbacks can exist at the same time. Failure to do so will leak the slot, and subsequent registrations may fail (with an exception) once all slots are used.
80
+ When you are done, call `koffi.unregister()` (with the value returned by `koffi.register()`) to release the slot. A maximum of 1024 callbacks can exist at the same time. Failure to do so will leak the slot, and subsequent registrations may fail (with an exception) once all slots are used.
81
81
 
82
82
  The example below shows how to register and unregister delayed callbacks.
83
83
 
@@ -172,9 +172,16 @@ console.log(array); // Prints ['123', 'bar', 'foo', 'foobar']
172
172
 
173
173
  *New in Koffi 2.2.2*
174
174
 
175
- In Koffi, [asynchronous native calls](functions.md#asynchronous-calls) happen on a secondary thread. However, JS execution is inherently single-threaded, callbacks must run on the main thread.
175
+ JS execution is inherently single-threaded, so JS callbacks must run on the main thread. There are two ways you may want to call a callback function from another thread:
176
176
 
177
- Koffi deals with this by running the JS callback function in the Node.js event loop. This means the callback cannot run while the engine is busy running synchronous code.
177
+ - Call the callback from an asynchronous FFI call (e.g. `waitpid.async`)
178
+ - Inside a synchronous FFI call, pass the callback to another thread
179
+
180
+ In both cases, Koffi will queue the call back to JS to run on the main thread, as soon as the JS event loop has a chance to run (for example when you await a promise).
181
+
182
+ ```{warning}
183
+ Be careful, you can easily get into a deadlock situation if you call a callback from a secondary thread and your main thread never lets the JS event loop run (for example, if the main thread waits for the secondary thread to finish something itself).
184
+ ```
178
185
 
179
186
  ## Handling of exceptions
180
187
 
package/doc/contribute.md CHANGED
@@ -59,7 +59,7 @@ These machines are not included directly in this repository (for license and siz
59
59
  For example, if you want to run the tests on Debian ARM64, run the following commands:
60
60
 
61
61
  ```sh
62
- cd rygel/src/koffi/qemu/
62
+ cd rygel/src/koffi/tools/
63
63
  wget -q -O- https://koromix.dev/files/machines/qemu_debian_arm64.tar.zst | zstd -d | tar xv
64
64
  sha256sum -c --ignore-missing registry/sha256sum.txt
65
65
  ```
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koffi",
3
- "version": "2.2.2-beta.5",
4
- "stable": "2.2.1",
3
+ "version": "2.2.2",
4
+ "stable": "2.2.2",
5
5
  "description": "Fast and simple C FFI (foreign function interface) for Node.js",
6
6
  "keywords": [
7
7
  "foreign",
@@ -48,78 +48,11 @@ extern "C" uint64_t ForwardCallXGG(const void *func, uint8_t *sp, uint8_t **out_
48
48
  extern "C" float ForwardCallXF(const void *func, uint8_t *sp, uint8_t **out_old_sp);
49
49
  extern "C" HfaRet ForwardCallXDDDD(const void *func, uint8_t *sp, uint8_t **out_old_sp);
50
50
 
51
- extern "C" int Trampoline0; extern "C" int TrampolineX0;
52
- extern "C" int Trampoline1; extern "C" int TrampolineX1;
53
- extern "C" int Trampoline2; extern "C" int TrampolineX2;
54
- extern "C" int Trampoline3; extern "C" int TrampolineX3;
55
- extern "C" int Trampoline4; extern "C" int TrampolineX4;
56
- extern "C" int Trampoline5; extern "C" int TrampolineX5;
57
- extern "C" int Trampoline6; extern "C" int TrampolineX6;
58
- extern "C" int Trampoline7; extern "C" int TrampolineX7;
59
- extern "C" int Trampoline8; extern "C" int TrampolineX8;
60
- extern "C" int Trampoline9; extern "C" int TrampolineX9;
61
- extern "C" int Trampoline10; extern "C" int TrampolineX10;
62
- extern "C" int Trampoline11; extern "C" int TrampolineX11;
63
- extern "C" int Trampoline12; extern "C" int TrampolineX12;
64
- extern "C" int Trampoline13; extern "C" int TrampolineX13;
65
- extern "C" int Trampoline14; extern "C" int TrampolineX14;
66
- extern "C" int Trampoline15; extern "C" int TrampolineX15;
67
- extern "C" int Trampoline16; extern "C" int TrampolineX16;
68
- extern "C" int Trampoline17; extern "C" int TrampolineX17;
69
- extern "C" int Trampoline18; extern "C" int TrampolineX18;
70
- extern "C" int Trampoline19; extern "C" int TrampolineX19;
71
- extern "C" int Trampoline20; extern "C" int TrampolineX20;
72
- extern "C" int Trampoline21; extern "C" int TrampolineX21;
73
- extern "C" int Trampoline22; extern "C" int TrampolineX22;
74
- extern "C" int Trampoline23; extern "C" int TrampolineX23;
75
- extern "C" int Trampoline24; extern "C" int TrampolineX24;
76
- extern "C" int Trampoline25; extern "C" int TrampolineX25;
77
- extern "C" int Trampoline26; extern "C" int TrampolineX26;
78
- extern "C" int Trampoline27; extern "C" int TrampolineX27;
79
- extern "C" int Trampoline28; extern "C" int TrampolineX28;
80
- extern "C" int Trampoline29; extern "C" int TrampolineX29;
81
- extern "C" int Trampoline30; extern "C" int TrampolineX30;
82
- extern "C" int Trampoline31; extern "C" int TrampolineX31;
83
-
84
51
  extern "C" napi_value CallSwitchStack(Napi::Function *func, size_t argc, napi_value *argv,
85
52
  uint8_t *old_sp, Span<uint8_t> *new_stack,
86
53
  napi_value (*call)(Napi::Function *func, size_t argc, napi_value *argv));
87
54
 
88
- static void *const Trampolines[][2] = {
89
- { &Trampoline0, &TrampolineX0 },
90
- { &Trampoline1, &TrampolineX1 },
91
- { &Trampoline2, &TrampolineX2 },
92
- { &Trampoline3, &TrampolineX3 },
93
- { &Trampoline4, &TrampolineX4 },
94
- { &Trampoline5, &TrampolineX5 },
95
- { &Trampoline6, &TrampolineX6 },
96
- { &Trampoline7, &TrampolineX7 },
97
- { &Trampoline8, &TrampolineX8 },
98
- { &Trampoline9, &TrampolineX9 },
99
- { &Trampoline10, &TrampolineX10 },
100
- { &Trampoline11, &TrampolineX11 },
101
- { &Trampoline12, &TrampolineX12 },
102
- { &Trampoline13, &TrampolineX13 },
103
- { &Trampoline14, &TrampolineX14 },
104
- { &Trampoline15, &TrampolineX15 },
105
- { &Trampoline16, &TrampolineX16 },
106
- { &Trampoline17, &TrampolineX17 },
107
- { &Trampoline18, &TrampolineX18 },
108
- { &Trampoline19, &TrampolineX19 },
109
- { &Trampoline20, &TrampolineX20 },
110
- { &Trampoline21, &TrampolineX21 },
111
- { &Trampoline22, &TrampolineX22 },
112
- { &Trampoline23, &TrampolineX23 },
113
- { &Trampoline24, &TrampolineX24 },
114
- { &Trampoline25, &TrampolineX25 },
115
- { &Trampoline26, &TrampolineX26 },
116
- { &Trampoline27, &TrampolineX27 },
117
- { &Trampoline28, &TrampolineX28 },
118
- { &Trampoline29, &TrampolineX29 },
119
- { &Trampoline30, &TrampolineX30 },
120
- { &Trampoline31, &TrampolineX31 }
121
- };
122
- RG_STATIC_ASSERT(RG_LEN(Trampolines) == MaxTrampolines * 2);
55
+ #include "abi_trampolines.inc"
123
56
 
124
57
  static inline int IsHFA(const TypeInfo *type)
125
58
  {
@@ -1031,7 +964,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool async,
1031
964
  if (RG_UNLIKELY(!ptr))
1032
965
  return;
1033
966
  } else if (CheckValueTag(instance, value, type->ref.marker)) {
1034
- ptr = value.As<Napi::External<uint8_t>>().Data();
967
+ ptr = value.As<Napi::External<void>>().Data();
1035
968
  } else if (IsNullOrUndefined(value)) {
1036
969
  ptr = nullptr;
1037
970
  } else {
@@ -1053,7 +986,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool async,
1053
986
  err_guard.Disable();
1054
987
  }
1055
988
 
1056
- void *GetTrampoline(Size idx, const FunctionInfo *proto)
989
+ void *GetTrampoline(int16_t idx, const FunctionInfo *proto)
1057
990
  {
1058
991
  bool vec = proto->forward_fp || IsFloat(proto->ret.type);
1059
992
  return Trampolines[idx][vec];