koffi 2.2.3-beta.2 → 2.2.3-beta.3

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.3-beta.3/koffi_darwin_arm64.tar.gz +0 -0
  3. package/src/koffi/build/2.2.3-beta.3/koffi_darwin_x64.tar.gz +0 -0
  4. package/src/koffi/build/2.2.3-beta.3/koffi_freebsd_arm64.tar.gz +0 -0
  5. package/src/koffi/build/2.2.3-beta.3/koffi_freebsd_ia32.tar.gz +0 -0
  6. package/src/koffi/build/2.2.3-beta.3/koffi_freebsd_x64.tar.gz +0 -0
  7. package/src/koffi/build/2.2.3-beta.3/koffi_linux_arm32hf.tar.gz +0 -0
  8. package/src/koffi/build/2.2.3-beta.3/koffi_linux_arm64.tar.gz +0 -0
  9. package/src/koffi/build/2.2.3-beta.3/koffi_linux_ia32.tar.gz +0 -0
  10. package/src/koffi/build/2.2.3-beta.3/koffi_linux_riscv64hf64.tar.gz +0 -0
  11. package/src/koffi/build/2.2.3-beta.3/koffi_linux_x64.tar.gz +0 -0
  12. package/src/koffi/build/2.2.3-beta.3/koffi_openbsd_ia32.tar.gz +0 -0
  13. package/src/koffi/build/2.2.3-beta.3/koffi_openbsd_x64.tar.gz +0 -0
  14. package/src/koffi/build/2.2.3-beta.3/koffi_win32_arm64.tar.gz +0 -0
  15. package/src/koffi/build/2.2.3-beta.3/koffi_win32_ia32.tar.gz +0 -0
  16. package/src/koffi/build/2.2.3-beta.3/koffi_win32_x64.tar.gz +0 -0
  17. package/src/koffi/src/abi_x64_win.cc +25 -27
  18. package/src/koffi/src/abi_x86.cc +28 -30
  19. package/src/koffi/src/ffi.cc +38 -42
  20. package/src/koffi/src/win32.hh +59 -0
  21. package/src/koffi/build/2.2.3-beta.2/koffi_darwin_arm64.tar.gz +0 -0
  22. package/src/koffi/build/2.2.3-beta.2/koffi_darwin_x64.tar.gz +0 -0
  23. package/src/koffi/build/2.2.3-beta.2/koffi_freebsd_arm64.tar.gz +0 -0
  24. package/src/koffi/build/2.2.3-beta.2/koffi_freebsd_ia32.tar.gz +0 -0
  25. package/src/koffi/build/2.2.3-beta.2/koffi_freebsd_x64.tar.gz +0 -0
  26. package/src/koffi/build/2.2.3-beta.2/koffi_linux_arm32hf.tar.gz +0 -0
  27. package/src/koffi/build/2.2.3-beta.2/koffi_linux_arm64.tar.gz +0 -0
  28. package/src/koffi/build/2.2.3-beta.2/koffi_linux_ia32.tar.gz +0 -0
  29. package/src/koffi/build/2.2.3-beta.2/koffi_linux_riscv64hf64.tar.gz +0 -0
  30. package/src/koffi/build/2.2.3-beta.2/koffi_linux_x64.tar.gz +0 -0
  31. package/src/koffi/build/2.2.3-beta.2/koffi_openbsd_ia32.tar.gz +0 -0
  32. package/src/koffi/build/2.2.3-beta.2/koffi_openbsd_x64.tar.gz +0 -0
  33. package/src/koffi/build/2.2.3-beta.2/koffi_win32_arm64.tar.gz +0 -0
  34. package/src/koffi/build/2.2.3-beta.2/koffi_win32_ia32.tar.gz +0 -0
  35. package/src/koffi/build/2.2.3-beta.2/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.3-beta.2",
3
+ "version": "2.2.3-beta.3",
4
4
  "stable": "2.2.2",
5
5
  "description": "Fast and simple C FFI (foreign function interface) for Node.js",
