koffi 2.1.5 → 2.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/ChangeLog.md +21 -1
  2. package/doc/Makefile +1 -1
  3. package/doc/callbacks.md +175 -0
  4. package/doc/changes.md +2 -3
  5. package/doc/conf.py +29 -6
  6. package/doc/functions.md +39 -124
  7. package/doc/index.rst +1 -0
  8. package/doc/make.bat +1 -1
  9. package/doc/types.md +36 -9
  10. package/package.json +2 -2
  11. package/src/core/libcc/libcc.cc +89 -27
  12. package/src/core/libcc/libcc.hh +74 -39
  13. package/src/koffi/build/2.2.1/koffi_darwin_arm64.tar.gz +0 -0
  14. package/src/koffi/build/2.2.1/koffi_darwin_x64.tar.gz +0 -0
  15. package/src/koffi/build/2.2.1/koffi_freebsd_arm64.tar.gz +0 -0
  16. package/src/koffi/build/2.2.1/koffi_freebsd_ia32.tar.gz +0 -0
  17. package/src/koffi/build/2.2.1/koffi_freebsd_x64.tar.gz +0 -0
  18. package/src/koffi/build/2.2.1/koffi_linux_arm32hf.tar.gz +0 -0
  19. package/src/koffi/build/2.2.1/koffi_linux_arm64.tar.gz +0 -0
  20. package/src/koffi/build/2.2.1/koffi_linux_ia32.tar.gz +0 -0
  21. package/src/koffi/build/2.2.1/koffi_linux_riscv64hf64.tar.gz +0 -0
  22. package/src/koffi/build/2.2.1/koffi_linux_x64.tar.gz +0 -0
  23. package/src/koffi/build/2.2.1/koffi_openbsd_ia32.tar.gz +0 -0
  24. package/src/koffi/build/2.2.1/koffi_openbsd_x64.tar.gz +0 -0
  25. package/src/koffi/build/2.2.1/koffi_win32_arm64.tar.gz +0 -0
  26. package/src/koffi/build/2.2.1/koffi_win32_ia32.tar.gz +0 -0
  27. package/src/koffi/build/2.2.1/koffi_win32_x64.tar.gz +0 -0
  28. package/src/koffi/qemu/qemu.js +3 -1
  29. package/src/koffi/src/abi_arm32.cc +26 -23
  30. package/src/koffi/src/abi_arm64.cc +25 -22
  31. package/src/koffi/src/abi_riscv64.cc +21 -18
  32. package/src/koffi/src/abi_x64_sysv.cc +20 -17
  33. package/src/koffi/src/abi_x64_win.cc +19 -16
  34. package/src/koffi/src/abi_x86.cc +23 -20
  35. package/src/koffi/src/call.cc +222 -607
  36. package/src/koffi/src/call.hh +7 -11
  37. package/src/koffi/src/ffi.cc +229 -29
  38. package/src/koffi/src/ffi.hh +6 -2
  39. package/src/koffi/src/parser.cc +3 -9
  40. package/src/koffi/src/util.cc +546 -8
  41. package/src/koffi/src/util.hh +8 -2
  42. package/src/koffi/test/CMakeLists.txt +3 -3
  43. package/src/koffi/test/callbacks.js +89 -0
  44. package/src/koffi/test/misc.c +78 -0
  45. package/src/koffi/test/raylib.js +2 -2
  46. package/src/koffi/test/sqlite.js +1 -1
  47. package/src/koffi/test/sync.js +28 -6
  48. package/vendor/brotli/c/common/platform.h +2 -0
  49. package/vendor/sqlite3mc/sqlite3.c +243532 -0
  50. package/vendor/sqlite3mc/sqlite3.h +12887 -0
  51. package/src/koffi/build/2.1.5/koffi_darwin_arm64.tar.gz +0 -0
  52. package/src/koffi/build/2.1.5/koffi_darwin_x64.tar.gz +0 -0
  53. package/src/koffi/build/2.1.5/koffi_freebsd_arm64.tar.gz +0 -0
  54. package/src/koffi/build/2.1.5/koffi_freebsd_ia32.tar.gz +0 -0
  55. package/src/koffi/build/2.1.5/koffi_freebsd_x64.tar.gz +0 -0
  56. package/src/koffi/build/2.1.5/koffi_linux_arm32hf.tar.gz +0 -0
  57. package/src/koffi/build/2.1.5/koffi_linux_arm64.tar.gz +0 -0
  58. package/src/koffi/build/2.1.5/koffi_linux_ia32.tar.gz +0 -0
  59. package/src/koffi/build/2.1.5/koffi_linux_riscv64hf64.tar.gz +0 -0
  60. package/src/koffi/build/2.1.5/koffi_linux_x64.tar.gz +0 -0
  61. package/src/koffi/build/2.1.5/koffi_openbsd_ia32.tar.gz +0 -0
  62. package/src/koffi/build/2.1.5/koffi_openbsd_x64.tar.gz +0 -0
  63. package/src/koffi/build/2.1.5/koffi_win32_arm64.tar.gz +0 -0
  64. package/src/koffi/build/2.1.5/koffi_win32_ia32.tar.gz +0 -0
  65. package/src/koffi/build/2.1.5/koffi_win32_x64.tar.gz +0 -0
