koffi 1.0.1 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CMakeLists.txt +12 -11
- package/README.md +23 -20
- package/build/qemu/1.0.4/koffi_darwin_x64.tar.gz +0 -0
- package/build/qemu/1.0.4/koffi_freebsd_arm64.tar.gz +0 -0
- package/build/qemu/1.0.4/koffi_freebsd_ia32.tar.gz +0 -0
- package/build/qemu/1.0.4/koffi_freebsd_x64.tar.gz +0 -0
- package/build/qemu/1.0.4/koffi_linux_arm.tar.gz +0 -0
- package/build/qemu/1.0.4/koffi_linux_arm64.tar.gz +0 -0
- package/build/qemu/1.0.4/koffi_linux_ia32.tar.gz +0 -0
- package/build/qemu/1.0.4/koffi_linux_x64.tar.gz +0 -0
- package/build/qemu/1.0.4/koffi_win32_ia32.tar.gz +0 -0
- package/build/qemu/1.0.4/koffi_win32_x64.tar.gz +0 -0
- package/package.json +8 -4
- package/qemu/qemu.js +794 -0
- package/qemu/registry/machines.json +415 -0
- package/qemu/registry/sha256sum.txt +45 -0
- package/src/{call_arm32.cc → abi_arm32.cc} +153 -219
- package/src/{call_arm32_fwd.S → abi_arm32_fwd.S} +0 -0
- package/src/{call_arm64.cc → abi_arm64.cc} +130 -123
- package/src/{call_arm64_fwd.S → abi_arm64_fwd.S} +0 -0
- package/src/{call_x64_sysv.cc → abi_x64_sysv.cc} +138 -135
- package/src/{call_x64_sysv_fwd.S → abi_x64_sysv_fwd.S} +0 -0
- package/src/{call_x64_win.cc → abi_x64_win.cc} +107 -99
- package/src/{call_x64_win_fwd.asm → abi_x64_win_fwd.asm} +0 -0
- package/src/{call_x86.cc → abi_x86.cc} +110 -107
- package/src/{call_x86_fwd.S → abi_x86_fwd.S} +0 -0
- package/src/{call_x86_fwd.asm → abi_x86_fwd.asm} +0 -0
- package/src/call.cc +353 -0
- package/src/call.hh +132 -4
- package/src/ffi.cc +16 -2
- package/src/ffi.hh +8 -12
- package/src/util.cc +7 -280
- package/src/util.hh +0 -107
- package/test/CMakeLists.txt +1 -0
- package/test/misc.c +355 -0
- package/test/misc.def +3 -0
- package/test/misc.js +227 -0
- package/test/raylib.js +165 -0
- package/test/sqlite.js +104 -0
- package/vendor/libcc/libcc.hh +1 -1
- package/build/qemu/1.0.1/koffi_darwin_x64.tar.gz +0 -0
- package/build/qemu/1.0.1/koffi_freebsd_arm64.tar.gz +0 -0
- package/build/qemu/1.0.1/koffi_freebsd_ia32.tar.gz +0 -0
- package/build/qemu/1.0.1/koffi_freebsd_x64.tar.gz +0 -0
- package/build/qemu/1.0.1/koffi_linux_arm.tar.gz +0 -0
- package/build/qemu/1.0.1/koffi_linux_arm64.tar.gz +0 -0
- package/build/qemu/1.0.1/koffi_linux_ia32.tar.gz +0 -0
- package/build/qemu/1.0.1/koffi_linux_x64.tar.gz +0 -0
- package/build/qemu/1.0.1/koffi_win32_ia32.tar.gz +0 -0
- package/build/qemu/1.0.1/koffi_win32_x64.tar.gz +0 -0
package/test/raylib.js
ADDED
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// This program is free software: you can redistribute it and/or modify
|
|
4
|
+
// it under the terms of the GNU Affero General Public License as published by
|
|
5
|
+
// the Free Software Foundation, either version 3 of the License, or
|
|
6
|
+
// (at your option) any later version.
|
|
7
|
+
//
|
|
8
|
+
// This program is distributed in the hope that it will be useful,
|
|
9
|
+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
10
|
+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
11
|
+
// GNU Affero General Public License for more details.
|
|
12
|
+
//
|
|
13
|
+
// You should have received a copy of the GNU Affero General Public License
|
|
14
|
+
// along with this program. If not, see https://www.gnu.org/licenses/.
|
|
15
|
+
|
|
16
|
+
const koffi = require('./build/koffi.node');
|
|
17
|
+
const crypto = require('crypto');
|
|
18
|
+
const fs = require('fs');
|
|
19
|
+
const os = require('os');
|
|
20
|
+
const path = require('path');
|
|
21
|
+
|
|
22
|
+
const Color = koffi.struct('Color', {
|
|
23
|
+
r: 'uchar',
|
|
24
|
+
g: 'uchar',
|
|
25
|
+
b: 'uchar',
|
|
26
|
+
a: 'uchar'
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
const Image = koffi.struct('Image', {
|
|
30
|
+
data: koffi.pointer('void'),
|
|
31
|
+
width: 'int',
|
|
32
|
+
height: 'int',
|
|
33
|
+
mipmaps: 'int',
|
|
34
|
+
format: 'int'
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
const GlyphInfo = koffi.struct('GlyphInfo', {
|
|
38
|
+
value: 'int',
|
|
39
|
+
offsetX: 'int',
|
|
40
|
+
offsetY: 'int',
|
|
41
|
+
advanceX: 'int',
|
|
42
|
+
image: Image
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
const Vector2 = koffi.struct('Vector2', {
|
|
46
|
+
x: 'float',
|
|
47
|
+
y: 'float'
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
const Rectangle = koffi.struct('Rectangle', {
|
|
51
|
+
x: 'float',
|
|
52
|
+
y: 'float',
|
|
53
|
+
width: 'float',
|
|
54
|
+
height: 'float'
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
const Texture = koffi.struct('Texture', {
|
|
58
|
+
id: 'uint',
|
|
59
|
+
width: 'int',
|
|
60
|
+
height: 'int',
|
|
61
|
+
mipmaps: 'int',
|
|
62
|
+
format: 'int'
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
const Font = koffi.struct('Font', {
|
|
66
|
+
baseSize: 'int',
|
|
67
|
+
glyphCount: 'int',
|
|
68
|
+
glyphPadding: 'int',
|
|
69
|
+
texture: Texture,
|
|
70
|
+
recs: koffi.pointer(Rectangle),
|
|
71
|
+
glyphs: koffi.pointer(GlyphInfo)
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
main();
|
|
75
|
+
|
|
76
|
+
async function main() {
|
|
77
|
+
try {
|
|
78
|
+
await test();
|
|
79
|
+
} catch (err) {
|
|
80
|
+
console.error(err);
|
|
81
|
+
process.exit(1);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
async function test() {
|
|
86
|
+
let lib_filename = path.dirname(__filename) + '/build/raylib' + koffi.extension;
|
|
87
|
+
let lib = koffi.load(lib_filename);
|
|
88
|
+
|
|
89
|
+
const InitWindow = lib.func('InitWindow', 'void', ['int', 'int', 'string']);
|
|
90
|
+
const SetTraceLogLevel = lib.func('SetTraceLogLevel', 'void', ['int']);
|
|
91
|
+
const SetWindowState = lib.func('SetWindowState', 'void', ['uint']);
|
|
92
|
+
const GenImageColor = lib.func('GenImageColor', Image, ['int', 'int', Color]);
|
|
93
|
+
const GetFontDefault = lib.func('GetFontDefault', Font, []);
|
|
94
|
+
const MeasureTextEx = lib.func('MeasureTextEx', Vector2, [Font, 'string', 'float', 'float']);
|
|
95
|
+
const ImageDrawTextEx = lib.func('ImageDrawTextEx', 'void', [koffi.pointer(Image), Font, 'string', Vector2, 'float', 'float', Color]);
|
|
96
|
+
const ExportImage = lib.func('ExportImage', 'bool', [Image, 'string']);
|
|
97
|
+
|
|
98
|
+
// We need to call InitWindow before using anything else (such as fonts)
|
|
99
|
+
SetTraceLogLevel(4); // Warnings
|
|
100
|
+
SetWindowState(0x80); // Hidden
|
|
101
|
+
InitWindow(640, 480, "Raylib Test");
|
|
102
|
+
|
|
103
|
+
let img = GenImageColor(800, 600, { r: 0, g: 0, b: 0, a: 255 });
|
|
104
|
+
let font = GetFontDefault();
|
|
105
|
+
|
|
106
|
+
for (let i = 0; i < 3600; i++) {
|
|
107
|
+
let text = 'Hello World!';
|
|
108
|
+
let text_width = MeasureTextEx(font, text, 10, 1).x;
|
|
109
|
+
|
|
110
|
+
let angle = (i * 7) * Math.PI / 180;
|
|
111
|
+
let color = {
|
|
112
|
+
r: 127.5 + 127.5 * Math.sin(angle),
|
|
113
|
+
g: 127.5 + 127.5 * Math.sin(angle + Math.PI / 2),
|
|
114
|
+
b: 127.5 + 127.5 * Math.sin(angle + Math.PI),
|
|
115
|
+
a: 255
|
|
116
|
+
};
|
|
117
|
+
let pos = {
|
|
118
|
+
x: (img.width / 2 - text_width / 2) + i * 0.1 * Math.cos(angle - Math.PI / 2),
|
|
119
|
+
y: (img.height / 2 - 16) + i * 0.1 * Math.sin(angle - Math.PI / 2)
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
ImageDrawTextEx(img, font, text, pos, 10, 1, color);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// In theory we could directly checksum the image data, but we can't do it easily right now
|
|
126
|
+
// until koffi gives us something to transform a pointer to a buffer.
|
|
127
|
+
let tmp_dir = fs.mkdtempSync(path.join(os.tmpdir(), 'raylib'));
|
|
128
|
+
|
|
129
|
+
try {
|
|
130
|
+
ExportImage(img, tmp_dir + '/hello.png');
|
|
131
|
+
|
|
132
|
+
let sha256 = await new Promise((resolve, reject) => {
|
|
133
|
+
try {
|
|
134
|
+
let reader = fs.createReadStream(tmp_dir + '/hello.png');
|
|
135
|
+
let sha = crypto.createHash('sha256');
|
|
136
|
+
|
|
137
|
+
reader.on('error', reject);
|
|
138
|
+
reader.on('data', buf => sha.update(buf));
|
|
139
|
+
reader.on('end', () => {
|
|
140
|
+
let hash = sha.digest('hex');
|
|
141
|
+
resolve(hash);
|
|
142
|
+
});
|
|
143
|
+
} catch (err) {
|
|
144
|
+
reject(err);
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
let expected = '5ec23005377082582a14d261f5d07f51a6615b3bcdf5b91ada29aba65da22c5f';
|
|
148
|
+
|
|
149
|
+
console.log('Computed checksum: ' + sha256);
|
|
150
|
+
console.log('Expected: ' + expected);
|
|
151
|
+
console.log('');
|
|
152
|
+
|
|
153
|
+
if (sha256 == expected) {
|
|
154
|
+
console.log('Success!');
|
|
155
|
+
} else {
|
|
156
|
+
throw new Error('Image mismatch');
|
|
157
|
+
}
|
|
158
|
+
} finally {
|
|
159
|
+
if (fs.rmSync != null) {
|
|
160
|
+
fs.rmSync(tmp_dir, { recursive: true });
|
|
161
|
+
} else {
|
|
162
|
+
fs.rmdirSync(tmp_dir, { recursive: true });
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
package/test/sqlite.js
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
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 crypto = require('crypto');
|
|
17
|
+
const koffi = require('./build/koffi.node');
|
|
18
|
+
const assert = require('assert');
|
|
19
|
+
const fs = require('fs');
|
|
20
|
+
const os = require('os');
|
|
21
|
+
const path = require('path');
|
|
22
|
+
|
|
23
|
+
const sqlite3_db = koffi.handle('sqlite3_db');
|
|
24
|
+
const sqlite3_stmt = koffi.handle('sqlite3_stmt');
|
|
25
|
+
|
|
26
|
+
main();
|
|
27
|
+
|
|
28
|
+
async function main() {
|
|
29
|
+
try {
|
|
30
|
+
await test();
|
|
31
|
+
console.log('Success!');
|
|
32
|
+
} catch (err) {
|
|
33
|
+
console.error(err);
|
|
34
|
+
process.exit(1);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async function test() {
|
|
39
|
+
let lib_filename = path.dirname(__filename) + '/build/sqlite3' + koffi.extension;
|
|
40
|
+
let lib = koffi.load(lib_filename);
|
|
41
|
+
|
|
42
|
+
const sqlite3_open_v2 = lib.func('sqlite3_open_v2', 'int', ['string', koffi.out(koffi.pointer(sqlite3_db)), 'int', 'string']);
|
|
43
|
+
const sqlite3_exec = lib.func('sqlite3_exec', 'int', [sqlite3_db, 'string', 'void *', 'void *', 'void *']);
|
|
44
|
+
const sqlite3_prepare_v2 = lib.func('sqlite3_prepare_v2', 'int', [sqlite3_db, 'string', 'int', koffi.out(koffi.pointer(sqlite3_stmt)), 'string']);
|
|
45
|
+
const sqlite3_reset = lib.func('sqlite3_reset', 'int', [sqlite3_stmt]);
|
|
46
|
+
const sqlite3_bind_text = lib.func('sqlite3_bind_text', 'int', [sqlite3_stmt, 'int', 'string', 'int', 'void *']);
|
|
47
|
+
const sqlite3_bind_int = lib.func('sqlite3_bind_int', 'int', [sqlite3_stmt, 'int', 'int']);
|
|
48
|
+
const sqlite3_step = lib.func('sqlite3_step', 'int', [sqlite3_stmt]);
|
|
49
|
+
const sqlite3_finalize = lib.func('sqlite3_finalize', 'int', [sqlite3_stmt]);
|
|
50
|
+
const sqlite3_close_v2 = lib.func('sqlite3_close_v2', 'int', [sqlite3_db]);
|
|
51
|
+
|
|
52
|
+
let filename = await create_temporary_file(path.join(os.tmpdir(), 'test_sqlite'));
|
|
53
|
+
let db = {};
|
|
54
|
+
|
|
55
|
+
try {
|
|
56
|
+
if (sqlite3_open_v2(filename, db, 0x2 | 0x4, null) != 0)
|
|
57
|
+
throw new Error('Failed to open database');
|
|
58
|
+
if (sqlite3_exec(db, 'CREATE TABLE foo (id INTEGER PRIMARY KEY, bar TEXT, value INT);', null, null, null) != 0)
|
|
59
|
+
throw new Error('Failed to create table');
|
|
60
|
+
|
|
61
|
+
let stmt = {};
|
|
62
|
+
if (sqlite3_prepare_v2(db, "INSERT INTO foo (bar, value) VALUES (?1, ?2)", -1, stmt, null) != 0)
|
|
63
|
+
throw new Error('Failed to prepare insert statement for table foo');
|
|
64
|
+
for (let i = 0; i < 200; i++) {
|
|
65
|
+
sqlite3_reset(stmt);
|
|
66
|
+
|
|
67
|
+
sqlite3_bind_text(stmt, 1, `TXT ${i}`, -1, null);
|
|
68
|
+
sqlite3_bind_int(stmt, 2, i * 2);
|
|
69
|
+
|
|
70
|
+
if (sqlite3_step(stmt) != 101)
|
|
71
|
+
throw new Erorr('Failed to insert new test row');
|
|
72
|
+
}
|
|
73
|
+
sqlite3_finalize(stmt);
|
|
74
|
+
} finally {
|
|
75
|
+
sqlite3_close_v2(db);
|
|
76
|
+
fs.unlinkSync(filename);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
async function create_temporary_file(prefix) {
|
|
81
|
+
let buf = Buffer.allocUnsafe(4);
|
|
82
|
+
|
|
83
|
+
for (;;) {
|
|
84
|
+
try {
|
|
85
|
+
crypto.randomFillSync(buf);
|
|
86
|
+
|
|
87
|
+
let suffix = buf.toString('hex').padStart(8, '0');
|
|
88
|
+
let filename = `${prefix}.${suffix}`;
|
|
89
|
+
|
|
90
|
+
let file = await new Promise((resolve, reject) => {
|
|
91
|
+
let file = fs.createWriteStream(filename, { flags: 'wx', mode: 0o644 });
|
|
92
|
+
|
|
93
|
+
file.on('open', () => resolve(file));
|
|
94
|
+
file.on('error', reject);
|
|
95
|
+
});
|
|
96
|
+
file.close();
|
|
97
|
+
|
|
98
|
+
return filename;
|
|
99
|
+
} catch (err) {
|
|
100
|
+
if (err.code != 'EEXIST')
|
|
101
|
+
throw err;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
package/vendor/libcc/libcc.hh
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|