koffi 2.0.0 → 2.1.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.
Files changed (127) hide show
  1. package/CMakeLists.txt +2 -9
  2. package/ChangeLog.md +25 -2
  3. package/benchmark/atoi_koffi.js +12 -8
  4. package/benchmark/atoi_napi.js +12 -8
  5. package/benchmark/atoi_node_ffi.js +11 -10
  6. package/benchmark/raylib_cc.cc +12 -9
  7. package/benchmark/raylib_koffi.js +15 -13
  8. package/benchmark/raylib_node_ffi.js +15 -13
  9. package/benchmark/raylib_node_raylib.js +14 -11
  10. package/build/qemu/2.1.0-beta.2/koffi_darwin_arm64.tar.gz +0 -0
  11. package/build/qemu/2.1.0-beta.2/koffi_darwin_x64.tar.gz +0 -0
  12. package/build/qemu/2.1.0-beta.2/koffi_freebsd_arm64.tar.gz +0 -0
  13. package/build/qemu/2.1.0-beta.2/koffi_freebsd_ia32.tar.gz +0 -0
  14. package/build/qemu/2.1.0-beta.2/koffi_freebsd_x64.tar.gz +0 -0
  15. package/build/qemu/2.1.0-beta.2/koffi_linux_arm32hf.tar.gz +0 -0
  16. package/build/qemu/2.1.0-beta.2/koffi_linux_arm64.tar.gz +0 -0
  17. package/build/qemu/2.1.0-beta.2/koffi_linux_ia32.tar.gz +0 -0
  18. package/build/qemu/2.1.0-beta.2/koffi_linux_riscv64hf64.tar.gz +0 -0
  19. package/build/qemu/2.1.0-beta.2/koffi_linux_x64.tar.gz +0 -0
  20. package/build/qemu/2.1.0-beta.2/koffi_openbsd_ia32.tar.gz +0 -0
  21. package/build/qemu/2.1.0-beta.2/koffi_openbsd_x64.tar.gz +0 -0
  22. package/build/qemu/2.1.0-beta.2/koffi_win32_arm64.tar.gz +0 -0
  23. package/build/qemu/2.1.0-beta.2/koffi_win32_ia32.tar.gz +0 -0
  24. package/build/qemu/2.1.0-beta.2/koffi_win32_x64.tar.gz +0 -0
  25. package/doc/benchmarks.md +2 -2
  26. package/doc/changes.md +23 -19
  27. package/doc/conf.py +14 -1
  28. package/doc/dist/doctrees/benchmarks.doctree +0 -0
  29. package/doc/dist/doctrees/changes.doctree +0 -0
  30. package/doc/dist/doctrees/environment.pickle +0 -0
  31. package/doc/dist/doctrees/functions.doctree +0 -0
  32. package/doc/dist/doctrees/index.doctree +0 -0
  33. package/doc/dist/doctrees/types.doctree +0 -0
  34. package/doc/functions.md +76 -10
  35. package/doc/templates/badges.html +4 -0
  36. package/doc/types.md +157 -161
  37. package/package.json +2 -2
  38. package/qemu/qemu.js +1 -1
  39. package/src/abi_arm32.cc +167 -3
  40. package/src/abi_arm64.cc +196 -3
  41. package/src/abi_riscv64.cc +107 -3
  42. package/src/abi_x64_sysv.cc +114 -4
  43. package/src/abi_x64_win.cc +113 -3
  44. package/src/abi_x86.cc +156 -5
  45. package/src/call.cc +241 -26
  46. package/src/call.hh +15 -3
  47. package/src/ffi.cc +123 -34
  48. package/src/ffi.hh +19 -0
  49. package/src/index.js +4 -2
  50. package/src/parser.cc +3 -5
  51. package/src/util.cc +44 -1
  52. package/src/util.hh +4 -0
  53. package/test/async.js +1 -2
  54. package/test/callbacks.js +2 -3
  55. package/test/misc.c +21 -1
  56. package/test/raylib.js +1 -1
  57. package/test/sqlite.js +7 -7
  58. package/test/sync.js +30 -4
  59. package/build/qemu/2.0.0/koffi_darwin_arm64.tar.gz +0 -0
  60. package/build/qemu/2.0.0/koffi_darwin_x64.tar.gz +0 -0
  61. package/build/qemu/2.0.0/koffi_freebsd_arm64.tar.gz +0 -0
  62. package/build/qemu/2.0.0/koffi_freebsd_ia32.tar.gz +0 -0
  63. package/build/qemu/2.0.0/koffi_freebsd_x64.tar.gz +0 -0
  64. package/build/qemu/2.0.0/koffi_linux_arm32hf.tar.gz +0 -0
  65. package/build/qemu/2.0.0/koffi_linux_arm64.tar.gz +0 -0
  66. package/build/qemu/2.0.0/koffi_linux_ia32.tar.gz +0 -0
  67. package/build/qemu/2.0.0/koffi_linux_riscv64hf64.tar.gz +0 -0
  68. package/build/qemu/2.0.0/koffi_linux_x64.tar.gz +0 -0
  69. package/build/qemu/2.0.0/koffi_openbsd_ia32.tar.gz +0 -0
  70. package/build/qemu/2.0.0/koffi_openbsd_x64.tar.gz +0 -0
  71. package/build/qemu/2.0.0/koffi_win32_arm64.tar.gz +0 -0
  72. package/build/qemu/2.0.0/koffi_win32_ia32.tar.gz +0 -0
  73. package/build/qemu/2.0.0/koffi_win32_x64.tar.gz +0 -0
  74. package/doc/dist/html/.buildinfo +0 -4
  75. package/doc/dist/html/_sources/benchmarks.md.txt +0 -137
  76. package/doc/dist/html/_sources/changes.md.txt +0 -157
  77. package/doc/dist/html/_sources/contribute.md.txt +0 -127
  78. package/doc/dist/html/_sources/functions.md.txt +0 -355
  79. package/doc/dist/html/_sources/index.rst.txt +0 -39
  80. package/doc/dist/html/_sources/memory.md.txt +0 -32
  81. package/doc/dist/html/_sources/platforms.md.txt +0 -31
  82. package/doc/dist/html/_sources/start.md.txt +0 -100
  83. package/doc/dist/html/_sources/types.md.txt +0 -545
  84. package/doc/dist/html/_static/_sphinx_javascript_frameworks_compat.js +0 -134
  85. package/doc/dist/html/_static/basic.css +0 -932
  86. package/doc/dist/html/_static/bench_linux.png +0 -0
  87. package/doc/dist/html/_static/bench_windows.png +0 -0
  88. package/doc/dist/html/_static/custom.css +0 -22
  89. package/doc/dist/html/_static/debug.css +0 -69
  90. package/doc/dist/html/_static/doctools.js +0 -264
  91. package/doc/dist/html/_static/documentation_options.js +0 -14
  92. package/doc/dist/html/_static/file.png +0 -0
  93. package/doc/dist/html/_static/jquery-3.6.0.js +0 -10881
  94. package/doc/dist/html/_static/jquery.js +0 -2
  95. package/doc/dist/html/_static/language_data.js +0 -199
  96. package/doc/dist/html/_static/minus.png +0 -0
  97. package/doc/dist/html/_static/perf_linux_20220623.png +0 -0
  98. package/doc/dist/html/_static/perf_linux_20220623_2.png +0 -0
  99. package/doc/dist/html/_static/perf_windows_20220623.png +0 -0
  100. package/doc/dist/html/_static/perf_windows_20220623_2.png +0 -0
  101. package/doc/dist/html/_static/plus.png +0 -0
  102. package/doc/dist/html/_static/pygments.css +0 -252
  103. package/doc/dist/html/_static/scripts/furo-extensions.js +0 -0
  104. package/doc/dist/html/_static/scripts/furo.js +0 -3
  105. package/doc/dist/html/_static/scripts/furo.js.LICENSE.txt +0 -7
  106. package/doc/dist/html/_static/scripts/furo.js.map +0 -1
  107. package/doc/dist/html/_static/searchtools.js +0 -531
  108. package/doc/dist/html/_static/skeleton.css +0 -296
  109. package/doc/dist/html/_static/styles/furo-extensions.css +0 -2
  110. package/doc/dist/html/_static/styles/furo-extensions.css.map +0 -1
  111. package/doc/dist/html/_static/styles/furo.css +0 -2
  112. package/doc/dist/html/_static/styles/furo.css.map +0 -1
  113. package/doc/dist/html/_static/underscore-1.13.1.js +0 -2042
  114. package/doc/dist/html/_static/underscore.js +0 -6
  115. package/doc/dist/html/benchmarks.html +0 -568
  116. package/doc/dist/html/changes.html +0 -653
  117. package/doc/dist/html/contribute.html +0 -400
  118. package/doc/dist/html/functions.html +0 -653
  119. package/doc/dist/html/genindex.html +0 -250
  120. package/doc/dist/html/index.html +0 -356
  121. package/doc/dist/html/memory.html +0 -343
  122. package/doc/dist/html/objects.inv +0 -0
  123. package/doc/dist/html/platforms.html +0 -368
  124. package/doc/dist/html/search.html +0 -258
  125. package/doc/dist/html/searchindex.js +0 -1
  126. package/doc/dist/html/start.html +0 -381
  127. package/doc/dist/html/types.html +0 -1044
