koffi 2.15.0 → 2.16.0-beta.1

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 (69) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/build/koffi/darwin_arm64/koffi.node +0 -0
  3. package/build/koffi/darwin_x64/koffi.node +0 -0
  4. package/build/koffi/freebsd_arm64/koffi.node +0 -0
  5. package/build/koffi/freebsd_ia32/koffi.node +0 -0
  6. package/build/koffi/freebsd_x64/koffi.node +0 -0
  7. package/build/koffi/linux_arm64/koffi.node +0 -0
  8. package/build/koffi/linux_armhf/koffi.node +0 -0
  9. package/build/koffi/linux_ia32/koffi.node +0 -0
  10. package/build/koffi/linux_loong64/koffi.node +0 -0
  11. package/build/koffi/linux_riscv64d/koffi.node +0 -0
  12. package/build/koffi/linux_x64/koffi.node +0 -0
  13. package/build/koffi/musl_arm64/koffi.node +0 -0
  14. package/build/koffi/musl_x64/koffi.node +0 -0
  15. package/build/koffi/openbsd_ia32/koffi.node +0 -0
  16. package/build/koffi/openbsd_x64/koffi.node +0 -0
  17. package/build/koffi/win32_arm64/koffi.node +0 -0
  18. package/build/koffi/win32_ia32/koffi.node +0 -0
  19. package/build/koffi/win32_x64/koffi.node +0 -0
  20. package/doc/pages/index.md +4 -2
  21. package/doc/pages/misc.md +2 -0
  22. package/doc/templates/code.html +1 -2
  23. package/doc/templates/page.html +1 -2
  24. package/index.d.ts +11 -9
  25. package/index.js +9 -9
  26. package/indirect.js +9 -9
  27. package/lib/native/base/base.cc +79 -44
  28. package/lib/native/base/base.hh +31 -33
  29. package/package.json +2 -2
  30. package/src/cnoke/assets/FindCNoke.cmake +16 -10
  31. package/src/cnoke/assets/win_delay_hook.c +4 -0
  32. package/src/cnoke/src/builder.js +49 -46
  33. package/src/koffi/CMakeLists.txt +18 -8
  34. package/src/koffi/src/abi_arm32.cc +222 -219
  35. package/src/koffi/src/abi_arm32_asm.S +1 -29
  36. package/src/koffi/src/abi_arm64.cc +257 -235
  37. package/src/koffi/src/abi_arm64_asm.S +1 -32
  38. package/src/koffi/src/abi_arm64_asm.asm +1 -23
  39. package/src/koffi/src/abi_loong64_asm.S +1 -25
  40. package/src/koffi/src/abi_riscv64.cc +220 -217
  41. package/src/koffi/src/abi_riscv64_asm.S +1 -25
  42. package/src/koffi/src/abi_x64_sysv.cc +196 -192
  43. package/src/koffi/src/abi_x64_sysv_asm.S +1 -31
  44. package/src/koffi/src/abi_x64_win.cc +188 -172
  45. package/src/koffi/src/abi_x64_win_asm.S +144 -0
  46. package/src/koffi/src/abi_x64_win_asm.asm +1 -21
  47. package/src/koffi/src/abi_x86.cc +224 -189
  48. package/src/koffi/src/abi_x86_asm.S +6 -25
  49. package/src/koffi/src/abi_x86_asm.asm +9 -22
  50. package/src/koffi/src/call.cc +246 -428
  51. package/src/koffi/src/call.hh +9 -8
  52. package/src/koffi/src/ffi.cc +142 -88
  53. package/src/koffi/src/ffi.hh +13 -59
  54. package/src/koffi/src/primitives.inc +39 -0
  55. package/src/koffi/src/trampolines/armasm.inc +0 -32770
  56. package/src/koffi/src/trampolines/gnu.inc +0 -24578
  57. package/src/koffi/src/trampolines/masm32.inc +0 -32770
  58. package/src/koffi/src/trampolines/masm64.inc +0 -32770
  59. package/src/koffi/src/trampolines/prototypes.inc +16385 -16385
  60. package/src/koffi/src/util.cc +155 -112
  61. package/src/koffi/src/util.hh +77 -40
  62. package/vendor/node-api-headers/CHANGELOG.md +22 -0
  63. package/vendor/node-api-headers/README.md +6 -17
  64. package/vendor/node-api-headers/include/js_native_api.h +3 -13
  65. package/vendor/node-api-headers/include/js_native_api_types.h +15 -0
  66. package/vendor/node-api-headers/include/node_api.h +0 -4
  67. package/vendor/node-api-headers/include/node_api_types.h +6 -0
  68. package/vendor/node-api-headers/package.json +1 -1
  69. package/vendor/node-api-headers/scripts/update-headers.js +6 -0
