koffi 1.1.2 → 1.1.5
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 +23 -19
- package/README.md +16 -27
- package/benchmark/CMakeLists.txt +11 -3
- package/benchmark/raylib_cc.cc +9 -9
- package/build/qemu/1.1.5/koffi_darwin_x64.tar.gz +0 -0
- package/build/qemu/1.1.5/koffi_freebsd_arm64.tar.gz +0 -0
- package/build/qemu/1.1.5/koffi_freebsd_ia32.tar.gz +0 -0
- package/build/qemu/1.1.5/koffi_freebsd_x64.tar.gz +0 -0
- package/build/qemu/1.1.5/koffi_linux_arm.tar.gz +0 -0
- package/build/qemu/1.1.5/koffi_linux_arm64.tar.gz +0 -0
- package/build/qemu/1.1.5/koffi_linux_ia32.tar.gz +0 -0
- package/build/qemu/1.1.5/koffi_linux_riscv64.tar.gz +0 -0
- package/build/qemu/1.1.5/koffi_linux_x64.tar.gz +0 -0
- package/build/qemu/1.1.5/koffi_openbsd_ia32.tar.gz +0 -0
- package/build/qemu/1.1.5/koffi_openbsd_x64.tar.gz +0 -0
- package/build/qemu/1.1.5/koffi_win32_ia32.tar.gz +0 -0
- package/build/qemu/1.1.5/koffi_win32_x64.tar.gz +0 -0
- package/package.json +2 -2
- package/qemu/qemu.js +18 -10
- package/qemu/registry/machines.json +138 -3
- package/qemu/registry/sha256sum.txt +27 -12
- package/src/abi_arm32.cc +29 -16
- package/src/abi_arm32_fwd.S +1 -1
- package/src/abi_arm64.cc +33 -17
- package/src/abi_arm64_fwd.S +1 -1
- package/src/abi_arm64_fwd.asm +107 -0
- package/src/abi_riscv64.cc +468 -0
- package/src/abi_riscv64_fwd.S +129 -0
- package/src/abi_x64_sysv.cc +9 -10
- package/src/abi_x64_sysv_fwd.S +113 -1
- package/src/abi_x64_win.cc +5 -8
- package/src/abi_x86.cc +11 -6
- package/src/call.cc +6 -18
- package/src/call.hh +13 -23
- package/src/ffi.cc +87 -25
- package/src/ffi.hh +14 -4
- package/src/parser.cc +18 -6
- package/src/util.cc +26 -57
- package/src/util.hh +17 -1
- package/test/CMakeLists.txt +4 -1
- package/test/misc.c +34 -0
- package/vendor/_patches/glfw_001_fix_openbsd_xlib_soname.patch +145 -0
- package/vendor/libcc/libcc.cc +7 -7
- package/vendor/libcc/libcc.hh +8 -2
- package/vendor/raylib/src/external/glfw/src/egl_context.c +6 -0
- package/vendor/raylib/src/external/glfw/src/osmesa_context.c +2 -0
- package/vendor/raylib/src/external/glfw/src/vulkan.c +2 -0
- package/vendor/raylib/src/external/glfw/src/x11_init.c +20 -0
- package/build/qemu/1.1.2/koffi_darwin_x64.tar.gz +0 -0
- package/build/qemu/1.1.2/koffi_freebsd_arm64.tar.gz +0 -0
- package/build/qemu/1.1.2/koffi_freebsd_ia32.tar.gz +0 -0
- package/build/qemu/1.1.2/koffi_freebsd_x64.tar.gz +0 -0
- package/build/qemu/1.1.2/koffi_linux_arm.tar.gz +0 -0
- package/build/qemu/1.1.2/koffi_linux_arm64.tar.gz +0 -0
- package/build/qemu/1.1.2/koffi_linux_ia32.tar.gz +0 -0
- package/build/qemu/1.1.2/koffi_linux_x64.tar.gz +0 -0
- package/build/qemu/1.1.2/koffi_win32_ia32.tar.gz +0 -0
- package/build/qemu/1.1.2/koffi_win32_x64.tar.gz +0 -0
package/src/ffi.cc
CHANGED
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
#else
|
|
30
30
|
#include <dlfcn.h>
|
|
31
31
|
#include <unistd.h>
|
|
32
|
+
#include <sys/mman.h>
|
|
32
33
|
#endif
|
|
33
34
|
|
|
34
35
|
#include <napi.h>
|
|
@@ -39,6 +40,11 @@
|
|
|
39
40
|
|
|
40
41
|
namespace RG {
|
|
41
42
|
|
|
43
|
+
const Size SyncStackSize = Mebibytes(2);
|
|
44
|
+
const Size SyncHeapSize = Mebibytes(4);
|
|
45
|
+
const Size AsyncStackSize = Mebibytes(1);
|
|
46
|
+
const Size AsyncHeapSize = Mebibytes(2);
|
|
47
|
+
|
|
42
48
|
// Value does not matter, the tag system uses memory addresses
|
|
43
49
|
const int TypeInfoMarker = 0xDEADBEEF;
|
|
44
50
|
|
|
@@ -100,6 +106,11 @@ static Napi::Value CreateStructType(const Napi::CallbackInfo &info, bool pad)
|
|
|
100
106
|
type->members.Append(member);
|
|
101
107
|
}
|
|
102
108
|
|
|
109
|
+
if (!type->size) {
|
|
110
|
+
ThrowError<Napi::TypeError>(env, "Empty struct '%1' is not allowed in C", type->name);
|
|
111
|
+
return env.Null();
|
|
112
|
+
}
|
|
113
|
+
|
|
103
114
|
type->size = (int16_t)AlignLen(type->size, type->align);
|
|
104
115
|
|
|
105
116
|
// If the insert succeeds, we cannot fail anymore
|
|
@@ -290,7 +301,7 @@ static Napi::Value CreateArrayType(const Napi::CallbackInfo &info)
|
|
|
290
301
|
if (!ref)
|
|
291
302
|
return env.Null();
|
|
292
303
|
if (len <= 0) {
|
|
293
|
-
ThrowError<Napi::TypeError>(env, "Array length must be non-zero
|
|
304
|
+
ThrowError<Napi::TypeError>(env, "Array length must be positive and non-zero");
|
|
294
305
|
return env.Null();
|
|
295
306
|
}
|
|
296
307
|
if (len > INT16_MAX / ref->size) {
|
|
@@ -369,21 +380,6 @@ static Napi::Value GetTypeDefinition(const Napi::CallbackInfo &info)
|
|
|
369
380
|
return type->defn.Value();
|
|
370
381
|
}
|
|
371
382
|
|
|
372
|
-
static Span<uint8_t> AllocateAndAlign16(Allocator *alloc, Size size)
|
|
373
|
-
{
|
|
374
|
-
RG_ASSERT(AlignLen(size, 16) == size);
|
|
375
|
-
RG_ASSERT(size >= Kibibytes(1));
|
|
376
|
-
|
|
377
|
-
// Account for allocator overhead
|
|
378
|
-
size -= 256;
|
|
379
|
-
|
|
380
|
-
uint8_t *ptr = (uint8_t *)Allocator::Allocate(alloc, size);
|
|
381
|
-
uint8_t *aligned = AlignUp(ptr, 16);
|
|
382
|
-
Size delta = AlignLen(aligned - ptr, 16);
|
|
383
|
-
|
|
384
|
-
return MakeSpan(aligned, size - delta);
|
|
385
|
-
}
|
|
386
|
-
|
|
387
383
|
static InstanceMemory *AllocateAsyncMemory(InstanceData *instance)
|
|
388
384
|
{
|
|
389
385
|
for (Size i = 1; i < instance->memories.len; i++) {
|
|
@@ -395,8 +391,23 @@ static InstanceMemory *AllocateAsyncMemory(InstanceData *instance)
|
|
|
395
391
|
|
|
396
392
|
InstanceMemory *mem = new InstanceMemory();
|
|
397
393
|
|
|
398
|
-
mem->stack =
|
|
399
|
-
|
|
394
|
+
mem->stack.len = AsyncStackSize;
|
|
395
|
+
#if defined(_WIN32)
|
|
396
|
+
mem->stack.ptr = (uint8_t *)VirtualAlloc(nullptr, mem->stack.len, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
|
|
397
|
+
#elif defined(__APPLE__)
|
|
398
|
+
mem->stack.ptr = (uint8_t *)mmap(nullptr, mem->stack.len, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
|
|
399
|
+
#else
|
|
400
|
+
mem->stack.ptr = (uint8_t *)mmap(nullptr, mem->stack.len, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON | MAP_STACK, -1, 0);
|
|
401
|
+
#endif
|
|
402
|
+
RG_CRITICAL(mem->stack.ptr, "Failed to allocate %1 of memory", mem->stack.len);
|
|
403
|
+
|
|
404
|
+
mem->heap.len = AsyncHeapSize;
|
|
405
|
+
#ifdef _WIN32
|
|
406
|
+
mem->heap.ptr = (uint8_t *)VirtualAlloc(nullptr, mem->heap.len, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
|
|
407
|
+
#else
|
|
408
|
+
mem->heap.ptr = (uint8_t *)mmap(nullptr, mem->heap.len, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
|
|
409
|
+
#endif
|
|
410
|
+
RG_CRITICAL(mem->heap.ptr, "Failed to allocate %1 of memory", mem->heap.len);
|
|
400
411
|
|
|
401
412
|
if (instance->memories.Available()) {
|
|
402
413
|
instance->memories.Append(mem);
|
|
@@ -421,7 +432,15 @@ static Napi::Value TranslateNormalCall(const Napi::CallbackInfo &info)
|
|
|
421
432
|
InstanceMemory *mem = instance->memories[0];
|
|
422
433
|
CallData call(env, instance, func, mem);
|
|
423
434
|
|
|
424
|
-
|
|
435
|
+
if (!RG_UNLIKELY(call.Prepare(info)))
|
|
436
|
+
return env.Null();
|
|
437
|
+
|
|
438
|
+
if (instance->debug) {
|
|
439
|
+
call.DumpDebug();
|
|
440
|
+
}
|
|
441
|
+
call.Execute();
|
|
442
|
+
|
|
443
|
+
return call.Complete();
|
|
425
444
|
}
|
|
426
445
|
|
|
427
446
|
static Napi::Value TranslateVariadicCall(const Napi::CallbackInfo &info)
|
|
@@ -430,7 +449,7 @@ static Napi::Value TranslateVariadicCall(const Napi::CallbackInfo &info)
|
|
|
430
449
|
InstanceData *instance = env.GetInstanceData<InstanceData>();
|
|
431
450
|
|
|
432
451
|
FunctionInfo func;
|
|
433
|
-
memcpy(&func, info.Data(), RG_SIZE(FunctionInfo));
|
|
452
|
+
memcpy((void *)&func, info.Data(), RG_SIZE(FunctionInfo));
|
|
434
453
|
func.lib = nullptr;
|
|
435
454
|
|
|
436
455
|
// This makes variadic calls non-reentrant
|
|
@@ -481,7 +500,15 @@ static Napi::Value TranslateVariadicCall(const Napi::CallbackInfo &info)
|
|
|
481
500
|
InstanceMemory *mem = instance->memories[0];
|
|
482
501
|
CallData call(env, instance, &func, mem);
|
|
483
502
|
|
|
484
|
-
|
|
503
|
+
if (!RG_UNLIKELY(call.Prepare(info)))
|
|
504
|
+
return env.Null();
|
|
505
|
+
|
|
506
|
+
if (instance->debug) {
|
|
507
|
+
call.DumpDebug();
|
|
508
|
+
}
|
|
509
|
+
call.Execute();
|
|
510
|
+
|
|
511
|
+
return call.Complete();
|
|
485
512
|
}
|
|
486
513
|
|
|
487
514
|
class AsyncCall: public Napi::AsyncWorker {
|
|
@@ -597,10 +624,10 @@ static bool ParseClassicFunction(Napi::Env env, Napi::String name, Napi::Value r
|
|
|
597
624
|
return false;
|
|
598
625
|
}
|
|
599
626
|
|
|
600
|
-
|
|
627
|
+
uint32_t parameters_len = parameters.Length();
|
|
601
628
|
|
|
602
629
|
if (parameters_len) {
|
|
603
|
-
Napi::String str = ((Napi::Value)parameters[
|
|
630
|
+
Napi::String str = ((Napi::Value)parameters[parameters_len - 1]).As<Napi::String>();
|
|
604
631
|
|
|
605
632
|
if (str.IsString() && str.Utf8Value() == "...") {
|
|
606
633
|
func->variadic = true;
|
|
@@ -788,6 +815,7 @@ static Napi::Value LoadSharedLibrary(const Napi::CallbackInfo &info)
|
|
|
788
815
|
ADD_CONVENTION("cdecl", CallConvention::Cdecl);
|
|
789
816
|
ADD_CONVENTION("stdcall", CallConvention::Stdcall);
|
|
790
817
|
ADD_CONVENTION("fastcall", CallConvention::Fastcall);
|
|
818
|
+
ADD_CONVENTION("thiscall", CallConvention::Thiscall);
|
|
791
819
|
|
|
792
820
|
#undef ADD_CONVENTION
|
|
793
821
|
|
|
@@ -928,12 +956,46 @@ void FunctionInfo::Unref() const
|
|
|
928
956
|
}
|
|
929
957
|
}
|
|
930
958
|
|
|
959
|
+
InstanceMemory::~InstanceMemory()
|
|
960
|
+
{
|
|
961
|
+
#ifdef _WIN32
|
|
962
|
+
if (stack.ptr) {
|
|
963
|
+
VirtualFree(stack.ptr, 0, MEM_RELEASE);
|
|
964
|
+
}
|
|
965
|
+
if (heap.ptr) {
|
|
966
|
+
VirtualFree(heap.ptr, 0, MEM_RELEASE);
|
|
967
|
+
}
|
|
968
|
+
#else
|
|
969
|
+
if (stack.ptr) {
|
|
970
|
+
munmap(stack.ptr, stack.len);
|
|
971
|
+
}
|
|
972
|
+
if (heap.ptr) {
|
|
973
|
+
munmap(heap.ptr, heap.len);
|
|
974
|
+
}
|
|
975
|
+
#endif
|
|
976
|
+
}
|
|
977
|
+
|
|
931
978
|
InstanceData::InstanceData()
|
|
932
979
|
{
|
|
933
980
|
InstanceMemory *mem = new InstanceMemory();
|
|
934
981
|
|
|
935
|
-
mem->stack =
|
|
936
|
-
|
|
982
|
+
mem->stack.len = SyncStackSize;
|
|
983
|
+
#if defined(_WIN32)
|
|
984
|
+
mem->stack.ptr = (uint8_t *)VirtualAlloc(nullptr, mem->stack.len, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
|
|
985
|
+
#elif defined(__APPLE__)
|
|
986
|
+
mem->stack.ptr = (uint8_t *)mmap(nullptr, mem->stack.len, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
|
|
987
|
+
#else
|
|
988
|
+
mem->stack.ptr = (uint8_t *)mmap(nullptr, mem->stack.len, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON | MAP_STACK, -1, 0);
|
|
989
|
+
#endif
|
|
990
|
+
RG_CRITICAL(mem->stack.ptr, "Failed to allocate %1 of memory", mem->stack.len);
|
|
991
|
+
|
|
992
|
+
mem->heap.len = SyncHeapSize;
|
|
993
|
+
#ifdef _WIN32
|
|
994
|
+
mem->heap.ptr = (uint8_t *)VirtualAlloc(nullptr, mem->heap.len, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
|
|
995
|
+
#else
|
|
996
|
+
mem->heap.ptr = (uint8_t *)mmap(nullptr, mem->heap.len, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
|
|
997
|
+
#endif
|
|
998
|
+
RG_CRITICAL(mem->heap.ptr, "Failed to allocate %1 of memory", mem->heap.len);
|
|
937
999
|
|
|
938
1000
|
memories.Append(mem);
|
|
939
1001
|
}
|
package/src/ffi.hh
CHANGED
|
@@ -109,12 +109,14 @@ struct LibraryHolder {
|
|
|
109
109
|
enum class CallConvention {
|
|
110
110
|
Cdecl,
|
|
111
111
|
Stdcall,
|
|
112
|
-
Fastcall
|
|
112
|
+
Fastcall,
|
|
113
|
+
Thiscall
|
|
113
114
|
};
|
|
114
115
|
static const char *const CallConventionNames[] = {
|
|
115
116
|
"Cdecl",
|
|
116
117
|
"Stdcall",
|
|
117
|
-
"Fastcall"
|
|
118
|
+
"Fastcall",
|
|
119
|
+
"Thiscall"
|
|
118
120
|
};
|
|
119
121
|
|
|
120
122
|
struct ParameterInfo {
|
|
@@ -139,6 +141,11 @@ struct ParameterInfo {
|
|
|
139
141
|
#elif defined(__i386__) || defined(_M_IX86)
|
|
140
142
|
bool trivial; // Only matters for return value
|
|
141
143
|
bool fast;
|
|
144
|
+
#elif __riscv_xlen == 64
|
|
145
|
+
bool use_memory;
|
|
146
|
+
int8_t gpr_count;
|
|
147
|
+
int8_t vec_count;
|
|
148
|
+
bool gpr_first; // Only for structs
|
|
142
149
|
#endif
|
|
143
150
|
};
|
|
144
151
|
|
|
@@ -160,9 +167,12 @@ struct FunctionInfo {
|
|
|
160
167
|
// ABI-specific part
|
|
161
168
|
|
|
162
169
|
Size args_size;
|
|
163
|
-
#if defined(__arm__) || defined(__aarch64__) || defined(__x86_64__) || defined(_WIN64)
|
|
170
|
+
#if defined(__arm__) || defined(__aarch64__) || defined(__x86_64__) || defined(_WIN64) || defined(__riscv)
|
|
164
171
|
bool forward_fp;
|
|
165
172
|
#endif
|
|
173
|
+
#if defined(__i386__) || defined(_M_IX86)
|
|
174
|
+
bool fast;
|
|
175
|
+
#endif
|
|
166
176
|
|
|
167
177
|
~FunctionInfo();
|
|
168
178
|
|
|
@@ -171,7 +181,7 @@ struct FunctionInfo {
|
|
|
171
181
|
};
|
|
172
182
|
|
|
173
183
|
struct InstanceMemory {
|
|
174
|
-
|
|
184
|
+
~InstanceMemory();
|
|
175
185
|
|
|
176
186
|
Span<uint8_t> stack;
|
|
177
187
|
Span<uint8_t> heap;
|
package/src/parser.cc
CHANGED
|
@@ -38,6 +38,8 @@ bool PrototypeParser::Parse(const char *str, FunctionInfo *out_func)
|
|
|
38
38
|
out_func->convention = CallConvention::Stdcall;
|
|
39
39
|
} else if (Match("__fastcall")) {
|
|
40
40
|
out_func->convention = CallConvention::Fastcall;
|
|
41
|
+
} else if (Match("__thiscall")) {
|
|
42
|
+
out_func->convention = CallConvention::Thiscall;
|
|
41
43
|
}
|
|
42
44
|
out_func->name = ParseIdentifier();
|
|
43
45
|
|
|
@@ -157,9 +159,9 @@ const TypeInfo *PrototypeParser::ParseType()
|
|
|
157
159
|
}
|
|
158
160
|
if (offset == start) {
|
|
159
161
|
if (offset < tokens.len) {
|
|
160
|
-
MarkError("Unexpected token '%1', expected
|
|
162
|
+
MarkError("Unexpected token '%1', expected type", tokens[offset]);
|
|
161
163
|
} else {
|
|
162
|
-
MarkError("Unexpected end of prototype, expected
|
|
164
|
+
MarkError("Unexpected end of prototype, expected type");
|
|
163
165
|
}
|
|
164
166
|
return instance->types_map.FindValue("void", nullptr);
|
|
165
167
|
}
|
|
@@ -169,11 +171,21 @@ const TypeInfo *PrototypeParser::ParseType()
|
|
|
169
171
|
}
|
|
170
172
|
buf.ptr[--buf.len] = 0;
|
|
171
173
|
|
|
172
|
-
if (
|
|
173
|
-
buf.
|
|
174
|
-
|
|
174
|
+
if (indirect) {
|
|
175
|
+
const TypeInfo *type = instance->types_map.FindValue(buf.ptr, nullptr);
|
|
176
|
+
PrimitiveKind primitive = type ? type->primitive : PrimitiveKind::Void;
|
|
177
|
+
|
|
178
|
+
if (primitive == PrimitiveKind::Int8 || primitive == PrimitiveKind::UInt8) {
|
|
179
|
+
buf.RemoveFrom(0);
|
|
180
|
+
Fmt(&buf, "string");
|
|
175
181
|
|
|
176
|
-
|
|
182
|
+
indirect--;
|
|
183
|
+
} else if (primitive == PrimitiveKind::Int16 || primitive == PrimitiveKind::UInt16) {
|
|
184
|
+
buf.RemoveFrom(0);
|
|
185
|
+
Fmt(&buf, "string16");
|
|
186
|
+
|
|
187
|
+
indirect--;
|
|
188
|
+
}
|
|
177
189
|
}
|
|
178
190
|
|
|
179
191
|
while (buf.len) {
|
package/src/util.cc
CHANGED
|
@@ -126,76 +126,45 @@ bool CheckValueTag(const InstanceData *instance, Napi::Value value, const void *
|
|
|
126
126
|
return match;
|
|
127
127
|
}
|
|
128
128
|
|
|
129
|
-
|
|
130
|
-
uint32_t primitives;
|
|
131
|
-
Size count;
|
|
132
|
-
|
|
133
|
-
public:
|
|
134
|
-
bool Analyse(const TypeInfo *type, int min, int max);
|
|
135
|
-
|
|
136
|
-
private:
|
|
137
|
-
void AnalyseStruct(const TypeInfo *type);
|
|
138
|
-
void AnalyseArray(const TypeInfo *type);
|
|
139
|
-
};
|
|
140
|
-
|
|
141
|
-
bool HfaAnalyser::Analyse(const TypeInfo *type, int min, int max)
|
|
129
|
+
static int AnalyseFlatRec(const TypeInfo *type, int offset, int count, FunctionRef<void(const TypeInfo *type, int offset, int count)> func)
|
|
142
130
|
{
|
|
143
|
-
primitives = 0;
|
|
144
|
-
count = 0;
|
|
145
|
-
|
|
146
131
|
if (type->primitive == PrimitiveKind::Record) {
|
|
147
|
-
|
|
132
|
+
for (int i = 0; i < count; i++) {
|
|
133
|
+
for (const RecordMember &member: type->members) {
|
|
134
|
+
offset = AnalyseFlatRec(member.type, offset, 1, func);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
148
137
|
} else if (type->primitive == PrimitiveKind::Array) {
|
|
149
|
-
|
|
138
|
+
count *= type->size / type->ref->size;
|
|
139
|
+
offset = AnalyseFlatRec(type->ref, offset, count, func);
|
|
150
140
|
} else {
|
|
151
|
-
|
|
141
|
+
func(type, offset, count);
|
|
142
|
+
offset += count;
|
|
152
143
|
}
|
|
153
144
|
|
|
154
|
-
|
|
155
|
-
return hfa;
|
|
145
|
+
return offset;
|
|
156
146
|
}
|
|
157
147
|
|
|
158
|
-
|
|
148
|
+
int AnalyseFlat(const TypeInfo *type, FunctionRef<void(const TypeInfo *type, int offset, int count)> func)
|
|
159
149
|
{
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
for (const RecordMember &member: type->members) {
|
|
163
|
-
if (member.type->primitive == PrimitiveKind::Record) {
|
|
164
|
-
AnalyseStruct(member.type);
|
|
165
|
-
} else if (member.type->primitive == PrimitiveKind::Array) {
|
|
166
|
-
AnalyseArray(member.type);
|
|
167
|
-
} else if (member.type->primitive == PrimitiveKind::Float32 ||
|
|
168
|
-
member.type->primitive == PrimitiveKind::Float64) {
|
|
169
|
-
primitives |= 1u << (int)member.type->primitive;
|
|
170
|
-
count++;
|
|
171
|
-
} else {
|
|
172
|
-
primitives = UINT_MAX;
|
|
173
|
-
return;
|
|
174
|
-
}
|
|
175
|
-
}
|
|
150
|
+
return AnalyseFlatRec(type, 0, 1, func);
|
|
176
151
|
}
|
|
177
152
|
|
|
178
|
-
|
|
153
|
+
int IsHFA(const TypeInfo *type, int min, int max)
|
|
179
154
|
{
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
if (type->ref->primitive == PrimitiveKind::Record) {
|
|
183
|
-
AnalyseStruct(type->ref);
|
|
184
|
-
} else if (type->ref->primitive == PrimitiveKind::Array) {
|
|
185
|
-
AnalyseArray(type->ref);
|
|
186
|
-
} else if (type->ref->primitive == PrimitiveKind::Float32 ||
|
|
187
|
-
type->ref->primitive == PrimitiveKind::Float64) {
|
|
188
|
-
primitives |= 1u << (int)type->ref->primitive;
|
|
189
|
-
count += type->size / type->ref->size;;
|
|
190
|
-
} else {
|
|
191
|
-
primitives = UINT_MAX;
|
|
192
|
-
}
|
|
193
|
-
}
|
|
155
|
+
uint32_t primitives = 0;
|
|
156
|
+
int count = 0;
|
|
194
157
|
|
|
195
|
-
|
|
196
|
-
{
|
|
197
|
-
|
|
198
|
-
|
|
158
|
+
count = AnalyseFlat(type, [&](const TypeInfo *type, int, int) {
|
|
159
|
+
if (IsFloat(type)) {
|
|
160
|
+
primitives |= 1u << (int)type->primitive;
|
|
161
|
+
} else {
|
|
162
|
+
primitives = UINT32_MAX;
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
bool hfa = (count >= min && count <= max && PopCount(primitives) == 1);
|
|
167
|
+
return hfa ? count : 0;
|
|
199
168
|
}
|
|
200
169
|
|
|
201
170
|
}
|
package/src/util.hh
CHANGED
|
@@ -53,6 +53,20 @@ static inline T *AlignDown(T *ptr, Size align)
|
|
|
53
53
|
return (T *)aligned;
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
+
static inline bool IsInteger(const TypeInfo *type)
|
|
57
|
+
{
|
|
58
|
+
bool integer = ((int)type->primitive >= (int)PrimitiveKind::Int8 &&
|
|
59
|
+
(int)type->primitive <= (int)PrimitiveKind::UInt64);
|
|
60
|
+
return integer;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
static inline bool IsFloat(const TypeInfo *type)
|
|
64
|
+
{
|
|
65
|
+
bool fp = (type->primitive == PrimitiveKind::Float32 ||
|
|
66
|
+
type->primitive == PrimitiveKind::Float64);
|
|
67
|
+
return fp;
|
|
68
|
+
}
|
|
69
|
+
|
|
56
70
|
const TypeInfo *ResolveType(const InstanceData *instance, Napi::Value value, int *out_directions = nullptr);
|
|
57
71
|
const TypeInfo *GetPointerType(InstanceData *instance, const TypeInfo *type);
|
|
58
72
|
|
|
@@ -89,6 +103,8 @@ T CopyNumber(const Napi::Value &value)
|
|
|
89
103
|
RG_UNREACHABLE();
|
|
90
104
|
}
|
|
91
105
|
|
|
92
|
-
|
|
106
|
+
int AnalyseFlat(const TypeInfo *type, FunctionRef<void(const TypeInfo *type, int offset, int count)> func);
|
|
107
|
+
|
|
108
|
+
int IsHFA(const TypeInfo *type, int min, int max);
|
|
93
109
|
|
|
94
110
|
}
|
package/test/CMakeLists.txt
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
# along with this program. If not, see https://www.gnu.org/licenses/.
|
|
13
13
|
|
|
14
14
|
cmake_minimum_required(VERSION 3.12)
|
|
15
|
-
project(
|
|
15
|
+
project(koffi_test C CXX)
|
|
16
16
|
|
|
17
17
|
if(NOT TARGET koffi)
|
|
18
18
|
add_subdirectory(.. koffi)
|
|
@@ -42,6 +42,9 @@ else()
|
|
|
42
42
|
-Wno-unused-function -Wno-missing-field-initializers
|
|
43
43
|
-Wno-unused-value -Wno-implicit-fallthrough -Wno-stringop-overflow
|
|
44
44
|
-Wno-unused-result)
|
|
45
|
+
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
|
46
|
+
target_compile_options(raylib PRIVATE -Wno-unknown-warning-option)
|
|
47
|
+
endif()
|
|
45
48
|
endif()
|
|
46
49
|
|
|
47
50
|
if(WIN32)
|
package/test/misc.c
CHANGED
|
@@ -75,6 +75,15 @@ typedef struct Double3 {
|
|
|
75
75
|
} s;
|
|
76
76
|
} Double3;
|
|
77
77
|
|
|
78
|
+
typedef struct FloatInt {
|
|
79
|
+
float f;
|
|
80
|
+
int i;
|
|
81
|
+
} FloatInt;
|
|
82
|
+
typedef struct IntFloat {
|
|
83
|
+
int i;
|
|
84
|
+
float f;
|
|
85
|
+
} IntFloat;
|
|
86
|
+
|
|
78
87
|
typedef struct IJK1 { int8_t i; int8_t j; int8_t k; } IJK1;
|
|
79
88
|
typedef struct IJK4 { int32_t i; int32_t j; int32_t k; } IJK4;
|
|
80
89
|
typedef struct IJK8 { int64_t i; int64_t j; int64_t k; } IJK8;
|
|
@@ -188,6 +197,11 @@ EXPORT Float2 PackFloat2(float a, float b, Float2 *out)
|
|
|
188
197
|
return ret;
|
|
189
198
|
}
|
|
190
199
|
|
|
200
|
+
EXPORT Float2 ThroughFloat2(Float2 f2)
|
|
201
|
+
{
|
|
202
|
+
return f2;
|
|
203
|
+
}
|
|
204
|
+
|
|
191
205
|
EXPORT Float3 PackFloat3(float a, float b, float c, Float3 *out)
|
|
192
206
|
{
|
|
193
207
|
Float3 ret;
|
|
@@ -228,6 +242,26 @@ EXPORT Double3 PackDouble3(double a, double b, double c, Double3 *out)
|
|
|
228
242
|
return ret;
|
|
229
243
|
}
|
|
230
244
|
|
|
245
|
+
EXPORT IntFloat ReverseFloatInt(FloatInt sfi)
|
|
246
|
+
{
|
|
247
|
+
IntFloat sif;
|
|
248
|
+
|
|
249
|
+
sif.i = (int)sfi.f;
|
|
250
|
+
sif.f = (float)sfi.i;
|
|
251
|
+
|
|
252
|
+
return sif;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
EXPORT FloatInt ReverseIntFloat(IntFloat sif)
|
|
256
|
+
{
|
|
257
|
+
FloatInt sfi;
|
|
258
|
+
|
|
259
|
+
sfi.i = (int)sif.f;
|
|
260
|
+
sfi.f = (float)sif.i;
|
|
261
|
+
|
|
262
|
+
return sfi;
|
|
263
|
+
}
|
|
264
|
+
|
|
231
265
|
EXPORT int64_t ConcatenateToInt1(int8_t a, int8_t b, int8_t c, int8_t d, int8_t e, int8_t f,
|
|
232
266
|
int8_t g, int8_t h, int8_t i, int8_t j, int8_t k, int8_t l)
|
|
233
267
|
{
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
diff --git a/koffi/vendor/raylib/src/external/glfw/src/egl_context.c b/koffi/vendor/raylib/src/external/glfw/src/egl_context.c
|
|
2
|
+
index 975c67be..4edd3dac 100644
|
|
3
|
+
--- a/koffi/vendor/raylib/src/external/glfw/src/egl_context.c
|
|
4
|
+
+++ b/koffi/vendor/raylib/src/external/glfw/src/egl_context.c
|
|
5
|
+
@@ -316,6 +316,8 @@ GLFWbool _glfwInitEGL(void)
|
|
6
|
+
"libEGL.dylib",
|
|
7
|
+
#elif defined(__CYGWIN__)
|
|
8
|
+
"libEGL-1.so",
|
|
9
|
+
+#elif defined(__OpenBSD__) || defined(__NetBSD__)
|
|
10
|
+
+ "libEGL.so",
|
|
11
|
+
#else
|
|
12
|
+
"libEGL.so.1",
|
|
13
|
+
#endif
|
|
14
|
+
@@ -686,6 +688,8 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
|
15
|
+
"libGLES_CM.dll",
|
|
16
|
+
#elif defined(_GLFW_COCOA)
|
|
17
|
+
"libGLESv1_CM.dylib",
|
|
18
|
+
+#elif defined(__OpenBSD__) || defined(__NetBSD__)
|
|
19
|
+
+ "libGLESv1_CM.so",
|
|
20
|
+
#else
|
|
21
|
+
"libGLESv1_CM.so.1",
|
|
22
|
+
"libGLES_CM.so.1",
|
|
23
|
+
@@ -703,6 +707,8 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
|
24
|
+
"libGLESv2.dylib",
|
|
25
|
+
#elif defined(__CYGWIN__)
|
|
26
|
+
"libGLESv2-2.so",
|
|
27
|
+
+#elif defined(__OpenBSD__) || defined(__NetBSD__)
|
|
28
|
+
+ "libGLESv2.so",
|
|
29
|
+
#else
|
|
30
|
+
"libGLESv2.so.2",
|
|
31
|
+
#endif
|
|
32
|
+
diff --git a/koffi/vendor/raylib/src/external/glfw/src/osmesa_context.c b/koffi/vendor/raylib/src/external/glfw/src/osmesa_context.c
|
|
33
|
+
index 70e8675b..62c31678 100644
|
|
34
|
+
--- a/koffi/vendor/raylib/src/external/glfw/src/osmesa_context.c
|
|
35
|
+
+++ b/koffi/vendor/raylib/src/external/glfw/src/osmesa_context.c
|
|
36
|
+
@@ -124,6 +124,8 @@ GLFWbool _glfwInitOSMesa(void)
|
|
37
|
+
"libOSMesa.8.dylib",
|
|
38
|
+
#elif defined(__CYGWIN__)
|
|
39
|
+
"libOSMesa-8.so",
|
|
40
|
+
+#elif defined(__OpenBSD__) || defined(__NetBSD__)
|
|
41
|
+
+ "libOSMesa.so",
|
|
42
|
+
#else
|
|
43
|
+
"libOSMesa.so.8",
|
|
44
|
+
"libOSMesa.so.6",
|
|
45
|
+
diff --git a/koffi/vendor/raylib/src/external/glfw/src/vulkan.c b/koffi/vendor/raylib/src/external/glfw/src/vulkan.c
|
|
46
|
+
index b5340520..7eb4fdf0 100644
|
|
47
|
+
--- a/koffi/vendor/raylib/src/external/glfw/src/vulkan.c
|
|
48
|
+
+++ b/koffi/vendor/raylib/src/external/glfw/src/vulkan.c
|
|
49
|
+
@@ -59,6 +59,8 @@ GLFWbool _glfwInitVulkan(int mode)
|
|
50
|
+
_glfw.vk.handle = _glfw_dlopen("libvulkan.1.dylib");
|
|
51
|
+
if (!_glfw.vk.handle)
|
|
52
|
+
_glfw.vk.handle = _glfwLoadLocalVulkanLoaderNS();
|
|
53
|
+
+#elif defined(__OpenBSD__) || defined(__NetBSD__)
|
|
54
|
+
+ _glfw.vk.handle = _glfw_dlopen("libvulkan.so");
|
|
55
|
+
#else
|
|
56
|
+
_glfw.vk.handle = _glfw_dlopen("libvulkan.so.1");
|
|
57
|
+
#endif
|
|
58
|
+
diff --git a/koffi/vendor/raylib/src/external/glfw/src/x11_init.c b/koffi/vendor/raylib/src/external/glfw/src/x11_init.c
|
|
59
|
+
index fc9ac427..c2233f56 100644
|
|
60
|
+
--- a/koffi/vendor/raylib/src/external/glfw/src/x11_init.c
|
|
61
|
+
+++ b/koffi/vendor/raylib/src/external/glfw/src/x11_init.c
|
|
62
|
+
@@ -601,7 +601,11 @@ static void detectEWMH(void)
|
|
63
|
+
//
|
|
64
|
+
static GLFWbool initExtensions(void)
|
|
65
|
+
{
|
|
66
|
+
+#if defined(__OpenBSD__) || defined(__NetBSD__)
|
|
67
|
+
+ _glfw.x11.vidmode.handle = _glfw_dlopen("libXxf86vm.so");
|
|
68
|
+
+#else
|
|
69
|
+
_glfw.x11.vidmode.handle = _glfw_dlopen("libXxf86vm.so.1");
|
|
70
|
+
+#endif
|
|
71
|
+
if (_glfw.x11.vidmode.handle)
|
|
72
|
+
{
|
|
73
|
+
_glfw.x11.vidmode.QueryExtension = (PFN_XF86VidModeQueryExtension)
|
|
74
|
+
@@ -621,6 +625,8 @@ static GLFWbool initExtensions(void)
|
|
75
|
+
|
|
76
|
+
#if defined(__CYGWIN__)
|
|
77
|
+
_glfw.x11.xi.handle = _glfw_dlopen("libXi-6.so");
|
|
78
|
+
+#elif defined(__OpenBSD__) || defined(__NetBSD__)
|
|
79
|
+
+ _glfw.x11.xi.handle = _glfw_dlopen("libXi.so");
|
|
80
|
+
#else
|
|
81
|
+
_glfw.x11.xi.handle = _glfw_dlopen("libXi.so.6");
|
|
82
|
+
#endif
|
|
83
|
+
@@ -651,6 +657,8 @@ static GLFWbool initExtensions(void)
|
|
84
|
+
|
|
85
|
+
#if defined(__CYGWIN__)
|
|
86
|
+
_glfw.x11.randr.handle = _glfw_dlopen("libXrandr-2.so");
|
|
87
|
+
+#elif defined(__OpenBSD__) || defined(__NetBSD__)
|
|
88
|
+
+ _glfw.x11.randr.handle = _glfw_dlopen("libXrandr.so");
|
|
89
|
+
#else
|
|
90
|
+
_glfw.x11.randr.handle = _glfw_dlopen("libXrandr.so.2");
|
|
91
|
+
#endif
|
|
92
|
+
@@ -743,6 +751,8 @@ static GLFWbool initExtensions(void)
|
|
93
|
+
|
|
94
|
+
#if defined(__CYGWIN__)
|
|
95
|
+
_glfw.x11.xcursor.handle = _glfw_dlopen("libXcursor-1.so");
|
|
96
|
+
+#elif defined(__OpenBSD__) || defined(__NetBSD__)
|
|
97
|
+
+ _glfw.x11.xcursor.handle = _glfw_dlopen("libXcursor.so");
|
|
98
|
+
#else
|
|
99
|
+
_glfw.x11.xcursor.handle = _glfw_dlopen("libXcursor.so.1");
|
|
100
|
+
#endif
|
|
101
|
+
@@ -764,6 +774,8 @@ static GLFWbool initExtensions(void)
|
|
102
|
+
|
|
103
|
+
#if defined(__CYGWIN__)
|
|
104
|
+
_glfw.x11.xinerama.handle = _glfw_dlopen("libXinerama-1.so");
|
|
105
|
+
+#elif defined(__OpenBSD__) || defined(__NetBSD__)
|
|
106
|
+
+ _glfw.x11.xinerama.handle = _glfw_dlopen("libXinerama.so");
|
|
107
|
+
#else
|
|
108
|
+
_glfw.x11.xinerama.handle = _glfw_dlopen("libXinerama.so.1");
|
|
109
|
+
#endif
|
|
110
|
+
@@ -817,6 +829,8 @@ static GLFWbool initExtensions(void)
|
|
111
|
+
{
|
|
112
|
+
#if defined(__CYGWIN__)
|
|
113
|
+
_glfw.x11.x11xcb.handle = _glfw_dlopen("libX11-xcb-1.so");
|
|
114
|
+
+#elif defined(__OpenBSD__) || defined(__NetBSD__)
|
|
115
|
+
+ _glfw.x11.x11xcb.handle = _glfw_dlopen("libX11-xcb.so");
|
|
116
|
+
#else
|
|
117
|
+
_glfw.x11.x11xcb.handle = _glfw_dlopen("libX11-xcb.so.1");
|
|
118
|
+
#endif
|
|
119
|
+
@@ -830,6 +844,8 @@ static GLFWbool initExtensions(void)
|
|
120
|
+
|
|
121
|
+
#if defined(__CYGWIN__)
|
|
122
|
+
_glfw.x11.xrender.handle = _glfw_dlopen("libXrender-1.so");
|
|
123
|
+
+#elif defined(__OpenBSD__) || defined(__NetBSD__)
|
|
124
|
+
+ _glfw.x11.xrender.handle = _glfw_dlopen("libXrender.so");
|
|
125
|
+
#else
|
|
126
|
+
_glfw.x11.xrender.handle = _glfw_dlopen("libXrender.so.1");
|
|
127
|
+
#endif
|
|
128
|
+
@@ -857,6 +873,8 @@ static GLFWbool initExtensions(void)
|
|
129
|
+
|
|
130
|
+
#if defined(__CYGWIN__)
|
|
131
|
+
_glfw.x11.xshape.handle = _glfw_dlopen("libXext-6.so");
|
|
132
|
+
+#elif defined(__OpenBSD__) || defined(__NetBSD__)
|
|
133
|
+
+ _glfw.x11.xshape.handle = _glfw_dlopen("libXext.so");
|
|
134
|
+
#else
|
|
135
|
+
_glfw.x11.xshape.handle = _glfw_dlopen("libXext.so.6");
|
|
136
|
+
#endif
|
|
137
|
+
@@ -1120,6 +1138,8 @@ int _glfwPlatformInit(void)
|
|
138
|
+
|
|
139
|
+
#if defined(__CYGWIN__)
|
|
140
|
+
_glfw.x11.xlib.handle = _glfw_dlopen("libX11-6.so");
|
|
141
|
+
+#elif defined(__OpenBSD__) || defined(__NetBSD__)
|
|
142
|
+
+ _glfw.x11.xlib.handle = _glfw_dlopen("libX11.so");
|
|
143
|
+
#else
|
|
144
|
+
_glfw.x11.xlib.handle = _glfw_dlopen("libX11.so.6");
|
|
145
|
+
#endif
|
package/vendor/libcc/libcc.cc
CHANGED
|
@@ -3745,7 +3745,7 @@ static std::atomic_bool flag_interrupt = false;
|
|
|
3745
3745
|
static std::atomic_bool explicit_interrupt = false;
|
|
3746
3746
|
static int interrupt_pfd[2] = {-1, -1};
|
|
3747
3747
|
|
|
3748
|
-
|
|
3748
|
+
void SetSignalHandler(int signal, void (*func)(int), struct sigaction *prev)
|
|
3749
3749
|
{
|
|
3750
3750
|
struct sigaction action = {};
|
|
3751
3751
|
|
|
@@ -3786,10 +3786,10 @@ RG_INIT(SetupDefaultHandlers)
|
|
|
3786
3786
|
int ret = setpgid(0, 0);
|
|
3787
3787
|
RG_ASSERT(!ret);
|
|
3788
3788
|
|
|
3789
|
-
SetSignalHandler(SIGINT,
|
|
3790
|
-
SetSignalHandler(SIGTERM,
|
|
3791
|
-
SetSignalHandler(SIGHUP,
|
|
3792
|
-
SetSignalHandler(SIGPIPE,
|
|
3789
|
+
SetSignalHandler(SIGINT, DefaultSignalHandler);
|
|
3790
|
+
SetSignalHandler(SIGTERM, DefaultSignalHandler);
|
|
3791
|
+
SetSignalHandler(SIGHUP, DefaultSignalHandler);
|
|
3792
|
+
SetSignalHandler(SIGPIPE, [](int) {});
|
|
3793
3793
|
}
|
|
3794
3794
|
|
|
3795
3795
|
RG_EXIT(TerminateChildren)
|
|
@@ -3797,7 +3797,7 @@ RG_EXIT(TerminateChildren)
|
|
|
3797
3797
|
pid_t pid = getpid();
|
|
3798
3798
|
RG_ASSERT(pid > 1);
|
|
3799
3799
|
|
|
3800
|
-
SetSignalHandler(SIGTERM,
|
|
3800
|
+
SetSignalHandler(SIGTERM, [](int) {});
|
|
3801
3801
|
kill(-pid, SIGTERM);
|
|
3802
3802
|
}
|
|
3803
3803
|
|
|
@@ -4168,7 +4168,7 @@ WaitForResult WaitForInterrupt(int64_t timeout)
|
|
|
4168
4168
|
static std::atomic_bool message = false;
|
|
4169
4169
|
|
|
4170
4170
|
flag_interrupt = true;
|
|
4171
|
-
SetSignalHandler(SIGUSR1,
|
|
4171
|
+
SetSignalHandler(SIGUSR1, [](int) { message = true; });
|
|
4172
4172
|
|
|
4173
4173
|
if (timeout >= 0) {
|
|
4174
4174
|
struct timespec ts;
|