koffi 2.4.2 → 2.5.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/2.5.0-beta.2/koffi_darwin_arm64/koffi.node +0 -0
- package/build/2.5.0-beta.2/koffi_darwin_x64/koffi.node +0 -0
- package/build/2.5.0-beta.2/koffi_freebsd_arm64/koffi.node +0 -0
- package/build/2.5.0-beta.2/koffi_freebsd_ia32/koffi.node +0 -0
- package/build/2.5.0-beta.2/koffi_freebsd_x64/koffi.node +0 -0
- package/build/2.5.0-beta.2/koffi_linux_arm32hf/koffi.node +0 -0
- package/build/2.5.0-beta.2/koffi_linux_arm64/koffi.node +0 -0
- package/build/2.5.0-beta.2/koffi_linux_ia32/koffi.node +0 -0
- package/build/2.5.0-beta.2/koffi_linux_riscv64hf64/koffi.node +0 -0
- package/build/2.5.0-beta.2/koffi_linux_x64/koffi.node +0 -0
- package/build/2.5.0-beta.2/koffi_openbsd_ia32/koffi.node +0 -0
- package/build/{2.4.2 → 2.5.0-beta.2}/koffi_openbsd_x64/koffi.node +0 -0
- package/build/2.5.0-beta.2/koffi_win32_arm64/koffi.node +0 -0
- package/build/{2.4.2 → 2.5.0-beta.2}/koffi_win32_ia32/koffi.node +0 -0
- package/build/{2.4.2 → 2.5.0-beta.2}/koffi_win32_x64/koffi.node +0 -0
- package/build/2.5.0-beta.2/koffi_win32_x64/koffi.pdb +0 -0
- package/doc/callbacks.md +1 -1
- package/doc/conf.py +1 -1
- package/doc/functions.md +1 -1
- package/doc/index.rst +1 -0
- package/doc/parameters.md +1 -1
- package/doc/pointers.md +1 -1
- package/doc/unions.md +187 -0
- package/package.json +1 -1
- package/src/core/libcc/libcc.cc +58 -54
- package/src/core/libcc/libcc.hh +33 -19
- package/src/koffi/src/abi_x86.cc +31 -4
- package/src/koffi/src/call.cc +42 -22
- package/src/koffi/src/ffi.cc +259 -311
- package/src/koffi/src/ffi.hh +3 -1
- package/src/koffi/src/util.cc +20 -13
- package/src/koffi/src/util.hh +5 -2
- package/vendor/node-addon-api/CHANGELOG.md +31 -0
- package/vendor/node-addon-api/README.md +3 -2
- package/vendor/node-addon-api/doc/async_worker.md +1 -0
- package/vendor/node-addon-api/doc/creating_a_release.md +21 -0
- package/vendor/node-addon-api/doc/value.md +7 -0
- package/vendor/node-addon-api/napi-inl.h +23 -7
- package/vendor/node-addon-api/package.json +9 -1
- package/vendor/node-addon-api/test/async_progress_queue_worker.cc +155 -0
- package/vendor/node-addon-api/test/async_progress_queue_worker.js +134 -0
- package/vendor/node-addon-api/test/async_progress_worker.cc +155 -0
- package/vendor/node-addon-api/test/async_progress_worker.js +134 -0
- package/vendor/node-addon-api/test/common/index.js +45 -0
- package/vendor/node-addon-api/test/objectwrap.js +9 -0
- package/build/2.4.2/koffi_darwin_arm64/koffi.node +0 -0
- package/build/2.4.2/koffi_darwin_x64/koffi.node +0 -0
- package/build/2.4.2/koffi_freebsd_arm64/koffi.node +0 -0
- package/build/2.4.2/koffi_freebsd_ia32/koffi.node +0 -0
- package/build/2.4.2/koffi_freebsd_x64/koffi.node +0 -0
- package/build/2.4.2/koffi_linux_arm32hf/koffi.node +0 -0
- package/build/2.4.2/koffi_linux_arm64/koffi.node +0 -0
- package/build/2.4.2/koffi_linux_ia32/koffi.node +0 -0
- package/build/2.4.2/koffi_linux_riscv64hf64/koffi.node +0 -0
- package/build/2.4.2/koffi_linux_x64/koffi.node +0 -0
- package/build/2.4.2/koffi_openbsd_ia32/koffi.node +0 -0
- package/build/2.4.2/koffi_win32_arm64/koffi.node +0 -0
- /package/build/{2.4.2 → 2.5.0-beta.2}/koffi_win32_arm64/koffi.exp +0 -0
- /package/build/{2.4.2 → 2.5.0-beta.2}/koffi_win32_arm64/koffi.lib +0 -0
- /package/build/{2.4.2 → 2.5.0-beta.2}/koffi_win32_ia32/koffi.exp +0 -0
- /package/build/{2.4.2 → 2.5.0-beta.2}/koffi_win32_ia32/koffi.lib +0 -0
- /package/build/{2.4.2 → 2.5.0-beta.2}/koffi_win32_x64/koffi.exp +0 -0
- /package/build/{2.4.2 → 2.5.0-beta.2}/koffi_win32_x64/koffi.lib +0 -0
|
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/callbacks.md
CHANGED
|
@@ -20,7 +20,7 @@ const ExampleCallback = koffi.proto('ExampleCallback', 'void', ['int']);
|
|
|
20
20
|
const AddDoubleFloat = koffi.proto('double AddDoubleFloat(double d, float f)');
|
|
21
21
|
```
|
|
22
22
|
|
|
23
|
-
Once your callback type is declared, you can use a pointer to it in struct definitions,
|
|
23
|
+
Once your callback type is declared, you can use a pointer to it in struct definitions, as function parameters and/or return types, or to call/decode function pointers.
|
|
24
24
|
|
|
25
25
|
```{note}
|
|
26
26
|
Callbacks **have changed in version 2.0**.
|
package/doc/conf.py
CHANGED
package/doc/functions.md
CHANGED
|
@@ -137,7 +137,7 @@ You can easily convert this callback-style async function to a promise-based ver
|
|
|
137
137
|
|
|
138
138
|
Variadic functions cannot be called asynchronously.
|
|
139
139
|
|
|
140
|
-
```{
|
|
140
|
+
```{warning}
|
|
141
141
|
Asynchronous functions run on worker threads. You need to deal with thread safety issues if you share data between threads.
|
|
142
142
|
|
|
143
143
|
Callbacks must be called from the main thread, or more precisely from the same thread as the V8 intepreter. Calling a callback from another thread is undefined behavior, and will likely lead to a crash or a big mess. You've been warned!
|
package/doc/index.rst
CHANGED
package/doc/parameters.md
CHANGED
|
@@ -9,6 +9,7 @@ By default, Koffi will only forward arguments from Javascript to C. However, man
|
|
|
9
9
|
For simplicity, and because Javascript only has value semantics for primitive types, Koffi can marshal out (or in/out) two types of parameters:
|
|
10
10
|
|
|
11
11
|
- [Structs](types.md#struct-types) (to/from JS objects)
|
|
12
|
+
- [Unions](unions.md)
|
|
12
13
|
- [Opaque types](types.md#opaque-types)
|
|
13
14
|
- String buffers
|
|
14
15
|
|
|
@@ -212,7 +213,6 @@ if (filename == null)
|
|
|
212
213
|
|
|
213
214
|
let hdr = {};
|
|
214
215
|
{
|
|
215
|
-
|
|
216
216
|
let fp = fopen(filename, 'rb');
|
|
217
217
|
if (!fp)
|
|
218
218
|
throw new Error(`Failed to open '${filename}'`);
|
package/doc/pointers.md
CHANGED
|
@@ -132,7 +132,7 @@ By default, just like for objects, array arguments are copied from JS to C but n
|
|
|
132
132
|
|
|
133
133
|
Disposable types allow you to register a function that will automatically called after each C to JS conversion performed by Koffi. This can be used to avoid leaking heap-allocated strings, for example.
|
|
134
134
|
|
|
135
|
-
Read the documentation for [disposable types](parameters.md#heap-allocated-values) on the page about
|
|
135
|
+
Read the documentation for [disposable types](parameters.md#heap-allocated-values) on the page about special parameters.
|
|
136
136
|
|
|
137
137
|
## Unwrap pointers
|
|
138
138
|
|
package/doc/unions.md
ADDED
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
# Union values
|
|
2
|
+
|
|
3
|
+
*New in Koffi 2.5*
|
|
4
|
+
|
|
5
|
+
## Union definition
|
|
6
|
+
|
|
7
|
+
You can declare unions with a syntax similar to structs, but with the `koffi.union()` function. This function takes two arguments: the first one is the name of the type, and the second one is an object containing the union member names and types. You can omit the first argument to declare an anonymous union.
|
|
8
|
+
|
|
9
|
+
The following example illustrates how to declare the same union in C and in JS with Koffi:
|
|
10
|
+
|
|
11
|
+
```c
|
|
12
|
+
typedef union IntOrDouble {
|
|
13
|
+
int64_t i;
|
|
14
|
+
double d;
|
|
15
|
+
} IntOrDouble;
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
```js
|
|
19
|
+
const IntOrDouble = koffi.union('IntOrDouble', {
|
|
20
|
+
i: 'int64_t',
|
|
21
|
+
d: 'double'
|
|
22
|
+
});
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Input unions
|
|
26
|
+
|
|
27
|
+
### Passing union values to C
|
|
28
|
+
|
|
29
|
+
You can instantiate an union object with `koffi.Union(type)`. This will create a special object that contains at most one active member.
|
|
30
|
+
|
|
31
|
+
Once you have created an instance of your union, you can simply set the member with the dot operator as you would with a basic object. Then, simply pass your union value to the C function you wish.
|
|
32
|
+
|
|
33
|
+
```js
|
|
34
|
+
const U = koffi.union('U', { i: 'int', str: 'char *' });
|
|
35
|
+
|
|
36
|
+
const DoSomething = lib.func('void DoSomething(const char *type, U u)');
|
|
37
|
+
|
|
38
|
+
const u1 = new koffi.Union('U'); u1.i = 42;
|
|
39
|
+
const u2 = new koffi.Union('U'); u2.str = 'Hello!';
|
|
40
|
+
|
|
41
|
+
DoSomething('int', u1);
|
|
42
|
+
DoSomething('string', u2);
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
For simplicity, Koffi also accepts object literals with one property (no more, no less) setting the corresponding union member. The example belows uses this to simplify the code shown above:
|
|
46
|
+
|
|
47
|
+
```js
|
|
48
|
+
const U = koffi.union('U', { i: 'int', str: 'char *' });
|
|
49
|
+
|
|
50
|
+
const DoSomething = lib.func('void DoSomething(const char *type, U u)');
|
|
51
|
+
|
|
52
|
+
DoSomething('int', { .i = 42 });
|
|
53
|
+
DoSomething('string', { .str = 'Hello!' });
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Win32 example
|
|
57
|
+
|
|
58
|
+
The following example uses the [SendInput](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-sendinput) Win32 API to emit the Win+D shortcut and hide windows (show the desktop).
|
|
59
|
+
|
|
60
|
+
```js
|
|
61
|
+
const koffi = require('koffi');
|
|
62
|
+
|
|
63
|
+
// Win32 type and functions
|
|
64
|
+
|
|
65
|
+
const user32 = koffi.load('user32.dll');
|
|
66
|
+
|
|
67
|
+
const INPUT_MOUSE = 0;
|
|
68
|
+
const INPUT_KEYBOARD = 1;
|
|
69
|
+
const INPUT_HARDWARE = 2;
|
|
70
|
+
|
|
71
|
+
const KEYEVENTF_KEYUP = 0x2;
|
|
72
|
+
const KEYEVENTF_SCANCODE = 0x8;
|
|
73
|
+
|
|
74
|
+
const VK_LWIN = 0x5B;
|
|
75
|
+
const VK_D = 0x44;
|
|
76
|
+
|
|
77
|
+
const MOUSEINPUT = koffi.struct('MOUSEINPUT', {
|
|
78
|
+
dx: 'long',
|
|
79
|
+
dy: 'long',
|
|
80
|
+
mouseData: 'uint32_t',
|
|
81
|
+
dwFlags: 'uint32_t',
|
|
82
|
+
time: 'uint32_t',
|
|
83
|
+
dwExtraInfo: 'uintptr_t'
|
|
84
|
+
});
|
|
85
|
+
const KEYBDINPUT = koffi.struct('KEYBDINPUT', {
|
|
86
|
+
wVk: 'uint16_t',
|
|
87
|
+
wScan: 'uint16_t',
|
|
88
|
+
dwFlags: 'uint32_t',
|
|
89
|
+
time: 'uint32_t',
|
|
90
|
+
dwExtraInfo: 'uintptr_t'
|
|
91
|
+
});
|
|
92
|
+
const HARDWAREINPUT = koffi.struct('HARDWAREINPUT', {
|
|
93
|
+
uMsg: 'uint32_t',
|
|
94
|
+
wParamL: 'uint16_t',
|
|
95
|
+
wParamH: 'uint16_t'
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
const INPUT = koffi.struct('INPUT', {
|
|
99
|
+
type: 'uint32_t',
|
|
100
|
+
u: koffi.union({
|
|
101
|
+
mi: MOUSEINPUT,
|
|
102
|
+
ki: KEYBDINPUT,
|
|
103
|
+
hi: HARDWAREINPUT
|
|
104
|
+
})
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
const SendInput = user32.func('unsigned int __stdcall SendInput(unsigned int cInputs, INPUT *pInputs, int cbSize');
|
|
108
|
+
|
|
109
|
+
// Show/hide desktop with Win+D shortcut
|
|
110
|
+
|
|
111
|
+
let events = [
|
|
112
|
+
make_keyboard_event(VK_WIN, true),
|
|
113
|
+
make_keyboard_event(VK_D, true),
|
|
114
|
+
make_keyboard_event(VK_D, false),
|
|
115
|
+
make_keyboard_event(VK_WIN, false)
|
|
116
|
+
];
|
|
117
|
+
|
|
118
|
+
SendInput(events.length, events, koffi.sizeof(INPUT));
|
|
119
|
+
|
|
120
|
+
// Utility
|
|
121
|
+
|
|
122
|
+
function make_keyboard_event(vk, down) {
|
|
123
|
+
let event = {
|
|
124
|
+
type: INPUT_KEYBOARD,
|
|
125
|
+
u: {
|
|
126
|
+
ki: {
|
|
127
|
+
wVk: vk,
|
|
128
|
+
wScan: 0,
|
|
129
|
+
dwFlags: down ? 0 : KEYEVENTF_KEYUP,
|
|
130
|
+
time: 0,
|
|
131
|
+
dwExtraInfo: 0
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
return event;
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## Output unions
|
|
141
|
+
|
|
142
|
+
Unlike structs, Koffi does not know which union member is valid, and it cannot decode it automatically. You can however use special `koffi.Union` objects for output parameters, and decode the memory after the call.
|
|
143
|
+
|
|
144
|
+
To decode an output union pointer parameter, create a placeholder object with `new koffi.Union(type)` and pass the resulting object to the function.
|
|
145
|
+
|
|
146
|
+
After the call, you can dereference the member value you want on this object and Koffi will decode it at this moment.
|
|
147
|
+
|
|
148
|
+
The following example illustrates the use of `koffi.Union()` to decode output unions after the call.
|
|
149
|
+
|
|
150
|
+
```c
|
|
151
|
+
#include <stdint.h>
|
|
152
|
+
|
|
153
|
+
typedef union IntOrDouble {
|
|
154
|
+
int64_t i;
|
|
155
|
+
double d;
|
|
156
|
+
} IntOrDouble;
|
|
157
|
+
|
|
158
|
+
void SetUnionInt(int64_t i, IntOrDouble *out)
|
|
159
|
+
{
|
|
160
|
+
out->i = i;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
void SetUnionDouble(double d, IntOrDouble *out)
|
|
164
|
+
{
|
|
165
|
+
out->d = d;
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
```js
|
|
170
|
+
const IntOrDouble = koffi.union('IntOrDouble', {
|
|
171
|
+
i: 'int64_t',
|
|
172
|
+
d: 'double',
|
|
173
|
+
raw: koffi.array('uint8_t', 8)
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
const SetUnionInt = lib.func('void SetUnionInt(int64_t i, _Out_ IntOrDouble *out)');
|
|
177
|
+
const SetUnionDouble = lib.func('void SetUnionDouble(double d, _Out_ IntOrDouble *out)');
|
|
178
|
+
|
|
179
|
+
let u1 = new koffi.Union('IntOrDouble');
|
|
180
|
+
let u2 = new koffi.Union('IntOrDouble');
|
|
181
|
+
|
|
182
|
+
SetUnionInt(123, u1);
|
|
183
|
+
SetUnionDouble(123, u2);
|
|
184
|
+
|
|
185
|
+
console.log(u1.i, '---', u1.raw); // Prints 123 --- Uint8Array(8) [123, 0, 0, 0, 0, 0, 0, 0]
|
|
186
|
+
console.log(u2.d, '---', u2.raw); // Prints 123 --- Uint8Array(8) [0, 0, 0, 0, 0, 0, 69, 64]
|
|
187
|
+
```
|
package/package.json
CHANGED
package/src/core/libcc/libcc.cc
CHANGED
|
@@ -2856,15 +2856,6 @@ const char *GetWorkingDirectory()
|
|
|
2856
2856
|
return buf;
|
|
2857
2857
|
}
|
|
2858
2858
|
|
|
2859
|
-
#ifdef __OpenBSD__
|
|
2860
|
-
RG_INIT(ExePathOpenBSD)
|
|
2861
|
-
{
|
|
2862
|
-
// This can depend on PATH, which could change during execution
|
|
2863
|
-
// so we want to cache the result as soon as possible.
|
|
2864
|
-
GetApplicationExecutable();
|
|
2865
|
-
}
|
|
2866
|
-
#endif
|
|
2867
|
-
|
|
2868
2859
|
const char *GetApplicationExecutable()
|
|
2869
2860
|
{
|
|
2870
2861
|
#if defined(_WIN32)
|
|
@@ -4068,26 +4059,6 @@ static void DefaultSignalHandler(int signal)
|
|
|
4068
4059
|
}
|
|
4069
4060
|
}
|
|
4070
4061
|
|
|
4071
|
-
RG_INIT(SetupDefaultHandlers)
|
|
4072
|
-
{
|
|
4073
|
-
// Best effort
|
|
4074
|
-
setpgid(0, 0);
|
|
4075
|
-
|
|
4076
|
-
SetSignalHandler(SIGINT, DefaultSignalHandler);
|
|
4077
|
-
SetSignalHandler(SIGTERM, DefaultSignalHandler);
|
|
4078
|
-
SetSignalHandler(SIGHUP, DefaultSignalHandler);
|
|
4079
|
-
SetSignalHandler(SIGPIPE, [](int) {});
|
|
4080
|
-
}
|
|
4081
|
-
|
|
4082
|
-
RG_EXIT(TerminateChildren)
|
|
4083
|
-
{
|
|
4084
|
-
pid_t pid = getpid();
|
|
4085
|
-
RG_ASSERT(pid > 1);
|
|
4086
|
-
|
|
4087
|
-
SetSignalHandler(SIGTERM, [](int) {});
|
|
4088
|
-
kill(-pid, SIGTERM);
|
|
4089
|
-
}
|
|
4090
|
-
|
|
4091
4062
|
bool CreatePipe(int pfd[2])
|
|
4092
4063
|
{
|
|
4093
4064
|
#ifdef __APPLE__
|
|
@@ -4625,6 +4596,42 @@ bool NotifySystemd()
|
|
|
4625
4596
|
}
|
|
4626
4597
|
#endif
|
|
4627
4598
|
|
|
4599
|
+
void InitRG()
|
|
4600
|
+
{
|
|
4601
|
+
#ifdef _WIN32
|
|
4602
|
+
// Use binary standard I/O
|
|
4603
|
+
_setmode(_fileno(stdin), _O_BINARY);
|
|
4604
|
+
_setmode(_fileno(stdout), _O_BINARY);
|
|
4605
|
+
_setmode(_fileno(stderr), _O_BINARY);
|
|
4606
|
+
#else
|
|
4607
|
+
// Best effort
|
|
4608
|
+
setpgid(0, 0);
|
|
4609
|
+
|
|
4610
|
+
// Setup default signal handlers
|
|
4611
|
+
SetSignalHandler(SIGINT, DefaultSignalHandler);
|
|
4612
|
+
SetSignalHandler(SIGTERM, DefaultSignalHandler);
|
|
4613
|
+
SetSignalHandler(SIGHUP, DefaultSignalHandler);
|
|
4614
|
+
SetSignalHandler(SIGPIPE, [](int) {});
|
|
4615
|
+
|
|
4616
|
+
// Kill children on exit
|
|
4617
|
+
atexit([]() {
|
|
4618
|
+
if (interrupt_pfd[1] >= 0) {
|
|
4619
|
+
pid_t pid = getpid();
|
|
4620
|
+
RG_ASSERT(pid > 1);
|
|
4621
|
+
|
|
4622
|
+
SetSignalHandler(SIGTERM, [](int) {});
|
|
4623
|
+
kill(-pid, SIGTERM);
|
|
4624
|
+
}
|
|
4625
|
+
});
|
|
4626
|
+
#endif
|
|
4627
|
+
|
|
4628
|
+
#ifdef __OpenBSD__
|
|
4629
|
+
// This can depend on PATH, which could change during execution
|
|
4630
|
+
// so we want to cache the result as soon as possible.
|
|
4631
|
+
GetApplicationExecutable();
|
|
4632
|
+
#endif
|
|
4633
|
+
}
|
|
4634
|
+
|
|
4628
4635
|
// ------------------------------------------------------------------------
|
|
4629
4636
|
// Standard paths
|
|
4630
4637
|
// ------------------------------------------------------------------------
|
|
@@ -4709,16 +4716,16 @@ const char *GetUserConfigPath(const char *name, Allocator *alloc)
|
|
|
4709
4716
|
RG_ASSERT(!strchr(RG_PATH_SEPARATORS, name[0]));
|
|
4710
4717
|
|
|
4711
4718
|
const char *xdg = getenv("XDG_CONFIG_HOME");
|
|
4719
|
+
const char *home = getenv("HOME");
|
|
4712
4720
|
|
|
4713
4721
|
if (xdg) {
|
|
4714
4722
|
const char *path = Fmt(alloc, "%1%/%2", xdg, name).ptr;
|
|
4715
4723
|
return path;
|
|
4716
|
-
} else {
|
|
4717
|
-
const char *home = getenv("HOME");
|
|
4718
|
-
RG_CRITICAL(home, "Failed to get HOME environment variable: %1", strerror(errno));
|
|
4719
|
-
|
|
4724
|
+
} else if (home) {
|
|
4720
4725
|
const char *path = Fmt(alloc, "%1%/.config/%2", home, name).ptr;
|
|
4721
4726
|
return path;
|
|
4727
|
+
} else {
|
|
4728
|
+
return nullptr;
|
|
4722
4729
|
}
|
|
4723
4730
|
}
|
|
4724
4731
|
|
|
@@ -4727,20 +4734,20 @@ const char *GetUserCachePath(const char *name, Allocator *alloc)
|
|
|
4727
4734
|
RG_ASSERT(!strchr(RG_PATH_SEPARATORS, name[0]));
|
|
4728
4735
|
|
|
4729
4736
|
const char *xdg = getenv("XDG_CACHE_HOME");
|
|
4737
|
+
const char *home = getenv("HOME");
|
|
4730
4738
|
|
|
4731
4739
|
if (xdg) {
|
|
4732
4740
|
const char *path = Fmt(alloc, "%1%/%2", xdg, name).ptr;
|
|
4733
4741
|
return path;
|
|
4734
|
-
} else {
|
|
4735
|
-
const char *home = getenv("HOME");
|
|
4736
|
-
RG_CRITICAL(home, "Failed to get HOME environment variable: %1", strerror(errno));
|
|
4737
|
-
|
|
4742
|
+
} else if (home) {
|
|
4738
4743
|
const char *path = Fmt(alloc, "%1%/.cache/%2", home, name).ptr;
|
|
4739
4744
|
return path;
|
|
4745
|
+
} else {
|
|
4746
|
+
return nullptr;
|
|
4740
4747
|
}
|
|
4741
4748
|
}
|
|
4742
4749
|
|
|
4743
|
-
|
|
4750
|
+
const char *GetSystemConfigPath(const char *name, Allocator *alloc)
|
|
4744
4751
|
{
|
|
4745
4752
|
RG_ASSERT(!strchr(RG_PATH_SEPARATORS, name[0]));
|
|
4746
4753
|
|
|
@@ -4792,6 +4799,9 @@ const char *FindConfigFile(const char *name, Allocator *alloc, LocalArray<const
|
|
|
4792
4799
|
for (const auto &func: funcs) {
|
|
4793
4800
|
const char *path = func(name, alloc);
|
|
4794
4801
|
|
|
4802
|
+
if (!path)
|
|
4803
|
+
continue;
|
|
4804
|
+
|
|
4795
4805
|
if (TestFile(path, FileType::File)) {
|
|
4796
4806
|
filename = path;
|
|
4797
4807
|
}
|
|
@@ -5129,8 +5139,9 @@ int OpenIPSocket(SocketType type, int port, SocketMode mode)
|
|
|
5129
5139
|
|
|
5130
5140
|
int flags = 0;
|
|
5131
5141
|
switch (mode) {
|
|
5132
|
-
case SocketMode::
|
|
5133
|
-
case SocketMode::
|
|
5142
|
+
case SocketMode::ConnectStream: { flags = SOCK_STREAM; } break;
|
|
5143
|
+
case SocketMode::ConnectDatagrams: { RG_UNREACHABLE(); } break;
|
|
5144
|
+
case SocketMode::FreeDatagrams: { flags = SOCK_DGRAM; } break;
|
|
5134
5145
|
}
|
|
5135
5146
|
|
|
5136
5147
|
#ifdef _WIN32
|
|
@@ -5199,8 +5210,9 @@ int OpenUnixSocket(const char *path, SocketMode mode)
|
|
|
5199
5210
|
{
|
|
5200
5211
|
int flags = 0;
|
|
5201
5212
|
switch (mode) {
|
|
5202
|
-
case SocketMode::
|
|
5203
|
-
case SocketMode::
|
|
5213
|
+
case SocketMode::ConnectStream: { flags = SOCK_STREAM; } break;
|
|
5214
|
+
case SocketMode::ConnectDatagrams: { flags = SOCK_SEQPACKET; } break;
|
|
5215
|
+
case SocketMode::FreeDatagrams: { flags = SOCK_DGRAM; } break;
|
|
5204
5216
|
}
|
|
5205
5217
|
|
|
5206
5218
|
#if defined(_WIN32)
|
|
@@ -5252,8 +5264,9 @@ int ConnectToUnixSocket(const char *path, SocketMode mode)
|
|
|
5252
5264
|
{
|
|
5253
5265
|
int flags = 0;
|
|
5254
5266
|
switch (mode) {
|
|
5255
|
-
case SocketMode::
|
|
5256
|
-
case SocketMode::
|
|
5267
|
+
case SocketMode::ConnectStream: { flags = SOCK_STREAM; } break;
|
|
5268
|
+
case SocketMode::ConnectDatagrams: { flags = SOCK_SEQPACKET; } break;
|
|
5269
|
+
case SocketMode::FreeDatagrams: { flags = SOCK_DGRAM; } break;
|
|
5257
5270
|
}
|
|
5258
5271
|
|
|
5259
5272
|
#if defined(_WIN32)
|
|
@@ -5867,15 +5880,6 @@ void Fiber::Toggle(int to, std::unique_lock<std::mutex> *lock)
|
|
|
5867
5880
|
// Streams
|
|
5868
5881
|
// ------------------------------------------------------------------------
|
|
5869
5882
|
|
|
5870
|
-
#ifdef _WIN32
|
|
5871
|
-
RG_INIT(BinaryStdIO)
|
|
5872
|
-
{
|
|
5873
|
-
_setmode(_fileno(stdin), _O_BINARY);
|
|
5874
|
-
_setmode(_fileno(stdout), _O_BINARY);
|
|
5875
|
-
_setmode(_fileno(stderr), _O_BINARY);
|
|
5876
|
-
}
|
|
5877
|
-
#endif
|
|
5878
|
-
|
|
5879
5883
|
StreamReader stdin_st(stdin, "<stdin>");
|
|
5880
5884
|
StreamWriter stdout_st(stdout, "<stdout>");
|
|
5881
5885
|
StreamWriter stderr_st(stderr, "<stderr>");
|
|
@@ -6416,7 +6420,7 @@ bool StreamWriter::Open(const char *filename, unsigned int flags,
|
|
|
6416
6420
|
dest.u.file.tmp_exclusive = true;
|
|
6417
6421
|
}
|
|
6418
6422
|
|
|
6419
|
-
dest.u.file.tmp_filename = CreateUniqueFile(directory, "", ".tmp", &str_alloc, &dest.u.file.fp);
|
|
6423
|
+
dest.u.file.tmp_filename = CreateUniqueFile(directory, ".", ".tmp", &str_alloc, &dest.u.file.fp);
|
|
6420
6424
|
if (!dest.u.file.tmp_filename)
|
|
6421
6425
|
return false;
|
|
6422
6426
|
dest.u.file.owned = true;
|
package/src/core/libcc/libcc.hh
CHANGED
|
@@ -2599,11 +2599,11 @@ public:
|
|
|
2599
2599
|
|
|
2600
2600
|
ValueType *Set(const KeyType &key, const ValueType &value)
|
|
2601
2601
|
{ return &table.Set({ key, value })->value; }
|
|
2602
|
-
|
|
2602
|
+
Bucket *SetDefault(const KeyType &key)
|
|
2603
2603
|
{
|
|
2604
2604
|
Bucket *table_it = table.SetDefault(key);
|
|
2605
2605
|
table_it->key = key;
|
|
2606
|
-
return
|
|
2606
|
+
return table_it;
|
|
2607
2607
|
}
|
|
2608
2608
|
|
|
2609
2609
|
ValueType *TrySet(const KeyType &key, const ValueType &value, bool *out_inserted = nullptr)
|
|
@@ -2611,7 +2611,7 @@ public:
|
|
|
2611
2611
|
Bucket *ptr = table.TrySet({ key, value }, out_inserted);
|
|
2612
2612
|
return &ptr->value;
|
|
2613
2613
|
}
|
|
2614
|
-
|
|
2614
|
+
Bucket *TrySetDefault(const KeyType &key, bool *out_inserted = nullptr)
|
|
2615
2615
|
{
|
|
2616
2616
|
bool inserted;
|
|
2617
2617
|
Bucket *ptr = table.TrySetDefault(key, &inserted);
|
|
@@ -2623,7 +2623,7 @@ public:
|
|
|
2623
2623
|
if (out_inserted) {
|
|
2624
2624
|
*out_inserted = inserted;
|
|
2625
2625
|
}
|
|
2626
|
-
return
|
|
2626
|
+
return ptr;
|
|
2627
2627
|
}
|
|
2628
2628
|
|
|
2629
2629
|
void Remove(ValueType *it)
|
|
@@ -2632,6 +2632,12 @@ public:
|
|
|
2632
2632
|
return;
|
|
2633
2633
|
table.Remove((Bucket *)((uint8_t *)it - RG_OFFSET_OF(Bucket, value)));
|
|
2634
2634
|
}
|
|
2635
|
+
void Remove(Bucket *it)
|
|
2636
|
+
{
|
|
2637
|
+
if (!it)
|
|
2638
|
+
return;
|
|
2639
|
+
table.Remove(it);
|
|
2640
|
+
}
|
|
2635
2641
|
template <typename T = KeyType>
|
|
2636
2642
|
void Remove(const KeyType &key) { Remove(Find(key)); }
|
|
2637
2643
|
|
|
@@ -3983,9 +3989,9 @@ bool ExecuteCommandLine(const char *cmd_line, FunctionRef<Span<const uint8_t>()>
|
|
|
3983
3989
|
FunctionRef<void(Span<uint8_t> buf)> out_func, int *out_code);
|
|
3984
3990
|
bool ExecuteCommandLine(const char *cmd_line, Span<const uint8_t> in_buf, Size max_len,
|
|
3985
3991
|
HeapArray<uint8_t> *out_buf, int *out_code);
|
|
3986
|
-
|
|
3987
|
-
|
|
3988
|
-
}
|
|
3992
|
+
|
|
3993
|
+
static inline bool ExecuteCommandLine(const char *cmd_line, int *out_code)
|
|
3994
|
+
{ return ExecuteCommandLine(cmd_line, {}, {}, out_code); }
|
|
3989
3995
|
static inline bool ExecuteCommandLine(const char *cmd_line, Span<const uint8_t> in_buf,
|
|
3990
3996
|
FunctionRef<void(Span<uint8_t> buf)> out_func, int *out_code)
|
|
3991
3997
|
{
|
|
@@ -4001,15 +4007,12 @@ static inline bool ExecuteCommandLine(const char *cmd_line, Span<const char> in_
|
|
|
4001
4007
|
FunctionRef<void(Span<char> buf)> out_func, int *out_code)
|
|
4002
4008
|
{
|
|
4003
4009
|
const auto write = [&](Span<uint8_t> buf) { out_func(buf.As<char>()); };
|
|
4004
|
-
|
|
4005
4010
|
return ExecuteCommandLine(cmd_line, in_buf.As<const uint8_t>(), write, out_code);
|
|
4006
4011
|
}
|
|
4007
4012
|
static inline bool ExecuteCommandLine(const char *cmd_line, Span<const char> in_buf, Size max_len,
|
|
4008
4013
|
HeapArray<char> *out_buf, int *out_code)
|
|
4009
|
-
{
|
|
4010
|
-
|
|
4011
|
-
(HeapArray<uint8_t> *)out_buf, out_code);
|
|
4012
|
-
}
|
|
4014
|
+
{ return ExecuteCommandLine(cmd_line, in_buf.As<const uint8_t>(), max_len,
|
|
4015
|
+
(HeapArray<uint8_t> *)out_buf, out_code); }
|
|
4013
4016
|
|
|
4014
4017
|
void WaitDelay(int64_t delay);
|
|
4015
4018
|
|
|
@@ -4043,12 +4046,22 @@ bool NotifySystemd();
|
|
|
4043
4046
|
})()
|
|
4044
4047
|
#endif
|
|
4045
4048
|
|
|
4049
|
+
static inline int RunApp(int argc, char **argv)
|
|
4050
|
+
{
|
|
4051
|
+
void InitRG();
|
|
4052
|
+
int Main(int argc, char **argv);
|
|
4053
|
+
|
|
4054
|
+
InitRG();
|
|
4055
|
+
return Main(argc, argv);
|
|
4056
|
+
}
|
|
4057
|
+
|
|
4046
4058
|
// ------------------------------------------------------------------------
|
|
4047
4059
|
// Standard paths
|
|
4048
4060
|
// ------------------------------------------------------------------------
|
|
4049
4061
|
|
|
4050
|
-
const char *GetUserConfigPath(const char *name, Allocator *alloc);
|
|
4051
|
-
const char *GetUserCachePath(const char *name, Allocator *alloc);
|
|
4062
|
+
const char *GetUserConfigPath(const char *name, Allocator *alloc); // Can return NULL
|
|
4063
|
+
const char *GetUserCachePath(const char *name, Allocator *alloc); // Can return NULL
|
|
4064
|
+
const char *GetSystemConfigPath(const char *name, Allocator *alloc);
|
|
4052
4065
|
const char *GetTemporaryDirectory();
|
|
4053
4066
|
|
|
4054
4067
|
const char *FindConfigFile(const char *name, Allocator *alloc, LocalArray<const char *, 4> *out_possibilities = nullptr);
|
|
@@ -4116,14 +4129,15 @@ static const char *const SocketTypeNames[] = {
|
|
|
4116
4129
|
};
|
|
4117
4130
|
|
|
4118
4131
|
enum class SocketMode {
|
|
4119
|
-
|
|
4120
|
-
|
|
4132
|
+
ConnectStream,
|
|
4133
|
+
ConnectDatagrams,
|
|
4134
|
+
FreeDatagrams
|
|
4121
4135
|
};
|
|
4122
4136
|
|
|
4123
|
-
int OpenIPSocket(SocketType type, int port, SocketMode mode = SocketMode::
|
|
4137
|
+
int OpenIPSocket(SocketType type, int port, SocketMode mode = SocketMode::ConnectStream);
|
|
4124
4138
|
|
|
4125
|
-
int OpenUnixSocket(const char *path, SocketMode mode = SocketMode::
|
|
4126
|
-
int ConnectToUnixSocket(const char *path, SocketMode mode = SocketMode::
|
|
4139
|
+
int OpenUnixSocket(const char *path, SocketMode mode = SocketMode::ConnectStream);
|
|
4140
|
+
int ConnectToUnixSocket(const char *path, SocketMode mode = SocketMode::ConnectStream);
|
|
4127
4141
|
|
|
4128
4142
|
void CloseSocket(int fd);
|
|
4129
4143
|
|
package/src/koffi/src/abi_x86.cc
CHANGED
|
@@ -75,11 +75,23 @@ bool AnalyseFunction(Napi::Env env, InstanceData *instance, FunctionInfo *func)
|
|
|
75
75
|
#if defined(_WIN32) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
|
|
76
76
|
} else {
|
|
77
77
|
func->ret.trivial = IsRegularSize(func->ret.type->size, 8);
|
|
78
|
+
|
|
79
|
+
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
|
|
80
|
+
if (func->ret.type->members.len == 1) {
|
|
81
|
+
const RecordMember &member = func->ret.type->members[0];
|
|
82
|
+
|
|
83
|
+
if (member.type->primitive == PrimitiveKind::Float32) {
|
|
84
|
+
func->ret.fast = 1;
|
|
85
|
+
} else if (member.type->primitive == PrimitiveKind::Float64) {
|
|
86
|
+
func->ret.fast = 2;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
#endif
|
|
78
90
|
#endif
|
|
79
91
|
}
|
|
80
92
|
#ifndef _WIN32
|
|
81
93
|
if (fast && !func->ret.trivial) {
|
|
82
|
-
func->ret.fast =
|
|
94
|
+
func->ret.fast = 1;
|
|
83
95
|
fast--;
|
|
84
96
|
}
|
|
85
97
|
#endif
|
|
@@ -87,7 +99,7 @@ bool AnalyseFunction(Napi::Env env, InstanceData *instance, FunctionInfo *func)
|
|
|
87
99
|
Size params_size = 0;
|
|
88
100
|
for (ParameterInfo ¶m: func->parameters) {
|
|
89
101
|
if (fast && param.type->size <= 4) {
|
|
90
|
-
param.fast =
|
|
102
|
+
param.fast = 1;
|
|
91
103
|
fast--;
|
|
92
104
|
}
|
|
93
105
|
|
|
@@ -362,9 +374,24 @@ void CallData::Execute(const FunctionInfo *func, void *native)
|
|
|
362
374
|
case PrimitiveKind::String:
|
|
363
375
|
case PrimitiveKind::String16:
|
|
364
376
|
case PrimitiveKind::Pointer:
|
|
365
|
-
case PrimitiveKind::Record:
|
|
366
|
-
case PrimitiveKind::Union:
|
|
367
377
|
case PrimitiveKind::Callback: { result.u64 = PERFORM_CALL(G); } break;
|
|
378
|
+
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
|
|
379
|
+
case PrimitiveKind::Record:
|
|
380
|
+
case PrimitiveKind::Union: {
|
|
381
|
+
if (!func->ret.fast) {
|
|
382
|
+
result.u64 = PERFORM_CALL(G);
|
|
383
|
+
} else if (func->ret.fast == 1) {
|
|
384
|
+
result.f = PERFORM_CALL(F);
|
|
385
|
+
} else if (func->ret.fast == 2) {
|
|
386
|
+
result.d = PERFORM_CALL(D);
|
|
387
|
+
} else {
|
|
388
|
+
RG_UNREACHABLE();
|
|
389
|
+
}
|
|
390
|
+
} break;
|
|
391
|
+
#else
|
|
392
|
+
case PrimitiveKind::Record:
|
|
393
|
+
case PrimitiveKind::Union: { result.u64 = PERFORM_CALL(G); } break;
|
|
394
|
+
#endif
|
|
368
395
|
case PrimitiveKind::Array: { RG_UNREACHABLE(); } break;
|
|
369
396
|
case PrimitiveKind::Float32: { result.f = PERFORM_CALL(F); } break;
|
|
370
397
|
case PrimitiveKind::Float64: { result.d = PERFORM_CALL(D); } break;
|