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.
- package/CMakeLists.txt +2 -9
- package/ChangeLog.md +25 -2
- package/benchmark/atoi_koffi.js +12 -8
- package/benchmark/atoi_napi.js +12 -8
- package/benchmark/atoi_node_ffi.js +11 -10
- package/benchmark/raylib_cc.cc +12 -9
- package/benchmark/raylib_koffi.js +15 -13
- package/benchmark/raylib_node_ffi.js +15 -13
- package/benchmark/raylib_node_raylib.js +14 -11
- package/build/qemu/2.1.0-beta.2/koffi_darwin_arm64.tar.gz +0 -0
- package/build/qemu/2.1.0-beta.2/koffi_darwin_x64.tar.gz +0 -0
- package/build/qemu/2.1.0-beta.2/koffi_freebsd_arm64.tar.gz +0 -0
- package/build/qemu/2.1.0-beta.2/koffi_freebsd_ia32.tar.gz +0 -0
- package/build/qemu/2.1.0-beta.2/koffi_freebsd_x64.tar.gz +0 -0
- package/build/qemu/2.1.0-beta.2/koffi_linux_arm32hf.tar.gz +0 -0
- package/build/qemu/2.1.0-beta.2/koffi_linux_arm64.tar.gz +0 -0
- package/build/qemu/2.1.0-beta.2/koffi_linux_ia32.tar.gz +0 -0
- package/build/qemu/2.1.0-beta.2/koffi_linux_riscv64hf64.tar.gz +0 -0
- package/build/qemu/2.1.0-beta.2/koffi_linux_x64.tar.gz +0 -0
- package/build/qemu/2.1.0-beta.2/koffi_openbsd_ia32.tar.gz +0 -0
- package/build/qemu/2.1.0-beta.2/koffi_openbsd_x64.tar.gz +0 -0
- package/build/qemu/2.1.0-beta.2/koffi_win32_arm64.tar.gz +0 -0
- package/build/qemu/2.1.0-beta.2/koffi_win32_ia32.tar.gz +0 -0
- package/build/qemu/2.1.0-beta.2/koffi_win32_x64.tar.gz +0 -0
- package/doc/benchmarks.md +2 -2
- package/doc/changes.md +23 -19
- package/doc/conf.py +14 -1
- package/doc/dist/doctrees/benchmarks.doctree +0 -0
- package/doc/dist/doctrees/changes.doctree +0 -0
- package/doc/dist/doctrees/environment.pickle +0 -0
- package/doc/dist/doctrees/functions.doctree +0 -0
- package/doc/dist/doctrees/index.doctree +0 -0
- package/doc/dist/doctrees/types.doctree +0 -0
- package/doc/functions.md +76 -10
- package/doc/templates/badges.html +4 -0
- package/doc/types.md +157 -161
- package/package.json +2 -2
- package/qemu/qemu.js +1 -1
- package/src/abi_arm32.cc +167 -3
- package/src/abi_arm64.cc +196 -3
- package/src/abi_riscv64.cc +107 -3
- package/src/abi_x64_sysv.cc +114 -4
- package/src/abi_x64_win.cc +113 -3
- package/src/abi_x86.cc +156 -5
- package/src/call.cc +241 -26
- package/src/call.hh +15 -3
- package/src/ffi.cc +123 -34
- package/src/ffi.hh +19 -0
- package/src/index.js +4 -2
- package/src/parser.cc +3 -5
- package/src/util.cc +44 -1
- package/src/util.hh +4 -0
- package/test/async.js +1 -2
- package/test/callbacks.js +2 -3
- package/test/misc.c +21 -1
- package/test/raylib.js +1 -1
- package/test/sqlite.js +7 -7
- package/test/sync.js +30 -4
- package/build/qemu/2.0.0/koffi_darwin_arm64.tar.gz +0 -0
- package/build/qemu/2.0.0/koffi_darwin_x64.tar.gz +0 -0
- package/build/qemu/2.0.0/koffi_freebsd_arm64.tar.gz +0 -0
- package/build/qemu/2.0.0/koffi_freebsd_ia32.tar.gz +0 -0
- package/build/qemu/2.0.0/koffi_freebsd_x64.tar.gz +0 -0
- package/build/qemu/2.0.0/koffi_linux_arm32hf.tar.gz +0 -0
- package/build/qemu/2.0.0/koffi_linux_arm64.tar.gz +0 -0
- package/build/qemu/2.0.0/koffi_linux_ia32.tar.gz +0 -0
- package/build/qemu/2.0.0/koffi_linux_riscv64hf64.tar.gz +0 -0
- package/build/qemu/2.0.0/koffi_linux_x64.tar.gz +0 -0
- package/build/qemu/2.0.0/koffi_openbsd_ia32.tar.gz +0 -0
- package/build/qemu/2.0.0/koffi_openbsd_x64.tar.gz +0 -0
- package/build/qemu/2.0.0/koffi_win32_arm64.tar.gz +0 -0
- package/build/qemu/2.0.0/koffi_win32_ia32.tar.gz +0 -0
- package/build/qemu/2.0.0/koffi_win32_x64.tar.gz +0 -0
- package/doc/dist/html/.buildinfo +0 -4
- package/doc/dist/html/_sources/benchmarks.md.txt +0 -137
- package/doc/dist/html/_sources/changes.md.txt +0 -157
- package/doc/dist/html/_sources/contribute.md.txt +0 -127
- package/doc/dist/html/_sources/functions.md.txt +0 -355
- package/doc/dist/html/_sources/index.rst.txt +0 -39
- package/doc/dist/html/_sources/memory.md.txt +0 -32
- package/doc/dist/html/_sources/platforms.md.txt +0 -31
- package/doc/dist/html/_sources/start.md.txt +0 -100
- package/doc/dist/html/_sources/types.md.txt +0 -545
- package/doc/dist/html/_static/_sphinx_javascript_frameworks_compat.js +0 -134
- package/doc/dist/html/_static/basic.css +0 -932
- package/doc/dist/html/_static/bench_linux.png +0 -0
- package/doc/dist/html/_static/bench_windows.png +0 -0
- package/doc/dist/html/_static/custom.css +0 -22
- package/doc/dist/html/_static/debug.css +0 -69
- package/doc/dist/html/_static/doctools.js +0 -264
- package/doc/dist/html/_static/documentation_options.js +0 -14
- package/doc/dist/html/_static/file.png +0 -0
- package/doc/dist/html/_static/jquery-3.6.0.js +0 -10881
- package/doc/dist/html/_static/jquery.js +0 -2
- package/doc/dist/html/_static/language_data.js +0 -199
- package/doc/dist/html/_static/minus.png +0 -0
- package/doc/dist/html/_static/perf_linux_20220623.png +0 -0
- package/doc/dist/html/_static/perf_linux_20220623_2.png +0 -0
- package/doc/dist/html/_static/perf_windows_20220623.png +0 -0
- package/doc/dist/html/_static/perf_windows_20220623_2.png +0 -0
- package/doc/dist/html/_static/plus.png +0 -0
- package/doc/dist/html/_static/pygments.css +0 -252
- package/doc/dist/html/_static/scripts/furo-extensions.js +0 -0
- package/doc/dist/html/_static/scripts/furo.js +0 -3
- package/doc/dist/html/_static/scripts/furo.js.LICENSE.txt +0 -7
- package/doc/dist/html/_static/scripts/furo.js.map +0 -1
- package/doc/dist/html/_static/searchtools.js +0 -531
- package/doc/dist/html/_static/skeleton.css +0 -296
- package/doc/dist/html/_static/styles/furo-extensions.css +0 -2
- package/doc/dist/html/_static/styles/furo-extensions.css.map +0 -1
- package/doc/dist/html/_static/styles/furo.css +0 -2
- package/doc/dist/html/_static/styles/furo.css.map +0 -1
- package/doc/dist/html/_static/underscore-1.13.1.js +0 -2042
- package/doc/dist/html/_static/underscore.js +0 -6
- package/doc/dist/html/benchmarks.html +0 -568
- package/doc/dist/html/changes.html +0 -653
- package/doc/dist/html/contribute.html +0 -400
- package/doc/dist/html/functions.html +0 -653
- package/doc/dist/html/genindex.html +0 -250
- package/doc/dist/html/index.html +0 -356
- package/doc/dist/html/memory.html +0 -343
- package/doc/dist/html/objects.inv +0 -0
- package/doc/dist/html/platforms.html +0 -368
- package/doc/dist/html/search.html +0 -258
- package/doc/dist/html/searchindex.js +0 -1
- package/doc/dist/html/start.html +0 -381
- 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
|
-
|
|
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
|
|
package/benchmark/atoi_koffi.js
CHANGED
|
@@ -26,14 +26,14 @@ let sum = 0;
|
|
|
26
26
|
main();
|
|
27
27
|
|
|
28
28
|
function main() {
|
|
29
|
-
let
|
|
29
|
+
let time = 5000;
|
|
30
30
|
|
|
31
31
|
if (process.argv.length >= 3) {
|
|
32
|
-
|
|
33
|
-
if (Number.isNaN(
|
|
32
|
+
time = parseFloat(process.argv[2]) * 1000;
|
|
33
|
+
if (Number.isNaN(time))
|
|
34
34
|
throw new Error('Not a valid number');
|
|
35
|
-
if (
|
|
36
|
-
throw new Error('
|
|
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
|
-
|
|
46
|
-
|
|
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
|
-
|
|
53
|
+
time = performance.now() - start;
|
|
50
54
|
console.log(JSON.stringify({ iterations: iterations, time: Math.round(time) }));
|
|
51
55
|
}
|
package/benchmark/atoi_napi.js
CHANGED
|
@@ -26,22 +26,26 @@ let sum = 0;
|
|
|
26
26
|
main();
|
|
27
27
|
|
|
28
28
|
function main() {
|
|
29
|
-
let
|
|
29
|
+
let time = 5000;
|
|
30
30
|
|
|
31
31
|
if (process.argv.length >= 3) {
|
|
32
|
-
|
|
33
|
-
if (Number.isNaN(
|
|
32
|
+
time = parseFloat(process.argv[2]) * 1000;
|
|
33
|
+
if (Number.isNaN(time))
|
|
34
34
|
throw new Error('Not a valid number');
|
|
35
|
-
if (
|
|
36
|
-
throw new Error('
|
|
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
|
-
|
|
42
|
-
|
|
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
|
-
|
|
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
|
|
31
|
+
let time = 5000;
|
|
32
32
|
|
|
33
33
|
if (process.argv.length >= 3) {
|
|
34
|
-
|
|
35
|
-
if (Number.isNaN(
|
|
34
|
+
time = parseFloat(process.argv[2]) * 1000;
|
|
35
|
+
if (Number.isNaN(time))
|
|
36
36
|
throw new Error('Not a valid number');
|
|
37
|
-
if (
|
|
38
|
-
throw new Error('
|
|
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
|
-
|
|
48
|
-
|
|
49
|
-
|
|
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
|
-
|
|
52
|
+
iterations += 1000000;
|
|
52
53
|
}
|
|
53
54
|
|
|
54
|
-
|
|
55
|
+
time = performance.now() - start;
|
|
55
56
|
console.log(JSON.stringify({ iterations: iterations, time: Math.round(time) }));
|
|
56
57
|
}
|
package/benchmark/raylib_cc.cc
CHANGED
|
@@ -18,10 +18,10 @@ namespace RG {
|
|
|
18
18
|
|
|
19
19
|
int Main(int argc, char **argv)
|
|
20
20
|
{
|
|
21
|
-
int
|
|
21
|
+
int time = 5000;
|
|
22
22
|
|
|
23
23
|
if (argc >= 2) {
|
|
24
|
-
if (!ParseInt(argv[1], &
|
|
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
|
-
|
|
39
|
+
while (GetMonotonicTime() - start < time) {
|
|
39
40
|
ImageClearBackground(&img, Color { 0, 0, 0, 255 });
|
|
40
41
|
|
|
41
|
-
for (int
|
|
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 = (
|
|
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) +
|
|
54
|
-
(float)((img.height / 2 - 16) +
|
|
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
|
-
|
|
62
|
-
PrintLn("{\"iterations\": %1
|
|
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
|
|
73
|
+
let time = 5000;
|
|
75
74
|
|
|
76
75
|
if (process.argv.length >= 3) {
|
|
77
|
-
|
|
78
|
-
if (Number.isNaN(
|
|
76
|
+
time = parseFloat(process.argv[2]) * 1000;
|
|
77
|
+
if (Number.isNaN(time))
|
|
79
78
|
throw new Error('Not a valid number');
|
|
80
|
-
if (
|
|
81
|
-
throw new Error('
|
|
79
|
+
if (time < 0)
|
|
80
|
+
throw new Error('Time must be positive');
|
|
82
81
|
}
|
|
83
82
|
|
|
84
|
-
let lib_filename =
|
|
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
|
-
|
|
107
|
+
while (performance.now() - start < time) {
|
|
108
108
|
ImageClearBackground(img, { r: 0, g: 0, b: 0, a: 255 });
|
|
109
109
|
|
|
110
|
-
for (let
|
|
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 = (
|
|
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) +
|
|
123
|
-
y: (img.height / 2 - 16) +
|
|
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
|
-
|
|
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
|
|
89
|
+
let time = 5000;
|
|
91
90
|
|
|
92
91
|
if (process.argv.length >= 3) {
|
|
93
|
-
|
|
94
|
-
if (Number.isNaN(
|
|
92
|
+
time = parseFloat(process.argv[2]) * 1000;
|
|
93
|
+
if (Number.isNaN(time))
|
|
95
94
|
throw new Error('Not a valid number');
|
|
96
|
-
if (
|
|
97
|
-
throw new Error('
|
|
95
|
+
if (time < 0)
|
|
96
|
+
throw new Error('Time must be positive');
|
|
98
97
|
}
|
|
99
98
|
|
|
100
|
-
let lib_filename =
|
|
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
|
-
|
|
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
|
|
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 = (
|
|
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) +
|
|
141
|
-
y: (img.height / 2 - 16) +
|
|
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
|
-
|
|
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
|
|
21
|
+
let time = 5000;
|
|
22
22
|
|
|
23
23
|
if (process.argv.length >= 3) {
|
|
24
|
-
|
|
25
|
-
if (Number.isNaN(
|
|
24
|
+
time = parseFloat(process.argv[2]) * 1000;
|
|
25
|
+
if (Number.isNaN(time))
|
|
26
26
|
throw new Error('Not a valid number');
|
|
27
|
-
if (
|
|
28
|
-
throw new Error('
|
|
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
|
-
|
|
42
|
+
while (performance.now() - start < time) {
|
|
42
43
|
r.ImageClearBackground(img, { r: 0, g: 0, b: 0, a: 255 });
|
|
43
44
|
|
|
44
|
-
for (let
|
|
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 = (
|
|
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) +
|
|
57
|
-
y: (img.height / 2 - 16) +
|
|
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
|
-
|
|
67
|
+
time = performance.now() - start;
|
|
65
68
|
console.log(JSON.stringify({ iterations: iterations, time: Math.round(time) }));
|
|
66
69
|
}
|
|
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/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="
|
|
14
|
-
<td><a href="
|
|
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
|
|
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
|
|
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
|
-
|
|
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('
|
|
80
|
-
const
|
|
81
|
+
const fopen = lib.func('fopen', 'FILE', ['str', 'str']);
|
|
82
|
+
const fopen = lib.func('fclose', 'int', ['FILE']);
|
|
81
83
|
|
|
82
|
-
let fp = fopen('
|
|
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.
|
|
91
|
+
// Koffi 2.1
|
|
90
92
|
|
|
91
|
-
const FILE = koffi.handle('FILE');
|
|
92
|
-
const
|
|
93
|
-
const
|
|
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('
|
|
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
|
|
109
|
+
const sqlite3 = koffi.handle('sqlite3');
|
|
107
110
|
|
|
108
|
-
const sqlite3_open_v2 = lib.func('sqlite3_open_v2
|
|
109
|
-
const sqlite3_close_v2 = lib.func('sqlite3_close_v2
|
|
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.
|
|
126
|
+
// Koffi 2.1
|
|
124
127
|
|
|
125
|
-
const
|
|
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
|
|
128
|
-
const sqlite3_close_v2 = lib.func('
|
|
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 = ['
|
|
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
|
|
Binary file
|
|
Binary file
|