koffi 2.6.3 → 2.6.4
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 +4 -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_arm32hf/koffi.node +0 -0
- package/build/koffi/linux_arm64/koffi.node +0 -0
- package/build/koffi/linux_ia32/koffi.node +0 -0
- package/build/koffi/linux_riscv64hf64/koffi.node +0 -0
- package/build/koffi/linux_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/contribute.md +1 -1
- package/doc/packaging.md +4 -2
- package/index.js +2 -2
- package/indirect.js +2 -2
- package/package.json +2 -2
- package/src/core/libcc/libcc.cc +258 -176
- package/src/core/libcc/libcc.hh +31 -19
- package/src/koffi/CMakeLists.txt +9 -9
- package/src/koffi/src/ffi.cc +2 -2
- package/src/koffi/src/win32.cc +1 -1
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
|
package/doc/contribute.md
CHANGED
package/doc/packaging.md
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# Bundlers and Koffi
|
|
2
2
|
|
|
3
|
-
## Bundling
|
|
3
|
+
## Bundling
|
|
4
|
+
|
|
5
|
+
### Native modules
|
|
4
6
|
|
|
5
7
|
*Simplified in Koffi 2.5.9*
|
|
6
8
|
|
|
@@ -36,7 +38,7 @@ resources/
|
|
|
36
38
|
MyApp.exe
|
|
37
39
|
```
|
|
38
40
|
|
|
39
|
-
|
|
41
|
+
### Indirect loader
|
|
40
42
|
|
|
41
43
|
*New in Koffi 2.6.2*
|
|
42
44
|
|
package/index.js
CHANGED
|
@@ -378,8 +378,8 @@ var require_package = __commonJS({
|
|
|
378
378
|
"build/dist/src/koffi/package.json"(exports2, module2) {
|
|
379
379
|
module2.exports = {
|
|
380
380
|
name: "koffi",
|
|
381
|
-
version: "2.6.
|
|
382
|
-
stable: "2.6.
|
|
381
|
+
version: "2.6.4",
|
|
382
|
+
stable: "2.6.4",
|
|
383
383
|
description: "Fast and simple C FFI (foreign function interface) for Node.js",
|
|
384
384
|
keywords: [
|
|
385
385
|
"foreign",
|
package/indirect.js
CHANGED
|
@@ -378,8 +378,8 @@ var require_package = __commonJS({
|
|
|
378
378
|
"build/dist/src/koffi/package.json"(exports2, module2) {
|
|
379
379
|
module2.exports = {
|
|
380
380
|
name: "koffi",
|
|
381
|
-
version: "2.6.
|
|
382
|
-
stable: "2.6.
|
|
381
|
+
version: "2.6.4",
|
|
382
|
+
stable: "2.6.4",
|
|
383
383
|
description: "Fast and simple C FFI (foreign function interface) for Node.js",
|
|
384
384
|
keywords: [
|
|
385
385
|
"foreign",
|
package/package.json
CHANGED
package/src/core/libcc/libcc.cc
CHANGED
|
@@ -1426,7 +1426,7 @@ static inline void ProcessArg(const FmtArg &arg, AppendFunc append)
|
|
|
1426
1426
|
RG_ASSERT(arg.u.random.len <= RG_SIZE(out_buf.data));
|
|
1427
1427
|
|
|
1428
1428
|
for (Size j = 0; j < arg.u.random.len; j++) {
|
|
1429
|
-
int rnd =
|
|
1429
|
+
int rnd = GetRandomIntFast(0, (int)chars.len);
|
|
1430
1430
|
out_buf.Append(chars[rnd]);
|
|
1431
1431
|
}
|
|
1432
1432
|
|
|
@@ -2146,37 +2146,6 @@ fail:
|
|
|
2146
2146
|
return str_buf;
|
|
2147
2147
|
}
|
|
2148
2148
|
|
|
2149
|
-
void SetEnvironmentVar(const char *name, const char *value)
|
|
2150
|
-
{
|
|
2151
|
-
RG_ASSERT(name && name[0] && !strchr(name, '='));
|
|
2152
|
-
RG_ASSERT(value);
|
|
2153
|
-
|
|
2154
|
-
if (win32_utf8) {
|
|
2155
|
-
RG_CRITICAL(SetEnvironmentVariableA(name, value), "Failed to set environment variable '%1' to '%2': %3", name, value, GetWin32ErrorString());
|
|
2156
|
-
} else {
|
|
2157
|
-
wchar_t name_w[256];
|
|
2158
|
-
wchar_t value_w[4096];
|
|
2159
|
-
|
|
2160
|
-
RG_CRITICAL(ConvertUtf8ToWin32Wide(name, name_w) >= 0, "Failed to set environment variable '%1' to '%2'", name, value);
|
|
2161
|
-
RG_CRITICAL(ConvertUtf8ToWin32Wide(value, value_w) >= 0, "Failed to set environment variable '%1' to '%2'", name, value);
|
|
2162
|
-
RG_CRITICAL(SetEnvironmentVariableW(name_w, value_w), "Failed to set environment variable '%1' to '%2': %3", name, value, GetWin32ErrorString());
|
|
2163
|
-
}
|
|
2164
|
-
}
|
|
2165
|
-
|
|
2166
|
-
void DeleteEnvironmentVar(const char *name)
|
|
2167
|
-
{
|
|
2168
|
-
RG_ASSERT(name && name[0] && !strchr(name, '='));
|
|
2169
|
-
|
|
2170
|
-
if (win32_utf8) {
|
|
2171
|
-
RG_CRITICAL(SetEnvironmentVariableA(name, nullptr), "Failed to clear environment variable '%1': %2", name, GetWin32ErrorString());
|
|
2172
|
-
} else {
|
|
2173
|
-
wchar_t name_w[256];
|
|
2174
|
-
|
|
2175
|
-
RG_CRITICAL(ConvertUtf8ToWin32Wide(name, name_w) >= 0, "Failed to clear environment variable '%1'", name);
|
|
2176
|
-
RG_CRITICAL(SetEnvironmentVariableW(name_w, nullptr), "Failed to clear environment variable '%1': %2", name, GetWin32ErrorString());
|
|
2177
|
-
}
|
|
2178
|
-
}
|
|
2179
|
-
|
|
2180
2149
|
static FileType FileAttributesToType(uint32_t attr)
|
|
2181
2150
|
{
|
|
2182
2151
|
if (attr & FILE_ATTRIBUTE_DIRECTORY) {
|
|
@@ -2360,20 +2329,6 @@ EnumResult EnumerateDirectory(const char *dirname, const char *filter, Size max_
|
|
|
2360
2329
|
|
|
2361
2330
|
#else
|
|
2362
2331
|
|
|
2363
|
-
void SetEnvironmentVar(const char *name, const char *value)
|
|
2364
|
-
{
|
|
2365
|
-
RG_ASSERT(name && name[0] && !strchr(name, '='));
|
|
2366
|
-
RG_ASSERT(value);
|
|
2367
|
-
|
|
2368
|
-
RG_CRITICAL(!setenv(name, value, 1), "Failed to set environment variable '%1' to '%2': %3", name, value, strerror(errno));
|
|
2369
|
-
}
|
|
2370
|
-
|
|
2371
|
-
void DeleteEnvironmentVar(const char *name)
|
|
2372
|
-
{
|
|
2373
|
-
RG_ASSERT(name && name[0] && !strchr(name, '='));
|
|
2374
|
-
RG_CRITICAL(!unsetenv(name), "Failed to clear environment variable '%1': %2", name, strerror(errno));
|
|
2375
|
-
}
|
|
2376
|
-
|
|
2377
2332
|
static FileType FileModeToType(mode_t mode)
|
|
2378
2333
|
{
|
|
2379
2334
|
if (S_ISDIR(mode)) {
|
|
@@ -3919,7 +3874,7 @@ struct PendingIO {
|
|
|
3919
3874
|
}
|
|
3920
3875
|
};
|
|
3921
3876
|
|
|
3922
|
-
bool ExecuteCommandLine(const char *cmd_line, const
|
|
3877
|
+
bool ExecuteCommandLine(const char *cmd_line, const ExecuteInfo &info,
|
|
3923
3878
|
FunctionRef<Span<const uint8_t>()> in_func,
|
|
3924
3879
|
FunctionRef<void(Span<uint8_t> buf)> out_func, int *out_code)
|
|
3925
3880
|
{
|
|
@@ -3934,9 +3889,9 @@ bool ExecuteCommandLine(const char *cmd_line, const char *work_dir,
|
|
|
3934
3889
|
|
|
3935
3890
|
// Convert work directory
|
|
3936
3891
|
Span<wchar_t> work_dir_w;
|
|
3937
|
-
if (work_dir) {
|
|
3938
|
-
work_dir_w = AllocateSpan<wchar_t>(&temp_alloc, 2 * strlen(work_dir) + 1);
|
|
3939
|
-
if (ConvertUtf8ToWin32Wide(work_dir, work_dir_w) < 0)
|
|
3892
|
+
if (info.work_dir) {
|
|
3893
|
+
work_dir_w = AllocateSpan<wchar_t>(&temp_alloc, 2 * strlen(info.work_dir) + 1);
|
|
3894
|
+
if (ConvertUtf8ToWin32Wide(info.work_dir, work_dir_w) < 0)
|
|
3940
3895
|
return false;
|
|
3941
3896
|
} else {
|
|
3942
3897
|
work_dir_w = {};
|
|
@@ -3988,6 +3943,45 @@ bool ExecuteCommandLine(const char *cmd_line, const char *work_dir,
|
|
|
3988
3943
|
if (out_func.IsValid() && !CreateOverlappedPipe(true, false, PipeMode::Byte, out_pipe))
|
|
3989
3944
|
return false;
|
|
3990
3945
|
|
|
3946
|
+
// Prepare environment (if needed)
|
|
3947
|
+
HeapArray<wchar_t> new_env_w;
|
|
3948
|
+
if (info.reset_env || info.env_variables.len) {
|
|
3949
|
+
if (!info.reset_env) {
|
|
3950
|
+
Span<wchar_t> current_env = MakeSpan(GetEnvironmentStringsW(), 0);
|
|
3951
|
+
|
|
3952
|
+
do {
|
|
3953
|
+
Size len = (Size)wcslen(current_env.end());
|
|
3954
|
+
current_env.len += len + 1;
|
|
3955
|
+
} while (current_env.ptr[current_env.len]);
|
|
3956
|
+
|
|
3957
|
+
new_env_w.Append(current_env);
|
|
3958
|
+
}
|
|
3959
|
+
|
|
3960
|
+
for (const ExecuteInfo::KeyValue &kv: info.env_variables) {
|
|
3961
|
+
Span<const char> key = kv.key;
|
|
3962
|
+
Span<const char> value = kv.value;
|
|
3963
|
+
|
|
3964
|
+
Size len = 2 * (key.len + value.len + 1) + 1;
|
|
3965
|
+
new_env_w.Reserve(len);
|
|
3966
|
+
|
|
3967
|
+
len = ConvertUtf8ToWin32Wide(key, new_env_w.TakeAvailable());
|
|
3968
|
+
if (len < 0) [[unlikely]]
|
|
3969
|
+
return false;
|
|
3970
|
+
new_env_w.len += len;
|
|
3971
|
+
|
|
3972
|
+
new_env_w.Append(L'=');
|
|
3973
|
+
|
|
3974
|
+
len = ConvertUtf8ToWin32Wide(value, new_env_w.TakeAvailable());
|
|
3975
|
+
if (len < 0) [[unlikely]]
|
|
3976
|
+
return false;
|
|
3977
|
+
new_env_w.len += len;
|
|
3978
|
+
|
|
3979
|
+
new_env_w.Append(0);
|
|
3980
|
+
}
|
|
3981
|
+
|
|
3982
|
+
new_env_w.Append(0);
|
|
3983
|
+
}
|
|
3984
|
+
|
|
3991
3985
|
// Start process
|
|
3992
3986
|
HANDLE process_handle;
|
|
3993
3987
|
{
|
|
@@ -4012,9 +4006,11 @@ bool ExecuteCommandLine(const char *cmd_line, const char *work_dir,
|
|
|
4012
4006
|
si.dwFlags |= STARTF_USESTDHANDLES;
|
|
4013
4007
|
}
|
|
4014
4008
|
|
|
4009
|
+
int flags = CREATE_NEW_PROCESS_GROUP | CREATE_UNICODE_ENVIRONMENT;
|
|
4010
|
+
|
|
4015
4011
|
PROCESS_INFORMATION pi = {};
|
|
4016
|
-
if (!CreateProcessW(nullptr, cmd_line_w.ptr, nullptr, nullptr, TRUE,
|
|
4017
|
-
|
|
4012
|
+
if (!CreateProcessW(nullptr, cmd_line_w.ptr, nullptr, nullptr, TRUE, flags,
|
|
4013
|
+
new_env_w.ptr, work_dir_w.ptr, &si, &pi)) {
|
|
4018
4014
|
LogError("Failed to start process: %1", GetWin32ErrorString());
|
|
4019
4015
|
return false;
|
|
4020
4016
|
}
|
|
@@ -4223,10 +4219,12 @@ void CloseDescriptorSafe(int *fd_ptr)
|
|
|
4223
4219
|
*fd_ptr = -1;
|
|
4224
4220
|
}
|
|
4225
4221
|
|
|
4226
|
-
bool ExecuteCommandLine(const char *cmd_line, const
|
|
4222
|
+
bool ExecuteCommandLine(const char *cmd_line, const ExecuteInfo &info,
|
|
4227
4223
|
FunctionRef<Span<const uint8_t>()> in_func,
|
|
4228
4224
|
FunctionRef<void(Span<uint8_t> buf)> out_func, int *out_code)
|
|
4229
4225
|
{
|
|
4226
|
+
BlockAllocator temp_alloc;
|
|
4227
|
+
|
|
4230
4228
|
// Create read pipes
|
|
4231
4229
|
int in_pfd[2] = {-1, -1};
|
|
4232
4230
|
RG_DEFER {
|
|
@@ -4277,6 +4275,26 @@ bool ExecuteCommandLine(const char *cmd_line, const char *work_dir,
|
|
|
4277
4275
|
}
|
|
4278
4276
|
}
|
|
4279
4277
|
|
|
4278
|
+
// Prepare new environment (if needed)
|
|
4279
|
+
HeapArray<char *> new_env;
|
|
4280
|
+
if (info.reset_env || info.env_variables.len) {
|
|
4281
|
+
if (!info.reset_env) {
|
|
4282
|
+
char **ptr = environ;
|
|
4283
|
+
|
|
4284
|
+
while (*ptr) {
|
|
4285
|
+
new_env.Append(*ptr);
|
|
4286
|
+
ptr++;
|
|
4287
|
+
}
|
|
4288
|
+
}
|
|
4289
|
+
|
|
4290
|
+
for (const ExecuteInfo::KeyValue &kv: info.env_variables) {
|
|
4291
|
+
const char *var = Fmt(&temp_alloc, "%1=%2", kv.key, kv.value).ptr;
|
|
4292
|
+
new_env.Append((char *)var);
|
|
4293
|
+
}
|
|
4294
|
+
|
|
4295
|
+
new_env.Append(nullptr);
|
|
4296
|
+
}
|
|
4297
|
+
|
|
4280
4298
|
// Start process
|
|
4281
4299
|
pid_t pid;
|
|
4282
4300
|
{
|
|
@@ -4297,12 +4315,12 @@ bool ExecuteCommandLine(const char *cmd_line, const char *work_dir,
|
|
|
4297
4315
|
return false;
|
|
4298
4316
|
}
|
|
4299
4317
|
|
|
4300
|
-
if (work_dir) {
|
|
4301
|
-
const char *argv[] = {"env", "-C", work_dir, "sh", "-c", cmd_line, nullptr };
|
|
4302
|
-
errno = posix_spawn(&pid, "/bin/env", &file_actions, nullptr, const_cast<char **>(argv), environ);
|
|
4318
|
+
if (info.work_dir) {
|
|
4319
|
+
const char *argv[] = {"env", "-C", info.work_dir, "sh", "-c", cmd_line, nullptr };
|
|
4320
|
+
errno = posix_spawn(&pid, "/bin/env", &file_actions, nullptr, const_cast<char **>(argv), new_env.ptr ? new_env.ptr : environ);
|
|
4303
4321
|
} else {
|
|
4304
4322
|
const char *argv[] = {"sh", "-c", cmd_line, nullptr};
|
|
4305
|
-
errno = posix_spawn(&pid, "/bin/sh", &file_actions, nullptr, const_cast<char **>(argv), environ);
|
|
4323
|
+
errno = posix_spawn(&pid, "/bin/sh", &file_actions, nullptr, const_cast<char **>(argv), new_env.ptr ? new_env.ptr : environ);
|
|
4306
4324
|
}
|
|
4307
4325
|
if (errno) {
|
|
4308
4326
|
LogError("Failed to start process: %1", strerror(errno));
|
|
@@ -4444,7 +4462,7 @@ bool ExecuteCommandLine(const char *cmd_line, const char *work_dir,
|
|
|
4444
4462
|
|
|
4445
4463
|
#endif
|
|
4446
4464
|
|
|
4447
|
-
bool ExecuteCommandLine(const char *cmd_line, const
|
|
4465
|
+
bool ExecuteCommandLine(const char *cmd_line, const ExecuteInfo &info,
|
|
4448
4466
|
Span<const uint8_t> in_buf, Size max_len,
|
|
4449
4467
|
HeapArray<uint8_t> *out_buf, int *out_code)
|
|
4450
4468
|
{
|
|
@@ -4467,8 +4485,8 @@ bool ExecuteCommandLine(const char *cmd_line, const char *work_dir,
|
|
|
4467
4485
|
// Don't f*ck up the log
|
|
4468
4486
|
bool warned = false;
|
|
4469
4487
|
|
|
4470
|
-
bool success = ExecuteCommandLine(cmd_line,
|
|
4471
|
-
|
|
4488
|
+
bool success = ExecuteCommandLine(cmd_line, info, [&]() { return in_buf; },
|
|
4489
|
+
[&](Span<uint8_t> buf) {
|
|
4472
4490
|
if (out_buf->len - start_len <= max_len - buf.len) {
|
|
4473
4491
|
out_buf->Append(buf);
|
|
4474
4492
|
} else if (!warned) {
|
|
@@ -4494,7 +4512,7 @@ Size ReadCommandOutput(const char *cmd_line, Span<char> out_output)
|
|
|
4494
4512
|
};
|
|
4495
4513
|
|
|
4496
4514
|
int exit_code;
|
|
4497
|
-
if (!ExecuteCommandLine(cmd_line,
|
|
4515
|
+
if (!ExecuteCommandLine(cmd_line, {}, MakeSpan((const uint8_t *)nullptr, 0), write, &exit_code))
|
|
4498
4516
|
return -1;
|
|
4499
4517
|
if (exit_code) {
|
|
4500
4518
|
LogDebug("Command '%1 failed (exit code: %2)", cmd_line, exit_code);
|
|
@@ -4507,7 +4525,7 @@ Size ReadCommandOutput(const char *cmd_line, Span<char> out_output)
|
|
|
4507
4525
|
bool ReadCommandOutput(const char *cmd_line, HeapArray<char> *out_output)
|
|
4508
4526
|
{
|
|
4509
4527
|
int exit_code;
|
|
4510
|
-
if (!ExecuteCommandLine(cmd_line,
|
|
4528
|
+
if (!ExecuteCommandLine(cmd_line, {}, {}, Mebibytes(1), out_output, &exit_code))
|
|
4511
4529
|
return false;
|
|
4512
4530
|
if (exit_code) {
|
|
4513
4531
|
LogDebug("Command '%1 failed (exit code: %2)", cmd_line, exit_code);
|
|
@@ -4759,7 +4777,7 @@ bool NotifySystemd()
|
|
|
4759
4777
|
return false;
|
|
4760
4778
|
}
|
|
4761
4779
|
|
|
4762
|
-
|
|
4780
|
+
unsetenv("NOTIFY_SOCKET");
|
|
4763
4781
|
return true;
|
|
4764
4782
|
}
|
|
4765
4783
|
#endif
|
|
@@ -5063,79 +5081,6 @@ const char *CreateUniqueDirectory(Span<const char> directory, const char *prefix
|
|
|
5063
5081
|
// Random
|
|
5064
5082
|
// ------------------------------------------------------------------------
|
|
5065
5083
|
|
|
5066
|
-
static inline uint32_t ROTL32(uint32_t v, int n)
|
|
5067
|
-
{
|
|
5068
|
-
return (v << n) | (v >> (32 - n));
|
|
5069
|
-
}
|
|
5070
|
-
|
|
5071
|
-
static inline uint64_t ROTL64(uint64_t v, int n) {
|
|
5072
|
-
return (v << n) | (v >> (64 - n));
|
|
5073
|
-
}
|
|
5074
|
-
|
|
5075
|
-
FastRandom::FastRandom()
|
|
5076
|
-
{
|
|
5077
|
-
do {
|
|
5078
|
-
FillRandomSafe(state, RG_SIZE(state));
|
|
5079
|
-
} while (std::all_of(std::begin(state), std::end(state), [](uint64_t v) { return !v; }));
|
|
5080
|
-
}
|
|
5081
|
-
|
|
5082
|
-
FastRandom::FastRandom(uint64_t seed)
|
|
5083
|
-
{
|
|
5084
|
-
// splitmix64 generator to seed xoshiro256++, as recommended
|
|
5085
|
-
|
|
5086
|
-
seed += 0x9e3779b97f4a7c15;
|
|
5087
|
-
|
|
5088
|
-
for (int i = 0; i < 4; i++) {
|
|
5089
|
-
seed = (seed ^ (seed >> 30)) * 0xbf58476d1ce4e5b9;
|
|
5090
|
-
seed = (seed ^ (seed >> 27)) * 0x94d049bb133111eb;
|
|
5091
|
-
state[i] = seed ^ (seed >> 31);
|
|
5092
|
-
}
|
|
5093
|
-
}
|
|
5094
|
-
|
|
5095
|
-
void FastRandom::Fill(void *out_buf, Size len)
|
|
5096
|
-
{
|
|
5097
|
-
for (Size i = 0; i < len; i += 8) {
|
|
5098
|
-
uint64_t rnd = Next();
|
|
5099
|
-
|
|
5100
|
-
Size copy_len = std::min(RG_SIZE(rnd), len - i);
|
|
5101
|
-
memcpy((uint8_t *)out_buf + i, &rnd, copy_len);
|
|
5102
|
-
}
|
|
5103
|
-
}
|
|
5104
|
-
|
|
5105
|
-
int FastRandom::GetInt(int min, int max)
|
|
5106
|
-
{
|
|
5107
|
-
int range = max - min;
|
|
5108
|
-
RG_ASSERT(range >= 2);
|
|
5109
|
-
|
|
5110
|
-
unsigned int treshold = (UINT_MAX - UINT_MAX % range);
|
|
5111
|
-
|
|
5112
|
-
unsigned int x;
|
|
5113
|
-
do {
|
|
5114
|
-
Fill(&x, RG_SIZE(x));
|
|
5115
|
-
} while (x >= treshold);
|
|
5116
|
-
x %= range;
|
|
5117
|
-
|
|
5118
|
-
return min + (int)x;
|
|
5119
|
-
}
|
|
5120
|
-
|
|
5121
|
-
uint64_t FastRandom::Next()
|
|
5122
|
-
{
|
|
5123
|
-
// xoshiro256++ by David Blackman and Sebastiano Vigna (vigna@acm.org)
|
|
5124
|
-
// Hopefully I did not screw it up :)
|
|
5125
|
-
|
|
5126
|
-
uint64_t result = ROTL64(state[0] + state[3], 23) + state[0];
|
|
5127
|
-
uint64_t t = state[1] << 17;
|
|
5128
|
-
|
|
5129
|
-
state[2] ^= state[0];
|
|
5130
|
-
state[3] ^= state[1];
|
|
5131
|
-
state[1] ^= state[2];
|
|
5132
|
-
state[0] ^= state[3];
|
|
5133
|
-
state[2] ^= t;
|
|
5134
|
-
state[3] = ROTL64(state[3], 45);
|
|
5135
|
-
|
|
5136
|
-
return result;
|
|
5137
|
-
}
|
|
5138
|
-
|
|
5139
5084
|
static RG_THREAD_LOCAL Size rnd_remain;
|
|
5140
5085
|
static RG_THREAD_LOCAL int64_t rnd_time;
|
|
5141
5086
|
#ifndef _WIN32
|
|
@@ -5145,6 +5090,17 @@ static RG_THREAD_LOCAL uint32_t rnd_state[16];
|
|
|
5145
5090
|
static RG_THREAD_LOCAL uint8_t rnd_buf[64];
|
|
5146
5091
|
static RG_THREAD_LOCAL Size rnd_offset;
|
|
5147
5092
|
|
|
5093
|
+
static thread_local FastRandom rng_fast;
|
|
5094
|
+
|
|
5095
|
+
static inline uint32_t ROTL32(uint32_t v, int n)
|
|
5096
|
+
{
|
|
5097
|
+
return (v << n) | (v >> (32 - n));
|
|
5098
|
+
}
|
|
5099
|
+
|
|
5100
|
+
static inline uint64_t ROTL64(uint64_t v, int n) {
|
|
5101
|
+
return (v << n) | (v >> (64 - n));
|
|
5102
|
+
}
|
|
5103
|
+
|
|
5148
5104
|
static void InitChaCha20(uint32_t state[16], uint32_t key[8], uint32_t iv[2])
|
|
5149
5105
|
{
|
|
5150
5106
|
alignas(uint32_t) static char str[] = "expand 32-byte k";
|
|
@@ -5251,18 +5207,18 @@ void FillRandomSafe(void *out_buf, Size len)
|
|
|
5251
5207
|
|
|
5252
5208
|
memset(rnd_state, 0, RG_SIZE(rnd_state));
|
|
5253
5209
|
#if defined(_WIN32)
|
|
5254
|
-
RG_CRITICAL(RtlGenRandom(&buf, RG_SIZE(buf)), "RtlGenRandom() failed: %
|
|
5210
|
+
RG_CRITICAL(RtlGenRandom(&buf, RG_SIZE(buf)), "RtlGenRandom() failed: %1", GetWin32ErrorString());
|
|
5255
5211
|
#elif defined(__linux__)
|
|
5256
5212
|
{
|
|
5257
5213
|
restart:
|
|
5258
5214
|
int ret = syscall(SYS_getrandom, &buf, RG_SIZE(buf), 0);
|
|
5259
|
-
RG_CRITICAL(ret >= 0, "getentropy() failed: %
|
|
5215
|
+
RG_CRITICAL(ret >= 0, "getentropy() failed: %1", strerror(errno));
|
|
5260
5216
|
|
|
5261
5217
|
if (ret < RG_SIZE(buf))
|
|
5262
5218
|
goto restart;
|
|
5263
5219
|
}
|
|
5264
5220
|
#else
|
|
5265
|
-
RG_CRITICAL(getentropy(&buf, RG_SIZE(buf)) == 0, "getentropy() failed: %
|
|
5221
|
+
RG_CRITICAL(getentropy(&buf, RG_SIZE(buf)) == 0, "getentropy() failed: %1", strerror(errno));
|
|
5266
5222
|
#endif
|
|
5267
5223
|
|
|
5268
5224
|
InitChaCha20(rnd_state, buf.key, buf.iv);
|
|
@@ -5312,6 +5268,75 @@ int GetRandomIntSafe(int min, int max)
|
|
|
5312
5268
|
return min + (int)x;
|
|
5313
5269
|
}
|
|
5314
5270
|
|
|
5271
|
+
FastRandom::FastRandom()
|
|
5272
|
+
{
|
|
5273
|
+
do {
|
|
5274
|
+
FillRandomSafe(state, RG_SIZE(state));
|
|
5275
|
+
} while (std::all_of(std::begin(state), std::end(state), [](uint64_t v) { return !v; }));
|
|
5276
|
+
}
|
|
5277
|
+
|
|
5278
|
+
FastRandom::FastRandom(uint64_t seed)
|
|
5279
|
+
{
|
|
5280
|
+
// splitmix64 generator to seed xoshiro256++, as recommended
|
|
5281
|
+
|
|
5282
|
+
seed += 0x9e3779b97f4a7c15;
|
|
5283
|
+
|
|
5284
|
+
for (int i = 0; i < 4; i++) {
|
|
5285
|
+
seed = (seed ^ (seed >> 30)) * 0xbf58476d1ce4e5b9;
|
|
5286
|
+
seed = (seed ^ (seed >> 27)) * 0x94d049bb133111eb;
|
|
5287
|
+
state[i] = seed ^ (seed >> 31);
|
|
5288
|
+
}
|
|
5289
|
+
}
|
|
5290
|
+
|
|
5291
|
+
void FastRandom::Fill(void *out_buf, Size len)
|
|
5292
|
+
{
|
|
5293
|
+
for (Size i = 0; i < len; i += 8) {
|
|
5294
|
+
uint64_t rnd = Next();
|
|
5295
|
+
|
|
5296
|
+
Size copy_len = std::min(RG_SIZE(rnd), len - i);
|
|
5297
|
+
memcpy((uint8_t *)out_buf + i, &rnd, copy_len);
|
|
5298
|
+
}
|
|
5299
|
+
}
|
|
5300
|
+
|
|
5301
|
+
int FastRandom::GetInt(int min, int max)
|
|
5302
|
+
{
|
|
5303
|
+
int range = max - min;
|
|
5304
|
+
RG_ASSERT(range >= 2);
|
|
5305
|
+
|
|
5306
|
+
unsigned int treshold = (UINT_MAX - UINT_MAX % range);
|
|
5307
|
+
|
|
5308
|
+
unsigned int x;
|
|
5309
|
+
do {
|
|
5310
|
+
x = (unsigned int)Next();
|
|
5311
|
+
} while (x >= treshold);
|
|
5312
|
+
x %= range;
|
|
5313
|
+
|
|
5314
|
+
return min + (int)x;
|
|
5315
|
+
}
|
|
5316
|
+
|
|
5317
|
+
uint64_t FastRandom::Next()
|
|
5318
|
+
{
|
|
5319
|
+
// xoshiro256++ by David Blackman and Sebastiano Vigna (vigna@acm.org)
|
|
5320
|
+
// Hopefully I did not screw it up :)
|
|
5321
|
+
|
|
5322
|
+
uint64_t result = ROTL64(state[0] + state[3], 23) + state[0];
|
|
5323
|
+
uint64_t t = state[1] << 17;
|
|
5324
|
+
|
|
5325
|
+
state[2] ^= state[0];
|
|
5326
|
+
state[3] ^= state[1];
|
|
5327
|
+
state[1] ^= state[2];
|
|
5328
|
+
state[0] ^= state[3];
|
|
5329
|
+
state[2] ^= t;
|
|
5330
|
+
state[3] = ROTL64(state[3], 45);
|
|
5331
|
+
|
|
5332
|
+
return result;
|
|
5333
|
+
}
|
|
5334
|
+
|
|
5335
|
+
int GetRandomIntFast(int min, int max)
|
|
5336
|
+
{
|
|
5337
|
+
return rng_fast.GetInt(min, max);
|
|
5338
|
+
}
|
|
5339
|
+
|
|
5315
5340
|
// ------------------------------------------------------------------------
|
|
5316
5341
|
// Sockets
|
|
5317
5342
|
// ------------------------------------------------------------------------
|
|
@@ -5517,7 +5542,10 @@ struct Task {
|
|
|
5517
5542
|
std::function<bool()> func;
|
|
5518
5543
|
};
|
|
5519
5544
|
|
|
5520
|
-
struct
|
|
5545
|
+
struct WorkerData {
|
|
5546
|
+
AsyncPool *pool = nullptr;
|
|
5547
|
+
int idx;
|
|
5548
|
+
|
|
5521
5549
|
std::mutex queue_mutex;
|
|
5522
5550
|
BucketArray<Task> tasks;
|
|
5523
5551
|
};
|
|
@@ -5533,15 +5561,13 @@ class AsyncPool {
|
|
|
5533
5561
|
int refcount = 0;
|
|
5534
5562
|
|
|
5535
5563
|
int async_count = 0;
|
|
5536
|
-
HeapArray<
|
|
5537
|
-
|
|
5538
|
-
HeapArray<TaskQueue> queues;
|
|
5564
|
+
HeapArray<WorkerData> workers;
|
|
5539
5565
|
std::atomic_int pending_tasks { 0 };
|
|
5540
5566
|
|
|
5541
5567
|
public:
|
|
5542
5568
|
AsyncPool(int threads, bool leak);
|
|
5543
5569
|
|
|
5544
|
-
int GetWorkerCount() const { return (int)
|
|
5570
|
+
int GetWorkerCount() const { return (int)workers.len; }
|
|
5545
5571
|
int CountPendingTasks() const { return pending_tasks; }
|
|
5546
5572
|
|
|
5547
5573
|
void RegisterAsync();
|
|
@@ -5552,7 +5578,7 @@ public:
|
|
|
5552
5578
|
void RunWorker(int worker_idx);
|
|
5553
5579
|
void SyncOn(Async *async);
|
|
5554
5580
|
|
|
5555
|
-
void RunTasks(int
|
|
5581
|
+
void RunTasks(int worker_idx);
|
|
5556
5582
|
void RunTask(Task *task);
|
|
5557
5583
|
};
|
|
5558
5584
|
|
|
@@ -5643,25 +5669,72 @@ AsyncPool::AsyncPool(int threads, bool leak)
|
|
|
5643
5669
|
threads = RG_ASYNC_MAX_THREADS;
|
|
5644
5670
|
}
|
|
5645
5671
|
|
|
5646
|
-
// The first queue is for the main thread
|
|
5647
|
-
|
|
5648
|
-
workers_state.AppendDefault(threads);
|
|
5649
|
-
queues.AppendDefault(threads);
|
|
5672
|
+
// The first queue is for the main thread
|
|
5673
|
+
workers.AppendDefault(threads);
|
|
5650
5674
|
|
|
5651
5675
|
refcount = leak;
|
|
5652
5676
|
}
|
|
5653
5677
|
|
|
5678
|
+
#ifdef _WIN32
|
|
5679
|
+
|
|
5680
|
+
static DWORD WINAPI RunWorkerWin32(void *udata)
|
|
5681
|
+
{
|
|
5682
|
+
WorkerData *worker = (WorkerData *)udata;
|
|
5683
|
+
worker->pool->RunWorker(worker->idx);
|
|
5684
|
+
return 0;
|
|
5685
|
+
}
|
|
5686
|
+
|
|
5687
|
+
#else
|
|
5688
|
+
|
|
5689
|
+
static void *RunWorkerPthread(void *udata)
|
|
5690
|
+
{
|
|
5691
|
+
WorkerData *worker = (WorkerData *)udata;
|
|
5692
|
+
worker->pool->RunWorker(worker->idx);
|
|
5693
|
+
return nullptr;
|
|
5694
|
+
}
|
|
5695
|
+
|
|
5696
|
+
#endif
|
|
5697
|
+
|
|
5654
5698
|
void AsyncPool::RegisterAsync()
|
|
5655
5699
|
{
|
|
5656
5700
|
std::lock_guard<std::mutex> lock_pool(pool_mutex);
|
|
5657
5701
|
|
|
5658
5702
|
if (!async_count++) {
|
|
5659
|
-
for (int i = 1; i <
|
|
5660
|
-
|
|
5661
|
-
|
|
5703
|
+
for (int i = 1; i < workers.len; i++) {
|
|
5704
|
+
WorkerData *worker = &workers[i];
|
|
5705
|
+
|
|
5706
|
+
if (!worker->pool) {
|
|
5707
|
+
worker->pool = this;
|
|
5708
|
+
worker->idx = i;
|
|
5709
|
+
|
|
5710
|
+
#ifdef _WIN32
|
|
5711
|
+
// Our worker threads may exit after main() has returned (or exit has been called),
|
|
5712
|
+
// which can trigger crashes in _Cnd_do_broadcast_at_thread_exit() because it
|
|
5713
|
+
// tries to dereference destroyed stuff. It turns out that std::thread calls this
|
|
5714
|
+
// function, and we don't want that, so avoid std::thread on Windows.
|
|
5715
|
+
HANDLE h = CreateThread(nullptr, 0, RunWorkerWin32, worker, 0, nullptr);
|
|
5716
|
+
if (!h) [[unlikely]] {
|
|
5717
|
+
LogError("Failed to create worker thread: %1", GetWin32ErrorString());
|
|
5718
|
+
|
|
5719
|
+
worker->pool = nullptr;
|
|
5720
|
+
return;
|
|
5721
|
+
}
|
|
5722
|
+
|
|
5723
|
+
CloseHandle(h);
|
|
5724
|
+
#else
|
|
5725
|
+
pthread_t thread;
|
|
5726
|
+
int ret = pthread_create(&thread, nullptr, RunWorkerPthread, worker);
|
|
5727
|
+
if (ret) [[unlikely]] {
|
|
5728
|
+
LogError("Failed to create worker thread: %1", strerror(ret));
|
|
5729
|
+
|
|
5730
|
+
worker->pool = nullptr;
|
|
5731
|
+
return;
|
|
5732
|
+
}
|
|
5733
|
+
|
|
5734
|
+
pthread_detach(thread);
|
|
5735
|
+
#endif
|
|
5662
5736
|
|
|
5663
5737
|
refcount++;
|
|
5664
|
-
workers_state[i] = true;
|
|
5665
5738
|
}
|
|
5666
5739
|
}
|
|
5667
5740
|
}
|
|
@@ -5677,20 +5750,20 @@ void AsyncPool::AddTask(Async *async, const std::function<bool()> &func)
|
|
|
5677
5750
|
{
|
|
5678
5751
|
if (async_running_pool != async->pool) {
|
|
5679
5752
|
for (;;) {
|
|
5680
|
-
int idx =
|
|
5681
|
-
|
|
5753
|
+
int idx = GetRandomIntFast(0, (int)workers.len);
|
|
5754
|
+
WorkerData *worker = &workers[idx];
|
|
5682
5755
|
|
|
5683
|
-
std::unique_lock<std::mutex> lock_queue(
|
|
5756
|
+
std::unique_lock<std::mutex> lock_queue(worker->queue_mutex, std::try_to_lock);
|
|
5684
5757
|
if (lock_queue.owns_lock()) {
|
|
5685
|
-
|
|
5758
|
+
worker->tasks.Append({ async, func });
|
|
5686
5759
|
break;
|
|
5687
5760
|
}
|
|
5688
5761
|
}
|
|
5689
5762
|
} else {
|
|
5690
|
-
|
|
5763
|
+
WorkerData *worker = &workers[async_running_worker_idx];
|
|
5691
5764
|
|
|
5692
|
-
std::lock_guard<std::mutex> lock_queue(
|
|
5693
|
-
|
|
5765
|
+
std::lock_guard<std::mutex> lock_queue(worker->queue_mutex);
|
|
5766
|
+
worker->tasks.Append({ async, func });
|
|
5694
5767
|
}
|
|
5695
5768
|
|
|
5696
5769
|
async->remaining_tasks++;
|
|
@@ -5720,7 +5793,8 @@ void AsyncPool::RunWorker(int worker_idx)
|
|
|
5720
5793
|
pending_cv.wait_for(lock_pool, duration, [&]() { return !!pending_tasks; });
|
|
5721
5794
|
}
|
|
5722
5795
|
|
|
5723
|
-
|
|
5796
|
+
workers[worker_idx].pool = nullptr;
|
|
5797
|
+
|
|
5724
5798
|
if (!--refcount) {
|
|
5725
5799
|
lock_pool.unlock();
|
|
5726
5800
|
delete this;
|
|
@@ -5739,31 +5813,31 @@ void AsyncPool::SyncOn(Async *async)
|
|
|
5739
5813
|
async_running_worker_idx = 0;
|
|
5740
5814
|
|
|
5741
5815
|
while (async->remaining_tasks) {
|
|
5742
|
-
RunTasks(
|
|
5816
|
+
RunTasks(0);
|
|
5743
5817
|
|
|
5744
5818
|
std::unique_lock<std::mutex> lock_sync(pool_mutex);
|
|
5745
5819
|
sync_cv.wait(lock_sync, [&]() { return pending_tasks || !async->remaining_tasks; });
|
|
5746
5820
|
}
|
|
5747
5821
|
}
|
|
5748
5822
|
|
|
5749
|
-
void AsyncPool::RunTasks(int
|
|
5823
|
+
void AsyncPool::RunTasks(int worker_idx)
|
|
5750
5824
|
{
|
|
5751
5825
|
// The '12' factor is pretty arbitrary, don't try to find meaning there
|
|
5752
|
-
for (int i = 0; i <
|
|
5753
|
-
|
|
5754
|
-
std::unique_lock<std::mutex> lock_queue(
|
|
5826
|
+
for (int i = 0; i < workers.len * 12; i++) {
|
|
5827
|
+
WorkerData *worker = &workers[worker_idx];
|
|
5828
|
+
std::unique_lock<std::mutex> lock_queue(worker->queue_mutex, std::try_to_lock);
|
|
5755
5829
|
|
|
5756
|
-
if (lock_queue.owns_lock() &&
|
|
5757
|
-
Task task = std::move(
|
|
5830
|
+
if (lock_queue.owns_lock() && worker->tasks.len) {
|
|
5831
|
+
Task task = std::move(worker->tasks[0]);
|
|
5758
5832
|
|
|
5759
|
-
|
|
5760
|
-
|
|
5833
|
+
worker->tasks.RemoveFirst();
|
|
5834
|
+
worker->tasks.Trim();
|
|
5761
5835
|
|
|
5762
5836
|
lock_queue.unlock();
|
|
5763
5837
|
|
|
5764
5838
|
RunTask(&task);
|
|
5765
5839
|
} else {
|
|
5766
|
-
|
|
5840
|
+
worker_idx = (++worker_idx < workers.len) ? worker_idx : 0;
|
|
5767
5841
|
}
|
|
5768
5842
|
}
|
|
5769
5843
|
}
|
|
@@ -5982,10 +6056,16 @@ void Fiber::FiberCallback(unsigned int high, unsigned int low)
|
|
|
5982
6056
|
static RG_THREAD_LOCAL std::unique_lock<std::mutex> *fib_lock;
|
|
5983
6057
|
static RG_THREAD_LOCAL Fiber *fib_self;
|
|
5984
6058
|
|
|
5985
|
-
Fiber::Fiber(const std::function<bool()> &f, Size
|
|
6059
|
+
Fiber::Fiber(const std::function<bool()> &f, Size)
|
|
5986
6060
|
: f(f)
|
|
5987
6061
|
{
|
|
5988
|
-
|
|
6062
|
+
int ret = pthread_create(&thread, nullptr, ThreadCallback, this);
|
|
6063
|
+
if (ret) {
|
|
6064
|
+
LogError("Failed to create thread: %1", strerror(ret));
|
|
6065
|
+
return;
|
|
6066
|
+
}
|
|
6067
|
+
joinable = true;
|
|
6068
|
+
|
|
5989
6069
|
done = false;
|
|
5990
6070
|
|
|
5991
6071
|
while (toggle == 1) {
|
|
@@ -5998,8 +6078,8 @@ Fiber::~Fiber()
|
|
|
5998
6078
|
// We are forced to execute it until the end
|
|
5999
6079
|
Finalize();
|
|
6000
6080
|
|
|
6001
|
-
if (
|
|
6002
|
-
thread
|
|
6081
|
+
if (joinable) {
|
|
6082
|
+
pthread_join(thread, nullptr);
|
|
6003
6083
|
}
|
|
6004
6084
|
}
|
|
6005
6085
|
|
|
@@ -6030,7 +6110,7 @@ bool Fiber::SwitchBack()
|
|
|
6030
6110
|
}
|
|
6031
6111
|
}
|
|
6032
6112
|
|
|
6033
|
-
void Fiber::ThreadCallback(void *udata)
|
|
6113
|
+
void *Fiber::ThreadCallback(void *udata)
|
|
6034
6114
|
{
|
|
6035
6115
|
Fiber *self = (Fiber *)udata;
|
|
6036
6116
|
|
|
@@ -6047,6 +6127,8 @@ void Fiber::ThreadCallback(void *udata)
|
|
|
6047
6127
|
|
|
6048
6128
|
self->toggle = 0;
|
|
6049
6129
|
self->cv.notify_one();
|
|
6130
|
+
|
|
6131
|
+
return nullptr;
|
|
6050
6132
|
}
|
|
6051
6133
|
|
|
6052
6134
|
void Fiber::Toggle(int to, std::unique_lock<std::mutex> *lock)
|
package/src/core/libcc/libcc.hh
CHANGED
|
@@ -3853,9 +3853,6 @@ Size ConvertWin32WideToUtf8(const wchar_t *str_w, Span<char> out_str);
|
|
|
3853
3853
|
char *GetWin32ErrorString(uint32_t error_code = UINT32_MAX);
|
|
3854
3854
|
#endif
|
|
3855
3855
|
|
|
3856
|
-
void SetEnvironmentVar(const char *name, const char *value);
|
|
3857
|
-
void DeleteEnvironmentVar(const char *name);
|
|
3858
|
-
|
|
3859
3856
|
static inline bool IsPathSeparator(char c)
|
|
3860
3857
|
{
|
|
3861
3858
|
#ifdef _WIN32
|
|
@@ -4055,17 +4052,29 @@ bool CreatePipe(int pfd[2]);
|
|
|
4055
4052
|
void CloseDescriptorSafe(int *fd_ptr);
|
|
4056
4053
|
#endif
|
|
4057
4054
|
|
|
4058
|
-
|
|
4055
|
+
struct ExecuteInfo {
|
|
4056
|
+
struct KeyValue {
|
|
4057
|
+
const char *key;
|
|
4058
|
+
const char *value;
|
|
4059
|
+
};
|
|
4060
|
+
|
|
4061
|
+
const char *work_dir = nullptr;
|
|
4062
|
+
|
|
4063
|
+
bool reset_env = false;
|
|
4064
|
+
Span<const KeyValue> env_variables = {};
|
|
4065
|
+
};
|
|
4066
|
+
|
|
4067
|
+
bool ExecuteCommandLine(const char *cmd_line, const ExecuteInfo &info,
|
|
4059
4068
|
FunctionRef<Span<const uint8_t>()> in_func,
|
|
4060
4069
|
FunctionRef<void(Span<uint8_t> buf)> out_func, int *out_code);
|
|
4061
|
-
bool ExecuteCommandLine(const char *cmd_line, const
|
|
4070
|
+
bool ExecuteCommandLine(const char *cmd_line, const ExecuteInfo &info,
|
|
4062
4071
|
Span<const uint8_t> in_buf, Size max_len,
|
|
4063
4072
|
HeapArray<uint8_t> *out_buf, int *out_code);
|
|
4064
4073
|
|
|
4065
4074
|
// Simple variants
|
|
4066
|
-
static inline bool ExecuteCommandLine(const char *cmd_line, const
|
|
4067
|
-
{ return ExecuteCommandLine(cmd_line,
|
|
4068
|
-
static inline bool ExecuteCommandLine(const char *cmd_line, const
|
|
4075
|
+
static inline bool ExecuteCommandLine(const char *cmd_line, const ExecuteInfo &info,int *out_code)
|
|
4076
|
+
{ return ExecuteCommandLine(cmd_line, info, {}, {}, out_code); }
|
|
4077
|
+
static inline bool ExecuteCommandLine(const char *cmd_line, const ExecuteInfo &info,
|
|
4069
4078
|
Span<const uint8_t> in_buf,
|
|
4070
4079
|
FunctionRef<void(Span<uint8_t> buf)> out_func, int *out_code)
|
|
4071
4080
|
{
|
|
@@ -4075,22 +4084,22 @@ static inline bool ExecuteCommandLine(const char *cmd_line, const char *work_dir
|
|
|
4075
4084
|
return buf;
|
|
4076
4085
|
};
|
|
4077
4086
|
|
|
4078
|
-
return ExecuteCommandLine(cmd_line,
|
|
4087
|
+
return ExecuteCommandLine(cmd_line, info, read_once, out_func, out_code);
|
|
4079
4088
|
}
|
|
4080
4089
|
|
|
4081
4090
|
// Char variants
|
|
4082
|
-
static inline bool ExecuteCommandLine(const char *cmd_line, const
|
|
4091
|
+
static inline bool ExecuteCommandLine(const char *cmd_line, const ExecuteInfo &info,
|
|
4083
4092
|
Span<const char> in_buf,
|
|
4084
4093
|
FunctionRef<void(Span<char> buf)> out_func, int *out_code)
|
|
4085
4094
|
{
|
|
4086
4095
|
const auto write = [&](Span<uint8_t> buf) { out_func(buf.As<char>()); };
|
|
4087
|
-
return ExecuteCommandLine(cmd_line,
|
|
4096
|
+
return ExecuteCommandLine(cmd_line, info, in_buf.As<const uint8_t>(), write, out_code);
|
|
4088
4097
|
}
|
|
4089
|
-
static inline bool ExecuteCommandLine(const char *cmd_line, const
|
|
4098
|
+
static inline bool ExecuteCommandLine(const char *cmd_line, const ExecuteInfo &info,
|
|
4090
4099
|
Span<const char> in_buf, Size max_len,
|
|
4091
4100
|
HeapArray<char> *out_buf, int *out_code)
|
|
4092
4101
|
{
|
|
4093
|
-
return ExecuteCommandLine(cmd_line,
|
|
4102
|
+
return ExecuteCommandLine(cmd_line, info, in_buf.As<const uint8_t>(), max_len,
|
|
4094
4103
|
(HeapArray<uint8_t> *)out_buf, out_code);
|
|
4095
4104
|
}
|
|
4096
4105
|
|
|
@@ -4158,6 +4167,11 @@ const char *CreateUniqueDirectory(Span<const char> directory, const char *prefix
|
|
|
4158
4167
|
// Random
|
|
4159
4168
|
// ------------------------------------------------------------------------
|
|
4160
4169
|
|
|
4170
|
+
void ZeroMemorySafe(void *ptr, Size len);
|
|
4171
|
+
void FillRandomSafe(void *buf, Size len);
|
|
4172
|
+
static inline void FillRandomSafe(Span<uint8_t> buf) { FillRandomSafe(buf.ptr, buf.len); }
|
|
4173
|
+
int GetRandomIntSafe(int min, int max);
|
|
4174
|
+
|
|
4161
4175
|
class FastRandom {
|
|
4162
4176
|
uint64_t state[4];
|
|
4163
4177
|
|
|
@@ -4190,10 +4204,7 @@ public:
|
|
|
4190
4204
|
int operator()() { return rng.GetInt(Min, Max); }
|
|
4191
4205
|
};
|
|
4192
4206
|
|
|
4193
|
-
|
|
4194
|
-
void FillRandomSafe(void *buf, Size len);
|
|
4195
|
-
static inline void FillRandomSafe(Span<uint8_t> buf) { FillRandomSafe(buf.ptr, buf.len); }
|
|
4196
|
-
int GetRandomIntSafe(int min, int max);
|
|
4207
|
+
int GetRandomIntFast(int min, int max);
|
|
4197
4208
|
|
|
4198
4209
|
// ------------------------------------------------------------------------
|
|
4199
4210
|
// Sockets
|
|
@@ -4269,7 +4280,8 @@ class Fiber {
|
|
|
4269
4280
|
#elif defined(RG_FIBER_USE_UCONTEXT)
|
|
4270
4281
|
ucontext_t ucp = {};
|
|
4271
4282
|
#else
|
|
4272
|
-
|
|
4283
|
+
pthread_t thread;
|
|
4284
|
+
bool joinable = false;
|
|
4273
4285
|
|
|
4274
4286
|
std::mutex mutex;
|
|
4275
4287
|
std::condition_variable cv;
|
|
@@ -4297,7 +4309,7 @@ private:
|
|
|
4297
4309
|
#elif defined(RG_FIBER_USE_UCONTEXT)
|
|
4298
4310
|
static void FiberCallback(unsigned int high, unsigned int low);
|
|
4299
4311
|
#else
|
|
4300
|
-
static void ThreadCallback(void *udata);
|
|
4312
|
+
static void *ThreadCallback(void *udata);
|
|
4301
4313
|
void Toggle(int to, std::unique_lock<std::mutex> *lock);
|
|
4302
4314
|
#endif
|
|
4303
4315
|
};
|
package/src/koffi/CMakeLists.txt
CHANGED
|
@@ -31,17 +31,17 @@ find_package(CNoke)
|
|
|
31
31
|
set(CMAKE_CXX_STANDARD 20)
|
|
32
32
|
if(MSVC)
|
|
33
33
|
set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreaded)
|
|
34
|
-
|
|
35
|
-
add_compile_options(/Zc:__cplusplus /W4 /wd4200 /wd4458 /wd4706 /wd4100 /wd4127 /wd4702 /wd4201 /wd4324)
|
|
34
|
+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Zc:__cplusplus /W4 /wd4200 /wd4201 /wd4127 /wd4458 /wd4706 /wd4702 /wd4324")
|
|
36
35
|
|
|
37
36
|
# ASM_MASM does not (yet) work on Windows ARM64
|
|
38
37
|
if(NOT CMAKE_GENERATOR_PLATFORM MATCHES "ARM64")
|
|
39
38
|
enable_language(ASM_MASM)
|
|
40
39
|
endif()
|
|
41
40
|
else()
|
|
42
|
-
|
|
41
|
+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wno-missing-field-initializers -Wno-unused-parameter -Wswitch -Werror=switch")
|
|
42
|
+
|
|
43
43
|
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
|
44
|
-
|
|
44
|
+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unknown-warning-option")
|
|
45
45
|
endif()
|
|
46
46
|
endif()
|
|
47
47
|
|
|
@@ -132,16 +132,16 @@ if(NOT MSVC OR CMAKE_C_COMPILER_ID MATCHES "[Cc]lang")
|
|
|
132
132
|
# Restore C/C++ compiler sanity
|
|
133
133
|
|
|
134
134
|
if(NOT MSVC)
|
|
135
|
-
target_compile_options(koffi PRIVATE
|
|
136
|
-
|
|
135
|
+
target_compile_options(koffi PRIVATE $<$<COMPILE_LANGUAGE:CXX>:-fno-exceptions -fno-strict-aliasing -fwrapv
|
|
136
|
+
-fno-delete-null-pointer-checks>)
|
|
137
137
|
else()
|
|
138
|
-
target_compile_options(koffi PRIVATE
|
|
139
|
-
|
|
138
|
+
target_compile_options(koffi PRIVATE $<$<COMPILE_LANGUAGE:CXX>:-fno-strict-aliasing /clang:-fwrapv
|
|
139
|
+
-fno-delete-null-pointer-checks>)
|
|
140
140
|
endif()
|
|
141
141
|
|
|
142
142
|
check_cxx_compiler_flag(-fno-finite-loops use_no_finite_loops)
|
|
143
143
|
if(use_no_finite_loops)
|
|
144
|
-
target_compile_options(koffi PRIVATE
|
|
144
|
+
target_compile_options(koffi PRIVATE $<$<COMPILE_LANGUAGE:CXX>:-fno-finite-loops>)
|
|
145
145
|
endif()
|
|
146
146
|
endif()
|
|
147
147
|
enable_unity_build(koffi)
|
package/src/koffi/src/ffi.cc
CHANGED
|
@@ -2224,7 +2224,7 @@ static Napi::Value ResetKoffi(const Napi::CallbackInfo &info)
|
|
|
2224
2224
|
return env.Undefined();
|
|
2225
2225
|
}
|
|
2226
2226
|
|
|
2227
|
-
static InstanceData *CreateInstance(
|
|
2227
|
+
static InstanceData *CreateInstance()
|
|
2228
2228
|
{
|
|
2229
2229
|
InstanceData *instance = new InstanceData();
|
|
2230
2230
|
RG_DEFER_N(err_guard) { delete instance; };
|
|
@@ -2247,7 +2247,7 @@ static InstanceData *CreateInstance(Napi::Env env)
|
|
|
2247
2247
|
|
|
2248
2248
|
static Napi::Object InitModule(Napi::Env env, Napi::Object exports)
|
|
2249
2249
|
{
|
|
2250
|
-
InstanceData *instance = CreateInstance(
|
|
2250
|
+
InstanceData *instance = CreateInstance();
|
|
2251
2251
|
RG_CRITICAL(instance, "Failed to initialize Koffi");
|
|
2252
2252
|
|
|
2253
2253
|
env.SetInstanceData(instance);
|
package/src/koffi/src/win32.cc
CHANGED