package/CMakeLists.txt CHANGED
@@ -15,11 +15,6 @@ cmake_minimum_required(VERSION 3.6)
15
15
  project(koffi C CXX ASM)
16
16
 
17
17
  include(CheckCXXCompilerFlag)
18
- if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.9.0")
19
- cmake_policy(SET CMP0069 NEW)
20
- include(CheckIPOSupported)
21
- check_ipo_supported(RESULT USE_LTO)
22
- endif()
23
18
 
24
19
  find_package(CNoke)
25
20
 
@@ -36,7 +31,7 @@ if(MSVC)
36
31
  enable_language(ASM_MASM)
37
32
  endif()
38
33
  else()
39
- add_compile_options(-Wall -Wextra -Wno-missing-field-initializers -Wno-unused-parameter)
34
+ add_compile_options(-Wall -Wextra -Wno-missing-field-initializers -Wno-unused-parameter -Wswitch -Werror=switch)
40
35
  if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
41
36
  add_compile_options(-Wno-unknown-warning-option)
42
37
  endif()
@@ -126,6 +121,4 @@ if(NOT MSVC OR CMAKE_C_COMPILER_ID MATCHES "[Cc]lang")
126
121
  target_compile_options(koffi PRIVATE -fno-finite-loops)
127
122
  endif()
