koffi 0.9.24 → 0.9.27
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 +78 -19
- package/benchmark/CMakeLists.txt +53 -0
- package/benchmark/atoi_cc.cc +59 -0
- package/benchmark/atoi_koffi.js +52 -0
- package/benchmark/atoi_napi.cc +68 -0
- package/benchmark/atoi_napi.js +48 -0
- package/benchmark/atoi_node_ffi.js +57 -0
- package/benchmark/{raylib_c.c → raylib_cc.cc} +25 -37
- package/benchmark/raylib_koffi.js +16 -10
- package/benchmark/raylib_node_ffi.js +17 -3
- package/package.json +7 -5
- package/src/ffi.cc +1 -1
- package/test/CMakeLists.txt +115 -0
- package/test/registry/machines.json +10 -30
- package/test/tests/misc.c +11 -0
- package/test/tests/misc.js +5 -1
- package/test/tests/raylib.js +1 -1
- package/test/tests/sqlite.js +1 -1
- package/benchmark/build.sh +0 -13
package/README.md
CHANGED
|
@@ -7,6 +7,8 @@
|
|
|
7
7
|
- [Get started](#get-started)
|
|
8
8
|
- [Tests](#tests)
|
|
9
9
|
- [Benchmarks](#benchmarks)
|
|
10
|
+
* [atoi results](#atoi-results)
|
|
11
|
+
* [Raylib results](#raylib-results)
|
|
10
12
|
|
|
11
13
|
# Introduction
|
|
12
14
|
|
|
@@ -253,33 +255,90 @@ node test.js info debian_x64
|
|
|
253
255
|
|
|
254
256
|
# Benchmarks
|
|
255
257
|
|
|
256
|
-
|
|
258
|
+
At this stage, two benchmarks are implemented:
|
|
259
|
+
* The first one is based around repeated calls to atoi, and has four implementations: one in C++, one calling atoi through an NAPI module, one using Koffi, and one with node-ffi-napi. This is a simple function, thus the JS and FFI overhead is clearly visible.
|
|
260
|
+
* The second one is based around Raylib, and will execute much more heavier functions repeatdly. Also in three versions: Koffi, node-ffi-napi and C code.
|
|
257
261
|
|
|
258
|
-
In order to run it, go to `koffi/benchmark` and run `
|
|
262
|
+
In order to run it, go to `koffi/benchmark` and run `../../cnoke/cnoke.js` (or `node ..\..\cnoke\cnoke.js` on Windows) before doing anything else.
|
|
259
263
|
|
|
260
|
-
Once this is done, you can execute each implementation
|
|
264
|
+
Once this is done, you can execute each implementation, e.g. `build/atoi_cc` or `./atoi_koffi.js`. You can optionally define a custom number of iterations, e.g. `./atoi_koffi.js 10000000`.
|
|
261
265
|
|
|
262
|
-
|
|
266
|
+
## atoi results
|
|
267
|
+
|
|
268
|
+
Here are some results from 2022-04-24 on my Linux machine (AMD® Ryzen™ 7 5800H 16G):
|
|
269
|
+
|
|
270
|
+
```sh
|
|
271
|
+
$ build/atoi_cc
|
|
272
|
+
Iterations: 20000000
|
|
273
|
+
Time: 0.24s
|
|
274
|
+
|
|
275
|
+
$ ./atoi_napi.js
|
|
276
|
+
Iterations: 20000000
|
|
277
|
+
Time: 1.10s
|
|
278
|
+
|
|
279
|
+
$ ./atoi_koffi.js
|
|
280
|
+
Iterations: 20000000
|
|
281
|
+
Time: 2.34s
|
|
282
|
+
|
|
283
|
+
# Note: the Node-FFI version does a few setTimeout calls to force the GC to run (around 20
|
|
284
|
+
# for the example below), without which Node will consume all memory because the GC never appears
|
|
285
|
+
# to run, or not enough. It's not ideal but on the other hand it counts as another limitation
|
|
286
|
+
# to Node-FFI performance.
|
|
287
|
+
$ ./atoi_node_ffi.js
|
|
288
|
+
Iterations: 20000000
|
|
289
|
+
Time: 640.49s
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
And on my Windows machine (Intel® Core™ i5-4460 16G):
|
|
293
|
+
|
|
294
|
+
```sh
|
|
295
|
+
$ build\atoi_cc.exe
|
|
296
|
+
Iterations: 20000000
|
|
297
|
+
Time: 0.66s
|
|
298
|
+
|
|
299
|
+
$ node atoi_napi.js
|
|
300
|
+
Iterations: 20000000
|
|
301
|
+
Time: 3.23s
|
|
302
|
+
|
|
303
|
+
$ node atoi_koffi.js
|
|
304
|
+
Iterations: 20000000
|
|
305
|
+
Time: 4.81s
|
|
306
|
+
|
|
307
|
+
$ node atoi_node_ffi.js
|
|
308
|
+
Iterations: 20000000
|
|
309
|
+
Time: 491.99s
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
## Raylib results
|
|
313
|
+
|
|
314
|
+
Here are some results from 2022-04-24 on my Linux machine (AMD® Ryzen™ 7 5800H 16G):
|
|
263
315
|
|
|
264
316
|
```sh
|
|
265
|
-
$
|
|
266
|
-
Iterations:
|
|
317
|
+
$ build/raylib_cc
|
|
318
|
+
Iterations: 100
|
|
319
|
+
Time: 4.14s
|
|
320
|
+
|
|
321
|
+
$ ./raylib_koffi.js
|
|
322
|
+
Iterations: 100
|
|
323
|
+
Time: 6.25s
|
|
267
324
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
325
|
+
$ ./raylib_node_ffi.js
|
|
326
|
+
Iterations: 100
|
|
327
|
+
Time: 27.13s
|
|
328
|
+
```
|
|
271
329
|
|
|
272
|
-
|
|
273
|
-
Iterations: 200
|
|
330
|
+
And on my Windows machine (Intel® Core™ i5-4460 16G):
|
|
274
331
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
332
|
+
```sh
|
|
333
|
+
$ build\raylib_cc.exe
|
|
334
|
+
Iterations: 100
|
|
335
|
+
Time: 10.53s
|
|
278
336
|
|
|
279
|
-
$
|
|
280
|
-
Iterations:
|
|
337
|
+
$ node raylib_koffi.js
|
|
338
|
+
Iterations: 100
|
|
339
|
+
Time: 14.60s
|
|
281
340
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
341
|
+
$ node raylib_node_ffi.js
|
|
342
|
+
Iterations: 100
|
|
343
|
+
Time: 44.97s
|
|
285
344
|
```
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# This program is free software: you can redistribute it and/or modify
|
|
2
|
+
# it under the terms of the GNU Affero General Public License as published by
|
|
3
|
+
# the Free Software Foundation, either version 3 of the License, or
|
|
4
|
+
# (at your option) any later version.
|
|
5
|
+
#
|
|
6
|
+
# This program is distributed in the hope that it will be useful,
|
|
7
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
8
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
9
|
+
# GNU Affero General Public License for more details.
|
|
10
|
+
#
|
|
11
|
+
# You should have received a copy of the GNU Affero General Public License
|
|
12
|
+
# along with this program. If not, see https://www.gnu.org/licenses/.
|
|
13
|
+
|
|
14
|
+
cmake_minimum_required(VERSION 3.12)
|
|
15
|
+
project(koffi C CXX ASM)
|
|
16
|
+
|
|
17
|
+
find_package(CNoke)
|
|
18
|
+
|
|
19
|
+
set(CMAKE_CXX_STANDARD 17)
|
|
20
|
+
|
|
21
|
+
if(NOT TARGET koffi)
|
|
22
|
+
add_subdirectory(.. koffi)
|
|
23
|
+
endif()
|
|
24
|
+
add_subdirectory(../test test)
|
|
25
|
+
|
|
26
|
+
# ---- atoi ----
|
|
27
|
+
|
|
28
|
+
add_executable(atoi_cc atoi_cc.cc ../vendor/libcc/libcc.cc)
|
|
29
|
+
target_include_directories(atoi_cc PRIVATE ..)
|
|
30
|
+
|
|
31
|
+
if(WIN32)
|
|
32
|
+
target_compile_definitions(atoi_cc PRIVATE _CRT_SECURE_NO_WARNINGS _CRT_NONSTDC_NO_DEPRECATE)
|
|
33
|
+
target_link_libraries(atoi_cc PRIVATE ws2_32)
|
|
34
|
+
endif()
|
|
35
|
+
|
|
36
|
+
add_node_addon(NAME atoi_napi SOURCES atoi_napi.cc ../vendor/libcc/libcc.cc)
|
|
37
|
+
target_include_directories(atoi_napi PRIVATE .. ../vendor/node-addon-api)
|
|
38
|
+
|
|
39
|
+
if(WIN32)
|
|
40
|
+
target_compile_definitions(atoi_napi PRIVATE _CRT_SECURE_NO_WARNINGS _CRT_NONSTDC_NO_DEPRECATE)
|
|
41
|
+
target_link_libraries(atoi_napi PRIVATE ws2_32)
|
|
42
|
+
endif()
|
|
43
|
+
|
|
44
|
+
# ---- Raylib ----
|
|
45
|
+
|
|
46
|
+
add_executable(raylib_cc atoi_cc.cc ../vendor/libcc/libcc.cc)
|
|
47
|
+
target_include_directories(raylib_cc PRIVATE ..)
|
|
48
|
+
add_dependencies(raylib_cc raylib)
|
|
49
|
+
|
|
50
|
+
if(WIN32)
|
|
51
|
+
target_compile_definitions(raylib_cc PRIVATE _CRT_SECURE_NO_WARNINGS _CRT_NONSTDC_NO_DEPRECATE)
|
|
52
|
+
target_link_libraries(raylib_cc PRIVATE ws2_32)
|
|
53
|
+
endif()
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
// This program is free software: you can redistribute it and/or modify
|
|
2
|
+
// it under the terms of the GNU Affero General Public License as published by
|
|
3
|
+
// the Free Software Foundation, either version 3 of the License, or
|
|
4
|
+
// (at your option) any later version.
|
|
5
|
+
//
|
|
6
|
+
// This program is distributed in the hope that it will be useful,
|
|
7
|
+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
8
|
+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
9
|
+
// GNU Affero General Public License for more details.
|
|
10
|
+
//
|
|
11
|
+
// You should have received a copy of the GNU Affero General Public License
|
|
12
|
+
// along with this program. If not, see https://www.gnu.org/licenses/.
|
|
13
|
+
|
|
14
|
+
#include "../vendor/libcc/libcc.hh"
|
|
15
|
+
|
|
16
|
+
namespace RG {
|
|
17
|
+
|
|
18
|
+
static const char * strings[] = {
|
|
19
|
+
"424242",
|
|
20
|
+
"foobar",
|
|
21
|
+
"123456789",
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
volatile uint64_t sum = 0;
|
|
25
|
+
|
|
26
|
+
int Main(int argc, char **argv)
|
|
27
|
+
{
|
|
28
|
+
int iterations = 20000000;
|
|
29
|
+
|
|
30
|
+
if (argc >= 2) {
|
|
31
|
+
if (!ParseInt(argv[1], &iterations))
|
|
32
|
+
return 1;
|
|
33
|
+
}
|
|
34
|
+
LogInfo("Iterations: %1", iterations);
|
|
35
|
+
|
|
36
|
+
int64_t start = GetMonotonicTime();
|
|
37
|
+
|
|
38
|
+
for (int i = 0; i < iterations; i++) {
|
|
39
|
+
sum += (uint64_t)atoi(strings[i % RG_LEN(strings)]);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Help prevent optimisation of loop
|
|
43
|
+
{
|
|
44
|
+
PushLogFilter([](LogLevel, const char *, const char *, FunctionRef<LogFunc>) {});
|
|
45
|
+
RG_DEFER { PopLogFilter(); };
|
|
46
|
+
|
|
47
|
+
LogInfo("Sum = %1", sum);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
int64_t time = GetMonotonicTime() - start;
|
|
51
|
+
LogInfo("Time: %1s", FmtDouble((double)time / 1000.0, 2));
|
|
52
|
+
|
|
53
|
+
return 0;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// C++ namespaces are stupid
|
|
59
|
+
int main(int argc, char **argv) { return RG::Main(argc, argv); }
|
|
@@ -0,0 +1,52 @@
|
|
|
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
|
+
|
|
18
|
+
const strings = [
|
|
19
|
+
'424242',
|
|
20
|
+
'foobar',
|
|
21
|
+
'123456789'
|
|
22
|
+
];
|
|
23
|
+
|
|
24
|
+
let sum = 0;
|
|
25
|
+
|
|
26
|
+
main();
|
|
27
|
+
|
|
28
|
+
function main() {
|
|
29
|
+
let iterations = 20000000;
|
|
30
|
+
|
|
31
|
+
if (process.argv.length >= 3) {
|
|
32
|
+
iterations = parseInt(process.argv[2], 10);
|
|
33
|
+
if (Number.isNaN(iterations))
|
|
34
|
+
throw new Error('Not a valid number');
|
|
35
|
+
if (iterations < 1)
|
|
36
|
+
throw new Error('Value must be positive');
|
|
37
|
+
}
|
|
38
|
+
console.log('Iterations:', iterations);
|
|
39
|
+
|
|
40
|
+
let lib = koffi.load(process.platform == 'win32' ? 'msvcrt.dll' : null);
|
|
41
|
+
|
|
42
|
+
const atoi = lib.cdecl('atoi', 'int', ['string']);
|
|
43
|
+
|
|
44
|
+
let start = performance.now();
|
|
45
|
+
|
|
46
|
+
for (let i = 0; i < iterations; i++) {
|
|
47
|
+
sum += atoi(strings[i % strings.length]);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
let time = performance.now()- start;
|
|
51
|
+
console.log('Time:', (time / 1000.0).toFixed(2) + 's');
|
|
52
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
// This program is free software: you can redistribute it and/or modify
|
|
2
|
+
// it under the terms of the GNU Affero General Public License as published by
|
|
3
|
+
// the Free Software Foundation, either version 3 of the License, or
|
|
4
|
+
// (at your option) any later version.
|
|
5
|
+
//
|
|
6
|
+
// This program is distributed in the hope that it will be useful,
|
|
7
|
+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
8
|
+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
9
|
+
// GNU Affero General Public License for more details.
|
|
10
|
+
//
|
|
11
|
+
// You should have received a copy of the GNU Affero General Public License
|
|
12
|
+
// along with this program. If not, see https://www.gnu.org/licenses/.
|
|
13
|
+
|
|
14
|
+
#include "vendor/libcc/libcc.hh"
|
|
15
|
+
#include <napi.h>
|
|
16
|
+
|
|
17
|
+
namespace RG {
|
|
18
|
+
|
|
19
|
+
template <typename T, typename... Args>
|
|
20
|
+
void ThrowError(Napi::Env env, const char *msg, Args... args)
|
|
21
|
+
{
|
|
22
|
+
char buf[1024];
|
|
23
|
+
Fmt(buf, msg, args...);
|
|
24
|
+
|
|
25
|
+
auto err = T::New(env, buf);
|
|
26
|
+
err.ThrowAsJavaScriptException();
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
static Napi::Value RunAtoi(const Napi::CallbackInfo &info)
|
|
30
|
+
{
|
|
31
|
+
Napi::Env env = info.Env();
|
|
32
|
+
|
|
33
|
+
if (RG_UNLIKELY(info.Length() < 1)) {
|
|
34
|
+
ThrowError<Napi::TypeError>(env, "Expected 1 argument, got %1", info.Length());
|
|
35
|
+
return env.Null();
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
char str[64];
|
|
39
|
+
{
|
|
40
|
+
napi_status status = napi_get_value_string_utf8(env, info[0], str, RG_SIZE(str), nullptr);
|
|
41
|
+
|
|
42
|
+
if (RG_UNLIKELY(status != napi_ok)) {
|
|
43
|
+
if (status == napi_string_expected) {
|
|
44
|
+
ThrowError<Napi::TypeError>(env, "Unexpected value for str, expected string");
|
|
45
|
+
} else {
|
|
46
|
+
ThrowError<Napi::TypeError>(env, "Failed to read JS string");
|
|
47
|
+
}
|
|
48
|
+
return env.Null();
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
int value = atoi(str);
|
|
53
|
+
|
|
54
|
+
return Napi::Number::New(env, value);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
static Napi::Object InitModule(Napi::Env env, Napi::Object exports)
|
|
60
|
+
{
|
|
61
|
+
using namespace RG;
|
|
62
|
+
|
|
63
|
+
exports.Set("atoi", Napi::Function::New(env, RunAtoi));
|
|
64
|
+
|
|
65
|
+
return exports;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
NODE_API_MODULE(koffi, InitModule);
|
|
@@ -0,0 +1,48 @@
|
|
|
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 atoi = require('./build/atoi_napi.node');
|
|
17
|
+
|
|
18
|
+
const strings = [
|
|
19
|
+
'424242',
|
|
20
|
+
'foobar',
|
|
21
|
+
'123456789'
|
|
22
|
+
];
|
|
23
|
+
|
|
24
|
+
let sum = 0;
|
|
25
|
+
|
|
26
|
+
main();
|
|
27
|
+
|
|
28
|
+
function main() {
|
|
29
|
+
let iterations = 20000000;
|
|
30
|
+
|
|
31
|
+
if (process.argv.length >= 3) {
|
|
32
|
+
iterations = parseInt(process.argv[2], 10);
|
|
33
|
+
if (Number.isNaN(iterations))
|
|
34
|
+
throw new Error('Not a valid number');
|
|
35
|
+
if (iterations < 1)
|
|
36
|
+
throw new Error('Value must be positive');
|
|
37
|
+
}
|
|
38
|
+
console.log('Iterations:', iterations);
|
|
39
|
+
|
|
40
|
+
let start = performance.now();
|
|
41
|
+
|
|
42
|
+
for (let i = 0; i < iterations; i++) {
|
|
43
|
+
sum += atoi.atoi(strings[i % strings.length]);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
let time = performance.now()- start;
|
|
47
|
+
console.log('Time:', (time / 1000.0).toFixed(2) + 's');
|
|
48
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
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 ref = require('ref-napi');
|
|
17
|
+
const ffi = require('ffi-napi');
|
|
18
|
+
const struct = require('ref-struct-di')(ref);
|
|
19
|
+
|
|
20
|
+
const strings = [
|
|
21
|
+
'424242',
|
|
22
|
+
'foobar',
|
|
23
|
+
'123456789'
|
|
24
|
+
];
|
|
25
|
+
|
|
26
|
+
let sum = 0;
|
|
27
|
+
|
|
28
|
+
main();
|
|
29
|
+
|
|
30
|
+
async function main() {
|
|
31
|
+
let iterations = 20000000;
|
|
32
|
+
|
|
33
|
+
if (process.argv.length >= 3) {
|
|
34
|
+
iterations = parseInt(process.argv[2], 10);
|
|
35
|
+
if (Number.isNaN(iterations))
|
|
36
|
+
throw new Error('Not a valid number');
|
|
37
|
+
if (iterations < 1)
|
|
38
|
+
throw new Error('Value must be positive');
|
|
39
|
+
}
|
|
40
|
+
console.log('Iterations:', iterations);
|
|
41
|
+
|
|
42
|
+
const lib = ffi.Library(process.platform == 'win32' ? 'msvcrt.dll' : null, {
|
|
43
|
+
atoi: ['int', ['string']]
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
let start = performance.now();
|
|
47
|
+
|
|
48
|
+
for (let i = 0; i < iterations; i++) {
|
|
49
|
+
if (i % 1000000 == 0)
|
|
50
|
+
await new Promise(resolve => setTimeout(resolve, 0));
|
|
51
|
+
|
|
52
|
+
sum += lib.atoi(strings[i % strings.length]);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
let time = performance.now()- start;
|
|
56
|
+
console.log('Time:', (time / 1000.0).toFixed(2) + 's');
|
|
57
|
+
}
|
|
@@ -11,51 +11,31 @@
|
|
|
11
11
|
// You should have received a copy of the GNU Affero General Public License
|
|
12
12
|
// along with this program. If not, see https://www.gnu.org/licenses/.
|
|
13
13
|
|
|
14
|
-
#include
|
|
15
|
-
#include <stdio.h>
|
|
16
|
-
#include <stdlib.h>
|
|
17
|
-
#include <limits.h>
|
|
14
|
+
#include "../vendor/libcc/libcc.hh"
|
|
18
15
|
#include "../vendor/raylib/src/raylib.h"
|
|
19
16
|
|
|
20
|
-
|
|
17
|
+
namespace RG {
|
|
21
18
|
|
|
22
|
-
|
|
19
|
+
int Main(int argc, char **argv)
|
|
23
20
|
{
|
|
24
|
-
|
|
25
|
-
long long value = strtoll(str, &end, 10);
|
|
21
|
+
int iterations = 100;
|
|
26
22
|
|
|
27
|
-
if (
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}
|
|
31
|
-
if (value < 1 || value == LLONG_MAX) {
|
|
32
|
-
fprintf(stderr, "Value must be between 1 and " STRINGIFY(LLONG_MAX) "\n");
|
|
33
|
-
return -1;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
return (int)value;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
int main(int argc, char **argv)
|
|
40
|
-
{
|
|
41
|
-
if (argc < 2) {
|
|
42
|
-
fprintf(stderr, "Missing number of iterations\n");
|
|
43
|
-
return 1;
|
|
23
|
+
if (argc >= 2) {
|
|
24
|
+
if (!ParseInt(argv[1], &iterations))
|
|
25
|
+
return 1;
|
|
44
26
|
}
|
|
45
|
-
|
|
46
|
-
int iterations = ParseInt(argv[1]);
|
|
47
|
-
if (iterations < 0)
|
|
48
|
-
return 1;
|
|
49
|
-
printf("Iterations: %d\n", iterations);
|
|
27
|
+
LogInfo("Iterations: %1", iterations);
|
|
50
28
|
|
|
51
29
|
// We need to call InitWindow before using anything else (such as fonts)
|
|
52
|
-
SetTraceLogLevel(
|
|
53
|
-
SetWindowState(
|
|
30
|
+
SetTraceLogLevel(LOG_WARNING);
|
|
31
|
+
SetWindowState(FLAG_WINDOW_HIDDEN);
|
|
54
32
|
InitWindow(640, 480, "Raylib Test");
|
|
55
33
|
|
|
56
34
|
Image img = GenImageColor(800, 600, (Color){ .r = 0, .g = 0, .b = 0, .a = 255 });
|
|
57
35
|
Font font = GetFontDefault();
|
|
58
36
|
|
|
37
|
+
int64_t start = GetMonotonicTime();
|
|
38
|
+
|
|
59
39
|
for (int i = 0; i < iterations; i++) {
|
|
60
40
|
ImageClearBackground(&img, (Color){ .r = 0, .g = 0, .b = 0, .a = 255 });
|
|
61
41
|
|
|
@@ -65,19 +45,27 @@ int main(int argc, char **argv)
|
|
|
65
45
|
|
|
66
46
|
double angle = (j * 7) * PI / 180;
|
|
67
47
|
Color color = {
|
|
68
|
-
.r = 127.5 + 127.5 * sin(angle),
|
|
69
|
-
.g = 127.5 + 127.5 * sin(angle + PI / 2),
|
|
70
|
-
.b = 127.5 + 127.5 * sin(angle + PI),
|
|
48
|
+
.r = (unsigned char)(127.5 + 127.5 * sin(angle)),
|
|
49
|
+
.g = (unsigned char)(127.5 + 127.5 * sin(angle + PI / 2)),
|
|
50
|
+
.b = (unsigned char)(127.5 + 127.5 * sin(angle + PI)),
|
|
71
51
|
.a = 255
|
|
72
52
|
};
|
|
73
53
|
Vector2 pos = {
|
|
74
|
-
.x = (img.width / 2 - text_width / 2) + j * 0.1 * cos(angle - PI / 2),
|
|
75
|
-
.y = (img.height / 2 - 16) + j * 0.1 * sin(angle - PI / 2)
|
|
54
|
+
.x = (float)((img.width / 2 - text_width / 2) + j * 0.1 * cos(angle - PI / 2)),
|
|
55
|
+
.y = (float)((img.height / 2 - 16) + j * 0.1 * sin(angle - PI / 2))
|
|
76
56
|
};
|
|
77
57
|
|
|
78
58
|
ImageDrawTextEx(&img, font, text, pos, 10, 1, color);
|
|
79
59
|
}
|
|
80
60
|
}
|
|
81
61
|
|
|
62
|
+
int64_t time = GetMonotonicTime() - start;
|
|
63
|
+
LogInfo("Time: %1s", FmtDouble((double)time / 1000.0, 2));
|
|
64
|
+
|
|
82
65
|
return 0;
|
|
83
66
|
}
|
|
67
|
+
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// C++ namespaces are stupid
|
|
71
|
+
int main(int argc, char **argv) { return RG::Main(argc, argv); }
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
// You should have received a copy of the GNU Affero General Public License
|
|
14
14
|
// along with this program. If not, see https://www.gnu.org/licenses/.
|
|
15
15
|
|
|
16
|
-
const koffi = require('
|
|
16
|
+
const koffi = require('./build/koffi.node');
|
|
17
17
|
const path = require('path');
|
|
18
18
|
|
|
19
19
|
const Color = koffi.struct('Color', {
|
|
@@ -71,17 +71,18 @@ const Font = koffi.struct('Font', {
|
|
|
71
71
|
main();
|
|
72
72
|
|
|
73
73
|
function main() {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
74
|
+
let iterations = 100;
|
|
75
|
+
|
|
76
|
+
if (process.argv.length >= 3) {
|
|
77
|
+
iterations = parseInt(process.argv[2], 10);
|
|
78
|
+
if (Number.isNaN(iterations))
|
|
79
|
+
throw new Error('Not a valid number');
|
|
80
|
+
if (iterations < 1)
|
|
81
|
+
throw new Error('Value must be positive');
|
|
82
|
+
}
|
|
82
83
|
console.log('Iterations:', iterations);
|
|
83
84
|
|
|
84
|
-
let lib_filename = path.dirname(__filename) + '
|
|
85
|
+
let lib_filename = path.dirname(__filename) + '/test/build/raylib' + koffi.extension;
|
|
85
86
|
let lib = koffi.load(lib_filename);
|
|
86
87
|
|
|
87
88
|
const InitWindow = lib.cdecl('InitWindow', 'void', ['int', 'int', 'string']);
|
|
@@ -102,6 +103,8 @@ function main() {
|
|
|
102
103
|
let img = GenImageColor(800, 600, { r: 0, g: 0, b: 0, a: 255 });
|
|
103
104
|
let font = GetFontDefault();
|
|
104
105
|
|
|
106
|
+
let start = performance.now();
|
|
107
|
+
|
|
105
108
|
for (let i = 0; i < iterations; i++) {
|
|
106
109
|
ImageClearBackground(img, { r: 0, g: 0, b: 0, a: 255 });
|
|
107
110
|
|
|
@@ -124,4 +127,7 @@ function main() {
|
|
|
124
127
|
ImageDrawTextEx(img, font, text, pos, 10, 1, color);
|
|
125
128
|
}
|
|
126
129
|
}
|
|
130
|
+
|
|
131
|
+
let time = performance.now()- start;
|
|
132
|
+
console.log('Time:', (time / 1000.0).toFixed(2) + 's');
|
|
127
133
|
}
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
const ref = require('ref-napi');
|
|
17
17
|
const ffi = require('ffi-napi');
|
|
18
18
|
const struct = require('ref-struct-di')(ref);
|
|
19
|
+
const koffi = require('./build/koffi.node');
|
|
19
20
|
const path = require('path');
|
|
20
21
|
|
|
21
22
|
const Color = struct({
|
|
@@ -86,8 +87,16 @@ const Font = struct({
|
|
|
86
87
|
main();
|
|
87
88
|
|
|
88
89
|
function main() {
|
|
89
|
-
|
|
90
|
-
|
|
90
|
+
let iterations = 100;
|
|
91
|
+
|
|
92
|
+
if (process.argv.length >= 3) {
|
|
93
|
+
iterations = parseInt(process.argv[2], 10);
|
|
94
|
+
if (Number.isNaN(iterations))
|
|
95
|
+
throw new Error('Not a valid number');
|
|
96
|
+
if (iterations < 1)
|
|
97
|
+
throw new Error('Value must be positive');
|
|
98
|
+
}
|
|
99
|
+
console.log('Iterations:', iterations);
|
|
91
100
|
|
|
92
101
|
let iterations = parseInt(process.argv[2], 10);
|
|
93
102
|
if (Number.isNaN(iterations))
|
|
@@ -96,7 +105,7 @@ function main() {
|
|
|
96
105
|
throw new Error('Value must be positive');
|
|
97
106
|
console.log('Iterations:', iterations);
|
|
98
107
|
|
|
99
|
-
let lib_filename = path.dirname(__filename) + '
|
|
108
|
+
let lib_filename = path.dirname(__filename) + '/test/build/raylib' + koffi.extension;
|
|
100
109
|
|
|
101
110
|
const r = ffi.Library(lib_filename, {
|
|
102
111
|
InitWindow: ['void', ['int', 'int', 'string']],
|
|
@@ -119,6 +128,8 @@ function main() {
|
|
|
119
128
|
let imgp = img.ref();
|
|
120
129
|
let font = r.GetFontDefault();
|
|
121
130
|
|
|
131
|
+
let start = performance.now();
|
|
132
|
+
|
|
122
133
|
for (let i = 0; i < iterations; i++) {
|
|
123
134
|
r.ImageClearBackground(imgp, new Color({ r: 0, g: 0, b: 0, a: 255 }));
|
|
124
135
|
|
|
@@ -141,4 +152,7 @@ function main() {
|
|
|
141
152
|
r.ImageDrawTextEx(imgp, font, text, pos, 10, 1, color);
|
|
142
153
|
}
|
|
143
154
|
}
|
|
155
|
+
|
|
156
|
+
let time = performance.now()- start;
|
|
157
|
+
console.log('Time:', (time / 1000.0).toFixed(2) + 's');
|
|
144
158
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "koffi",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.27",
|
|
4
4
|
"description": "Fast and simple FFI (foreign function interface) for Node.js",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"foreign",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
},
|
|
24
24
|
"license": "AGPL-3.0",
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"cnoke": "^0.
|
|
26
|
+
"cnoke": "^1.0.1"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
29
|
"chalk": "^4.1.2",
|
|
@@ -35,11 +35,13 @@
|
|
|
35
35
|
},
|
|
36
36
|
"files": [
|
|
37
37
|
"src",
|
|
38
|
-
"benchmark",
|
|
39
|
-
"
|
|
38
|
+
"benchmark/CMakeLists.txt",
|
|
39
|
+
"benchmark/atoi_*",
|
|
40
|
+
"benchmark/raylib_*",
|
|
41
|
+
"test/CMakeLists.txt",
|
|
42
|
+
"test/test.js",
|
|
40
43
|
"test/registry",
|
|
41
44
|
"test/tests",
|
|
42
|
-
"test/test.js",
|
|
43
45
|
"vendor",
|
|
44
46
|
"LICENSE.txt",
|
|
45
47
|
"README.md",
|
package/src/ffi.cc
CHANGED
|
@@ -116,7 +116,7 @@ static Napi::Value CreateStructType(const Napi::CallbackInfo &info)
|
|
|
116
116
|
if (!member.type)
|
|
117
117
|
return env.Null();
|
|
118
118
|
|
|
119
|
-
type->size = AlignLen(type->size, member.type->align) + member.type->size;
|
|
119
|
+
type->size = (int16_t)(AlignLen(type->size, member.type->align) + member.type->size);
|
|
120
120
|
type->align = std::max(type->align, member.type->align);
|
|
121
121
|
|
|
122
122
|
type->members.Append(member);
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# This program is free software: you can redistribute it and/or modify
|
|
2
|
+
# it under the terms of the GNU Affero General Public License as published by
|
|
3
|
+
# the Free Software Foundation, either version 3 of the License, or
|
|
4
|
+
# (at your option) any later version.
|
|
5
|
+
#
|
|
6
|
+
# This program is distributed in the hope that it will be useful,
|
|
7
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
8
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
9
|
+
# GNU Affero General Public License for more details.
|
|
10
|
+
#
|
|
11
|
+
# You should have received a copy of the GNU Affero General Public License
|
|
12
|
+
# along with this program. If not, see https://www.gnu.org/licenses/.
|
|
13
|
+
|
|
14
|
+
cmake_minimum_required(VERSION 3.12)
|
|
15
|
+
project(koffi C CXX)
|
|
16
|
+
|
|
17
|
+
if(NOT TARGET koffi)
|
|
18
|
+
add_subdirectory(.. koffi)
|
|
19
|
+
endif()
|
|
20
|
+
|
|
21
|
+
# ---- Raylib ----
|
|
22
|
+
|
|
23
|
+
add_library(raylib SHARED
|
|
24
|
+
../vendor/raylib/src/rcore.c
|
|
25
|
+
../vendor/raylib/src/rshapes.c
|
|
26
|
+
../vendor/raylib/src/rtextures.c
|
|
27
|
+
../vendor/raylib/src/rtext.c
|
|
28
|
+
../vendor/raylib/src/rmodels.c
|
|
29
|
+
../vendor/raylib/src/utils.c
|
|
30
|
+
../vendor/raylib/src/rglfw.c
|
|
31
|
+
../vendor/raylib/src/raudio.c
|
|
32
|
+
)
|
|
33
|
+
set_target_properties(raylib PROPERTIES PREFIX "")
|
|
34
|
+
target_include_directories(raylib PRIVATE ../vendor/raylib/src/external/glfw/include)
|
|
35
|
+
target_compile_definitions(raylib PRIVATE PLATFORM_DESKTOP GRAPHICS_API_OPENGL_21
|
|
36
|
+
BUILD_LIBTYPE_SHARED NDEBUG)
|
|
37
|
+
|
|
38
|
+
if(MSVC)
|
|
39
|
+
target_compile_options(raylib PRIVATE /wd4244 /wd4305)
|
|
40
|
+
else()
|
|
41
|
+
target_compile_options(raylib PRIVATE -Wno-sign-compare -Wno-old-style-declaration
|
|
42
|
+
-Wno-unused-function -Wno-missing-field-initializers
|
|
43
|
+
-Wno-unused-value -Wno-implicit-fallthrough -Wno-stringop-overflow
|
|
44
|
+
-Wno-unused-result)
|
|
45
|
+
endif()
|
|
46
|
+
|
|
47
|
+
if(WIN32)
|
|
48
|
+
target_compile_definitions(raylib PRIVATE _CRT_SECURE_NO_WARNINGS _CRT_NONSTDC_NO_DEPRECATE)
|
|
49
|
+
target_link_libraries(raylib PRIVATE winmm)
|
|
50
|
+
endif()
|
|
51
|
+
|
|
52
|
+
if(CMAKE_SYSTEM_NAME MATCHES "BSD")
|
|
53
|
+
target_include_directories(raylib PRIVATE /usr/local/include)
|
|
54
|
+
endif()
|
|
55
|
+
|
|
56
|
+
if(APPLE)
|
|
57
|
+
target_compile_options(raylib PRIVATE -Wno-unknown-warning-option -Wno-macro-redefined)
|
|
58
|
+
target_compile_definitions(raylib PRIVATE GL_SILENCE_DEPRECATION)
|
|
59
|
+
set_source_files_properties(../vendor/raylib/src/rglfw.c PROPERTIES COMPILE_FLAGS "-x objective-c")
|
|
60
|
+
target_link_libraries(raylib PRIVATE "-framework Cocoa" "-framework IOKit" "-framework CoreFoundation" "-framework OpenGL")
|
|
61
|
+
endif()
|
|
62
|
+
|
|
63
|
+
if(UNIX AND NOT APPLE)
|
|
64
|
+
set(missing_xlib "")
|
|
65
|
+
|
|
66
|
+
find_path(XLIB_INCLUDE_DIRS X11/Xlib.h)
|
|
67
|
+
if(NOT XLIB_INCLUDE_DIRS)
|
|
68
|
+
list(APPEND missing_xlib Xlib)
|
|
69
|
+
endif()
|
|
70
|
+
find_path(XCURSOR_INCLUDE_DIRS X11/Xcursor/Xcursor.h)
|
|
71
|
+
if(NOT XCURSOR_INCLUDE_DIRS)
|
|
72
|
+
list(APPEND missing_xlib Xcursor)
|
|
73
|
+
endif()
|
|
74
|
+
find_path(XRANDR_INCLUDE_DIRS X11/extensions/Xrandr.h)
|
|
75
|
+
if(NOT XRANDR_INCLUDE_DIRS)
|
|
76
|
+
list(APPEND missing_xlib Xrandr)
|
|
77
|
+
endif()
|
|
78
|
+
find_path(XKB_INCLUDE_DIRS X11/XKBlib.h)
|
|
79
|
+
if(NOT XKB_INCLUDE_DIRS)
|
|
80
|
+
list(APPEND missing_xlib Xkbcommon)
|
|
81
|
+
endif()
|
|
82
|
+
find_path(XINERAMA_INCLUDE_DIRS X11/extensions/Xinerama.h)
|
|
83
|
+
if(NOT XINERAMA_INCLUDE_DIRS)
|
|
84
|
+
list(APPEND missing_xlib Xinerama)
|
|
85
|
+
endif()
|
|
86
|
+
find_path(XINPUT_INCLUDE_DIRS X11/extensions/XInput2.h)
|
|
87
|
+
if(NOT XINPUT_INCLUDE_DIRS)
|
|
88
|
+
list(APPEND missing_xlib XInput2)
|
|
89
|
+
endif()
|
|
90
|
+
|
|
91
|
+
if(missing_xlib)
|
|
92
|
+
list(JOIN missing_xlib ", " missing_xlib_str)
|
|
93
|
+
message(FATAL_ERROR "Missing X11 development files: ${missing_xlib_str}")
|
|
94
|
+
endif()
|
|
95
|
+
|
|
96
|
+
target_include_directories(raylib PRIVATE ${XLIB_INCLUDE_DIRS})
|
|
97
|
+
endif()
|
|
98
|
+
|
|
99
|
+
# ---- SQLite ----
|
|
100
|
+
|
|
101
|
+
add_library(sqlite3 SHARED ../vendor/sqlite3/sqlite3.c)
|
|
102
|
+
set_target_properties(sqlite3 PROPERTIES PREFIX "")
|
|
103
|
+
|
|
104
|
+
if(WIN32)
|
|
105
|
+
target_compile_definitions(sqlite3 PRIVATE SQLITE_API=__declspec\(dllexport\))
|
|
106
|
+
endif()
|
|
107
|
+
|
|
108
|
+
# ---- Misc ----
|
|
109
|
+
|
|
110
|
+
add_library(misc SHARED tests/misc.c)
|
|
111
|
+
set_target_properties(misc PROPERTIES PREFIX "")
|
|
112
|
+
|
|
113
|
+
if(MSVC)
|
|
114
|
+
target_compile_options(misc PRIVATE /wd4116)
|
|
115
|
+
endif()
|
|
@@ -25,9 +25,7 @@
|
|
|
25
25
|
"Linux ARM32": {
|
|
26
26
|
"directory": "/home/debian/luigi",
|
|
27
27
|
"build": {
|
|
28
|
-
"
|
|
29
|
-
"Build Koffi": "node ../cnoke/cnoke.js",
|
|
30
|
-
"Build dependencies": "node ../cnoke/cnoke.js -C test"
|
|
28
|
+
"Build": "node ../cnoke/cnoke.js -C test"
|
|
31
29
|
},
|
|
32
30
|
"commands": {
|
|
33
31
|
"Test Raylib": "xvfb-run node test/tests/raylib.js",
|
|
@@ -64,9 +62,7 @@
|
|
|
64
62
|
"Linux ARM64": {
|
|
65
63
|
"directory": "/home/debian/luigi",
|
|
66
64
|
"build": {
|
|
67
|
-
"
|
|
68
|
-
"Build Koffi": "node ../cnoke/cnoke.js",
|
|
69
|
-
"Build dependencies": "node ../cnoke/cnoke.js -C test"
|
|
65
|
+
"Build": "node ../cnoke/cnoke.js -C test"
|
|
70
66
|
},
|
|
71
67
|
"commands": {
|
|
72
68
|
"Test Raylib": "xvfb-run node test/tests/raylib.js",
|
|
@@ -103,9 +99,7 @@
|
|
|
103
99
|
"Linux i386": {
|
|
104
100
|
"directory": "/home/debian/luigi",
|
|
105
101
|
"build": {
|
|
106
|
-
"
|
|
107
|
-
"Build Koffi": "node ../cnoke/cnoke.js",
|
|
108
|
-
"Build dependencies": "node ../cnoke/cnoke.js -C test"
|
|
102
|
+
"Build": "node ../cnoke/cnoke.js -C test"
|
|
109
103
|
},
|
|
110
104
|
"commands": {
|
|
111
105
|
"Test Raylib": "xvfb-run node test/tests/raylib.js",
|
|
@@ -142,9 +136,7 @@
|
|
|
142
136
|
"Linux x64": {
|
|
143
137
|
"directory": "/home/debian/luigi",
|
|
144
138
|
"build": {
|
|
145
|
-
"
|
|
146
|
-
"Build Koffi": "node ../cnoke/cnoke.js",
|
|
147
|
-
"Build dependencies": "node ../cnoke/cnoke.js -C test"
|
|
139
|
+
"Build": "node ../cnoke/cnoke.js -C test"
|
|
148
140
|
},
|
|
149
141
|
"commands": {
|
|
150
142
|
"Test Raylib": "xvfb-run node test/tests/raylib.js",
|
|
@@ -181,9 +173,7 @@
|
|
|
181
173
|
"Windows i386": {
|
|
182
174
|
"directory": "C:/Users/windows/Desktop/luigi32",
|
|
183
175
|
"build": {
|
|
184
|
-
"
|
|
185
|
-
"Build Koffi": "C:\\Node32\\node32.cmd node ../cnoke/cnoke.js",
|
|
186
|
-
"Build dependencies": "C:\\Node32\\node32.cmd node ../cnoke/cnoke.js -C test"
|
|
176
|
+
"Build": "C:\\Node32\\node32.cmd node ../cnoke/cnoke.js -C test"
|
|
187
177
|
},
|
|
188
178
|
"commands": {
|
|
189
179
|
"Test Raylib": "seatsh C:\\Node32\\node32.cmd node test/tests/raylib.js",
|
|
@@ -195,9 +185,7 @@
|
|
|
195
185
|
"Windows x64": {
|
|
196
186
|
"directory": "C:/Users/windows/Desktop/luigi64",
|
|
197
187
|
"build": {
|
|
198
|
-
"
|
|
199
|
-
"Build Koffi": "C:\\Node64\\node64.cmd node ../cnoke/cnoke.js",
|
|
200
|
-
"Build dependencies": "C:\\Node64\\node64.cmd node ../cnoke/cnoke.js -C test"
|
|
188
|
+
"Build": "C:\\Node64\\node64.cmd node ../cnoke/cnoke.js -C test"
|
|
201
189
|
},
|
|
202
190
|
"commands": {
|
|
203
191
|
"Test Raylib": "seatsh C:\\Node64\\node64.cmd node test/tests/raylib.js",
|
|
@@ -234,9 +222,7 @@
|
|
|
234
222
|
"FreeBSD x64": {
|
|
235
223
|
"directory": "/home/freebsd/luigi",
|
|
236
224
|
"build": {
|
|
237
|
-
"
|
|
238
|
-
"Build Koffi": "node ../cnoke/cnoke.js",
|
|
239
|
-
"Build dependencies": "node ../cnoke/cnoke.js -C test"
|
|
225
|
+
"Build": "node ../cnoke/cnoke.js -C test"
|
|
240
226
|
},
|
|
241
227
|
"commands": {
|
|
242
228
|
"Test Raylib": "xvfb-run node test/tests/raylib.js",
|
|
@@ -273,9 +259,7 @@
|
|
|
273
259
|
"FreeBSD i386": {
|
|
274
260
|
"directory": "/home/freebsd/luigi",
|
|
275
261
|
"build": {
|
|
276
|
-
"
|
|
277
|
-
"Build Koffi": "node ../cnoke/cnoke.js",
|
|
278
|
-
"Build dependencies": "node ../cnoke/cnoke.js -C test"
|
|
262
|
+
"Build": "node ../cnoke/cnoke.js -C test"
|
|
279
263
|
},
|
|
280
264
|
"commands": {
|
|
281
265
|
"Test Raylib": "xvfb-run node test/tests/raylib.js",
|
|
@@ -312,9 +296,7 @@
|
|
|
312
296
|
"FreeBSD ARM64": {
|
|
313
297
|
"directory": "/home/freebsd/luigi",
|
|
314
298
|
"build": {
|
|
315
|
-
"
|
|
316
|
-
"Build Koffi": "node ../cnoke/cnoke.js",
|
|
317
|
-
"Build dependencies": "node ../cnoke/cnoke.js -C test"
|
|
299
|
+
"Build": "node ../cnoke/cnoke.js -C test"
|
|
318
300
|
},
|
|
319
301
|
"commands": {
|
|
320
302
|
"Test Raylib": "xvfb-run node test/tests/raylib.js",
|
|
@@ -351,9 +333,7 @@
|
|
|
351
333
|
"macOS x64": {
|
|
352
334
|
"directory": "/Users/macos/luigi",
|
|
353
335
|
"build": {
|
|
354
|
-
"
|
|
355
|
-
"Build Koffi": "PATH=/usr/local/bin:/usr/bin:/bin SDKROOT=/Library/Developer/CommandLineTools/SDKs/MacOSX11.3.sdk node ../cnoke/cnoke.js",
|
|
356
|
-
"Build dependencies": "PATH=/usr/local/bin:/usr/bin:/bin SDKROOT=/Library/Developer/CommandLineTools/SDKs/MacOSX11.3.sdk node ../cnoke/cnoke.js -C test"
|
|
336
|
+
"Build": "PATH=/usr/local/bin:/usr/bin:/bin SDKROOT=/Library/Developer/CommandLineTools/SDKs/MacOSX11.3.sdk node ../cnoke/cnoke.js -C test"
|
|
357
337
|
},
|
|
358
338
|
"commands": {
|
|
359
339
|
"Test Misc": "PATH=/usr/local/bin:/usr/bin:/bin node test/tests/misc.js",
|
package/test/tests/misc.c
CHANGED
|
@@ -61,6 +61,17 @@ EXPORT void FillPack3(int a, int b, int c, Pack3 *p)
|
|
|
61
61
|
p->c = c;
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
+
EXPORT Pack3 RetPack3(int a, int b, int c)
|
|
65
|
+
{
|
|
66
|
+
Pack3 p;
|
|
67
|
+
|
|
68
|
+
p.a = a;
|
|
69
|
+
p.b = b;
|
|
70
|
+
p.c = c;
|
|
71
|
+
|
|
72
|
+
return p;
|
|
73
|
+
}
|
|
74
|
+
|
|
64
75
|
EXPORT void FASTCALL AddPack3(int a, int b, int c, Pack3 *p)
|
|
65
76
|
{
|
|
66
77
|
p->a += a;
|
package/test/tests/misc.js
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
// You should have received a copy of the GNU Affero General Public License
|
|
14
14
|
// along with this program. If not, see https://www.gnu.org/licenses/.
|
|
15
15
|
|
|
16
|
-
const koffi = require('
|
|
16
|
+
const koffi = require('../build/koffi.node');
|
|
17
17
|
const assert = require('assert');
|
|
18
18
|
const path = require('path');
|
|
19
19
|
|
|
@@ -52,6 +52,7 @@ async function test() {
|
|
|
52
52
|
let lib = koffi.load(lib_filename);
|
|
53
53
|
|
|
54
54
|
const FillPack3 = lib.cdecl('FillPack3', 'void', ['int', 'int', 'int', koffi.out(koffi.pointer(Pack3))]);
|
|
55
|
+
const RetPack3 = lib.cdecl('RetPack3', Pack3, ['int', 'int', 'int']);
|
|
55
56
|
const AddPack3 = lib.fastcall('AddPack3', 'void', ['int', 'int', 'int', koffi.inout(koffi.pointer(Pack3))]);
|
|
56
57
|
const ConcatenateToInt1 = lib.cdecl('ConcatenateToInt1', 'int64_t', Array(12).fill('int8_t'));
|
|
57
58
|
const ConcatenateToInt4 = lib.cdecl('ConcatenateToInt4', 'int64_t', Array(12).fill('int32_t'));
|
|
@@ -66,6 +67,9 @@ async function test() {
|
|
|
66
67
|
FillPack3(1, 2, 3, p);
|
|
67
68
|
assert.deepEqual(p, { a: 1, b: 2, c: 3 });
|
|
68
69
|
|
|
70
|
+
let q = RetPack3(6, 9, -12);
|
|
71
|
+
assert.deepEqual(q, { a: 6, b: 9, c: -12 });
|
|
72
|
+
|
|
69
73
|
AddPack3(6, 9, -12, p);
|
|
70
74
|
assert.deepEqual(p, { a: 7, b: 11, c: -9 });
|
|
71
75
|
|
package/test/tests/raylib.js
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
// You should have received a copy of the GNU Affero General Public License
|
|
14
14
|
// along with this program. If not, see https://www.gnu.org/licenses/.
|
|
15
15
|
|
|
16
|
-
const koffi = require('
|
|
16
|
+
const koffi = require('../build/koffi.node');
|
|
17
17
|
const crypto = require('crypto');
|
|
18
18
|
const fs = require('fs');
|
|
19
19
|
const os = require('os');
|
package/test/tests/sqlite.js
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
// along with this program. If not, see https://www.gnu.org/licenses/.
|
|
15
15
|
|
|
16
16
|
const crypto = require('crypto');
|
|
17
|
-
const koffi = require('
|
|
17
|
+
const koffi = require('../build/koffi.node');
|
|
18
18
|
const assert = require('assert');
|
|
19
19
|
const fs = require('fs');
|
|
20
20
|
const os = require('os');
|
package/benchmark/build.sh
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
#!/bin/sh -e
|
|
2
|
-
|
|
3
|
-
cd $(dirname $0)/..
|
|
4
|
-
|
|
5
|
-
echo "Install all dependencies..."
|
|
6
|
-
npm install
|
|
7
|
-
|
|
8
|
-
echo "Building dependencies..."
|
|
9
|
-
node ../cnoke/cnoke.js
|
|
10
|
-
node ../cnoke/cnoke.js -C test
|
|
11
|
-
|
|
12
|
-
echo "Building raylib_c..."
|
|
13
|
-
gcc -O2 -std=gnu99 -Wall -Wl,-rpath,$(realpath $(pwd)/test/build) -fPIC benchmark/raylib_c.c -o benchmark/raylib_c test/build/raylib.so -lm -pthread -ldl
|