package/CHANGELOG.md CHANGED
@@ -7,6 +7,13 @@
7
7
 
8
8
  ### Koffi 2.15
9
9
 
10
+ #### Koffi 2.15.1
11
+
12
+ *Released on 2025-01-24*
13
+
14
+ - Fix possible union-related crashes
15
+ - Support MinGW-w64 x64 builds on Windows
16
+
10
17
  #### Koffi 2.15.0
11
18
 
12
19
  *Released on 2025-12-21*
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
@@ -9,8 +9,10 @@ Koffi is a **fast and easy-to-use C FFI module for Node.js**, featuring:
9
9
 
10
10
  If you like this project, consider supporting me:
11
11
 
12
- <p style="display: flex; gap: 2em; justify-content: center;">
13
- <a href="https://buymeacoffee.com/koromix" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/default-orange.png" alt="Buy Me A Coffee" height="41" width="174" style="border-radius: 12px;"></a>
12
+ <p style="display: flex; gap: 1em; justify-content: center; align-items: center;">
13
+ <a href="https://liberapay.com/Koromix/donate" target="_blank"><img alt="Donate using Liberapay" src="https://liberapay.com/assets/widgets/donate.svg"></a>
14
+ <a href="https://github.com/sponsors/koromix" target="_blank"><img src="https://img.shields.io/static/v1?label=Sponsor&message=%E2%9D%A4&logo=GitHub&color=%23fe8e86"></a>
15
+ <a href="https://buymeacoffee.com/koromix" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/default-yellow.png" alt="Buy Me A Coffee" height="30" width="108" style="border-radius: 12px;"></a>
14
16
  </p>
15
17
 