6
6
  "keywords": [
@@ -17,6 +17,7 @@
17
17
  #include "ffi.hh"
18
18
  #include "call.hh"
19
19
  #include "util.hh"
20
+ #include "win32.hh"
20
21
 
21
22
  #include <napi.h>
22
23
 
@@ -40,10 +41,6 @@ extern "C" napi_value CallSwitchStack(Napi::Function *func, size_t argc, napi_va
40
41
 
41
42
  #include "abi_trampolines.inc"
42
43
 
43
- #define TEB_STACK_BASE(TEB) (*(void **)((uint8_t *)(TEB) + 0x08))
44
- #define TEB_STACK_LIMIT(TEB) (*(void **)((uint8_t *)(TEB) + 0x10))
45
- #define TEB_DEALLOCATION_STACK(TEB) (*(void **)((uint8_t *)(TEB) + 0x1478))
46
-
47
44
  bool AnalyseFunction(Napi::Env, InstanceData *, FunctionInfo *func)
48
45
  {
49
46
  func->ret.regular = IsRegularSize(func->ret.type->size, 8);
@@ -220,21 +217,21 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
220
217
 
221
218
  void CallData::Execute(const FunctionInfo *func)
222
219
  {
223
- void *teb = (void *)__readgsqword(0x30);
224
-
225
- // Store current stack limits
226
- RG_DEFER_C(base = TEB_STACK_BASE(teb),
227
- limit = TEB_STACK_LIMIT(teb),
228
- dealloc = TEB_DEALLOCATION_STACK(teb)) {
229
- TEB_STACK_BASE(teb) = base;
230
- TEB_STACK_LIMIT(teb) = limit;
231
- TEB_DEALLOCATION_STACK(teb) = dealloc;
220
+ TEB *teb = GetTEB();
221
+
222
+ // Restore previous stack limits at the end
223
+ RG_DEFER_C(base = teb->StackBase,
224
+ limit = teb->StackLimit,
225
+ dealloc = teb->DeallocationStack) {
226
+ teb->StackBase = base;
227
+ teb->StackLimit = limit;
228
+ teb->DeallocationStack = dealloc;
232
229
  };
233
230
 
234
231
  // Adjust stack limits so SEH works correctly
235
- TEB_STACK_BASE(teb) = mem->stack0.end();
236
- TEB_STACK_LIMIT(teb) = mem->stack0.ptr;
237
- TEB_DEALLOCATION_STACK(teb) = mem->stack0.ptr;
232
+ teb->StackBase = mem->stack0.end();
233
+ teb->StackLimit = mem->stack0.ptr;
234
+ teb->DeallocationStack = mem->stack0.ptr;
238
235
 
239
236
  #define PERFORM_CALL(Suffix) \
240
237
  ([&]() { \
@@ -337,20 +334,21 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool async,
337
334
  if (RG_UNLIKELY(env.IsExceptionPending()))
338
335
  return;
339
336
 
340
- void *teb = (void *)__readgsqword(0x30);
337
+ TEB *teb = GetTEB();
341
338
 
342
- RG_DEFER_C(base = TEB_STACK_BASE(teb),
343
- limit = TEB_STACK_LIMIT(teb),
344
- dealloc = TEB_DEALLOCATION_STACK(teb)) {
345
- TEB_STACK_BASE(teb) = base;
346
- TEB_STACK_LIMIT(teb) = limit;
347
- TEB_DEALLOCATION_STACK(teb) = dealloc;
339
+ // Restore previous stack limits at the end
340
+ RG_DEFER_C(base = teb->StackBase,
341
+ limit = teb->StackLimit,
342
+ dealloc = teb->DeallocationStack) {
343
+ teb->StackBase = base;
344
+ teb->StackLimit = limit;
345
+ teb->DeallocationStack = dealloc;
348
346
  };
349
347
 
350
- // Restore real thread stack limits
351
- TEB_STACK_BASE(teb) = instance->main_stack_max;
352
- TEB_STACK_LIMIT(teb) = instance->main_stack_min;
353
- TEB_DEALLOCATION_STACK(teb) = instance->main_stack_min;
348
+ // Adjust stack limits so SEH works correctly
349
+ teb->StackBase = instance->main_stack_max;
350
+ teb->StackLimit = instance->main_stack_min;
351
+ teb->DeallocationStack = instance->main_stack_min;
354
352
 
355
353
  const TrampolineInfo &trampoline = shared.trampolines[idx];
356
354
 
@@ -17,6 +17,9 @@
17
17
  #include "ffi.hh"
18
18
  #include "call.hh"
19
19
  #include "util.hh"
20
+ #ifdef _WIN32
21
+ #include "win32.hh"
22
+ #endif
20
23
 
21
24
  #include <napi.h>
22
25
 
@@ -46,12 +49,6 @@ extern "C" napi_value CallSwitchStack(Napi::Function *func, size_t argc, napi_va
46
49
 
47
50
  #include "abi_trampolines.inc"
48
51
 
49
- #ifdef _WIN32
50
- #define TEB_STACK_BASE(TEB) (*(void **)((uint8_t *)(TEB) + 0x04))
51
- #define TEB_STACK_LIMIT(TEB) (*(void **)((uint8_t *)(TEB) + 0x08))
52
- #define TEB_DEALLOCATION_STACK(TEB) (*(void **)((uint8_t *)(TEB) + 0xE0C))
53
- #endif
54
-
55
52
  bool AnalyseFunction(Napi::Env env, InstanceData *instance, FunctionInfo *func)
56
53
  {
57
54
  if (!func->lib && func->convention != CallConvention::Cdecl &&
@@ -304,21 +301,21 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
304
301
  void CallData::Execute(const FunctionInfo *func)
305
302
  {
306
303
  #ifdef _WIN32
307
- void *teb = (void *)__readfsdword(0x18);
308
-
309
- // Store current stack limits
310
- RG_DEFER_C(base = TEB_STACK_BASE(teb),
311
- limit = TEB_STACK_LIMIT(teb),
312
- dealloc = TEB_DEALLOCATION_STACK(teb)) {
313
- TEB_STACK_BASE(teb) = base;
314
- TEB_STACK_LIMIT(teb) = limit;
315
- TEB_DEALLOCATION_STACK(teb) = dealloc;
304
+ TEB *teb = GetTEB();
305
+
306
+ // Restore previous stack limits at the end
307
+ RG_DEFER_C(base = teb->StackBase,
308
+ limit = teb->StackLimit,
309
+ dealloc = teb->DeallocationStack) {
310
+ teb->StackBase = base;
311
+ teb->StackLimit = limit;
312
+ teb->DeallocationStack = dealloc;
316
313
  };
317
314
 
318
315
  // Adjust stack limits so SEH works correctly
319
- TEB_STACK_BASE(teb) = mem->stack0.end();
320
- TEB_STACK_LIMIT(teb) = mem->stack0.ptr;
321
- TEB_DEALLOCATION_STACK(teb) = mem->stack0.ptr;
316
+ teb->StackBase = mem->stack0.end();
317
+ teb->StackLimit = mem->stack0.ptr;
318
+ teb->DeallocationStack = mem->stack0.ptr;
322
319
  #endif
323
320
 
324
321
  #define PERFORM_CALL(Suffix) \
@@ -424,20 +421,21 @@ void CallData::Relay(Size idx, uint8_t *, uint8_t *caller_sp, bool async, BackRe
424
421
  return;
425
422
 
426
423
  #ifdef _WIN32
427
- void *teb = (void *)__readfsdword(0x18);
428
-
429
- RG_DEFER_C(base = TEB_STACK_BASE(teb),
430
- limit = TEB_STACK_LIMIT(teb),
431
- dealloc = TEB_DEALLOCATION_STACK(teb)) {
432
- TEB_STACK_BASE(teb) = base;
433
- TEB_STACK_LIMIT(teb) = limit;
434
- TEB_DEALLOCATION_STACK(teb) = dealloc;
424
+ TEB *teb = GetTEB();
425
+
426
+ // Restore previous stack limits at the end
427
+ RG_DEFER_C(base = teb->StackBase,
428
+ limit = teb->StackLimit,
429
+ dealloc = teb->DeallocationStack) {
430
+ teb->StackBase = base;
431
+ teb->StackLimit = limit;
432
+ teb->DeallocationStack = dealloc;
435
433
  };
436
434
 
437
- // Restore real thread stack limits
438
- TEB_STACK_BASE(teb) = instance->main_stack_max;
439
- TEB_STACK_LIMIT(teb) = instance->main_stack_min;
440
- TEB_DEALLOCATION_STACK(teb) = instance->main_stack_min;
435
+ // Adjust stack limits so SEH works correctly
436
+ teb->StackBase = instance->main_stack_max;
437
+ teb->StackLimit = instance->main_stack_min;
438
+ teb->DeallocationStack = instance->main_stack_min;
441
439
  #endif
442
440
 
443
441
  const TrampolineInfo &trampoline = shared.trampolines[idx];
@@ -16,6 +16,9 @@
16
16
  #include "call.hh"
17
17
  #include "parser.hh"
18
18
  #include "util.hh"
19
+ #ifdef _WIN32
20
+ #include "win32.hh"
21
+ #endif
19
22
 
20
23
  #ifdef _WIN32
21
24
  #ifndef NOMINMAX
@@ -1045,17 +1048,10 @@ static InstanceMemory *AllocateMemory(InstanceData *instance, Size stack_size, S
1045
1048
  FIBER_FLAG_FLOAT_SWITCH, [](void *udata) {
1046
1049
  FiberContext *ctx = (FiberContext *)udata;
1047
1050
 
1048
- // Handle initial call just below
1049
- #if defined(__aarch64__) || defined(_M_ARM64)
1050
- NT_TIB *tib = (NT_TIB *)__getReg(18);
1051
- #elif defined(__x86_64__) || defined(_M_AMD64)
1052
- NT_TIB *tib = (NT_TIB *)__readgsqword(0x30);
1053
- #else
1054
- NT_TIB *tib = (NT_TIB *)__readfsdword(0x18);
1055
- #endif
1051
+ TEB *teb = GetTEB();
1056
1052
 
1057
- ctx->mem->stack.ptr = (uint8_t *)tib->StackLimit;
1058
- ctx->mem->stack.len = (uint8_t *)tib->StackBase - ctx->mem->stack.ptr;
1053
+ ctx->mem->stack.ptr = (uint8_t *)teb->DeallocationStack;
1054
+ ctx->mem->stack.len = (uint8_t *)teb->StackBase - ctx->mem->stack.ptr;
1059
1055
 
1060
1056
  SwitchToFiber(ctx->self);
1061
1057
  }, &ctx);
@@ -1761,6 +1757,38 @@ InstanceMemory::~InstanceMemory()
1761
1757
  #endif
1762
1758
  }
1763
1759
 
1760
+ static InstanceData *CreateInstance(Napi::Env env)
1761
+ {
1762
+ InstanceData *instance = new InstanceData();
1763
+ RG_DEFER_N(err_guard) { delete instance; };
1764
+
1765
+ instance->main_thread_id = std::this_thread::get_id();
1766
+
1767
+ if (napi_create_threadsafe_function(env, nullptr, nullptr,
1768
+ Napi::String::New(env, "Koffi Async Callback Broker"),
1769
+ 0, 1, nullptr, nullptr, nullptr,
1770
+ CallData::RelayAsync, &instance->broker) != napi_ok) {
1771
+ LogError("Failed to create async callback broker");
1772
+ return nullptr;
1773
+ }
1774
+ napi_unref_threadsafe_function(env, instance->broker);
1775
+
1776
+ #if defined(_WIN32) && (defined(__x86_64__) || defined(_M_AMD64))
1777
+ void *teb = (void *)__readgsqword(0x30);
1778
+
1779
+ instance->main_stack_max = *(void **)((uint8_t *)teb + 0x08); // StackBase
1780
+ instance->main_stack_min = *(void **)((uint8_t *)teb + 0x1478); // DeallocationStack
1781
+ #elif defined(_WIN32) && (defined(__i386__) || defined(_M_IX86))
1782
+ void *teb = (void *)__readfsdword(0x18);
1783
+
1784
+ instance->main_stack_max = *(void **)((uint8_t *)teb + 0x04); // StackBase
1785
+ instance->main_stack_min = *(void **)((uint8_t *)teb + 0xE0C); // DeallocationStack
1786
+ #endif
1787
+
1788
+ err_guard.Disable();
1789
+ return instance;
1790
+ }
1791
+
1764
1792
  InstanceData::~InstanceData()
1765
1793
  {
1766
1794
  for (InstanceMemory *mem: memories) {
@@ -1970,38 +1998,6 @@ extern "C" void RelayCallback(Size idx, uint8_t *own_sp, uint8_t *caller_sp, Bac
1970
1998
  }
1971
1999
  }
1972
2000
 
1973
- static InstanceData *CreateInstance(Napi::Env env)
1974
- {
1975
- InstanceData *instance = new InstanceData();
1976
- RG_DEFER_N(err_guard) { delete instance; };
1977
-
1978
- instance->main_thread_id = std::this_thread::get_id();
1979
-
1980
- if (napi_create_threadsafe_function(env, nullptr, nullptr,
1981
- Napi::String::New(env, "Koffi Async Callback Broker"),
1982
- 0, 1, nullptr, nullptr, nullptr,
1983
- CallData::RelayAsync, &instance->broker) != napi_ok) {
1984
- LogError("Failed to create async callback broker");
1985
- return nullptr;
1986
- }
1987
- napi_unref_threadsafe_function(env, instance->broker);
1988
-
1989
- #if defined(_WIN32) && (defined(__x86_64__) || defined(_M_AMD64))
1990
- void *teb = (void *)__readgsqword(0x30);
1991
-
1992
- instance->main_stack_max = *(void **)((uint8_t *)teb + 0x08); // StackBase
1993
- instance->main_stack_min = *(void **)((uint8_t *)teb + 0x1478); // DeallocationStack
1994
- #elif defined(_WIN32) && (defined(__i386__) || defined(_M_IX86))
1995
- void *teb = (void *)__readfsdword(0x18);
1996
-
1997
- instance->main_stack_max = *(void **)((uint8_t *)teb + 0x04); // StackBase
1998
- instance->main_stack_min = *(void **)((uint8_t *)teb + 0xE0C); // DeallocationStack
1999
- #endif
2000
-
2001
- err_guard.Disable();
2002
- return instance;
2003
- }
2004
-
2005
2001
  template <typename Func>
2006
2002
  static void SetExports(Napi::Env env, Func func)
2007
2003
  {
@@ -0,0 +1,59 @@
1
+ // This program is free software: you can redistribute it and/or modify
2
+ // it under the terms of the GNU Affero General Public License as published by
3
+ // the Free Software Foundation, either version 3 of the License, or
4
+ // (at your option) any later version.
5
+ //
6
+ // This program is distributed in the hope that it will be useful,
7
+ // but WITHOUT ANY WARRANTY; without even the implied warranty of
8
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9
+ // GNU Affero General Public License for more details.
10
+ //
11
+ // You should have received a copy of the GNU Affero General Public License
12
+ // along with this program. If not, see https://www.gnu.org/licenses/.
13
+
14
+ #pragma once
15
+
16
+ #include "src/core/libcc/libcc.hh"
17
+
18
+ #include <intrin.h>
19
+
20
+ namespace RG {
21
+
22
+ #if _WIN64
23
+
24
+ struct TEB {
25
+ char _pad1[8];
26
+ void *StackBase;
27
+ void *StackLimit;
28
+ char _pad2[5216];
29
+ void *DeallocationStack;
30
+ };
31
+ RG_STATIC_ASSERT(RG_OFFSET_OF(TEB, DeallocationStack) == 0x1478);
32
+
33
+ #else
34
+
35
+ struct TEB {
36
+ char _pad1[4];
37
+ void *StackBase;
38
+ void *StackLimit;
39
+ char _pad2[3584];
40
+ void *DeallocationStack;
41
+ };
42
+ RG_STATIC_ASSERT(RG_OFFSET_OF(TEB, DeallocationStack) == 0xE0C);
43
+
44
+ #endif
45
+
46
+ static inline TEB *GetTEB()
47
+ {
48
+ #if defined(__aarch64__) || defined(_M_ARM64)
49
+ TEB *teb = (TEB *)__getReg(18);
50
+ #elif defined(__x86_64__) || defined(_M_AMD64)
51
+ TEB *teb = (TEB *)__readgsqword(0x30);
52
+ #else
53
+ TEB *teb = (TEB *)__readfsdword(0x18);
54
+ #endif
55
+
56
+ return teb;
57
+ }
58
+
59
+ }