koffi 1.2.0-alpha.3 → 1.2.0-alpha.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/README.md +9 -7
- package/package.json +4 -2
- package/qemu/registry/machines.json +26 -26
- package/src/abi_arm32.cc +63 -73
- package/src/abi_arm32_fwd.S +2 -2
- package/src/abi_arm64.cc +48 -55
- package/src/abi_arm64_fwd.S +2 -2
- package/src/abi_arm64_fwd.asm +2 -2
- package/src/abi_riscv64_fwd.S +2 -2
- package/src/abi_x64_sysv.cc +6 -1
- package/src/abi_x64_sysv_fwd.S +2 -2
- package/src/abi_x64_win.cc +4 -0
- package/src/abi_x64_win_fwd.asm +5 -5
- package/src/abi_x86.cc +2 -0
- package/src/abi_x86_fwd.S +4 -4
- package/src/abi_x86_fwd.asm +4 -4
- package/src/call.cc +49 -46
- package/src/call.hh +6 -6
- package/src/ffi.cc +4 -4
- package/src/util.cc +17 -0
- package/src/util.hh +2 -0
- package/test/async.js +92 -0
- package/test/callbacks.js +87 -0
- package/test/misc.c +25 -5
- package/test/sqlite.js +34 -5
- package/test/sync.js +323 -0
package/test/sync.js
ADDED
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// This program is free software: you can redistribute it and/or modify
|
|
4
|
+
// it under the terms of the GNU Affero General Public License as published by
|
|
5
|
+
// the Free Software Foundation, either version 3 of the License, or
|
|
6
|
+
// (at your option) any later version.
|
|
7
|
+
//
|
|
8
|
+
// This program is distributed in the hope that it will be useful,
|
|
9
|
+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
10
|
+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
11
|
+
// GNU Affero General Public License for more details.
|
|
12
|
+
//
|
|
13
|
+
// You should have received a copy of the GNU Affero General Public License
|
|
14
|
+
// along with this program. If not, see https://www.gnu.org/licenses/.
|
|
15
|
+
|
|
16
|
+
const koffi = require('./build/koffi.node');
|
|
17
|
+
const assert = require('assert');
|
|
18
|
+
const path = require('path');
|
|
19
|
+
|
|
20
|
+
const Pack1 = koffi.struct('Pack1', {
|
|
21
|
+
a: 'int'
|
|
22
|
+
});
|
|
23
|
+
const Pack2 = koffi.struct('Pack2', {
|
|
24
|
+
a: 'int',
|
|
25
|
+
b: 'int'
|
|
26
|
+
});
|
|
27
|
+
const Pack3 = koffi.struct('Pack3', {
|
|
28
|
+
a: 'int',
|
|
29
|
+
b: 'int',
|
|
30
|
+
c: 'int'
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
const Float2 = koffi.struct('Float2', {
|
|
34
|
+
a: 'float',
|
|
35
|
+
b: 'float'
|
|
36
|
+
});
|
|
37
|
+
const Float3 = koffi.struct('Float3', {
|
|
38
|
+
a: 'float',
|
|
39
|
+
b: koffi.array('float', 2)
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
const Double2 = koffi.struct('Double2', {
|
|
43
|
+
a: 'double',
|
|
44
|
+
b: 'double'
|
|
45
|
+
});
|
|
46
|
+
const Double3 = koffi.struct('Double3', {
|
|
47
|
+
a: 'double',
|
|
48
|
+
s: koffi.struct({
|
|
49
|
+
b: 'double',
|
|
50
|
+
c: 'double'
|
|
51
|
+
})
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
const FloatInt = koffi.struct('FloatInt', {
|
|
55
|
+
f: 'float',
|
|
56
|
+
i: 'int'
|
|
57
|
+
});
|
|
58
|
+
const IntFloat = koffi.struct('IntFloat', {
|
|
59
|
+
i: 'int',
|
|
60
|
+
f: 'float'
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
const BFG = koffi.struct('BFG', {
|
|
64
|
+
a: 'int8_t',
|
|
65
|
+
b: 'int64_t',
|
|
66
|
+
c: 'char',
|
|
67
|
+
d: 'string',
|
|
68
|
+
e: 'short',
|
|
69
|
+
inner: koffi.struct({
|
|
70
|
+
f: 'float',
|
|
71
|
+
g: 'double'
|
|
72
|
+
})
|
|
73
|
+
});
|
|
74
|
+
const PackedBFG = koffi.pack('PackedBFG', {
|
|
75
|
+
a: 'int8_t',
|
|
76
|
+
b: 'int64_t',
|
|
77
|
+
c: 'char',
|
|
78
|
+
d: 'string',
|
|
79
|
+
e: 'short',
|
|
80
|
+
inner: koffi.pack({
|
|
81
|
+
f: 'float',
|
|
82
|
+
g: 'double'
|
|
83
|
+
})
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
const FixedString = koffi.struct('FixedString', {
|
|
87
|
+
buf: koffi.array('char', 64)
|
|
88
|
+
});
|
|
89
|
+
const FixedString2 = koffi.struct('FixedString2', {
|
|
90
|
+
buf: koffi.array('char', 64, 'string')
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
const FixedWide = koffi.struct('FixedWide', {
|
|
94
|
+
buf: koffi.array('char16', 64)
|
|
95
|
+
});
|
|
96
|
+
const FixedWide2 = koffi.struct('FixedWide2', {
|
|
97
|
+
buf: koffi.array('char16', 64, 'string')
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
const SingleU32 = koffi.struct('SingleU32', { v: 'uint32_t' });
|
|
101
|
+
const SingleU64 = koffi.struct('SingleU64', { v: 'uint64_t' });
|
|
102
|
+
const SingleI64 = koffi.struct('SingleI64', { v: 'int64_t' });
|
|
103
|
+
|
|
104
|
+
main();
|
|
105
|
+
|
|
106
|
+
async function main() {
|
|
107
|
+
try {
|
|
108
|
+
await test();
|
|
109
|
+
console.log('Success!');
|
|
110
|
+
} catch (err) {
|
|
111
|
+
console.error(err);
|
|
112
|
+
process.exit(1);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
async function test() {
|
|
117
|
+
let lib_filename = path.dirname(__filename) + '/build/misc' + koffi.extension;
|
|
118
|
+
let lib = koffi.load(lib_filename);
|
|
119
|
+
|
|
120
|
+
const FillPack1 = lib.func('FillPack1', 'void', ['int', koffi.out(koffi.pointer(Pack1))]);
|
|
121
|
+
const RetPack1 = lib.func('RetPack1', Pack1, ['int']);
|
|
122
|
+
const AddPack1 = lib.fastcall('AddPack1', 'void', ['int', koffi.inout(koffi.pointer(Pack1))]);
|
|
123
|
+
const FillPack2 = lib.func('FillPack2', 'void', ['int', 'int', koffi.out(koffi.pointer(Pack2))]);
|
|
124
|
+
const RetPack2 = lib.func('RetPack2', Pack2, ['int', 'int']);
|
|
125
|
+
const AddPack2 = lib.fastcall('AddPack2', 'void', ['int', 'int', koffi.inout(koffi.pointer(Pack2))]);
|
|
126
|
+
const FillPack3 = lib.func('FillPack3', 'void', ['int', 'int', 'int', koffi.out(koffi.pointer(Pack3))]);
|
|
127
|
+
const RetPack3 = lib.func('RetPack3', Pack3, ['int', 'int', 'int']);
|
|
128
|
+
const AddPack3 = lib.fastcall('AddPack3', 'void', ['int', 'int', 'int', koffi.inout(koffi.pointer(Pack3))]);
|
|
129
|
+
const PackFloat2 = lib.func('Float2 PackFloat2(float a, float b, _Out_ Float2 *out)');
|
|
130
|
+
const ThroughFloat2 = lib.func('Float2 ThroughFloat2(Float2 f2)');
|
|
131
|
+
const PackFloat3 = lib.func('Float3 PackFloat3(float a, float b, float c, _Out_ Float3 *out)');
|
|
132
|
+
const ThroughFloat3 = lib.func('Float3 ThroughFloat3(Float3 f3)');
|
|
133
|
+
const PackDouble2 = lib.func('Double2 PackDouble2(double a, double b, _Out_ Double2 *out)');
|
|
134
|
+
const PackDouble3 = lib.func('Double3 PackDouble3(double a, double b, double c, _Out_ Double3 *out)');
|
|
135
|
+
const ReverseFloatInt = lib.func('IntFloat ReverseFloatInt(FloatInt sfi)');
|
|
136
|
+
const ReverseIntFloat = lib.func('FloatInt ReverseIntFloat(IntFloat sif)');
|
|
137
|
+
const ConcatenateToInt1 = lib.func('ConcatenateToInt1', 'int64_t', Array(12).fill('int8_t'));
|
|
138
|
+
const ConcatenateToInt4 = lib.func('ConcatenateToInt4', 'int64_t', Array(12).fill('int32_t'));
|
|
139
|
+
const ConcatenateToInt8 = lib.func('ConcatenateToInt8', 'int64_t', Array(12).fill('int64_t'));
|
|
140
|
+
const ConcatenateToStr1 = lib.func('ConcatenateToStr1', 'string', [...Array(8).fill('int8_t'), koffi.struct('IJK1', {i: 'int8_t', j: 'int8_t', k: 'int8_t'}), 'int8_t']);
|
|
141
|
+
const ConcatenateToStr4 = lib.func('ConcatenateToStr4', 'string', [...Array(8).fill('int32_t'), koffi.pointer(koffi.struct('IJK4', {i: 'int32_t', j: 'int32_t', k: 'int32_t'})), 'int32_t']);
|
|
142
|
+
const ConcatenateToStr8 = lib.func('ConcatenateToStr8', 'string', [...Array(8).fill('int64_t'), koffi.struct('IJK8', {i: 'int64_t', j: 'int64_t', k: 'int64_t'}), 'int64_t']);
|
|
143
|
+
const MakeBFG = lib.func('BFG __stdcall MakeBFG(_Out_ BFG *p, int x, double y, const char *str)');
|
|
144
|
+
const MakePackedBFG = lib.func('PackedBFG __fastcall MakePackedBFG(int x, double y, _Out_ PackedBFG *p, const char *str)');
|
|
145
|
+
const ReturnBigString = process.platform == 'win32' ?
|
|
146
|
+
lib.stdcall(1, 'string', ['string']) :
|
|
147
|
+
lib.func('const char * __stdcall ReturnBigString(const char *str)');
|
|
148
|
+
const PrintFmt = lib.func('const char *PrintFmt(const char *fmt, ...)');
|
|
149
|
+
const Concat16 = lib.func('const char16_t *Concat16(const char16_t *str1, const char16_t *str2)')
|
|
150
|
+
const ReturnFixedStr = lib.func('FixedString ReturnFixedStr(FixedString str)');
|
|
151
|
+
const ReturnFixedStr2 = lib.func('FixedString2 ReturnFixedStr(FixedString2 str)');
|
|
152
|
+
const ReturnFixedWide = lib.func('FixedWide ReturnFixedWide(FixedWide str)');
|
|
153
|
+
const ReturnFixedWide2 = lib.func('FixedWide2 ReturnFixedWide(FixedWide2 str)');
|
|
154
|
+
const ThroughUInt32UU = lib.func('uint32_t ThroughUInt32UU(uint32_t v)');
|
|
155
|
+
const ThroughUInt32SS = lib.func('SingleU32 ThroughUInt32SS(SingleU32 s)');
|
|
156
|
+
const ThroughUInt32SU = lib.func('SingleU32 ThroughUInt32SU(uint32_t v)');
|
|
157
|
+
const ThroughUInt32US = lib.func('uint32_t ThroughUInt32US(SingleU32 s)');
|
|
158
|
+
const ThroughUInt64UU = lib.func('uint64_t ThroughUInt64UU(uint64_t v)');
|
|
159
|
+
const ThroughUInt64SS = lib.func('SingleU64 ThroughUInt64SS(SingleU64 s)');
|
|
160
|
+
const ThroughUInt64SU = lib.func('SingleU64 ThroughUInt64SU(uint64_t v)');
|
|
161
|
+
const ThroughUInt64US = lib.func('uint64_t ThroughUInt64US(SingleU64 s)');
|
|
162
|
+
const ThroughInt64II = lib.func('int64_t ThroughInt64II(int64_t v)');
|
|
163
|
+
const ThroughInt64SS = lib.func('SingleI64 ThroughInt64SS(SingleI64 s)');
|
|
164
|
+
const ThroughInt64SI = lib.func('SingleI64 ThroughInt64SI(int64_t v)');
|
|
165
|
+
const ThroughInt64IS = lib.func('int64_t ThroughInt64IS(SingleI64 s)');
|
|
166
|
+
|
|
167
|
+
// Simple tests with Pack1
|
|
168
|
+
{
|
|
169
|
+
let p = {};
|
|
170
|
+
|
|
171
|
+
FillPack1(777, p);
|
|
172
|
+
assert.deepEqual(p, { a: 777 });
|
|
173
|
+
|
|
174
|
+
let q = RetPack1(6);
|
|
175
|
+
assert.deepEqual(q, { a: 6 });
|
|
176
|
+
|
|
177
|
+
AddPack1(6, p);
|
|
178
|
+
assert.deepEqual(p, { a: 783 });
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// Simple tests with Pack2
|
|
182
|
+
{
|
|
183
|
+
let p = {};
|
|
184
|
+
|
|
185
|
+
FillPack2(123, 456, p);
|
|
186
|
+
assert.deepEqual(p, { a: 123, b: 456 });
|
|
187
|
+
|
|
188
|
+
let q = RetPack2(6, 9);
|
|
189
|
+
assert.deepEqual(q, { a: 6, b: 9 });
|
|
190
|
+
|
|
191
|
+
AddPack2(6, 9, p);
|
|
192
|
+
assert.deepEqual(p, { a: 129, b: 465 });
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// Simple tests with Pack3
|
|
196
|
+
{
|
|
197
|
+
let p = {};
|
|
198
|
+
|
|
199
|
+
FillPack3(1, 2, 3, p);
|
|
200
|
+
assert.deepEqual(p, { a: 1, b: 2, c: 3 });
|
|
201
|
+
|
|
202
|
+
let q = RetPack3(6, 9, -12);
|
|
203
|
+
assert.deepEqual(q, { a: 6, b: 9, c: -12 });
|
|
204
|
+
|
|
205
|
+
AddPack3(6, 9, -12, p);
|
|
206
|
+
assert.deepEqual(p, { a: 7, b: 11, c: -9 });
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// HFA tests
|
|
210
|
+
{
|
|
211
|
+
let f2p = {};
|
|
212
|
+
let f2 = PackFloat2(1.5, 3.0, f2p);
|
|
213
|
+
assert.deepEqual(f2, { a: 1.5, b: 3.0 });
|
|
214
|
+
assert.deepEqual(f2, f2p);
|
|
215
|
+
assert.deepEqual(ThroughFloat2({ a: 1.5, b: 3.0 }), f2);
|
|
216
|
+
assert.deepEqual(ThroughFloat2(f2), f2);
|
|
217
|
+
|
|
218
|
+
let f3p = {};
|
|
219
|
+
let f3 = PackFloat3(20.0, 30.0, 40.0, f3p);
|
|
220
|
+
assert.deepEqual(f3, { a: 20.0, b: Float32Array.from([30.0, 40.0]) });
|
|
221
|
+
assert.deepEqual(f3, f3p);
|
|
222
|
+
assert.deepEqual(ThroughFloat3({ a: 20.0, b: [30.0, 40.0] }), f3);
|
|
223
|
+
assert.deepEqual(ThroughFloat3(f3), f3);
|
|
224
|
+
|
|
225
|
+
let d2p = {};
|
|
226
|
+
let d2 = PackDouble2(1.0, 2.0, d2p);
|
|
227
|
+
assert.deepEqual(d2, { a: 1.0, b: 2.0 });
|
|
228
|
+
assert.deepEqual(d2, d2p);
|
|
229
|
+
|
|
230
|
+
let d3p = {};
|
|
231
|
+
let d3 = PackDouble3(0.5, 10.0, 5.0, d3p);
|
|
232
|
+
assert.deepEqual(d3, { a: 0.5, s: { b: 10.0, c: 5.0 } });
|
|
233
|
+
assert.deepEqual(d3, d3p);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// Mixed int/float structs
|
|
237
|
+
{
|
|
238
|
+
let sif = { i: 4, f: 2.0 };
|
|
239
|
+
assert.deepEqual(ReverseIntFloat(sif), { i: 2, f: 4 });
|
|
240
|
+
assert.deepEqual(ReverseFloatInt(sif), { i: 2, f: 4 });
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// Many parameters
|
|
244
|
+
{
|
|
245
|
+
assert.equal(ConcatenateToInt1(5, 6, 1, 2, 3, 9, 4, 4, 0, 6, 8, 7), 561239440687n);
|
|
246
|
+
assert.equal(ConcatenateToInt4(5, 6, 1, 2, 3, 9, 4, 4, 0, 6, 8, 7), 561239440687n);
|
|
247
|
+
assert.equal(ConcatenateToInt8(5, 6, 1, 2, 3, 9, 4, 4, 0, 6, 8, 7), 561239440687n);
|
|
248
|
+
assert.equal(ConcatenateToStr1(5, 6, 1, 2, 3, 9, 4, 4, {i: 0, j: 6, k: 8}, 7), '561239440687');
|
|
249
|
+
assert.equal(ConcatenateToStr4(5, 6, 1, 2, 3, 9, 4, 4, {i: 0, j: 6, k: 8}, 7), '561239440687');
|
|
250
|
+
assert.equal(ConcatenateToStr8(5, 6, 1, 2, 3, 9, 4, 4, {i: 0, j: 6, k: 8}, 7), '561239440687');
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// Big struct
|
|
254
|
+
{
|
|
255
|
+
let out = {};
|
|
256
|
+
let bfg = MakeBFG(out, 2, 7, '__Hello123456789++++foobarFOOBAR!__');
|
|
257
|
+
assert.deepEqual(bfg, { a: 2, b: 4, c: -25, d: 'X/__Hello123456789++++foobarFOOBAR!__/X', e: 54, inner: { f: 14, g: 5 } });
|
|
258
|
+
assert.deepEqual(out, bfg);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// Packed struct
|
|
262
|
+
{
|
|
263
|
+
let out = {};
|
|
264
|
+
let bfg = MakePackedBFG(2, 7, out, '__Hello123456789++++foobarFOOBAR!__');
|
|
265
|
+
assert.deepEqual(bfg, { a: 2, b: 4, c: -25, d: 'X/__Hello123456789++++foobarFOOBAR!__/X', e: 54, inner: { f: 14, g: 5 } });
|
|
266
|
+
assert.deepEqual(out, bfg);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// Big string
|
|
270
|
+
{
|
|
271
|
+
let str = 'fooBAR!'.repeat(1024 * 1024);
|
|
272
|
+
assert.equal(ReturnBigString(str), str);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
// Variadic
|
|
276
|
+
{
|
|
277
|
+
let str = PrintFmt('foo %d %g %s', 'int', 200, 'double', 1.5, 'string', 'BAR');
|
|
278
|
+
assert.equal(str, 'foo 200 1.5 BAR');
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
// UTF-16LE strings
|
|
282
|
+
{
|
|
283
|
+
let str = Concat16('Hello ', 'World!');
|
|
284
|
+
assert.equal(str, 'Hello World!');
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
// String to/from fixed-size buffers
|
|
288
|
+
{
|
|
289
|
+
let str = { buf: 'Hello!' };
|
|
290
|
+
assert.deepEqual(ReturnFixedStr(str), { buf: Int8Array.from([72, 101, 108, 108, 111, 33, ...Array(58).fill(0)]) });
|
|
291
|
+
assert.deepEqual(ReturnFixedStr2(str), { buf: 'Hello!' });
|
|
292
|
+
assert.deepEqual(ReturnFixedWide(str), { buf: Int16Array.from([72, 101, 108, 108, 111, 33, ...Array(58).fill(0)]) });
|
|
293
|
+
assert.deepEqual(ReturnFixedWide2(str), { buf: 'Hello!' });
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
// Big numbers
|
|
297
|
+
{
|
|
298
|
+
assert.equal(ThroughUInt32UU(4294967284), 4294967284);
|
|
299
|
+
assert.deepEqual(ThroughUInt32SS({ v: 4294967284 }), { v: 4294967284 });
|
|
300
|
+
assert.deepEqual(ThroughUInt32SU(4294967284), { v: 4294967284 });
|
|
301
|
+
assert.equal(ThroughUInt32US({ v: 4294967284 }), 4294967284);
|
|
302
|
+
|
|
303
|
+
assert.equal(ThroughUInt64UU(9007199254740989), 9007199254740989);
|
|
304
|
+
assert.deepEqual(ThroughUInt64SS({ v: 9007199254740989 }), { v: 9007199254740989 });
|
|
305
|
+
assert.deepEqual(ThroughUInt64SU(9007199254740989), { v: 9007199254740989 });
|
|
306
|
+
assert.equal(ThroughUInt64US({ v: 9007199254740989 }), 9007199254740989);
|
|
307
|
+
|
|
308
|
+
assert.equal(ThroughUInt64UU(18446744073709551598n), 18446744073709551598n);
|
|
309
|
+
assert.deepEqual(ThroughUInt64SS({ v: 18446744073709551598n }), { v: 18446744073709551598n });
|
|
310
|
+
assert.deepEqual(ThroughUInt64SU(18446744073709551598n), { v: 18446744073709551598n });
|
|
311
|
+
assert.equal(ThroughUInt64US({ v: 18446744073709551598n }), 18446744073709551598n);
|
|
312
|
+
|
|
313
|
+
assert.equal(ThroughInt64II(-9007199254740989), -9007199254740989);
|
|
314
|
+
assert.deepEqual(ThroughInt64SS({ v: -9007199254740989 }), { v: -9007199254740989 });
|
|
315
|
+
assert.deepEqual(ThroughInt64SI(-9007199254740989), { v: -9007199254740989 });
|
|
316
|
+
assert.equal(ThroughInt64IS({ v: -9007199254740989 }), -9007199254740989);
|
|
317
|
+
|
|
318
|
+
assert.equal(ThroughInt64II(-9223372036854775803n), -9223372036854775803n);
|
|
319
|
+
assert.deepEqual(ThroughInt64SS({ v: -9223372036854775803n }), { v: -9223372036854775803n });
|
|
320
|
+
assert.deepEqual(ThroughInt64SI(-9223372036854775803n), { v: -9223372036854775803n });
|
|
321
|
+
assert.equal(ThroughInt64IS({ v: -9223372036854775803n }), -9223372036854775803n);
|
|
322
|
+
}
|
|
323
|
+
}
|