16
18
  Koffi requires [Node.js](https://nodejs.org/) version 16 or later. Use [NVM](https://github.com/nvm-sh/nvm) to install more recent Node versions on older Linux distributions.
package/doc/pages/misc.md CHANGED
@@ -123,6 +123,8 @@ Async calls run on worker threads, the number of which depends on the number of
123
123
 
124
124
  ## Default settings
125
125
 
126
+ *Changed in Koffi 2.15*
127
+
126
128
  Setting | Default | Maximum | Description
127
129
  -------------------- | ------- | ------- | ----------------------------------------------------
128
130
  sync_stack_size | 1 MiB | 16 MiB | Stack size for synchronous calls
@@ -17,9 +17,8 @@
17
17
  </head>
18
18
 
19
19
  <body>
20
- <div id="deploy"></div>
21
-
22
20
  <nav id="top">
21
+ <div class="deploy"></div>
23
22
  <menu>
24
23
  <a id="logo" href="/"><img src="{{ ASSET static/logo.webp }}" width="370" height="198" alt="" /></a>
25
24
 
@@ -16,9 +16,8 @@
16
16
  </head>
17
17
 
18
18
  <body>
19
- <div id="deploy"></div>
20
-
21
19
  <nav id="top">
20
+ <div class="deploy"></div>
22
21
  <menu>
23
22
  <a id="logo" href="/"><img src="{{ ASSET static/logo.webp }}" width="370" height="198" alt="" /></a>
24
23
 
package/index.d.ts CHANGED
@@ -145,13 +145,15 @@ export function introspect(type: TypeSpec): TypeInfo;
145
145
  export function alias(name: string, type: TypeSpec): IKoffiCType;
146
146
 
147
147
  type KoffiConfig = {
148
- sync_stack_size: number
149
- sync_heap_size: number
150
- async_stack_size: number
151
- async_heap_size: number
152
- resident_async_pools: number
153
- max_async_calls: number
154
- max_type_size: number
148
+ sync_stack_size?: number;
149
+ sync_heap_size?: number;
150
+ async_stack_size?: number;
151
+ async_heap_size?: number;
152
+ resident_async_pools?: number;
153
+ max_async_calls?: number;
154
+ max_type_size?: number;
155
+ fast_pointers?: boolean;
156
+ fast_callbacks?: boolean;
155
157
  };
156
158
  type KoffiStats = {
157
159
  disposed: number
@@ -169,8 +171,8 @@ export function errno(value: number): number;
169
171
 
170
172
  export function reset(): void;
171
173
 
172
- export const internal: Boolean;
173
- export const extension: String;
174
+ export const internal: boolean;
175
+ export const extension: string;
174
176
 
175
177
  export const os: {
176
178
  errno: Record<string, number>
package/index.js CHANGED
@@ -4,9 +4,9 @@ var __commonJS = (cb, mod3) => function __require() {
4
4
  return mod3 || (0, cb[__getOwnPropNames(cb)[0]])((mod3 = { exports: {} }).exports, mod3), mod3.exports;
5
5
  };
6
6
 
7
- // bin/Koffi/package/src/cnoke/src/tools.js
7
+ // ../../bin/Koffi/package/src/cnoke/src/tools.js
8
8
  var require_tools = __commonJS({
9
- "bin/Koffi/package/src/cnoke/src/tools.js"(exports2, module2) {
9
+ "../../bin/Koffi/package/src/cnoke/src/tools.js"(exports2, module2) {
10
10
  "use strict";
11
11
  var crypto = require("crypto");
12
12
  var fs2 = require("fs");
@@ -397,12 +397,12 @@ var require_tools = __commonJS({
397
397
  }
398
398
  });
399
399
 
400
- // bin/Koffi/package/src/koffi/package.json
400
+ // ../../bin/Koffi/package/src/koffi/package.json
401
401
  var require_package = __commonJS({
402
- "bin/Koffi/package/src/koffi/package.json"(exports2, module2) {
402
+ "../../bin/Koffi/package/src/koffi/package.json"(exports2, module2) {
403
403
  module2.exports = {
404
404
  name: "koffi",
405
- version: "2.15.0",
405
+ version: "2.16.0-beta.1",
406
406
  description: "Fast and simple C FFI (foreign function interface) for Node.js",
407
407
  keywords: [
408
408
  "foreign",
@@ -439,14 +439,14 @@ var require_package = __commonJS({
439
439
  napi: 8,
440
440
  require: "./index.js"
441
441
  },
442
- funding: "https://buymeacoffee.com/koromix"
442
+ funding: "https://liberapay.com/Koromix"
443
443
  };
444
444
  }
445
445
  });
446
446
 
447
- // bin/Koffi/package/src/koffi/src/init.js
447
+ // ../../bin/Koffi/package/src/koffi/src/init.js
448
448
  var require_init = __commonJS({
449
- "bin/Koffi/package/src/koffi/src/init.js"(exports, module) {
449
+ "../../bin/Koffi/package/src/koffi/src/init.js"(exports, module) {
450
450
  var fs = require("fs");
451
451
  var path = require("path");
452
452
  var util = require("util");
@@ -529,7 +529,7 @@ var require_init = __commonJS({
529
529
  }
530
530
  });
531
531
 
532
- // bin/Koffi/package/src/koffi/index.js
532
+ // ../../bin/Koffi/package/src/koffi/index.js
533
533
  var { detect: detect2, init: init2 } = require_init();
534
534
  var triplet2 = detect2();
535
535
  var native2 = null;
package/indirect.js CHANGED
@@ -4,9 +4,9 @@ var __commonJS = (cb, mod3) => function __require() {
4
4
  return mod3 || (0, cb[__getOwnPropNames(cb)[0]])((mod3 = { exports: {} }).exports, mod3), mod3.exports;
5
5
  };
6
6
 
7
- // bin/Koffi/package/src/cnoke/src/tools.js
7
+ // ../../bin/Koffi/package/src/cnoke/src/tools.js
8
8
  var require_tools = __commonJS({
9
- "bin/Koffi/package/src/cnoke/src/tools.js"(exports2, module2) {
9
+ "../../bin/Koffi/package/src/cnoke/src/tools.js"(exports2, module2) {
10
10
  "use strict";
11
11
  var crypto = require("crypto");
12
12
  var fs2 = require("fs");
@@ -397,12 +397,12 @@ var require_tools = __commonJS({
397
397
  }
398
398
  });
399
399
 
400
- // bin/Koffi/package/src/koffi/package.json
400
+ // ../../bin/Koffi/package/src/koffi/package.json
401
401
  var require_package = __commonJS({
402
- "bin/Koffi/package/src/koffi/package.json"(exports2, module2) {
402
+ "../../bin/Koffi/package/src/koffi/package.json"(exports2, module2) {
403
403
  module2.exports = {
404
404
  name: "koffi",
405
- version: "2.15.0",
405
+ version: "2.16.0-beta.1",
406
406
  description: "Fast and simple C FFI (foreign function interface) for Node.js",
407
407
  keywords: [
408
408
  "foreign",
@@ -439,14 +439,14 @@ var require_package = __commonJS({
439
439
  napi: 8,
440
440
  require: "./index.js"
441
441
  },
442
- funding: "https://buymeacoffee.com/koromix"
442
+ funding: "https://liberapay.com/Koromix"
443
443
  };
444
444
  }
445
445
  });
446
446
 
447
- // bin/Koffi/package/src/koffi/src/init.js
447
+ // ../../bin/Koffi/package/src/koffi/src/init.js
448
448
  var require_init = __commonJS({
449
- "bin/Koffi/package/src/koffi/src/init.js"(exports, module) {
449
+ "../../bin/Koffi/package/src/koffi/src/init.js"(exports, module) {
450
450
  var fs = require("fs");
451
451
  var path = require("path");
452
452
  var util = require("util");
@@ -529,7 +529,7 @@ var require_init = __commonJS({
529
529
  }
530
530
  });
531
531
 
532
- // bin/Koffi/package/src/koffi/indirect.js
532
+ // ../../bin/Koffi/package/src/koffi/indirect.js
533
533
  var { detect: detect2, init: init2 } = require_init();
534
534
  var triplet2 = detect2();
535
535
  var mod2 = init2(triplet2, null);
@@ -750,25 +750,6 @@ int64_t GetUnixTime()
750
750
  #endif
751
751
  }
752
752
 
753
- int64_t GetMonotonicTime()
754
- {
755
- #if defined(_WIN32)
756
- return (int64_t)GetTickCount64();
757
- #elif defined(__EMSCRIPTEN__)
758
- return (int64_t)emscripten_get_now();
759
- #elif defined(CLOCK_MONOTONIC_COARSE)
760
- struct timespec ts;
761
- K_CRITICAL(clock_gettime(CLOCK_MONOTONIC_COARSE, &ts) == 0, "clock_gettime(CLOCK_MONOTONIC_COARSE) failed: %1", strerror(errno));
762
-
763
- return (int64_t)ts.tv_sec * 1000 + (int64_t)ts.tv_nsec / 1000000;
764
- #else
765
- struct timespec ts;
766
- K_CRITICAL(clock_gettime(CLOCK_MONOTONIC, &ts) == 0, "clock_gettime(CLOCK_MONOTONIC) failed: %1", strerror(errno));
767
-
768
- return (int64_t)ts.tv_sec * 1000 + (int64_t)ts.tv_nsec / 1000000;
769
- #endif
770
- }
771
-
772
753
  TimeSpec DecomposeTimeUTC(int64_t time)
773
754
  {
774
755
  TimeSpec spec = {};
@@ -862,6 +843,39 @@ int64_t ComposeTimeUTC(const TimeSpec &spec)
862
843
  return time;
863
844
  }
864
845
 
846
+ // ------------------------------------------------------------------------
847
+ // Clock
848
+ // ------------------------------------------------------------------------
849
+
850
+ int64_t GetMonotonicClock()
851
+ {
852
+ static std::atomic_int64_t memory;
853
+
854
+ #if defined(_WIN32)
855
+ int64_t clock = (int64_t)GetTickCount64();
856
+ #elif defined(__EMSCRIPTEN__)
857
+ int64_t clock = emscripten_get_now();
858
+ #elif defined(CLOCK_MONOTONIC_COARSE)
859
+ struct timespec ts;
860
+ K_CRITICAL(clock_gettime(CLOCK_MONOTONIC_COARSE, &ts) == 0, "clock_gettime(CLOCK_MONOTONIC_COARSE) failed: %1", strerror(errno));
861
+
862
+ int64_t clock = (int64_t)ts.tv_sec * 1000 + (int64_t)ts.tv_nsec / 1000000;
863
+ #else
864
+ struct timespec ts;
865
+ K_CRITICAL(clock_gettime(CLOCK_MONOTONIC, &ts) == 0, "clock_gettime(CLOCK_MONOTONIC) failed: %1", strerror(errno));
866
+
867
+ int64_t clock = (int64_t)ts.tv_sec * 1000 + (int64_t)ts.tv_nsec / 1000000;
868
+ #endif
869
+
870
+ // Protect against clock going backwards
871
+ int64_t prev = memory.load(std::memory_order_relaxed);
872
+ if (clock < prev) [[unlikely]]
873
+ return prev;
874
+ memory.compare_exchange_weak(prev, clock, std::memory_order_relaxed, std::memory_order_relaxed);
875
+
876
+ return clock;
877
+ }
878
+
865
879
  // ------------------------------------------------------------------------
866
880
  // Strings
867
881
  // ------------------------------------------------------------------------
@@ -2031,7 +2045,7 @@ FmtArg FmtVersion(int64_t version, int parts, int by)
2031
2045
  // Debug and errors
2032
2046
  // ------------------------------------------------------------------------
2033
2047
 
2034
- static int64_t start_time = GetMonotonicTime();
2048
+ static int64_t start_clock = GetMonotonicClock();
2035
2049
 
2036
2050
  static std::function<LogFunc> log_handler = DefaultLogHandler;
2037
2051
  static bool log_vt100 = FileIsVt100(STDERR_FILENO);
@@ -2130,7 +2144,7 @@ void LogFmt(LogLevel level, const char *ctx, const char *fmt, Span<const FmtArg>
2130
2144
 
2131
2145
  char ctx_buf[512];
2132
2146
  if (log_times) {
2133
- double time = (double)(GetMonotonicTime() - start_time) / 1000;
2147
+ double time = (double)(GetMonotonicClock() - start_clock) / 1000;
2134
2148
  Fmt(ctx_buf, "[%1] %2", FmtDouble(time, 3, 8), ctx ? ctx : "");
2135
2149
 
2136
2150
  ctx = ctx_buf;
@@ -5565,7 +5579,7 @@ bool ExecuteCommandLine(const char *cmd_line, const ExecuteInfo &info,
5565
5579
  // Wait for process exit
5566
5580
  int status;
5567
5581
  {
5568
- int64_t start = GetMonotonicTime();
5582
+ int64_t start = GetMonotonicClock();
5569
5583
 
5570
5584
  for (;;) {
5571
5585
  int ret = K_RESTART_EINTR(waitpid(pid, &status, terminate ? WNOHANG : 0), < 0);
@@ -5574,7 +5588,7 @@ bool ExecuteCommandLine(const char *cmd_line, const ExecuteInfo &info,
5574
5588
  LogError("Failed to wait for process exit: %1", strerror(errno));
5575
5589
  return false;
5576
5590
  } else if (!ret) {
5577
- int64_t delay = GetMonotonicTime() - start;
5591
+ int64_t delay = GetMonotonicClock() - start;
5578
5592
 
5579
5593
  if (delay < 2000) {
5580
5594
  // A timeout on waitpid would be better, but... sigh
@@ -5837,7 +5851,7 @@ WaitResult WaitEvents(Span<const WaitSource> sources, int64_t timeout, uint64_t
5837
5851
  InitInterruptPipe();
5838
5852
  pfds.Append({ interrupt_pfd[0], POLLIN, 0 });
5839
5853
 
5840
- int64_t start = (timeout >= 0) ? GetMonotonicTime() : 0;
5854
+ int64_t start = (timeout >= 0) ? GetMonotonicClock() : 0;
5841
5855
  int64_t until = start + timeout;
5842
5856
  int timeout32 = (int)std::min(until - start, (int64_t)INT_MAX);
5843
5857
 
@@ -5874,10 +5888,10 @@ WaitResult WaitEvents(Span<const WaitSource> sources, int64_t timeout, uint64_t
5874
5888
  }
5875
5889
 
5876
5890
  if (timeout >= 0) {
5877
- int64_t now = GetMonotonicTime();
5878
- if (now >= until)
5891
+ int64_t clock = GetMonotonicClock();
5892
+ if (clock >= until)
5879
5893
  break;
5880
- timeout32 = (int)std::min(until - now, (int64_t)INT_MAX);
5894
+ timeout32 = (int)std::min(until - clock, (int64_t)INT_MAX);
5881
5895
  }
5882
5896
  }
5883
5897
 
@@ -6741,7 +6755,7 @@ bool ParseVersion(Span<const char> str, int parts, int multiplier,
6741
6755
  // ------------------------------------------------------------------------
6742
6756
 
6743
6757
  static thread_local Size rnd_remain;
6744
- static thread_local int64_t rnd_time;
6758
+ static thread_local int64_t rnd_clock;
6745
6759
  #if !defined(_WIN32)
6746
6760
  static thread_local pid_t rnd_pid;
6747
6761
  #endif
@@ -6854,7 +6868,7 @@ void FillRandomSafe(void *out_buf, Size len)
6854
6868
 
6855
6869
  // Reseed every 4 megabytes, or every hour, or after a fork
6856
6870
  reseed |= (rnd_remain <= 0);
6857
- reseed |= (GetMonotonicTime() - rnd_time > 3600 * 1000);
6871
+ reseed |= (GetMonotonicClock() - rnd_clock > 3600 * 1000);
6858
6872
  #if !defined(_WIN32)
6859
6873
  reseed |= (getpid() != rnd_pid);
6860
6874
  #endif
@@ -6882,7 +6896,7 @@ restart:
6882
6896
  ZeroSafe(&buf, K_SIZE(buf));
6883
6897
 
6884
6898
  rnd_remain = Mebibytes(4);
6885
- rnd_time = GetMonotonicTime();
6899
+ rnd_clock = GetMonotonicClock();
6886
6900
  #if !defined(_WIN32)
6887
6901
  rnd_pid = getpid();
6888
6902
  #endif
@@ -9265,12 +9279,14 @@ static HeapArray<TranslationTable> i18n_tables;
9265
9279
  static NoDestroy<HeapArray<TranslationMap>> i18n_maps;
9266
9280
  static HashMap<Span<const char> , const TranslationTable *> i18n_locales;
9267
9281
 
9268
- static const TranslationMap *i18n_default;
9269
- static thread_local const TranslationMap *i18n_thread = i18n_default;
9282
+ static const TranslationTable *i18n_default_table;
9283
+ static const TranslationMap *i18n_default_map;
9284
+ static thread_local const TranslationTable *i18n_thread_table = i18n_default_table;
9285
+ static thread_local const TranslationMap *i18n_thread_map = i18n_default_map;
9270
9286
 
9271
- static void SetDefaultLocale()
9287
+ static void SetDefaultLocale(const char *default_lang)
9272
9288
  {
9273
- if (i18n_default)
9289
+ if (i18n_default_table)
9274
9290
  return;
9275
9291
 
9276
9292
  // Obey environment settings, even on Windows, for easy override
@@ -9283,9 +9299,11 @@ static void SetDefaultLocale()
9283
9299
 
9284
9300
  if (env) {
9285
9301
  ChangeThreadLocale(env);
9286
- i18n_default = i18n_thread;
9287
9302
 
9288
- if (i18n_default)
9303
+ i18n_default_table = i18n_thread_table;
9304
+ i18n_default_map = i18n_thread_map;
9305
+
9306
+ if (i18n_default_table)
9289
9307
  return;
9290
9308
  }
9291
9309
  }
@@ -9303,9 +9321,11 @@ static void SetDefaultLocale()
9303
9321
  ConvertWin32WideToUtf8(buffer, lang);
9304
9322
 
9305
9323
  ChangeThreadLocale(lang);
9306
- i18n_default = i18n_thread;
9307
9324
 
9308
- if (i18n_default)
9325
+ i18n_default_table = i18n_thread_table;
9326
+ i18n_default_map = i18n_thread_map;
9327
+
9328
+ if (i18n_default_table)
9309
9329
  return;
9310
9330
  }
9311
9331
  } else {
@@ -9313,9 +9333,15 @@ static void SetDefaultLocale()
9313
9333
  }
9314
9334
  }
9315
9335
  #endif
9336
+
9337
+ ChangeThreadLocale(default_lang);
9338
+ K_CRITICAL(i18n_thread_table, "Missing default locale");
9339
+
9340
+ i18n_default_table = i18n_thread_table;
9341
+ i18n_default_map = i18n_thread_map;
9316
9342
  }
9317
9343
 
9318
- void InitLocales(Span<const TranslationTable> tables)
9344
+ void InitLocales(Span<const TranslationTable> tables, const char *default_lang)
9319
9345
  {
9320
9346
  K_ASSERT(!i18n_tables.len);
9321
9347
 
@@ -9332,7 +9358,7 @@ void InitLocales(Span<const TranslationTable> tables)
9332
9358
  i18n_locales.Set(table.language, &table);
9333
9359
  }
9334
9360
 
9335
- SetDefaultLocale();
9361
+ SetDefaultLocale(default_lang);
9336
9362
  }
9337
9363
 
9338
9364
  void ChangeThreadLocale(const char *name)
@@ -9342,18 +9368,27 @@ void ChangeThreadLocale(const char *name)
9342
9368
 
9343
9369
  if (table) {
9344
9370
  Size idx = table - i18n_tables.ptr;
9345
- i18n_thread = &(*i18n_maps)[idx];
9371
+
9372
+ i18n_thread_table = table;
9373
+ i18n_thread_map = &(*i18n_maps)[idx];
9346
9374
  } else {
9347
- i18n_thread = i18n_default;
9375
+ i18n_thread_table = i18n_default_table;
9376
+ i18n_thread_map = i18n_default_map;
9348
9377
  }
9349
9378
  }
9350
9379
 
9380
+ const char *GetThreadLocale()
9381
+ {
9382
+ K_ASSERT(i18n_thread_table);
9383
+ return i18n_thread_table->language;
9384
+ }
9385
+
9351
9386
  const char *T(const char *key)
9352
9387
  {
9353
- if (!i18n_thread)
9388
+ if (!i18n_thread_map)
9354
9389
  return key;
9355
9390
 
9356
- return i18n_thread->FindValue(key, key);
9391
+ return i18n_thread_map->FindValue(key, key);
9357
9392
  }
9358
9393
 
9359
9394
  // ------------------------------------------------------------------------
@@ -1388,7 +1388,7 @@ static constexpr inline bool IsAsciiWhite(int c)
1388
1388
  }
1389
1389
  static constexpr inline bool IsAsciiControl(int c)
1390
1390
  {
1391
- return c == 0x7F || (c < ' ' && c != '\t');
1391
+ return c == 0x7F || ((uint8_t)c < ' ' && c != '\t');
1392
1392
  }
1393
1393
 
1394
1394
  static constexpr inline char UpperAscii(int c)
@@ -3395,7 +3395,7 @@ public:
3395
3395
 
3396
3396
  constexpr ConstMap(std::initializer_list<Bucket> l)
3397
3397
  {
3398
- K_CRITICAL(l.size() <= N, "ConstMap<%1> cannot be store %2 values", N, l.size());
3398
+ K_CRITICAL(l.size() <= N, "ConstMap<%1> cannot store %2 values", N, l.size());
3399
3399
 
3400
3400
  for (const Bucket &it: l) {
3401
3401
  Bucket *bucket = Insert(it.key);
@@ -3404,14 +3404,6 @@ public:
3404
3404
  bucket->value = it.value;
3405
3405
  }
3406
3406
  }
3407
- ~ConstMap()
3408
- {
3409
- if constexpr(!std::is_trivial<ValueType>::value) {
3410
- for (Size i = 0; i < N; i++) {
3411
- data[i].~ValueType();
3412
- }
3413
- }
3414
- }
3415
3407
 
3416
3408
  template <typename T = KeyType>
3417
3409
  ValueType *Find(const T &key)
@@ -3587,15 +3579,36 @@ union LocalDate {
3587
3579
  // ------------------------------------------------------------------------
3588
3580
 
3589
3581
  int64_t GetUnixTime();
3590
- int64_t GetMonotonicTime();
3582
+
3583
+ struct TimeSpec {
3584
+ int16_t year;
3585
+ int8_t month;
3586
+ int8_t day;
3587
+ int8_t week_day; // 1 (monday) to 7 (sunday)
3588
+
3589
+ int8_t hour;
3590
+ int8_t min;
3591
+ int8_t sec;
3592
+ int16_t msec;
3593
+
3594
+ int16_t offset; // minutes
3595
+ };
3596
+
3597
+ TimeSpec DecomposeTimeUTC(int64_t time);
3598
+ TimeSpec DecomposeTimeLocal(int64_t time);
3599
+ int64_t ComposeTimeUTC(const TimeSpec &spec);
3600
+
3601
+ // ------------------------------------------------------------------------
3602
+ // Clock
3603
+ // ------------------------------------------------------------------------
3591
3604
 
3592
3605
  #if defined(_MSC_VER) && !defined(_M_ARM64)
3593
- static inline int64_t GetClockCounter()
3606
+ static inline int64_t GetCoreCycles()
3594
3607
  {
3595
3608
  return (int64_t)__rdtsc();
3596
3609
  }
3597
3610
  #elif defined(__i386__) || defined(__x86_64__)
3598
- static inline int64_t GetClockCounter()
3611
+ static inline int64_t GetCoreCycles()
3599
3612
  {
3600
3613
  uint32_t counter_low, counter_high;
3601
3614
  __asm__ __volatile__ ("cpuid; rdtsc"
@@ -3605,7 +3618,7 @@ static inline int64_t GetClockCounter()
3605
3618
  return counter;
3606
3619
  }
3607
3620
  #elif defined(__aarch64__)
3608
- static inline int64_t GetClockCounter()
3621
+ static inline int64_t GetCoreCycles()
3609
3622
  {
3610
3623
  uint64_t counter;
3611
3624
  __asm__ __volatile__ ("mrs %0, cntvct_el0" : "=r" (counter));
@@ -3613,23 +3626,7 @@ static inline int64_t GetClockCounter()
3613
3626
  }
3614
3627
  #endif
3615
3628
 
3616
- struct TimeSpec {
3617
- int16_t year;
3618
- int8_t month;
3619
- int8_t day;
3620
- int8_t week_day; // 1 (monday) to 7 (sunday)
3621
-
3622
- int8_t hour;
3623
- int8_t min;
3624
- int8_t sec;
3625
- int16_t msec;
3626
-
3627
- int16_t offset; // minutes
3628
- };
3629
-
3630
- TimeSpec DecomposeTimeUTC(int64_t time);
3631
- TimeSpec DecomposeTimeLocal(int64_t time);
3632
- int64_t ComposeTimeUTC(const TimeSpec &spec);
3629
+ int64_t GetMonotonicClock();
3633
3630
 
3634
3631
  // ------------------------------------------------------------------------
3635
3632
  // Format
@@ -5572,10 +5569,11 @@ struct TranslationTable {
5572
5569
 
5573
5570
  extern "C" const Span<const TranslationTable> TranslationTables;
5574
5571
 
5575
- void InitLocales(Span<const TranslationTable> tables);
5572
+ void InitLocales(Span<const TranslationTable> tables, const char *default_lang);
5576
5573
 
5577
- // Resets the localgale to the process default if lang is NULL or is unknown
5574
+ // Resets the locale to the process default if lang is NULL or is unknown
5578
5575
  void ChangeThreadLocale(const char *name);
5576
+ const char *GetThreadLocale();
5579
5577
 
5580
5578
  // ------------------------------------------------------------------------
5581
5579
  // Options
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "koffi",
3
- "version": "2.15.0",
3
+ "version": "2.16.0-beta.1",
4
4
  "description": "Fast and simple C FFI (foreign function interface) for Node.js",
5
5
  "keywords": [
6
6
  "foreign",
@@ -34,5 +34,5 @@
34
34
  "napi": 8,
35
35
  "require": "./index.js"
36
36
  },
37
- "funding": "https://buymeacoffee.com/koromix"
37
+ "funding": "https://liberapay.com/Koromix"
38
38
  }