koffi 2.15.0 → 2.15.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.
- package/CHANGELOG.md +7 -0
- package/build/koffi/darwin_arm64/koffi.node +0 -0
- package/build/koffi/darwin_x64/koffi.node +0 -0
- package/build/koffi/freebsd_arm64/koffi.node +0 -0
- package/build/koffi/freebsd_ia32/koffi.node +0 -0
- package/build/koffi/freebsd_x64/koffi.node +0 -0
- package/build/koffi/linux_arm64/koffi.node +0 -0
- package/build/koffi/linux_armhf/koffi.node +0 -0
- package/build/koffi/linux_ia32/koffi.node +0 -0
- package/build/koffi/linux_loong64/koffi.node +0 -0
- package/build/koffi/linux_riscv64d/koffi.node +0 -0
- package/build/koffi/linux_x64/koffi.node +0 -0
- package/build/koffi/musl_arm64/koffi.node +0 -0
- package/build/koffi/musl_x64/koffi.node +0 -0
- package/build/koffi/openbsd_ia32/koffi.node +0 -0
- package/build/koffi/openbsd_x64/koffi.node +0 -0
- package/build/koffi/win32_arm64/koffi.node +0 -0
- package/build/koffi/win32_ia32/koffi.node +0 -0
- package/build/koffi/win32_x64/koffi.node +0 -0
- package/doc/pages/index.md +4 -2
- package/doc/pages/misc.md +2 -0
- package/doc/templates/code.html +1 -2
- package/doc/templates/page.html +1 -2
- package/index.js +2 -2
- package/indirect.js +2 -2
- package/lib/native/base/base.cc +79 -44
- package/lib/native/base/base.hh +31 -33
- package/package.json +2 -2
- package/src/cnoke/assets/FindCNoke.cmake +16 -10
- package/src/cnoke/assets/win_delay_hook.c +4 -0
- package/src/cnoke/src/builder.js +49 -46
- package/src/koffi/CMakeLists.txt +18 -8
- package/src/koffi/src/abi_x64_win_asm.S +162 -0
- package/src/koffi/src/ffi.cc +2 -1
- package/src/koffi/src/ffi.hh +1 -1
- package/src/koffi/src/util.cc +6 -5
- package/src/koffi/src/util.hh +2 -1
- package/vendor/node-api-headers/CHANGELOG.md +22 -0
- package/vendor/node-api-headers/README.md +6 -17
- package/vendor/node-api-headers/include/js_native_api.h +3 -13
- package/vendor/node-api-headers/include/js_native_api_types.h +15 -0
- package/vendor/node-api-headers/include/node_api.h +0 -4
- package/vendor/node-api-headers/include/node_api_types.h +6 -0
- package/vendor/node-api-headers/package.json +1 -1
- package/vendor/node-api-headers/scripts/update-headers.js +6 -0
package/CHANGELOG.md
CHANGED
|
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
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/doc/pages/index.md
CHANGED
|
@@ -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:
|
|
13
|
-
<a href="https://
|
|
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
|
package/doc/templates/code.html
CHANGED
package/doc/templates/page.html
CHANGED
package/index.js
CHANGED
|
@@ -402,7 +402,7 @@ var require_package = __commonJS({
|
|
|
402
402
|
"bin/Koffi/package/src/koffi/package.json"(exports2, module2) {
|
|
403
403
|
module2.exports = {
|
|
404
404
|
name: "koffi",
|
|
405
|
-
version: "2.15.
|
|
405
|
+
version: "2.15.1",
|
|
406
406
|
description: "Fast and simple C FFI (foreign function interface) for Node.js",
|
|
407
407
|
keywords: [
|
|
408
408
|
"foreign",
|
|
@@ -439,7 +439,7 @@ var require_package = __commonJS({
|
|
|
439
439
|
napi: 8,
|
|
440
440
|
require: "./index.js"
|
|
441
441
|
},
|
|
442
|
-
funding: "https://
|
|
442
|
+
funding: "https://liberapay.com/Koromix"
|
|
443
443
|
};
|
|
444
444
|
}
|
|
445
445
|
});
|
package/indirect.js
CHANGED
|
@@ -402,7 +402,7 @@ var require_package = __commonJS({
|
|
|
402
402
|
"bin/Koffi/package/src/koffi/package.json"(exports2, module2) {
|
|
403
403
|
module2.exports = {
|
|
404
404
|
name: "koffi",
|
|
405
|
-
version: "2.15.
|
|
405
|
+
version: "2.15.1",
|
|
406
406
|
description: "Fast and simple C FFI (foreign function interface) for Node.js",
|
|
407
407
|
keywords: [
|
|
408
408
|
"foreign",
|
|
@@ -439,7 +439,7 @@ var require_package = __commonJS({
|
|
|
439
439
|
napi: 8,
|
|
440
440
|
require: "./index.js"
|
|
441
441
|
},
|
|
442
|
-
funding: "https://
|
|
442
|
+
funding: "https://liberapay.com/Koromix"
|
|
443
443
|
};
|
|
444
444
|
}
|
|
445
445
|
});
|
package/lib/native/base/base.cc
CHANGED
|
@@ -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
|
|
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)(
|
|
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 =
|
|
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 =
|
|
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) ?
|
|
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
|
|
5878
|
-
if (
|
|
5891
|
+
int64_t clock = GetMonotonicClock();
|
|
5892
|
+
if (clock >= until)
|
|
5879
5893
|
break;
|
|
5880
|
-
timeout32 = (int)std::min(until -
|
|
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
|
|
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 |= (
|
|
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
|
-
|
|
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
|
|
9269
|
-
static
|
|
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 (
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
9371
|
+
|
|
9372
|
+
i18n_thread_table = table;
|
|
9373
|
+
i18n_thread_map = &(*i18n_maps)[idx];
|
|
9346
9374
|
} else {
|
|
9347
|
-
|
|
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 (!
|
|
9388
|
+
if (!i18n_thread_map)
|
|
9354
9389
|
return key;
|
|
9355
9390
|
|
|
9356
|
-
return
|
|
9391
|
+
return i18n_thread_map->FindValue(key, key);
|
|
9357
9392
|
}
|
|
9358
9393
|
|
|
9359
9394
|
// ------------------------------------------------------------------------
|
package/lib/native/base/base.hh
CHANGED
|
@@ -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
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
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.
|
|
3
|
+
"version": "2.15.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://
|
|
37
|
+
"funding": "https://liberapay.com/Koromix"
|
|
38
38
|
}
|
|
@@ -9,12 +9,19 @@ else()
|
|
|
9
9
|
endif()
|
|
10
10
|
|
|
11
11
|
if(NODE_JS_LINK_DEF)
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
12
|
+
set(NODE_JS_LINK_LIB "${CMAKE_CURRENT_BINARY_DIR}/node.lib")
|
|
13
|
+
if (MSVC)
|
|
14
|
+
add_custom_command(OUTPUT node.lib
|
|
15
|
+
COMMAND ${CMAKE_AR} ${CMAKE_STATIC_LINKER_FLAGS}
|
|
16
|
+
/def:${NODE_JS_LINK_DEF} /out:${NODE_JS_LINK_LIB}
|
|
17
|
+
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
|
18
|
+
MAIN_DEPENDENCY ${NODE_JS_LINK_DEF})
|
|
19
|
+
else()
|
|
20
|
+
add_custom_command(OUTPUT node.lib
|
|
21
|
+
COMMAND ${CMAKE_DLLTOOL} -d ${NODE_JS_LINK_DEF} -l ${NODE_JS_LINK_LIB}
|
|
22
|
+
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
|
23
|
+
MAIN_DEPENDENCY ${NODE_JS_LINK_DEF})
|
|
24
|
+
endif()
|
|
18
25
|
endif()
|
|
19
26
|
|
|
20
27
|
function(add_node_addon)
|
|
@@ -26,10 +33,10 @@ endfunction()
|
|
|
26
33
|
|
|
27
34
|
function(target_link_node TARGET)
|
|
28
35
|
target_include_directories(${TARGET} PRIVATE ${NODE_JS_INCLUDE_DIRS})
|
|
36
|
+
if(NODE_JS_LINK_DEF)
|
|
37
|
+
target_sources(${TARGET} PRIVATE node.lib)
|
|
38
|
+
endif()
|
|
29
39
|
if(NODE_JS_LINK_LIB)
|
|
30
|
-
if(TARGET node.lib)
|
|
31
|
-
add_dependencies(${TARGET} node.lib)
|
|
32
|
-
endif()
|
|
33
40
|
target_link_libraries(${TARGET} PRIVATE ${NODE_JS_LINK_LIB})
|
|
34
41
|
endif()
|
|
35
42
|
target_compile_options(${TARGET} PRIVATE ${NODE_JS_COMPILE_FLAGS})
|
|
@@ -100,7 +107,6 @@ else()
|
|
|
100
107
|
endif()
|
|
101
108
|
|
|
102
109
|
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
|
103
|
-
message(STATUS ${CMAKE_SYSTEM_PROCESSOR})
|
|
104
110
|
if(CMAKE_SYSTEM_PROCESSOR MATCHES "(amd64|x86_64)")
|
|
105
111
|
foreach(lang C CXX)
|
|
106
112
|
set(CMAKE_${lang}_FLAGS_RELEASE "${CMAKE_${lang}_FLAGS_RELEASE} -mpopcnt -msse4.1 -msse4.2 -mssse3 -mcx16")
|
package/src/cnoke/src/builder.js
CHANGED
|
@@ -106,44 +106,41 @@ function Builder(config = {}) {
|
|
|
106
106
|
args.push(`-DNODE_JS_INCLUDE_DIRS=${options.api}/include`);
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
-
|
|
110
|
-
if (process.platform == 'win32') {
|
|
111
|
-
if (options.api == null) {
|
|
112
|
-
let dirname;
|
|
113
|
-
switch (arch) {
|
|
114
|
-
case 'ia32': { dirname = 'win-x86'; } break;
|
|
115
|
-
case 'x64': { dirname = 'win-x64'; } break;
|
|
116
|
-
case 'arm64': { dirname = 'win-arm64'; } break;
|
|
117
|
-
|
|
118
|
-
default: {
|
|
119
|
-
throw new Error(`Unsupported architecture '${arch}' for Node on Windows`);
|
|
120
|
-
} break;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
let destname = `${cache_dir}/node_v${runtime_version}_${arch}.lib`;
|
|
124
|
-
|
|
125
|
-
if (!fs.existsSync(destname)) {
|
|
126
|
-
fs.mkdirSync(cache_dir, { recursive: true, mode: 0o755 });
|
|
109
|
+
args.push(`-DCMAKE_MODULE_PATH=${app_dir}/assets`);
|
|
127
110
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
111
|
+
let win32 = (process.platform == 'win32');
|
|
112
|
+
let msvc = (process.platform == 'win32' && process.env.MSYSTEM == null);
|
|
113
|
+
let darwin = (process.platform == 'darwin');
|
|
114
|
+
|
|
115
|
+
// Handle Node import library on Windows
|
|
116
|
+
if (win32) {
|
|
117
|
+
if (msvc) {
|
|
118
|
+
if (options.api == null) {
|
|
119
|
+
let dirname;
|
|
120
|
+
switch (arch) {
|
|
121
|
+
case 'ia32': { dirname = 'win-x86'; } break;
|
|
122
|
+
case 'x64': { dirname = 'win-x64'; } break;
|
|
123
|
+
case 'arm64': { dirname = 'win-arm64'; } break;
|
|
124
|
+
|
|
125
|
+
default: {
|
|
126
|
+
throw new Error(`Unsupported architecture '${arch}' for Node on Windows`);
|
|
127
|
+
} break;
|
|
128
|
+
}
|
|
131
129
|
|
|
132
|
-
|
|
133
|
-
} else {
|
|
134
|
-
args.push(`-DNODE_JS_LINK_DEF=${options.api}/def/node_api.def`);
|
|
135
|
-
}
|
|
136
|
-
}
|
|
130
|
+
let destname = `${cache_dir}/node_v${runtime_version}_${arch}.lib`;
|
|
137
131
|
|
|
138
|
-
|
|
132
|
+
if (!fs.existsSync(destname)) {
|
|
133
|
+
fs.mkdirSync(cache_dir, { recursive: true, mode: 0o755 });
|
|
139
134
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
fs.copyFileSync(`${app_dir}/assets/win_delay_hook.c`, work_dir + '/win_delay_hook.c');
|
|
135
|
+
let url = `https://nodejs.org/dist/v${runtime_version}/${dirname}/node.lib`;
|
|
136
|
+
await tools.download_http(url, destname);
|
|
137
|
+
}
|
|
144
138
|
|
|
145
|
-
|
|
146
|
-
|
|
139
|
+
fs.copyFileSync(destname, work_dir + '/node.lib');
|
|
140
|
+
args.push(`-DNODE_JS_LINK_LIB=${work_dir}/node.lib`);
|
|
141
|
+
} else {
|
|
142
|
+
args.push(`-DNODE_JS_LINK_DEF=${options.api}/def/node_api.def`);
|
|
143
|
+
}
|
|
147
144
|
|
|
148
145
|
switch (arch) {
|
|
149
146
|
case 'ia32': {
|
|
@@ -159,22 +156,29 @@ function Builder(config = {}) {
|
|
|
159
156
|
args.push('-A', 'x64');
|
|
160
157
|
} break;
|
|
161
158
|
}
|
|
162
|
-
} break;
|
|
163
159
|
|
|
164
|
-
|
|
165
|
-
args.push(
|
|
160
|
+
fs.copyFileSync(`${app_dir}/assets/win_delay_hook.c`, work_dir + '/win_delay_hook.c');
|
|
161
|
+
args.push(`-DNODE_JS_SOURCES=${work_dir}/win_delay_hook.c`);
|
|
162
|
+
} else {
|
|
163
|
+
args.push(`-DNODE_JS_LINK_LIB=node.dll`);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
if (darwin) {
|
|
168
|
+
args.push('-DNODE_JS_LINK_FLAGS=-undefined;dynamic_lookup');
|
|
166
169
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
} break;
|
|
170
|
+
switch (arch) {
|
|
171
|
+
case 'arm64': { args.push('-DCMAKE_OSX_ARCHITECTURES=arm64'); } break;
|
|
172
|
+
case 'x64': { args.push('-DCMAKE_OSX_ARCHITECTURES=x86_64'); } break;
|
|
173
|
+
}
|
|
172
174
|
}
|
|
173
175
|
|
|
174
|
-
if (
|
|
175
|
-
|
|
176
|
-
if (spawnSync('ninja', ['--version']).status === 0)
|
|
176
|
+
if (!msvc) {
|
|
177
|
+
if (spawnSync('ninja', ['--version']).status === 0) {
|
|
177
178
|
args.push('-G', 'Ninja');
|
|
179
|
+
} else if (process.platform == 'win32') {
|
|
180
|
+
args.push('-G', 'MinGW Makefiles');
|
|
181
|
+
}
|
|
178
182
|
|
|
179
183
|
// Use CCache if available
|
|
180
184
|
if (spawnSync('ccache', ['--version']).status === 0) {
|
|
@@ -182,9 +186,8 @@ function Builder(config = {}) {
|
|
|
182
186
|
args.push('-DCMAKE_CXX_COMPILER_LAUNCHER=ccache');
|
|
183
187
|
}
|
|
184
188
|
}
|
|
185
|
-
|
|
186
189
|
if (prefer_clang) {
|
|
187
|
-
if (
|
|
190
|
+
if (msvc) {
|
|
188
191
|
args.push('-T', 'ClangCL');
|
|
189
192
|
} else {
|
|
190
193
|
args.push('-DCMAKE_C_COMPILER=clang');
|
package/src/koffi/CMakeLists.txt
CHANGED
|
@@ -99,7 +99,11 @@ if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
|
|
99
99
|
list(APPEND KOFFI_SRC src/abi_riscv64.cc src/abi_loong64_asm.S)
|
|
100
100
|
else()
|
|
101
101
|
if(WIN32)
|
|
102
|
-
|
|
102
|
+
if(MSVC)
|
|
103
|
+
list(APPEND KOFFI_SRC src/abi_x64_win.cc src/abi_x64_win_asm.asm)
|
|
104
|
+
else()
|
|
105
|
+
list(APPEND KOFFI_SRC src/abi_x64_win.cc src/abi_x64_win_asm.S)
|
|
106
|
+
endif()
|
|
103
107
|
else()
|
|
104
108
|
list(APPEND KOFFI_SRC src/abi_x64_sysv.cc src/abi_x64_sysv_asm.S)
|
|
105
109
|
endif()
|
|
@@ -121,13 +125,19 @@ target_include_directories(koffi PRIVATE . ../.. ../../vendor/node-addon-api)
|
|
|
121
125
|
|
|
122
126
|
if(WIN32)
|
|
123
127
|
set(UV_LINK_LIB "${CMAKE_CURRENT_BINARY_DIR}/uv.lib")
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
128
|
+
if(MSVC)
|
|
129
|
+
add_custom_command(OUTPUT uv.lib
|
|
130
|
+
COMMAND ${CMAKE_AR} ${CMAKE_STATIC_LINKER_FLAGS}
|
|
131
|
+
/def:src/uv.def /out:${UV_LINK_LIB}
|
|
132
|
+
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
|
133
|
+
MAIN_DEPENDENCY src/uv.def)
|
|
134
|
+
else()
|
|
135
|
+
add_custom_command(OUTPUT uv.lib
|
|
136
|
+
COMMAND ${CMAKE_DLLTOOL} -d src/uv.def -l ${UV_LINK_LIB}
|
|
137
|
+
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
|
138
|
+
MAIN_DEPENDENCY src/uv.def)
|
|
139
|
+
endif()
|
|
140
|
+
target_sources(koffi PRIVATE uv.lib)
|
|
131
141
|
target_link_libraries(koffi PRIVATE ${UV_LINK_LIB})
|
|
132
142
|
endif()
|
|
133
143
|
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
# SPDX-License-Identifier: MIT
|
|
2
|
+
# SPDX-FileCopyrightText: 2025 Niels Martignène <niels.martignene@protonmail.com>
|
|
3
|
+
|
|
4
|
+
#define SYMBOL(Symbol) Symbol
|
|
5
|
+
|
|
6
|
+
# Forward
|
|
7
|
+
# ----------------------------
|
|
8
|
+
|
|
9
|
+
.global ForwardCallG
|
|
10
|
+
.global ForwardCallF
|
|
11
|
+
.global ForwardCallD
|
|
12
|
+
.global ForwardCallXG
|
|
13
|
+
.global ForwardCallXF
|
|
14
|
+
.global ForwardCallXD
|
|
15
|
+
|
|
16
|
+
# Copy function pointer to RAX, in order to save it through argument forwarding.
|
|
17
|
+
# Also make a copy of the SP to CallData::old_sp because the callback system might need it.
|
|
18
|
+
# Save RSP in RBX (non-volatile), and use carefully assembled stack provided by caller.
|
|
19
|
+
.macro prologue
|
|
20
|
+
endbr64
|
|
21
|
+
movq %rcx, %rax
|
|
22
|
+
push %rbp
|
|
23
|
+
movq %rsp, %rbp
|
|
24
|
+
movq %rsp, (%r8)
|
|
25
|
+
movq %rdx, %rsp
|
|
26
|
+
.endm
|
|
27
|
+
|
|
28
|
+
# Call native function.
|
|
29
|
+
# Once done, restore normal stack pointer and return.
|
|
30
|
+
# The return value is passed untouched through RAX or XMM0.
|
|
31
|
+
.macro epilogue
|
|
32
|
+
call *%rax
|
|
33
|
+
movq %rbp, %rsp
|
|
34
|
+
pop %rbp
|
|
35
|
+
ret
|
|
36
|
+
.endm
|
|
37
|
+
|
|
38
|
+
# Prepare integer argument registers from array passed by caller.
|
|
39
|
+
.macro forward_gpr
|
|
40
|
+
movq 24(%rdx), %r9
|
|
41
|
+
movq 16(%rdx), %r8
|
|
42
|
+
movq 0(%rdx), %rcx
|
|
43
|
+
movq 8(%rdx), %rdx
|
|
44
|
+
.endm
|
|
45
|
+
|
|
46
|
+
# Prepare XMM argument registers from array passed by caller.
|
|
47
|
+
.macro forward_xmm
|
|
48
|
+
movsd 24(%rdx), %xmm3
|
|
49
|
+
movsd 16(%rdx), %xmm2
|
|
50
|
+
movsd 8(%rdx), %xmm1
|
|
51
|
+
movsd 0(%rdx), %xmm0
|
|
52
|
+
.endm
|
|
53
|
+
|
|
54
|
+
ForwardCallG:
|
|
55
|
+
prologue
|
|
56
|
+
forward_gpr
|
|
57
|
+
epilogue
|
|
58
|
+
|
|
59
|
+
ForwardCallF:
|
|
60
|
+
prologue
|
|
61
|
+
forward_gpr
|
|
62
|
+
epilogue
|
|
63
|
+
|
|
64
|
+
ForwardCallD:
|
|
65
|
+
prologue
|
|
66
|
+
forward_gpr
|
|
67
|
+
epilogue
|
|
68
|
+
|
|
69
|
+
ForwardCallXG:
|
|
70
|
+
prologue
|
|
71
|
+
forward_xmm
|
|
72
|
+
forward_gpr
|
|
73
|
+
epilogue
|
|
74
|
+
|
|
75
|
+
ForwardCallXF:
|
|
76
|
+
prologue
|
|
77
|
+
forward_xmm
|
|
78
|
+
forward_gpr
|
|
79
|
+
epilogue
|
|
80
|
+
|
|
81
|
+
ForwardCallXD:
|
|
82
|
+
prologue
|
|
83
|
+
forward_xmm
|
|
84
|
+
forward_gpr
|
|
85
|
+
epilogue
|
|
86
|
+
|
|
87
|
+
# Callbacks
|
|
88
|
+
# ----------------------------
|
|
89
|
+
|
|
90
|
+
.global RelayCallback
|
|
91
|
+
.global CallSwitchStack
|
|
92
|
+
|
|
93
|
+
# First, make a copy of the GPR argument registers (rcx, rdx, r8, r9).
|
|
94
|
+
# Then call the C function RelayCallback with the following arguments:
|
|
95
|
+
# static trampoline ID, a pointer to the saved GPR array, a pointer to the stack
|
|
96
|
+
# arguments of this call, and a pointer to a struct that will contain the result registers.
|
|
97
|
+
# After the call, simply load these registers from the output struct.
|
|
98
|
+
.macro trampoline id
|
|
99
|
+
endbr64
|
|
100
|
+
subq $120, %rsp
|
|
101
|
+
movq %rcx, 32(%rsp)
|
|
102
|
+
movq %rdx, 40(%rsp)
|
|
103
|
+
movq %r8, 48(%rsp)
|
|
104
|
+
movq %r9, 56(%rsp)
|
|
105
|
+
movq $\id, %rcx
|
|
106
|
+
leaq 32(%rsp), %rdx
|
|
107
|
+
leaq 160(%rsp), %r8
|
|
108
|
+
leaq 96(%rsp), %r9
|
|
109
|
+
call RelayCallback
|
|
110
|
+
movq 96(%rsp), %rax
|
|
111
|
+
addq $120, %rsp
|
|
112
|
+
ret
|
|
113
|
+
.endm
|
|
114
|
+
|
|
115
|
+
# Same thing, but also forward the XMM argument registers and load the XMM result registers.
|
|
116
|
+
.macro trampoline_vec id
|
|
117
|
+
endbr64
|
|
118
|
+
subq $120, %rsp
|
|
119
|
+
movq %rcx, 32(%rsp)
|
|
120
|
+
movq %rdx, 40(%rsp)
|
|
121
|
+
movq %r8, 48(%rsp)
|
|
122
|
+
movq %r9, 56(%rsp)
|
|
123
|
+
movsd %xmm0, 64(%rsp)
|
|
124
|
+
movsd %xmm1, 72(%rsp)
|
|
125
|
+
movsd %xmm2, 80(%rsp)
|
|
126
|
+
movsd %xmm3, 88(%rsp)
|
|
127
|
+
movq $\id, %rcx
|
|
128
|
+
leaq 32(%rsp), %rdx
|
|
129
|
+
leaq 160(%rsp), %r8
|
|
130
|
+
leaq 96(%rsp), %r9
|
|
131
|
+
call RelayCallback
|
|
132
|
+
movq 96(%rsp), %rax
|
|
133
|
+
movsd 104(%rsp), %xmm0
|
|
134
|
+
addq $120, %rsp
|
|
135
|
+
ret
|
|
136
|
+
.endm
|
|
137
|
+
|
|
138
|
+
# When a callback is relayed, Koffi will call into Node.js and V8 to execute Javascript.
|
|
139
|
+
# The problem is that we're still running on the separate Koffi stack, and V8 will
|
|
140
|
+
# probably misdetect this as a "stack overflow". We have to restore the old
|
|
141
|
+
# stack pointer, call Node.js/V8 and go back to ours.
|
|
142
|
+
# The first three parameters (rcx, rdx, r8) are passed through untouched.
|
|
143
|
+
CallSwitchStack:
|
|
144
|
+
endbr64
|
|
145
|
+
push %rbp
|
|
146
|
+
movq %rsp, %rbp
|
|
147
|
+
movq 56(%rsp), %rax
|
|
148
|
+
movq %rsp, %r10
|
|
149
|
+
movq 48(%rsp), %r11
|
|
150
|
+
subq 0(%r11), %r10
|
|
151
|
+
andq $-16, %r10
|
|
152
|
+
movq %r10, 8(%r11)
|
|
153
|
+
leaq -32(%r9), %rsp
|
|
154
|
+
call *%rax
|
|
155
|
+
movq %rbp, %rsp
|
|
156
|
+
pop %rbp
|
|
157
|
+
ret
|
|
158
|
+
|
|
159
|
+
# Trampolines
|
|
160
|
+
# ----------------------------
|
|
161
|
+
|
|
162
|
+
#include "trampolines/gnu.inc"
|
package/src/koffi/src/ffi.cc
CHANGED
|
@@ -2582,7 +2582,8 @@ static Napi::Object InitModule(Napi::Env env, Napi::Object exports)
|
|
|
2582
2582
|
instance->str16_type = instance->types_map.FindValue("char16_t *", nullptr);
|
|
2583
2583
|
instance->str32_type = instance->types_map.FindValue("char32_t *", nullptr);
|
|
2584
2584
|
|
|
2585
|
-
|
|
2585
|
+
Napi::Symbol symbol = Napi::Symbol::New(env, "active");
|
|
2586
|
+
instance->active_symbol.Reset(symbol, 1);
|
|
2586
2587
|
|
|
2587
2588
|
instance->base_types_count = instance->types.count;
|
|
2588
2589
|
}
|
package/src/koffi/src/ffi.hh
CHANGED
package/src/koffi/src/util.cc
CHANGED
|
@@ -43,7 +43,7 @@ MagicUnion::MagicUnion(const Napi::CallbackInfo &info)
|
|
|
43
43
|
Napi::Env env = info.Env();
|
|
44
44
|
InstanceData *instance = env.GetInstanceData<InstanceData>();
|
|
45
45
|
|
|
46
|
-
active_symbol
|
|
46
|
+
active_symbol.Reset(instance->active_symbol.Value(), 1);
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
void MagicUnion::SetRaw(const uint8_t *ptr)
|
|
@@ -51,7 +51,7 @@ void MagicUnion::SetRaw(const uint8_t *ptr)
|
|
|
51
51
|
raw.RemoveFrom(0);
|
|
52
52
|
raw.Append(MakeSpan(ptr, type->size));
|
|
53
53
|
|
|
54
|
-
Value().Set(active_symbol, Env().Undefined());
|
|
54
|
+
Value().Set(active_symbol.Value(), Env().Undefined());
|
|
55
55
|
active_idx = -1;
|
|
56
56
|
}
|
|
57
57
|
|
|
@@ -63,7 +63,7 @@ Napi::Value MagicUnion::Getter(const Napi::CallbackInfo &info)
|
|
|
63
63
|
Napi::Value value;
|
|
64
64
|
|
|
65
65
|
if (idx == active_idx) {
|
|
66
|
-
value = Value().Get(active_symbol);
|
|
66
|
+
value = Value().Get(active_symbol.Value());
|
|
67
67
|
} else {
|
|
68
68
|
Napi::Env env = info.Env();
|
|
69
69
|
|
|
@@ -74,7 +74,7 @@ Napi::Value MagicUnion::Getter(const Napi::CallbackInfo &info)
|
|
|
74
74
|
|
|
75
75
|
value = Decode(env, raw.ptr, member.type);
|
|
76
76
|
|
|
77
|
-
Value().Set(active_symbol, value);
|
|
77
|
+
Value().Set(active_symbol.Value(), value);
|
|
78
78
|
active_idx = idx;
|
|
79
79
|
}
|
|
80
80
|
|
|
@@ -86,7 +86,7 @@ void MagicUnion::Setter(const Napi::CallbackInfo &info, const Napi::Value &value
|
|
|
86
86
|
{
|
|
87
87
|
Size idx = (Size)info.Data();
|
|
88
88
|
|
|
89
|
-
Value().Set(active_symbol, value);
|
|
89
|
+
Value().Set(active_symbol.Value(), value);
|
|
90
90
|
active_idx = idx;
|
|
91
91
|
|
|
92
92
|
raw.Clear();
|
|
@@ -549,6 +549,7 @@ const char *GetValueType(const InstanceData *instance, Napi::Value value)
|
|
|
549
549
|
case napi_uint16_array: return "Uint16Array";
|
|
550
550
|
case napi_int32_array: return "Int32Array";
|
|
551
551
|
case napi_uint32_array: return "Uint32Array";
|
|
552
|
+
case napi_float16_array: return "Float16Array";
|
|
552
553
|
case napi_float32_array: return "Float32Array";
|
|
553
554
|
case napi_float64_array: return "Float64Array";
|
|
554
555
|
case napi_bigint64_array: return "BigInt64Array";
|
package/src/koffi/src/util.hh
CHANGED
|
@@ -17,7 +17,7 @@ extern const napi_type_tag MagicUnionMarker;
|
|
|
17
17
|
class MagicUnion: public Napi::ObjectWrap<MagicUnion> {
|
|
18
18
|
const TypeInfo *type;
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
Napi::Reference<Napi::Symbol> active_symbol;
|
|
21
21
|
Size active_idx = -1;
|
|
22
22
|
|
|
23
23
|
HeapArray<uint8_t> raw;
|
|
@@ -120,6 +120,7 @@ static inline Span<uint8_t> GetRawBuffer(Napi::Value value)
|
|
|
120
120
|
case napi_uint16_array: { length *= 2; } break;
|
|
121
121
|
case napi_int32_array: { length *= 4; } break;
|
|
122
122
|
case napi_uint32_array: { length *= 4; } break;
|
|
123
|
+
case napi_float16_array: { length *= 2; } break;
|
|
123
124
|
case napi_float32_array: { length *= 4; } break;
|
|
124
125
|
case napi_float64_array: { length *= 8; } break;
|
|
125
126
|
case napi_bigint64_array: { length *= 8; } break;
|
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
# node-api-headers Changelog
|
|
2
2
|
|
|
3
|
+
## [1.8.0](https://github.com/nodejs/node-api-headers/compare/v1.7.0...v1.8.0) (2026-01-23)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* update headers from nodejs/node tag v25.4.0 ([#70](https://github.com/nodejs/node-api-headers/issues/70)) ([ebc02e1](https://github.com/nodejs/node-api-headers/commit/ebc02e18357a4d49f127f094c144371948b60c84))
|
|
9
|
+
|
|
10
|
+
## [1.7.0](https://github.com/nodejs/node-api-headers/compare/v1.6.0...v1.7.0) (2025-11-28)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Features
|
|
14
|
+
|
|
15
|
+
* update headers from nodejs/node tag v25.1.0 ([#65](https://github.com/nodejs/node-api-headers/issues/65)) ([f90f754](https://github.com/nodejs/node-api-headers/commit/f90f75459375cb4725914895aa418efefdde7af2))
|
|
16
|
+
* update headers from nodejs/node tag v25.2.1 ([#68](https://github.com/nodejs/node-api-headers/issues/68)) ([769031b](https://github.com/nodejs/node-api-headers/commit/769031b208acd820bf3f2c3b2cf9f8b4b2e2bd83))
|
|
17
|
+
|
|
18
|
+
## [1.6.0](https://github.com/nodejs/node-api-headers/compare/v1.5.0...v1.6.0) (2025-09-26)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
### Features
|
|
22
|
+
|
|
23
|
+
* update headers from nodejs/node tag v24.9.0 ([#60](https://github.com/nodejs/node-api-headers/issues/60)) ([5963ef9](https://github.com/nodejs/node-api-headers/commit/5963ef9937c8f6bd8f33cb45c50f70bd9cbc0ffd))
|
|
24
|
+
|
|
3
25
|
## [1.5.0](https://github.com/nodejs/node-api-headers/compare/v1.4.0...v1.5.0) (2025-01-09)
|
|
4
26
|
|
|
5
27
|
|
|
@@ -9,10 +9,6 @@
|
|
|
9
9
|
- **[Team](#team)**
|
|
10
10
|
- **[License](#license)**
|
|
11
11
|
|
|
12
|
-
## Current Node-API version: 9
|
|
13
|
-
|
|
14
|
-
(See [CHANGELOG.md](CHANGELOG.md) for complete Changelog)
|
|
15
|
-
|
|
16
12
|
<a name="introduction"></a>
|
|
17
13
|
|
|
18
14
|
## Introduction
|
|
@@ -45,8 +41,8 @@ npm i node-api-headers
|
|
|
45
41
|
|
|
46
42
|
## Versions
|
|
47
43
|
|
|
48
|
-
Node-API C headers are backward-compatible. Its version (e.g. `8`) is released
|
|
49
|
-
separately from the Node.js version stream (e.g. `19.8.1`) and changes are
|
|
44
|
+
Node-API C headers are backward-compatible. Its version (e.g. `8`) is released
|
|
45
|
+
separately from the Node.js version stream (e.g. `19.8.1`) and changes are
|
|
50
46
|
backported to active Node.js LTS lines (e.g. `16.x` and `18.x`).
|
|
51
47
|
|
|
52
48
|
This package publishes semver-minor versions with new Node-API C headers changes.
|
|
@@ -57,6 +53,7 @@ JS API breaking changes are published with new semver-major versions.
|
|
|
57
53
|
## API
|
|
58
54
|
|
|
59
55
|
The module exports two properties `include_dir` and `symbols`.
|
|
56
|
+
|
|
60
57
|
### `include_dir`
|
|
61
58
|
|
|
62
59
|
This property is a string that represents the include path for the Node-API
|
|
@@ -89,18 +86,10 @@ grouped by version and api types.
|
|
|
89
86
|
|
|
90
87
|
## Team members
|
|
91
88
|
|
|
92
|
-
|
|
93
|
-
| Name | GitHub Link |
|
|
94
|
-
| ------------------- | ----------------------------------------------------- |
|
|
95
|
-
| Anna Henningsen | [addaleax](https://github.com/addaleax) |
|
|
96
|
-
| Chengzhong Wu | [legendecas](https://github.com/legendecas) |
|
|
97
|
-
| Gabriel Schulhof | [gabrielschulhof](https://github.com/gabrielschulhof) |
|
|
98
|
-
| Hitesh Kanwathirtha | [digitalinfinity](https://github.com/digitalinfinity) |
|
|
99
|
-
| Jim Schlight | [jschlight](https://github.com/jschlight) |
|
|
100
|
-
| Michael Dawson | [mhdawson](https://github.com/mhdawson) |
|
|
101
|
-
| Kevin Eady | [KevinEady](https://github.com/KevinEady)
|
|
102
|
-
| Nicola Del Gobbo | [NickNaso](https://github.com/NickNaso) |
|
|
89
|
+
The project is maintained by the [Node-API team members](https://github.com/nodejs/abi-stable-node/?tab=readme-ov-file#project-participants).
|
|
103
90
|
|
|
104
91
|
<a name="license"></a>
|
|
105
92
|
|
|
93
|
+
## License
|
|
94
|
+
|
|
106
95
|
Licensed under [MIT](./LICENSE.md)
|
|
@@ -5,18 +5,6 @@
|
|
|
5
5
|
#include <stdbool.h> // NOLINT(modernize-deprecated-headers)
|
|
6
6
|
#include <stddef.h> // NOLINT(modernize-deprecated-headers)
|
|
7
7
|
|
|
8
|
-
// Use INT_MAX, this should only be consumed by the pre-processor anyway.
|
|
9
|
-
#define NAPI_VERSION_EXPERIMENTAL 2147483647
|
|
10
|
-
#ifndef NAPI_VERSION
|
|
11
|
-
// The baseline version for N-API.
|
|
12
|
-
// The NAPI_VERSION controls which version will be used by default when
|
|
13
|
-
// compilling a native addon. If the addon developer specifically wants to use
|
|
14
|
-
// functions available in a new version of N-API that is not yet ported in all
|
|
15
|
-
// LTS versions, they can set NAPI_VERSION knowing that they have specifically
|
|
16
|
-
// depended on that version.
|
|
17
|
-
#define NAPI_VERSION 8
|
|
18
|
-
#endif
|
|
19
|
-
|
|
20
8
|
#include "js_native_api_types.h"
|
|
21
9
|
|
|
22
10
|
// If you need __declspec(dllimport), either include <node_api.h> instead, or
|
|
@@ -62,6 +50,7 @@ NAPI_EXTERN napi_status NAPI_CDECL napi_get_boolean(napi_env env,
|
|
|
62
50
|
// Methods to create Primitive types/Objects
|
|
63
51
|
NAPI_EXTERN napi_status NAPI_CDECL napi_create_object(napi_env env,
|
|
64
52
|
napi_value* result);
|
|
53
|
+
|
|
65
54
|
NAPI_EXTERN napi_status NAPI_CDECL napi_create_array(napi_env env,
|
|
66
55
|
napi_value* result);
|
|
67
56
|
NAPI_EXTERN napi_status NAPI_CDECL
|
|
@@ -348,7 +337,7 @@ napi_create_reference(napi_env env,
|
|
|
348
337
|
|
|
349
338
|
// Deletes a reference. The referenced value is released, and may
|
|
350
339
|
// be GC'd unless there are other references to it.
|
|
351
|
-
NAPI_EXTERN napi_status NAPI_CDECL napi_delete_reference(
|
|
340
|
+
NAPI_EXTERN napi_status NAPI_CDECL napi_delete_reference(node_api_basic_env env,
|
|
352
341
|
napi_ref ref);
|
|
353
342
|
|
|
354
343
|
// Increments the reference count, optionally returning the resulting count.
|
|
@@ -470,6 +459,7 @@ napi_get_dataview_info(napi_env env,
|
|
|
470
459
|
napi_value* arraybuffer,
|
|
471
460
|
size_t* byte_offset);
|
|
472
461
|
|
|
462
|
+
|
|
473
463
|
// version management
|
|
474
464
|
NAPI_EXTERN napi_status NAPI_CDECL napi_get_version(node_api_basic_env env,
|
|
475
465
|
uint32_t* result);
|
|
@@ -1,6 +1,19 @@
|
|
|
1
1
|
#ifndef SRC_JS_NATIVE_API_TYPES_H_
|
|
2
2
|
#define SRC_JS_NATIVE_API_TYPES_H_
|
|
3
3
|
|
|
4
|
+
// Use INT_MAX, this should only be consumed by the pre-processor anyway.
|
|
5
|
+
#define NAPI_VERSION_EXPERIMENTAL 2147483647
|
|
6
|
+
#ifndef NAPI_VERSION
|
|
7
|
+
// The baseline version for N-API.
|
|
8
|
+
// The NAPI_VERSION controls which version will be used by default when
|
|
9
|
+
// compilling a native addon. If the addon developer specifically wants to use
|
|
10
|
+
// functions available in a new version of N-API that is not yet ported in all
|
|
11
|
+
// LTS versions, they can set NAPI_VERSION knowing that they have specifically
|
|
12
|
+
// depended on that version.
|
|
13
|
+
#define NAPI_VERSION 8
|
|
14
|
+
#endif
|
|
15
|
+
|
|
16
|
+
|
|
4
17
|
// This file needs to be compatible with C compilers.
|
|
5
18
|
// This is a public include file, and these includes have essentially
|
|
6
19
|
// became part of it's API.
|
|
@@ -98,6 +111,8 @@ typedef enum {
|
|
|
98
111
|
napi_float64_array,
|
|
99
112
|
napi_bigint64_array,
|
|
100
113
|
napi_biguint64_array,
|
|
114
|
+
#define NODE_API_HAS_FLOAT16_ARRAY
|
|
115
|
+
napi_float16_array,
|
|
101
116
|
} napi_typedarray_type;
|
|
102
117
|
|
|
103
118
|
typedef enum {
|
|
@@ -33,10 +33,6 @@ struct uv_loop_s; // Forward declaration.
|
|
|
33
33
|
#define NAPI_NO_RETURN
|
|
34
34
|
#endif
|
|
35
35
|
|
|
36
|
-
typedef napi_value(NAPI_CDECL* napi_addon_register_func)(napi_env env,
|
|
37
|
-
napi_value exports);
|
|
38
|
-
typedef int32_t(NAPI_CDECL* node_api_addon_get_api_version_func)(void);
|
|
39
|
-
|
|
40
36
|
// Used by deprecated registration method napi_module_register.
|
|
41
37
|
typedef struct napi_module {
|
|
42
38
|
int nm_version;
|
|
@@ -3,6 +3,12 @@
|
|
|
3
3
|
|
|
4
4
|
#include "js_native_api_types.h"
|
|
5
5
|
|
|
6
|
+
typedef napi_value(NAPI_CDECL* napi_addon_register_func)(napi_env env,
|
|
7
|
+
napi_value exports);
|
|
8
|
+
// False positive: https://github.com/cpplint/cpplint/issues/409
|
|
9
|
+
// NOLINTNEXTLINE (readability/casting)
|
|
10
|
+
typedef int32_t(NAPI_CDECL* node_api_addon_get_api_version_func)(void);
|
|
11
|
+
|
|
6
12
|
typedef struct napi_callback_scope__* napi_callback_scope;
|
|
7
13
|
typedef struct napi_async_context__* napi_async_context;
|
|
8
14
|
typedef struct napi_async_work__* napi_async_work;
|
|
@@ -71,6 +71,12 @@ function removeExperimentals(stream, destination, verbose = false) {
|
|
|
71
71
|
const identifier = matches[2];
|
|
72
72
|
macroStack.push(identifier);
|
|
73
73
|
|
|
74
|
+
if (mode.length && mode[mode.length - 1] === 'ignore') {
|
|
75
|
+
debug(`Line ${lineNumber} Continued-Ignored ${identifier}`);
|
|
76
|
+
mode.push('ignore');
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
|
|
74
80
|
debug(`Line ${lineNumber} Pushed ${identifier}`);
|
|
75
81
|
|
|
76
82
|
if (identifier === 'NAPI_EXPERIMENTAL') {
|