@@ -28,12 +28,20 @@ const BFG = koffi.struct('BFG', {
28
28
  })
29
29
  });
30
30
 
31
+ const Vec2 = koffi.struct('Vec2', {
32
+ x: 'double',
33
+ y: 'double'
34
+ });
35
+
31
36
  const SimpleCallback = koffi.callback('int SimpleCallback(const char *str)');
32
37
  const RecursiveCallback = koffi.callback('RecursiveCallback', 'float', ['int', 'str', 'double']);
33
38
  const BigCallback = koffi.callback('BFG BigCallback(BFG bfg)');
34
39
  const SuperCallback = koffi.callback('void SuperCallback(int i, int v1, double v2, int v3, int v4, int v5, int v6, float v7, int v8)');
35
40
  const ApplyCallback = koffi.callback('int __stdcall ApplyCallback(int a, int b, int c)');
36
41
  const IntCallback = koffi.callback('int IntCallback(int x)');
42
+ const VectorCallback = koffi.callback('int VectorCallback(int len, Vec2 *vec)');
43
+ const SortCallback = koffi.callback('int SortCallback(const void *ptr1, const void *ptr2)');
44
+ const CharCallback = koffi.callback('int CharCallback(int idx, char c)');
37
45
 
38
46
  const StructCallbacks = koffi.struct('StructCallbacks', {
39
47
  first: koffi.pointer(IntCallback),
@@ -66,6 +74,10 @@ async function test() {
66
74
  const ApplyStruct = lib.func('int ApplyStruct(int x, StructCallbacks callbacks)');
67
75
  const SetCallback = lib.func('void SetCallback(IntCallback *func)');
68
76
  const CallCallback = lib.func('int CallCallback(int x)');
77
+ const MakeVectors = lib.func('int MakeVectors(int len, VectorCallback *func)');
78
+ const CallQSort = lib.func('void CallQSort(_Inout_ void *base, size_t nmemb, size_t size, SortCallback *cb)');
79
+ const CallMeChar = lib.func('int CallMeChar(CharCallback *func)');
80
+ const GetMinusOne1 = lib.func('int8_t GetMinusOne1(void)');
69
81
 
70
82
  // Simple test similar to README example
71
83
  {
@@ -160,4 +172,81 @@ async function test() {
160
172
  assert.equal(koffi.unregister(cb), null);
161
173
  assert.throws(() => koffi.unregister(cb));
162
174
  }
175
+
176
+ // Register with binding
177
+ {
178
+ class Multiplier {
179
+ constructor(k) { this.k = k; }
180
+ multiply(x) { return this.k * x; }
181
+ }
182
+
183
+ let mult = new Multiplier(5);
184
+ let cb = koffi.register(mult, mult.multiply, 'IntCallback *');
185
+
186
+ SetCallback(cb);
187
+ assert.equal(CallCallback(42), 5 * 42);
188
+
189
+ assert.equal(koffi.unregister(cb), null);
190
+ assert.throws(() => koffi.unregister(cb));
191
+ }
192
+
193
+ // Test decoding callback pointers
194
+ {
195
+ assert.equal(koffi.offsetof('Vec2', 'x'), 0);
196
+ assert.equal(koffi.offsetof('Vec2', 'y'), 8);
197
+
198
+ let ret = MakeVectors(5, (len, ptr) => {
199
+ assert.equal(len, 5);
200
+
201
+ for (let i = 0; i < len; i++) {
202
+ let x = koffi.decode(ptr, i * koffi.sizeof('Vec2'), 'double');
203
+ let y = koffi.decode(ptr, i * koffi.sizeof('Vec2') + 8, 'double');
204
+
205
+ assert.equal(x, i);
206
+ assert.equal(y, -i);
207
+ }
208
+
209
+ for (let i = 0; i < len; i++) {
210
+ let vec = koffi.decode(ptr, i * koffi.sizeof('Vec2'), 'Vec2');
211
+ assert.deepEqual(vec, { x: i, y: -i });
212
+ }
213
+
214
+ let all = koffi.decode(ptr, koffi.array('double', 10, 'array'), 10);
215
+ assert.deepEqual(all, [0, 0, 1, -1, 2, -2, 3, -3, 4, -4]);
216
+
217
+ return 424242;
218
+ });
219
+
220
+ assert.equal(ret, 424242);
221
+ }
222
+
223
+ // Test koffi.as() and koffi.decode() with qsort
224
+ {
225
+ let array = ['foo', 'bar', '123', 'foobar'];
226
+
227
+ CallQSort(koffi.as(array, 'char **'), array.length, koffi.sizeof('void *'), (ptr1, ptr2) => {
228
+ let str1 = koffi.decode(ptr1, 'char *');
229
+ let str2 = koffi.decode(ptr2, 'char *');
230
+
231
+ return str1.localeCompare(str2);
232
+ });
233
+
234
+ assert.deepEqual(array, ['123', 'bar', 'foo', 'foobar']);
235
+ }
236
+
237
+ // Make sure thread local CallData is restored after nested call inside callback
238
+ // Regression test for issue #15
239
+ {
240
+ let chars = [97, 98];
241
+
242
+ let cb = koffi.register((idx, c) => {
243
+ assert.equal(GetMinusOne1(), -1);
244
+ assert.equal(c, chars[idx]);
245
+
246
+ return c;
247
+ }, 'CharCallback *');
248
+
249
+ let ret = CallMeChar(cb);
250
+ assert.equal(ret, 97 + 98);
251
+ }
163
252
  }
@@ -162,6 +162,15 @@ typedef struct BigText {
162
162
  char text[262145];
163
163
  } BigText;
164
164
 
165
+ typedef struct Vec2 {
166
+ double x;
167
+ double y;
168
+ } Vec2;
169
+
170
+ typedef int VectorCallback(int len, Vec2 *vec);
171
+ typedef int SortCallback(const void *ptr1, const void *ptr2);
172
+ typedef int CharCallback(int idx, char c);
173
+
165
174
  EXPORT int8_t GetMinusOne1(void)
166
175
  {
167
176
  return -1;
@@ -709,3 +718,72 @@ EXPORT BigText ReverseBigText(BigText buf)
709
718
  }
710
719
  return ret;
711
720
  }
721
+
722
+ EXPORT int MakeVectors(int len, VectorCallback *func)
723
+ {
724
+ Vec2 vectors[512];
725
+
726
+ for (int i = 0; i < len; i++) {
727
+ vectors[i].x = (double)i;
728
+ vectors[i].y = (double)-i;
729
+ }
730
+
731
+ int ret = func(len, vectors);
732
+
733
+ return ret;
734
+ }
735
+
736
+ EXPORT size_t UpperCaseStrAscii(const char *str, char *out)
737
+ {
738
+ size_t len = 0;
739
+
740
+ while (str[len]) {
741
+ char c = str[len];
742
+
743
+ if (c >= 'a' && c <= 'z') {
744
+ out[len] = (char)(c - 32);
745
+ } else {
746
+ out[len] = c;
747
+ }
748
+
749
+ len++;
750
+ }
751
+ out[len] = 0;
752
+
753
+ return len;
754
+ }
755
+
756
+ EXPORT size_t UpperCaseStrAscii16(const char16_t *str, char16_t *out)
757
+ {
758
+ size_t len = 0;
759
+
760
+ while (str[len]) {
761
+ char16_t c = str[len];
762
+
763
+ if (c >= 'a' && c <= 'z') {
764
+ out[len] = (char16_t)(c - 32);
765
+ } else {
766
+ out[len] = c;
767
+ }
768
+
769
+ len++;
770
+ }
771
+ out[len] = 0;
772
+
773
+ return len;
774
+ }
775
+
776
+ EXPORT void CallQSort(void *base, size_t nmemb, size_t size, SortCallback *cb)
777
+ {
778
+ qsort(base, nmemb, size, cb);
779
+ }
780
+
781
+ EXPORT int CallMeChar(CharCallback *func)
782
+ {
783
+ int ret = 0;
784
+
785
+ ret += func(0, 'a');
786
+ ret += func(1, 'b');
787
+
788
+ return ret;
789
+ }
@@ -145,9 +145,9 @@ async function test(display) {
145
145
 
146
146
  if (display) {
147
147
  BeginDrawing();
148
- ClearBackground({r: 0, g: 0, b: 0, a: 255});
148
+ ClearBackground({ r: 0, g: 0, b: 0, a: 255 });
149
149
  let tex = LoadTextureFromImage(img);
150
- DrawTexture(tex, 0, 0, {r: 255, g: 255, b: 255, a: 255});
150
+ DrawTexture(tex, 0, 0, { r: 255, g: 255, b: 255, a: 255 });
151
151
  EndDrawing();
152
152
 
153
153
  while (!WindowShouldClose())
@@ -36,7 +36,7 @@ async function main() {
36
36
  }
37
37
 
38
38
  async function test() {
39
- let lib_filename = __dirname + '/build/sqlite3mc' + koffi.extension;
39
+ let lib_filename = __dirname + '/build/sqlite3' + koffi.extension;
40
40
  let lib = koffi.load(lib_filename);
41
41
 
42
42
  const sqlite3_open_v2 = lib.func('sqlite3_open_v2', 'int', ['str', koffi.out(koffi.pointer(sqlite3, 2)), 'int', 'str']);
@@ -173,9 +173,9 @@ async function test() {
173
173
  const ConcatenateToInt1 = lib.func('ConcatenateToInt1', 'int64_t', Array(12).fill('int8_t'));
174
174
  const ConcatenateToInt4 = lib.func('ConcatenateToInt4', 'int64_t', Array(12).fill('int32_t'));
175
175
  const ConcatenateToInt8 = lib.func('ConcatenateToInt8', 'int64_t', Array(12).fill('int64_t'));
176
- const ConcatenateToStr1 = lib.func('ConcatenateToStr1', 'str', [...Array(8).fill('int8_t'), koffi.struct('IJK1', {i: 'int8_t', j: 'int8_t', k: 'int8_t'}), 'int8_t']);
177
- const ConcatenateToStr4 = lib.func('ConcatenateToStr4', 'str', [...Array(8).fill('int32_t'), koffi.pointer(koffi.struct('IJK4', {i: 'int32_t', j: 'int32_t', k: 'int32_t'})), 'int32_t']);
178
- const ConcatenateToStr8 = lib.func('ConcatenateToStr8', 'str', [...Array(8).fill('int64_t'), koffi.struct('IJK8', {i: 'int64_t', j: 'int64_t', k: 'int64_t'}), 'int64_t']);
176
+ const ConcatenateToStr1 = lib.func('ConcatenateToStr1', 'str', [...Array(8).fill('int8_t'), koffi.struct('IJK1', { i: 'int8_t', j: 'int8_t', k: 'int8_t' }), 'int8_t']);
177
+ const ConcatenateToStr4 = lib.func('ConcatenateToStr4', 'str', [...Array(8).fill('int32_t'), koffi.pointer(koffi.struct('IJK4', { i: 'int32_t', j: 'int32_t', k: 'int32_t' })), 'int32_t']);
178
+ const ConcatenateToStr8 = lib.func('ConcatenateToStr8', 'str', [...Array(8).fill('int64_t'), koffi.struct('IJK8', { i: 'int64_t', j: 'int64_t', k: 'int64_t' }), 'int64_t']);
179
179
  const MakeBFG = lib.func('BFG __stdcall MakeBFG(_Out_ BFG *p, int x, double y, const char *str)');
180
180
  const MakePackedBFG = lib.func('AliasBFG __fastcall MakePackedBFG(int x, double y, _Out_ PackedBFG *p, const char *str)');
181
181
  const MakePolymorphBFG = lib.func('void MakePolymorphBFG(int type, int x, double y, const char *str, _Out_ void *p)');
@@ -224,6 +224,8 @@ async function test() {
224
224
  const ReturnEndianInt8UL = lib.func('uint64_le_t ReturnEndianInt8(uint64_be_t v)');
225
225
  const ReturnEndianInt8UB = lib.func('uint64_be_t ReturnEndianInt8(uint64_le_t v)');
226
226
  const ReverseBigText = lib.func('BigText ReverseBigText(BigText buf)');
227
+ const UpperCaseStrAscii = lib.func('size_t UpperCaseStrAscii(const char *str, _Out_ char *out)');
228
+ const UpperCaseStrAscii16 = lib.func('size_t UpperCaseStrAscii16(const char16_t *str16, _Out_ char16_t *out)');
227
229
 
228
230
  // Simple signed value returns
229
231
  assert.equal(GetMinusOne1(), -1);
@@ -312,9 +314,9 @@ async function test() {
312
314
  assert.equal(ConcatenateToInt1(5, 6, 1, 2, 3, 9, 4, 4, 0, 6, 8, 7), 561239440687);
313
315
  assert.equal(ConcatenateToInt4(5, 6, 1, 2, 3, 9, 4, 4, 0, 6, 8, 7), 561239440687);
314
316
  assert.equal(ConcatenateToInt8(5, 6, 1, 2, 3, 9, 4, 4, 0, 6, 8, 7), 561239440687);
315
- assert.equal(ConcatenateToStr1(5, 6, 1, 2, 3, 9, 4, 4, {i: 0, j: 6, k: 8}, 7), '561239440687');
316
- assert.equal(ConcatenateToStr4(5, 6, 1, 2, 3, 9, 4, 4, {i: 0, j: 6, k: 8}, 7), '561239440687');
317
- assert.equal(ConcatenateToStr8(5, 6, 1, 2, 3, 9, 4, 4, {i: 0, j: 6, k: 8}, 7), '561239440687');
317
+ assert.equal(ConcatenateToStr1(5, 6, 1, 2, 3, 9, 4, 4, { i: 0, j: 6, k: 8 }, 7), '561239440687');
318
+ assert.equal(ConcatenateToStr4(5, 6, 1, 2, 3, 9, 4, 4, { i: 0, j: 6, k: 8 }, 7), '561239440687');
319
+ assert.equal(ConcatenateToStr8(5, 6, 1, 2, 3, 9, 4, 4, { i: 0, j: 6, k: 8 }, 7), '561239440687');
318
320
  }
319
321
 
320
322
  // Big struct
@@ -516,4 +518,24 @@ async function test() {
516
518
  assert.equal(ret.len, big.len);
517
519
  assert.equal(Buffer.from(ret.text).toString(), expected);
518
520
  }
521
+
522
+ // Test output string arguments
523
+ {
524
+ let str = ['\0'.repeat(32)];
525
+
526
+ let len = UpperCaseStrAscii('fooBAR_1x3', str);
527
+
528
+ assert.equal(len, 10);
529
+ assert.equal(str[0], 'FOOBAR_1X3');
530
+ }
531
+
532
+ // Test output string16 arguments
533
+ {
534
+ let str = ['\0'.repeat(32)];
535
+
536
+ let len = UpperCaseStrAscii16('fooBAR_1x3', str);
537
+
538
+ assert.equal(len, 10);
539
+ assert.equal(str[0], 'FOOBAR_1X3');
540
+ }
519
541
  }
@@ -280,6 +280,8 @@ OR:
280
280
 
281
281
  #if defined(BROTLI_BUILD_PORTABLE)
282
282
  #define BROTLI_ALIGNED_READ (!!1)
283
+ #elif !defined(NDEBUG)
284
+ #define BROTLI_ALIGNED_READ (!!1)
283
285
  #elif defined(BROTLI_TARGET_X86) || defined(BROTLI_TARGET_X64) || \
284
286
  defined(BROTLI_TARGET_ARMV7) || defined(BROTLI_TARGET_ARMV8_ANY) || \
285
287
  defined(BROTLI_TARGET_RISCV64)