128
123
  endif()
129
- if(USE_LTO)
130
- set_target_properties(koffi PROPERTIES INTERPROCEDURAL_OPTIMIZATION TRUE)
131
- endif()
124
+ enable_unity_build(koffi)
package/ChangeLog.md CHANGED
@@ -2,12 +2,35 @@
2
2
 
3
3
  ## History
4
4
 
5
+ ### Koffi 2.1.0 (in beta)
6
+
7
+ **Main changes:**
8
+
9
+ - Add [koffi.as()](functions.md#polymorphic-parameters) to support polymorphic APIs based on `void *` parameters
10
+ - Add [endian-sensitive integer types](types.md#endian-sensitive-types): `intX_le_t`, `intX_be_t`
11
+ - Accept typed arrays for `void *` parameters
12
+ - Introduce `koffi.opaque()` to replace `koffi.handle()` (which remains supported until Koffi 3.0)
13
+
14
+ **Other changes:**
15
+
16
+ - Improve global performance with inlining and unity builds
17
+ - Add `size_t` primitive type
18
+ - Support member-specific alignement value in structs
19
+ - Detect impossible parameters and return types (such as non-pointer opaque types)
20
+ - Various documentation fixes and improvements
21
+
22
+ ### Koffi 2.0.1
23
+
24
+ **Main changes:**
25
+
26
+ - Return `undefined` (instead of null) for `void` functions
27
+
5
28
  ### Koffi 2.0.0
6
29
 
7
30
  **Major new features:**
8
31
 
9
- - Add disposable types for automatic disposal of C values (such as heap-allocated strings)
10
- - Add support for registered callbacks, that can be called after the initial FFI call
32
+ - Add [disposable types](functions.md#heap-allocated-values) for automatic disposal of C values (such as heap-allocated strings)
33
+ - Add support for [registered callbacks](functions.md#registered-callbacks), that can be called after the initial FFI call
11
34
  - Support named pointer types
12
35
  - Support complex type specifications outside of prototype parser
13
36
 
@@ -26,14 +26,14 @@ let sum = 0;
26
26
  main();
27
27
 
28
28
  function main() {
29
- let iterations = 20000000;
29
+ let time = 5000;
30
30
 
31
31
  if (process.argv.length >= 3) {
32
- iterations = parseInt(process.argv[2], 10);
33
- if (Number.isNaN(iterations))
32
+ time = parseFloat(process.argv[2]) * 1000;
33
+ if (Number.isNaN(time))
34
34
  throw new Error('Not a valid number');
35
- if (iterations < 1)
36
- throw new Error('Value must be positive');
35
+ if (time < 0)
36
+ throw new Error('Time must be positive');
37
37
  }
38
38
 
39
39
  let lib = koffi.load(process.platform == 'win32' ? 'msvcrt.dll' : null);
@@ -41,11 +41,15 @@ function main() {
41
41
  const atoi = lib.cdecl('atoi', 'int', ['str']);
42
42
 
43
43
  let start = performance.now();
44
+ let iterations = 0;
44
45
 
45
- for (let i = 0; i < iterations; i++) {
46
- sum += atoi(strings[i % strings.length]);
46
+ while (performance.now() - start < time) {
47
+ for (let i = 0; i < 1000000; i++)
48
+ sum += atoi(strings[i % strings.length]);
49
+
50
+ iterations += 1000000;
47
51
  }
48
52
 
49
- let time = performance.now() - start;
53
+ time = performance.now() - start;
50
54
  console.log(JSON.stringify({ iterations: iterations, time: Math.round(time) }));
51
55
  }
@@ -26,22 +26,26 @@ let sum = 0;
26
26
  main();
27
27
 
28
28
  function main() {
29
- let iterations = 20000000;
29
+ let time = 5000;
30
30
 
31
31
  if (process.argv.length >= 3) {
32
- iterations = parseInt(process.argv[2], 10);
33
- if (Number.isNaN(iterations))
32
+ time = parseFloat(process.argv[2]) * 1000;
33
+ if (Number.isNaN(time))
34
34
  throw new Error('Not a valid number');
35
- if (iterations < 1)
36
- throw new Error('Value must be positive');
35
+ if (time < 0)
36
+ throw new Error('Time must be positive');
37
37
  }
38
38
 
39
39
  let start = performance.now();
40
+ let iterations = 0;
40
41
 
41
- for (let i = 0; i < iterations; i++) {
42
- sum += atoi.atoi(strings[i % strings.length]);
42
+ while (performance.now() - start < time) {
43
+ for (let i = 0; i < 1000000; i++)
44
+ sum += atoi.atoi(strings[i % strings.length]);
45
+
46
+ iterations += 1000000;
43
47
  }
44
48
 
45
- let time = performance.now() - start;
49
+ time = performance.now() - start;
46
50
  console.log(JSON.stringify({ iterations: iterations, time: Math.round(time) }));
47
51
  }
@@ -28,14 +28,14 @@ let sum = 0;
28
28
  main();
29
29
 
30
30
  async function main() {
31
- let iterations = 200000;
31
+ let time = 5000;
32
32
 
33
33
  if (process.argv.length >= 3) {
34
- iterations = parseInt(process.argv[2], 10);
35
- if (Number.isNaN(iterations))
34
+ time = parseFloat(process.argv[2]) * 1000;
35
+ if (Number.isNaN(time))
36
36
  throw new Error('Not a valid number');
37
- if (iterations < 1)
38
- throw new Error('Value must be positive');
37
+ if (time < 0)
38
+ throw new Error('Time must be positive');
39
39
  }
40
40
 
41
41
  const lib = ffi.Library(process.platform == 'win32' ? 'msvcrt.dll' : null, {
@@ -43,14 +43,15 @@ async function main() {
43
43
  });
44
44
 
45
45
  let start = performance.now();
46
+ let iterations = 0;
46
47
 
47
- for (let i = 0; i < iterations; i++) {
48
- if (i % 1000000 == 0)
49
- await new Promise(resolve => setTimeout(resolve, 0));
48
+ while (performance.now() - start < time) {
49
+ for (let i = 0; i < 1000000; i++)
50
+ sum += lib.atoi(strings[i % strings.length]);
50
51
 
51
- sum += lib.atoi(strings[i % strings.length]);
52
+ iterations += 1000000;
52
53
  }
53
54
 
54
- let time = performance.now() - start;
55
+ time = performance.now() - start;
55
56
  console.log(JSON.stringify({ iterations: iterations, time: Math.round(time) }));
56
57
  }
@@ -18,10 +18,10 @@ namespace RG {
18
18
 
19
19
  int Main(int argc, char **argv)
20
20
  {
21
- int iterations = 360000;
21
+ int time = 5000;
22
22
 
23
23
  if (argc >= 2) {
24
- if (!ParseInt(argv[1], &iterations))
24
+ if (!ParseInt(argv[1], &time))
25
25
  return 1;
26
26
  }
27
27
 
@@ -34,15 +34,16 @@ int Main(int argc, char **argv)
34
34
  Font font = GetFontDefault();
35
35
 
36
36
  int64_t start = GetMonotonicTime();
37
+ int64_t iterations = 0;
37
38
 
38
- for (int i = 0; i < iterations; i += 3600) {
39
+ while (GetMonotonicTime() - start < time) {
39
40
  ImageClearBackground(&img, Color { 0, 0, 0, 255 });
40
41
 
41
- for (int j = 0; j < 3600; j++) {
42
+ for (int i = 0; i < 3600; i++) {
42
43
  const char *text = "Hello World!";
43
44
  float text_width = MeasureTextEx(font, text, 10, 1).x;
44
45
 
45
- double angle = (j * 7) * PI / 180;
46
+ double angle = (i * 7) * PI / 180;
46
47
  Color color = {
47
48
  (unsigned char)(127.5 + 127.5 * sin(angle)),
48
49
  (unsigned char)(127.5 + 127.5 * sin(angle + PI / 2)),
@@ -50,16 +51,18 @@ int Main(int argc, char **argv)
50
51
  255
51
52
  };
52
53
  Vector2 pos = {
53
- (float)((img.width / 2 - text_width / 2) + j * 0.1 * cos(angle - PI / 2)),
54
- (float)((img.height / 2 - 16) + j * 0.1 * sin(angle - PI / 2))
54
+ (float)((img.width / 2 - text_width / 2) + i * 0.1 * cos(angle - PI / 2)),
55
+ (float)((img.height / 2 - 16) + i * 0.1 * sin(angle - PI / 2))
55
56
  };
56
57
 
57
58
  ImageDrawTextEx(&img, font, text, pos, 10, 1, color);
58
59
  }
60
+
61
+ iterations += 3600;
59
62
  }
60
63
 
61
- int64_t time = GetMonotonicTime() - start;
62
- PrintLn("{\"iterations\": %1,\"time\": %2}", iterations, time);
64
+ time = GetMonotonicTime() - start;
65
+ PrintLn("{\"iterations\": %1, \"time\": %2}", iterations, time);
63
66
 
64
67
  return 0;
65
68
  }
@@ -14,7 +14,6 @@
14
14
  // along with this program. If not, see https://www.gnu.org/licenses/.
15
15
 
16
16
  const koffi = require('./build/koffi.node');
17
- const path = require('path');
18
17
 
19
18
  const Color = koffi.struct('Color', {
20
19
  r: 'uchar',
@@ -71,17 +70,17 @@ const Font = koffi.struct('Font', {
71
70
  main();
72
71
 
73
72
  function main() {
74
- let iterations = 360000;
73
+ let time = 5000;
75
74
 
76
75
  if (process.argv.length >= 3) {
77
- iterations = parseInt(process.argv[2], 10);
78
- if (Number.isNaN(iterations))
76
+ time = parseFloat(process.argv[2]) * 1000;
77
+ if (Number.isNaN(time))
79
78
  throw new Error('Not a valid number');
80
- if (iterations < 1)
81
- throw new Error('Value must be positive');
79
+ if (time < 0)
80
+ throw new Error('Time must be positive');
82
81
  }
83
82
 
84
- let lib_filename = path.dirname(__filename) + '/build/raylib' + koffi.extension;
83
+ let lib_filename = __dirname + '/build/raylib' + koffi.extension;
85
84
  let lib = koffi.load(lib_filename);
86
85
 
87
86
  const InitWindow = lib.cdecl('InitWindow', 'void', ['int', 'int', 'str']);
@@ -103,15 +102,16 @@ function main() {
103
102
  let font = GetFontDefault();
104
103
 
105
104
  let start = performance.now();
105
+ let iterations = 0;
106
106
 
107
- for (let i = 0; i < iterations; i += 3600) {
107
+ while (performance.now() - start < time) {
108
108
  ImageClearBackground(img, { r: 0, g: 0, b: 0, a: 255 });
109
109
 
110
- for (let j = 0; j < 3600; j++) {
110
+ for (let i = 0; i < 3600; i++) {
111
111
  let text = 'Hello World!';
112
112
  let text_width = MeasureTextEx(font, text, 10, 1).x;
113
113
 
114
- let angle = (j * 7) * Math.PI / 180;
114
+ let angle = (i * 7) * Math.PI / 180;
115
115
  let color = {
116
116
  r: 127.5 + 127.5 * Math.sin(angle),
117
117
  g: 127.5 + 127.5 * Math.sin(angle + Math.PI / 2),
@@ -119,14 +119,16 @@ function main() {
119
119
  a: 255
120
120
  };
121
121
  let pos = {
122
- x: (img.width / 2 - text_width / 2) + j * 0.1 * Math.cos(angle - Math.PI / 2),
123
- y: (img.height / 2 - 16) + j * 0.1 * Math.sin(angle - Math.PI / 2)
122
+ x: (img.width / 2 - text_width / 2) + i * 0.1 * Math.cos(angle - Math.PI / 2),
123
+ y: (img.height / 2 - 16) + i * 0.1 * Math.sin(angle - Math.PI / 2)
124
124
  };
125
125
 
126
126
  ImageDrawTextEx(img, font, text, pos, 10, 1, color);
127
127
  }
128
+
129
+ iterations += 3600;
128
130
  }
129
131
 
130
- let time = performance.now() - start;
132
+ time = performance.now() - start;
131
133
  console.log(JSON.stringify({ iterations: iterations, time: Math.round(time) }));
132
134
  }
@@ -17,7 +17,6 @@ const ref = require('ref-napi');
17
17
  const ffi = require('ffi-napi');
18
18
  const struct = require('ref-struct-di')(ref);
19
19
  const koffi = require('./build/koffi.node');
20
- const path = require('path');
21
20
 
22
21
  const Color = struct({
23
22
  r: 'uchar',
@@ -87,17 +86,17 @@ const Font = struct({
87
86
  main();
88
87
 
89
88
  function main() {
90
- let iterations = 180000;
89
+ let time = 5000;
91
90
 
92
91
  if (process.argv.length >= 3) {
93
- iterations = parseInt(process.argv[2], 10);
94
- if (Number.isNaN(iterations))
92
+ time = parseFloat(process.argv[2]) * 1000;
93
+ if (Number.isNaN(time))
95
94
  throw new Error('Not a valid number');
96
- if (iterations < 1)
97
- throw new Error('Value must be positive');
95
+ if (time < 0)
96
+ throw new Error('Time must be positive');
98
97
  }
99
98
 
100
- let lib_filename = path.dirname(__filename) + '/build/raylib' + koffi.extension;
99
+ let lib_filename = __dirname + '/build/raylib' + koffi.extension;
101
100
 
102
101
  const r = ffi.Library(lib_filename, {
103
102
  InitWindow: ['void', ['int', 'int', 'string']],
@@ -121,15 +120,16 @@ function main() {
121
120
  let font = r.GetFontDefault();
122
121
 
123
122
  let start = performance.now();
123
+ let iterations = 0;
124
124
 
125
- for (let i = 0; i < iterations; i += 3600) {
125
+ while (performance.now() - start < time) {
126
126
  r.ImageClearBackground(imgp, new Color({ r: 0, g: 0, b: 0, a: 255 }));
127
127
 
128
- for (let j = 0; j < 3600; j++) {
128
+ for (let i = 0; i < 3600; i++) {
129
129
  let text = 'Hello World!';
130
130
  let text_width = r.MeasureTextEx(font, text, 10, 1).x;
131
131
 
132
- let angle = (j * 7) * Math.PI / 180;
132
+ let angle = (i * 7) * Math.PI / 180;
133
133
  let color = new Color({
134
134
  r: 127.5 + 127.5 * Math.sin(angle),
135
135
  g: 127.5 + 127.5 * Math.sin(angle + Math.PI / 2),
@@ -137,14 +137,16 @@ function main() {
137
137
  a: 255
138
138
  });
139
139
  let pos = new Vector2({
140
- x: (img.width / 2 - text_width / 2) + j * 0.1 * Math.cos(angle - Math.PI / 2),
141
- y: (img.height / 2 - 16) + j * 0.1 * Math.sin(angle - Math.PI / 2)
140
+ x: (img.width / 2 - text_width / 2) + i * 0.1 * Math.cos(angle - Math.PI / 2),
141
+ y: (img.height / 2 - 16) + i * 0.1 * Math.sin(angle - Math.PI / 2)
142
142
  });
143
143
 
144
144
  r.ImageDrawTextEx(imgp, font, text, pos, 10, 1, color);
145
145
  }
146
+
147
+ iterations += 3600;
146
148
  }
147
149
 
148
- let time = performance.now() - start;
150
+ time = performance.now() - start;
149
151
  console.log(JSON.stringify({ iterations: iterations, time: Math.round(time) }));
150
152
  }
@@ -18,14 +18,14 @@ const r = require('raylib');
18
18
  main();
19
19
 
20
20
  function main() {
21
- let iterations = 360000;
21
+ let time = 5000;
22
22
 
23
23
  if (process.argv.length >= 3) {
24
- iterations = parseInt(process.argv[2], 10);
25
- if (Number.isNaN(iterations))
24
+ time = parseFloat(process.argv[2]) * 1000;
25
+ if (Number.isNaN(time))
26
26
  throw new Error('Not a valid number');
27
- if (iterations < 1)
28
- throw new Error('Value must be positive');
27
+ if (time < 0)
28
+ throw new Error('Time must be positive');
29
29
  }
30
30
 
31
31
  // We need to call InitWindow before using anything else (such as fonts)
@@ -37,15 +37,16 @@ function main() {
37
37
  let font = r.GetFontDefault();
38
38
 
39
39
  let start = performance.now();
40
+ let iterations = 0;
40
41
 
41
- for (let i = 0; i < iterations; i += 3600) {
42
+ while (performance.now() - start < time) {
42
43
  r.ImageClearBackground(img, { r: 0, g: 0, b: 0, a: 255 });
43
44
 
44
- for (let j = 0; j < 3600; j++) {
45
+ for (let i = 0; i < 3600; i++) {
45
46
  let text = 'Hello World!';
46
47
  let text_width = r.MeasureTextEx(font, text, 10, 1).x;
47
48
 
48
- let angle = (j * 7) * Math.PI / 180;
49
+ let angle = (i * 7) * Math.PI / 180;
49
50
  let color = {
50
51
  r: 127.5 + 127.5 * Math.sin(angle),
51
52
  g: 127.5 + 127.5 * Math.sin(angle + Math.PI / 2),
@@ -53,14 +54,16 @@ function main() {
53
54
  a: 255
54
55
  };
55
56
  let pos = {
56
- x: (img.width / 2 - text_width / 2) + j * 0.1 * Math.cos(angle - Math.PI / 2),
57
- y: (img.height / 2 - 16) + j * 0.1 * Math.sin(angle - Math.PI / 2)
57
+ x: (img.width / 2 - text_width / 2) + i * 0.1 * Math.cos(angle - Math.PI / 2),
58
+ y: (img.height / 2 - 16) + i * 0.1 * Math.sin(angle - Math.PI / 2)
58
59
  };
59
60
 
60
61
  r.ImageDrawTextEx(img, font, text, pos, 10, 1, color);
61
62
  }
63
+
64
+ iterations += 3600;
62
65
  }
63
66
 
64
- let time = performance.now() - start;
67
+ time = performance.now() - start;
65
68
  console.log(JSON.stringify({ iterations: iterations, time: Math.round(time) }));
66
69
  }
package/doc/benchmarks.md CHANGED
@@ -10,8 +10,8 @@ Here is a quick overview of the execution time of Koffi calls on three benchmark
10
10
 
11
11
  <table style="margin: 0 auto;">
12
12
  <tr>
13
- <td><a href="static/perf_linux_20220628.png" target="_blank"><img src="static/perf_linux_20220628.png" alt="Linux x86_64 performance" style="width: 350px;"/></a></td>
14
- <td><a href="static/perf_windows_20220628.png" target="_blank"><img src="static/perf_windows_20220628.png" alt="Windows x86_64 performance" style="width: 350px;"/></a></td>
13
+ <td><a href="_static/perf_linux_20220628.png" target="_blank"><img src="_static/perf_linux_20220628.png" alt="Linux x86_64 performance" style="width: 350px;"/></a></td>
14
+ <td><a href="_static/perf_windows_20220628.png" target="_blank"><img src="_static/perf_windows_20220628.png" alt="Windows x86_64 performance" style="width: 350px;"/></a></td>
15
15
  </tr>
16
16
  </table>
17
17
 
package/doc/changes.md CHANGED
@@ -10,7 +10,7 @@ The API was changed in 2.x in a few ways, in order to reduce some excessively "m
10
10
  You may need to change your code if you use:
11
11
 
12
12
  - Callback functions
13
- - Opaque handles
13
+ - Opaque types
14
14
  - `koffi.introspect()`
15
15
 
16
16
  #### Callback types
@@ -66,33 +66,36 @@ console.log(ret);
66
66
 
67
67
  Koffi 1.x only supported [transient callbacks](functions.md#javascript-callbacks), you must use Koffi 2.x for registered callbacks.
68
68
 
69
- #### Opaque handles
69
+ #### Opaque types
70
70
 
71
- In Koffi 1.x, opaque handles were defined in a way that made them usable directly as parameter and return types, obscuring the underlying pointer. Now, you must use them through a pointer, and use an array for output parameters.
71
+ In Koffi 1.x, opaque handles were defined in a way that made them usable directly as parameter and return types, obscuring the underlying pointer. Now, in Koffi 2.0, you must use them through a pointer, and use an array for output parameters.
72
72
 
73
- For functions that return handles or pass them by parameter:
73
+ In addition to that, `koffi.handle()` has been deprecated in Koffi 2.1 and replaced with `koffi.opaque()`. They work the same but new code should use `koffi.opaque()`, the former one will eventually be removed in Koffi 3.0.
74
+
75
+ For functions that return opaque pointers or pass them by parameter:
74
76
 
75
77
  ```js
76
78
  // Koffi 1.x
77
79
 
78
80
  const FILE = koffi.handle('FILE');
79
- const fopen = lib.func('FILE fopen(const char *path, const char *mode)');
80
- const fclose = lib.func('int fclose(FILE stream)');
81
+ const fopen = lib.func('fopen', 'FILE', ['str', 'str']);
82
+ const fopen = lib.func('fclose', 'int', ['FILE']);
81
83
 
82
- let fp = fopen('touch', 'wb');
84
+ let fp = fopen('EMPTY', 'wb');
83
85
  if (!fp)
84
86
  throw new Error('Failed to open file');
85
87
  fclose(fp);
86
88
  ```
87
89
 
88
90
  ```js
89
- // Koffi 2.x
91
+ // Koffi 2.1
90
92
 
91
- const FILE = koffi.handle('FILE');
92
- const fopen = lib.func('FILE *fopen(const char *path, const char *mode)');
93
- const fclose = lib.func('int fclose(FILE *stream)');
93
+ // If you use Koffi 2.0: const FILE = koffi.handle('FILE');
94
+ const FILE = koffi.opaque('FILE');
95
+ const fopen = lib.func('fopen', 'FILE *', ['str', 'str']);
96
+ const fopen = lib.func('fclose', 'int', ['FILE *']);
94
97
 
95
- let fp = fopen('touch', 'wb');
98
+ let fp = fopen('EMPTY', 'wb');
96
99
  if (!fp)
97
100
  throw new Error('Failed to open file');
98
101
  fclose(fp);
@@ -103,10 +106,10 @@ For functions that set opaque handles through output parameters (such as `sqlite
103
106
  ```js
104
107
  // Koffi 1.x
105
108
 
106
- const sqlite3_db = koffi.handle('sqlite3_db');
109
+ const sqlite3 = koffi.handle('sqlite3');
107
110
 
108
- const sqlite3_open_v2 = lib.func('sqlite3_open_v2', 'int', ['str', koffi.out(sqlite3_db), 'int', 'str']);
109
- const sqlite3_close_v2 = lib.func('sqlite3_close_v2', 'int', [sqlite3_db]);
111
+ const sqlite3_open_v2 = lib.func('int sqlite3_open_v2(const char *, _Out_ sqlite3 *db, int, const char *)');
112
+ const sqlite3_close_v2 = lib.func('int sqlite3_close_v2(sqlite3 db)');
110
113
 
111
114
  const SQLITE_OPEN_READWRITE = 0x2;
112
115
  const SQLITE_OPEN_CREATE = 0x4;
@@ -120,12 +123,13 @@ sqlite3_close_v2(db);
120
123
  ```
121
124
 
122
125
  ```js
123
- // Koffi 2.x
126
+ // Koffi 2.1
124
127
 
125
- const sqlite3_db = koffi.handle('sqlite3_db');
128
+ // If you use Koffi 2.0: const sqlite3 = koffi.handle('sqlite3');
129
+ const sqlite3 = koffi.opaque('sqlite3');
126
130
 
127
- const sqlite3_open_v2 = lib.func('sqlite3_open_v2', 'int', ['str', koffi.out(koffi.pointer(sqlite3_db, 2)), 'int', 'str']);
128
- const sqlite3_close_v2 = lib.func('sqlite3_close_v2', 'int', [koffi.pointer(sqlite3_db)]);
131
+ const sqlite3_open_v2 = lib.func('int sqlite3_open_v2(const char *, _Out_ sqlite3 **db, int, const char *)');
132
+ const sqlite3_close_v2 = lib.func('int sqlite3_close_v2(sqlite3 *db)');
129
133
 
130
134
  const SQLITE_OPEN_READWRITE = 0x2;
131
135
  const SQLITE_OPEN_CREATE = 0x4;
package/doc/conf.py CHANGED
@@ -21,7 +21,7 @@ extensions = [
21
21
  ]
22
22
 
23
23
  # Add any paths that contain templates here, relative to this directory.
24
- templates_path = ['_templates']
24
+ templates_path = ['templates']
25
25
 
26
26
  exclude_patterns = []
27
27
 
@@ -48,6 +48,19 @@ html_link_suffix = ''
48
48
 
49
49
  html_css_files = ['custom.css']
50
50
 
51
+ html_sidebars = {
52
+ "**": [
53
+ "sidebar/brand.html",
54
+ "sidebar/search.html",
55
+ "sidebar/scroll-start.html",
56
+ "sidebar/navigation.html",
57
+ "sidebar/ethical-ads.html",
58
+ "badges.html",
59
+ "sidebar/scroll-end.html",
60
+ "sidebar/variant-selector.html"
61
+ ]
62
+ }
63
+
51
64
  # -- MyST parser options -------------------------------------------------
52
65
 
53
66
  myst_enable_extensions = [
Binary file
Binary file
Binary file
Binary file