koffi 2.6.3 → 2.6.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/CHANGELOG.md +9 -0
- package/build/koffi/darwin_arm64/koffi.node +0 -0
- package/build/koffi/darwin_x64/koffi.node +0 -0
- package/build/koffi/freebsd_arm64/koffi.node +0 -0
- package/build/koffi/freebsd_ia32/koffi.node +0 -0
- package/build/koffi/freebsd_x64/koffi.node +0 -0
- package/build/koffi/linux_arm32hf/koffi.node +0 -0
- package/build/koffi/linux_arm64/koffi.node +0 -0
- package/build/koffi/linux_ia32/koffi.node +0 -0
- package/build/koffi/linux_riscv64hf64/koffi.node +0 -0
- package/build/koffi/linux_x64/koffi.node +0 -0
- package/build/koffi/openbsd_ia32/koffi.node +0 -0
- package/build/koffi/openbsd_x64/koffi.node +0 -0
- package/build/koffi/win32_arm64/koffi.node +0 -0
- package/build/koffi/win32_ia32/koffi.node +0 -0
- package/build/koffi/win32_x64/koffi.node +0 -0
- package/doc/benchmarks.md +26 -33
- package/doc/benchmarks.xlsx +0 -0
- package/doc/contribute.md +1 -1
- package/doc/packaging.md +4 -2
- package/doc/static/perf_linux_20231028.png +0 -0
- package/doc/static/perf_windows_20231028.png +0 -0
- package/index.js +3 -4
- package/indirect.js +3 -4
- package/package.json +2 -2
- package/src/cnoke/src/builder.js +2 -2
- package/src/core/libcc/libcc.cc +263 -177
- package/src/core/libcc/libcc.hh +31 -19
- package/src/koffi/CMakeLists.txt +9 -9
- package/src/koffi/cmake/raylib.cmake +98 -0
- package/src/koffi/cmake/sqlite.cmake +27 -0
- package/src/koffi/src/ffi.cc +50 -28
- package/src/koffi/src/ffi.hh +3 -2
- package/src/koffi/src/util.cc +8 -1
- package/src/koffi/src/win32.cc +1 -1
package/src/core/libcc/libcc.hh
CHANGED
|
@@ -3853,9 +3853,6 @@ Size ConvertWin32WideToUtf8(const wchar_t *str_w, Span<char> out_str);
|
|
|
3853
3853
|
char *GetWin32ErrorString(uint32_t error_code = UINT32_MAX);
|
|
3854
3854
|
#endif
|
|
3855
3855
|
|
|
3856
|
-
void SetEnvironmentVar(const char *name, const char *value);
|
|
3857
|
-
void DeleteEnvironmentVar(const char *name);
|
|
3858
|
-
|
|
3859
3856
|
static inline bool IsPathSeparator(char c)
|
|
3860
3857
|
{
|
|
3861
3858
|
#ifdef _WIN32
|
|
@@ -4055,17 +4052,29 @@ bool CreatePipe(int pfd[2]);
|
|
|
4055
4052
|
void CloseDescriptorSafe(int *fd_ptr);
|
|
4056
4053
|
#endif
|
|
4057
4054
|
|
|
4058
|
-
|
|
4055
|
+
struct ExecuteInfo {
|
|
4056
|
+
struct KeyValue {
|
|
4057
|
+
const char *key;
|
|
4058
|
+
const char *value;
|
|
4059
|
+
};
|
|
4060
|
+
|
|
4061
|
+
const char *work_dir = nullptr;
|
|
4062
|
+
|
|
4063
|
+
bool reset_env = false;
|
|
4064
|
+
Span<const KeyValue> env_variables = {};
|
|
4065
|
+
};
|
|
4066
|
+
|
|
4067
|
+
bool ExecuteCommandLine(const char *cmd_line, const ExecuteInfo &info,
|
|
4059
4068
|
FunctionRef<Span<const uint8_t>()> in_func,
|
|
4060
4069
|
FunctionRef<void(Span<uint8_t> buf)> out_func, int *out_code);
|
|
4061
|
-
bool ExecuteCommandLine(const char *cmd_line, const
|
|
4070
|
+
bool ExecuteCommandLine(const char *cmd_line, const ExecuteInfo &info,
|
|
4062
4071
|
Span<const uint8_t> in_buf, Size max_len,
|
|
4063
4072
|
HeapArray<uint8_t> *out_buf, int *out_code);
|
|
4064
4073
|
|
|
4065
4074
|
// Simple variants
|
|
4066
|
-
static inline bool ExecuteCommandLine(const char *cmd_line, const
|
|
4067
|
-
{ return ExecuteCommandLine(cmd_line,
|
|
4068
|
-
static inline bool ExecuteCommandLine(const char *cmd_line, const
|
|
4075
|
+
static inline bool ExecuteCommandLine(const char *cmd_line, const ExecuteInfo &info,int *out_code)
|
|
4076
|
+
{ return ExecuteCommandLine(cmd_line, info, {}, {}, out_code); }
|
|
4077
|
+
static inline bool ExecuteCommandLine(const char *cmd_line, const ExecuteInfo &info,
|
|
4069
4078
|
Span<const uint8_t> in_buf,
|
|
4070
4079
|
FunctionRef<void(Span<uint8_t> buf)> out_func, int *out_code)
|
|
4071
4080
|
{
|
|
@@ -4075,22 +4084,22 @@ static inline bool ExecuteCommandLine(const char *cmd_line, const char *work_dir
|
|
|
4075
4084
|
return buf;
|
|
4076
4085
|
};
|
|
4077
4086
|
|
|
4078
|
-
return ExecuteCommandLine(cmd_line,
|
|
4087
|
+
return ExecuteCommandLine(cmd_line, info, read_once, out_func, out_code);
|
|
4079
4088
|
}
|
|
4080
4089
|
|
|
4081
4090
|
// Char variants
|
|
4082
|
-
static inline bool ExecuteCommandLine(const char *cmd_line, const
|
|
4091
|
+
static inline bool ExecuteCommandLine(const char *cmd_line, const ExecuteInfo &info,
|
|
4083
4092
|
Span<const char> in_buf,
|
|
4084
4093
|
FunctionRef<void(Span<char> buf)> out_func, int *out_code)
|
|
4085
4094
|
{
|
|
4086
4095
|
const auto write = [&](Span<uint8_t> buf) { out_func(buf.As<char>()); };
|
|
4087
|
-
return ExecuteCommandLine(cmd_line,
|
|
4096
|
+
return ExecuteCommandLine(cmd_line, info, in_buf.As<const uint8_t>(), write, out_code);
|
|
4088
4097
|
}
|
|
4089
|
-
static inline bool ExecuteCommandLine(const char *cmd_line, const
|
|
4098
|
+
static inline bool ExecuteCommandLine(const char *cmd_line, const ExecuteInfo &info,
|
|
4090
4099
|
Span<const char> in_buf, Size max_len,
|
|
4091
4100
|
HeapArray<char> *out_buf, int *out_code)
|
|
4092
4101
|
{
|
|
4093
|
-
return ExecuteCommandLine(cmd_line,
|
|
4102
|
+
return ExecuteCommandLine(cmd_line, info, in_buf.As<const uint8_t>(), max_len,
|
|
4094
4103
|
(HeapArray<uint8_t> *)out_buf, out_code);
|
|
4095
4104
|
}
|
|
4096
4105
|
|
|
@@ -4158,6 +4167,11 @@ const char *CreateUniqueDirectory(Span<const char> directory, const char *prefix
|
|
|
4158
4167
|
// Random
|
|
4159
4168
|
// ------------------------------------------------------------------------
|
|
4160
4169
|
|
|
4170
|
+
void ZeroMemorySafe(void *ptr, Size len);
|
|
4171
|
+
void FillRandomSafe(void *buf, Size len);
|
|
4172
|
+
static inline void FillRandomSafe(Span<uint8_t> buf) { FillRandomSafe(buf.ptr, buf.len); }
|
|
4173
|
+
int GetRandomIntSafe(int min, int max);
|
|
4174
|
+
|
|
4161
4175
|
class FastRandom {
|
|
4162
4176
|
uint64_t state[4];
|
|
4163
4177
|
|
|
@@ -4190,10 +4204,7 @@ public:
|
|
|
4190
4204
|
int operator()() { return rng.GetInt(Min, Max); }
|
|
4191
4205
|
};
|
|
4192
4206
|
|
|
4193
|
-
|
|
4194
|
-
void FillRandomSafe(void *buf, Size len);
|
|
4195
|
-
static inline void FillRandomSafe(Span<uint8_t> buf) { FillRandomSafe(buf.ptr, buf.len); }
|
|
4196
|
-
int GetRandomIntSafe(int min, int max);
|
|
4207
|
+
int GetRandomIntFast(int min, int max);
|
|
4197
4208
|
|
|
4198
4209
|
// ------------------------------------------------------------------------
|
|
4199
4210
|
// Sockets
|
|
@@ -4269,7 +4280,8 @@ class Fiber {
|
|
|
4269
4280
|
#elif defined(RG_FIBER_USE_UCONTEXT)
|
|
4270
4281
|
ucontext_t ucp = {};
|
|
4271
4282
|
#else
|
|
4272
|
-
|
|
4283
|
+
pthread_t thread;
|
|
4284
|
+
bool joinable = false;
|
|
4273
4285
|
|
|
4274
4286
|
std::mutex mutex;
|
|
4275
4287
|
std::condition_variable cv;
|
|
@@ -4297,7 +4309,7 @@ private:
|
|
|
4297
4309
|
#elif defined(RG_FIBER_USE_UCONTEXT)
|
|
4298
4310
|
static void FiberCallback(unsigned int high, unsigned int low);
|
|
4299
4311
|
#else
|
|
4300
|
-
static void ThreadCallback(void *udata);
|
|
4312
|
+
static void *ThreadCallback(void *udata);
|
|
4301
4313
|
void Toggle(int to, std::unique_lock<std::mutex> *lock);
|
|
4302
4314
|
#endif
|
|
4303
4315
|
};
|
package/src/koffi/CMakeLists.txt
CHANGED
|
@@ -31,17 +31,17 @@ find_package(CNoke)
|
|
|
31
31
|
set(CMAKE_CXX_STANDARD 20)
|
|
32
32
|
if(MSVC)
|
|
33
33
|
set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreaded)
|
|
34
|
-
|
|
35
|
-
add_compile_options(/Zc:__cplusplus /W4 /wd4200 /wd4458 /wd4706 /wd4100 /wd4127 /wd4702 /wd4201 /wd4324)
|
|
34
|
+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Zc:__cplusplus /W4 /wd4200 /wd4201 /wd4127 /wd4458 /wd4706 /wd4702 /wd4324")
|
|
36
35
|
|
|
37
36
|
# ASM_MASM does not (yet) work on Windows ARM64
|
|
38
37
|
if(NOT CMAKE_GENERATOR_PLATFORM MATCHES "ARM64")
|
|
39
38
|
enable_language(ASM_MASM)
|
|
40
39
|
endif()
|
|
41
40
|
else()
|
|
42
|
-
|
|
41
|
+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wno-missing-field-initializers -Wno-unused-parameter -Wswitch -Werror=switch")
|
|
42
|
+
|
|
43
43
|
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
|
44
|
-
|
|
44
|
+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unknown-warning-option")
|
|
45
45
|
endif()
|
|
46
46
|
endif()
|
|
47
47
|
|
|
@@ -132,16 +132,16 @@ if(NOT MSVC OR CMAKE_C_COMPILER_ID MATCHES "[Cc]lang")
|
|
|
132
132
|
# Restore C/C++ compiler sanity
|
|
133
133
|
|
|
134
134
|
if(NOT MSVC)
|
|
135
|
-
target_compile_options(koffi PRIVATE
|
|
136
|
-
|
|
135
|
+
target_compile_options(koffi PRIVATE $<$<COMPILE_LANGUAGE:CXX>:-fno-exceptions -fno-strict-aliasing -fwrapv
|
|
136
|
+
-fno-delete-null-pointer-checks>)
|
|
137
137
|
else()
|
|
138
|
-
target_compile_options(koffi PRIVATE
|
|
139
|
-
|
|
138
|
+
target_compile_options(koffi PRIVATE $<$<COMPILE_LANGUAGE:CXX>:-fno-strict-aliasing /clang:-fwrapv
|
|
139
|
+
-fno-delete-null-pointer-checks>)
|
|
140
140
|
endif()
|
|
141
141
|
|
|
142
142
|
check_cxx_compiler_flag(-fno-finite-loops use_no_finite_loops)
|
|
143
143
|
if(use_no_finite_loops)
|
|
144
|
-
target_compile_options(koffi PRIVATE
|
|
144
|
+
target_compile_options(koffi PRIVATE $<$<COMPILE_LANGUAGE:CXX>:-fno-finite-loops>)
|
|
145
145
|
endif()
|
|
146
146
|
endif()
|
|
147
147
|
enable_unity_build(koffi)
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# Copyright 2023 Niels Martignène <niels.martignene@protonmail.com>
|
|
2
|
+
#
|
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
4
|
+
# this software and associated documentation files (the “Software”), to deal in
|
|
5
|
+
# the Software without restriction, including without limitation the rights to use,
|
|
6
|
+
# copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
|
7
|
+
# Software, and to permit persons to whom the Software is furnished to do so,
|
|
8
|
+
# subject to the following conditions:
|
|
9
|
+
#
|
|
10
|
+
# The above copyright notice and this permission notice shall be included in all
|
|
11
|
+
# copies or substantial portions of the Software.
|
|
12
|
+
#
|
|
13
|
+
# THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
|
|
14
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|
15
|
+
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
16
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
17
|
+
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
18
|
+
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
19
|
+
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
20
|
+
# OTHER DEALINGS IN THE SOFTWARE.
|
|
21
|
+
|
|
22
|
+
add_library(raylib SHARED
|
|
23
|
+
../../../vendor/raylib/src/rcore.c
|
|
24
|
+
../../../vendor/raylib/src/rshapes.c
|
|
25
|
+
../../../vendor/raylib/src/rtextures.c
|
|
26
|
+
../../../vendor/raylib/src/rtext.c
|
|
27
|
+
../../../vendor/raylib/src/rmodels.c
|
|
28
|
+
../../../vendor/raylib/src/utils.c
|
|
29
|
+
../../../vendor/raylib/src/rglfw.c
|
|
30
|
+
../../../vendor/raylib/src/raudio.c
|
|
31
|
+
)
|
|
32
|
+
set_target_properties(raylib PROPERTIES PREFIX "")
|
|
33
|
+
target_include_directories(raylib PRIVATE ../../../vendor/raylib/src/external/glfw/include)
|
|
34
|
+
target_compile_definitions(raylib PRIVATE PLATFORM_DESKTOP GRAPHICS_API_OPENGL_21 BUILD_LIBTYPE_SHARED NDEBUG)
|
|
35
|
+
|
|
36
|
+
if(MSVC)
|
|
37
|
+
target_compile_options(raylib PRIVATE /wd4244 /wd4305)
|
|
38
|
+
else()
|
|
39
|
+
target_compile_options(raylib PRIVATE -Wno-sign-compare -Wno-old-style-declaration
|
|
40
|
+
-Wno-unused-function -Wno-missing-field-initializers
|
|
41
|
+
-Wno-unused-value -Wno-implicit-fallthrough -Wno-stringop-overflow
|
|
42
|
+
-Wno-unused-result)
|
|
43
|
+
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
|
44
|
+
target_compile_options(raylib PRIVATE -Wno-unknown-warning-option)
|
|
45
|
+
endif()
|
|
46
|
+
endif()
|
|
47
|
+
|
|
48
|
+
if(WIN32)
|
|
49
|
+
target_compile_definitions(raylib PRIVATE _CRT_SECURE_NO_WARNINGS _CRT_NONSTDC_NO_DEPRECATE)
|
|
50
|
+
target_link_libraries(raylib PRIVATE winmm)
|
|
51
|
+
endif()
|
|
52
|
+
|
|
53
|
+
if(CMAKE_SYSTEM_NAME MATCHES "BSD")
|
|
54
|
+
target_include_directories(raylib PRIVATE /usr/local/include)
|
|
55
|
+
endif()
|
|
56
|
+
|
|
57
|
+
if(APPLE)
|
|
58
|
+
target_compile_options(raylib PRIVATE -Wno-unknown-warning-option -Wno-macro-redefined)
|
|
59
|
+
target_compile_definitions(raylib PRIVATE GL_SILENCE_DEPRECATION)
|
|
60
|
+
set_source_files_properties(../../../vendor/raylib/src/rglfw.c PROPERTIES COMPILE_FLAGS "-x objective-c")
|
|
61
|
+
target_link_libraries(raylib PRIVATE "-framework Cocoa" "-framework IOKit" "-framework CoreFoundation" "-framework OpenGL")
|
|
62
|
+
endif()
|
|
63
|
+
|
|
64
|
+
if(UNIX AND NOT APPLE)
|
|
65
|
+
set(missing_xlib "")
|
|
66
|
+
|
|
67
|
+
find_path(XLIB_INCLUDE_DIRS X11/Xlib.h)
|
|
68
|
+
if(NOT XLIB_INCLUDE_DIRS)
|
|
69
|
+
list(APPEND missing_xlib Xlib)
|
|
70
|
+
endif()
|
|
71
|
+
find_path(XCURSOR_INCLUDE_DIRS X11/Xcursor/Xcursor.h)
|
|
72
|
+
if(NOT XCURSOR_INCLUDE_DIRS)
|
|
73
|
+
list(APPEND missing_xlib Xcursor)
|
|
74
|
+
endif()
|
|
75
|
+
find_path(XRANDR_INCLUDE_DIRS X11/extensions/Xrandr.h)
|
|
76
|
+
if(NOT XRANDR_INCLUDE_DIRS)
|
|
77
|
+
list(APPEND missing_xlib Xrandr)
|
|
78
|
+
endif()
|
|
79
|
+
find_path(XKB_INCLUDE_DIRS X11/XKBlib.h)
|
|
80
|
+
if(NOT XKB_INCLUDE_DIRS)
|
|
81
|
+
list(APPEND missing_xlib Xkbcommon)
|
|
82
|
+
endif()
|
|
83
|
+
find_path(XINERAMA_INCLUDE_DIRS X11/extensions/Xinerama.h)
|
|
84
|
+
if(NOT XINERAMA_INCLUDE_DIRS)
|
|
85
|
+
list(APPEND missing_xlib Xinerama)
|
|
86
|
+
endif()
|
|
87
|
+
find_path(XINPUT_INCLUDE_DIRS X11/extensions/XInput2.h)
|
|
88
|
+
if(NOT XINPUT_INCLUDE_DIRS)
|
|
89
|
+
list(APPEND missing_xlib XInput2)
|
|
90
|
+
endif()
|
|
91
|
+
|
|
92
|
+
if(missing_xlib)
|
|
93
|
+
list(JOIN missing_xlib ", " missing_xlib_str)
|
|
94
|
+
message(FATAL_ERROR "Missing X11 development files: ${missing_xlib_str}")
|
|
95
|
+
endif()
|
|
96
|
+
|
|
97
|
+
target_include_directories(raylib PRIVATE ${XLIB_INCLUDE_DIRS})
|
|
98
|
+
endif()
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Copyright 2023 Niels Martignène <niels.martignene@protonmail.com>
|
|
2
|
+
#
|
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
4
|
+
# this software and associated documentation files (the “Software”), to deal in
|
|
5
|
+
# the Software without restriction, including without limitation the rights to use,
|
|
6
|
+
# copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
|
7
|
+
# Software, and to permit persons to whom the Software is furnished to do so,
|
|
8
|
+
# subject to the following conditions:
|
|
9
|
+
#
|
|
10
|
+
# The above copyright notice and this permission notice shall be included in all
|
|
11
|
+
# copies or substantial portions of the Software.
|
|
12
|
+
#
|
|
13
|
+
# THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
|
|
14
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|
15
|
+
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
16
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
17
|
+
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
18
|
+
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
19
|
+
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
20
|
+
# OTHER DEALINGS IN THE SOFTWARE.
|
|
21
|
+
|
|
22
|
+
add_library(sqlite3 SHARED ../../../vendor/sqlite3/sqlite3.c)
|
|
23
|
+
set_target_properties(sqlite3 PROPERTIES PREFIX "")
|
|
24
|
+
|
|
25
|
+
if(WIN32)
|
|
26
|
+
target_compile_definitions(sqlite3 PRIVATE SQLITE_API=__declspec\(dllexport\))
|
|
27
|
+
endif()
|
package/src/koffi/src/ffi.cc
CHANGED
|
@@ -225,18 +225,38 @@ static Napi::Value CreateStructType(const Napi::CallbackInfo &info, bool pad)
|
|
|
225
225
|
return env.Null();
|
|
226
226
|
}
|
|
227
227
|
|
|
228
|
+
RG_DEFER_NC(err_guard, len = instance->types.len) {
|
|
229
|
+
for (Size i = len + 1; i < instance->types.len; i++) {
|
|
230
|
+
const TypeInfo &type = instance->types[i];
|
|
231
|
+
instance->types_map.Remove(type.name);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
instance->types.RemoveFrom(len);
|
|
235
|
+
};
|
|
236
|
+
|
|
228
237
|
TypeInfo *type = instance->types.AppendDefault();
|
|
229
|
-
RG_DEFER_N(err_guard) { instance->types.RemoveLast(1); };
|
|
230
238
|
|
|
231
239
|
Napi::String name = info[0].As<Napi::String>();
|
|
232
240
|
Napi::Object obj = info[named].As<Napi::Object>();
|
|
233
241
|
Napi::Array keys = obj.GetPropertyNames();
|
|
234
242
|
|
|
235
|
-
|
|
236
|
-
|
|
243
|
+
if (named) {
|
|
244
|
+
type->name = DuplicateString(name.Utf8Value().c_str(), &instance->str_alloc).ptr;
|
|
245
|
+
|
|
246
|
+
bool inserted;
|
|
247
|
+
instance->types_map.TrySet(type->name, type, &inserted);
|
|
248
|
+
|
|
249
|
+
if (!inserted) {
|
|
250
|
+
ThrowError<Napi::Error>(env, "Duplicate type name '%1'", type->name);
|
|
251
|
+
return env.Null();
|
|
252
|
+
}
|
|
253
|
+
} else {
|
|
254
|
+
type->name = Fmt(&instance->str_alloc, "<anonymous_%1>", instance->types.len).ptr;
|
|
255
|
+
}
|
|
237
256
|
|
|
238
257
|
type->primitive = PrimitiveKind::Record;
|
|
239
258
|
type->align = 1;
|
|
259
|
+
type->flags = (int)TypeFlag::IsIncomplete;
|
|
240
260
|
|
|
241
261
|
HashSet<const char *> members;
|
|
242
262
|
int64_t size = 0;
|
|
@@ -308,16 +328,7 @@ static Napi::Value CreateStructType(const Napi::CallbackInfo &info, bool pad)
|
|
|
308
328
|
}
|
|
309
329
|
type->size = (int32_t)size;
|
|
310
330
|
|
|
311
|
-
|
|
312
|
-
if (named) {
|
|
313
|
-
bool inserted;
|
|
314
|
-
instance->types_map.TrySet(type->name, type, &inserted);
|
|
315
|
-
|
|
316
|
-
if (!inserted) {
|
|
317
|
-
ThrowError<Napi::Error>(env, "Duplicate type name '%1'", type->name);
|
|
318
|
-
return env.Null();
|
|
319
|
-
}
|
|
320
|
-
}
|
|
331
|
+
type->flags &= ~(int)TypeFlag::IsIncomplete;
|
|
321
332
|
err_guard.Disable();
|
|
322
333
|
|
|
323
334
|
return WrapType(env, instance, type);
|
|
@@ -354,18 +365,38 @@ static Napi::Value CreateUnionType(const Napi::CallbackInfo &info)
|
|
|
354
365
|
return env.Null();
|
|
355
366
|
}
|
|
356
367
|
|
|
368
|
+
RG_DEFER_NC(err_guard, len = instance->types.len) {
|
|
369
|
+
for (Size i = len + 1; i < instance->types.len; i++) {
|
|
370
|
+
const TypeInfo &type = instance->types[i];
|
|
371
|
+
instance->types_map.Remove(type.name);
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
instance->types.RemoveFrom(len);
|
|
375
|
+
};
|
|
376
|
+
|
|
357
377
|
TypeInfo *type = instance->types.AppendDefault();
|
|
358
|
-
RG_DEFER_N(err_guard) { instance->types.RemoveLast(1); };
|
|
359
378
|
|
|
360
379
|
Napi::String name = info[0].As<Napi::String>();
|
|
361
380
|
Napi::Object obj = info[named].As<Napi::Object>();
|
|
362
381
|
Napi::Array keys = obj.GetPropertyNames();
|
|
363
382
|
|
|
364
|
-
|
|
365
|
-
|
|
383
|
+
if (named) {
|
|
384
|
+
type->name = DuplicateString(name.Utf8Value().c_str(), &instance->str_alloc).ptr;
|
|
385
|
+
|
|
386
|
+
bool inserted;
|
|
387
|
+
instance->types_map.TrySet(type->name, type, &inserted);
|
|
388
|
+
|
|
389
|
+
if (!inserted) {
|
|
390
|
+
ThrowError<Napi::Error>(env, "Duplicate type name '%1'", type->name);
|
|
391
|
+
return env.Null();
|
|
392
|
+
}
|
|
393
|
+
} else {
|
|
394
|
+
type->name = Fmt(&instance->str_alloc, "<anonymous_%1>", instance->types.len).ptr;
|
|
395
|
+
}
|
|
366
396
|
|
|
367
397
|
type->primitive = PrimitiveKind::Union;
|
|
368
398
|
type->align = 1;
|
|
399
|
+
type->flags = (int)TypeFlag::IsIncomplete;
|
|
369
400
|
|
|
370
401
|
HashSet<const char *> members;
|
|
371
402
|
int32_t size = 0;
|
|
@@ -428,16 +459,7 @@ static Napi::Value CreateUnionType(const Napi::CallbackInfo &info)
|
|
|
428
459
|
}
|
|
429
460
|
type->size = (int32_t)size;
|
|
430
461
|
|
|
431
|
-
|
|
432
|
-
if (named) {
|
|
433
|
-
bool inserted;
|
|
434
|
-
instance->types_map.TrySet(type->name, type, &inserted);
|
|
435
|
-
|
|
436
|
-
if (!inserted) {
|
|
437
|
-
ThrowError<Napi::Error>(env, "Duplicate type name '%1'", type->name);
|
|
438
|
-
return env.Null();
|
|
439
|
-
}
|
|
440
|
-
}
|
|
462
|
+
type->flags &= ~(int)TypeFlag::IsIncomplete;
|
|
441
463
|
err_guard.Disable();
|
|
442
464
|
|
|
443
465
|
// Union constructor
|
|
@@ -2224,7 +2246,7 @@ static Napi::Value ResetKoffi(const Napi::CallbackInfo &info)
|
|
|
2224
2246
|
return env.Undefined();
|
|
2225
2247
|
}
|
|
2226
2248
|
|
|
2227
|
-
static InstanceData *CreateInstance(
|
|
2249
|
+
static InstanceData *CreateInstance()
|
|
2228
2250
|
{
|
|
2229
2251
|
InstanceData *instance = new InstanceData();
|
|
2230
2252
|
RG_DEFER_N(err_guard) { delete instance; };
|
|
@@ -2247,7 +2269,7 @@ static InstanceData *CreateInstance(Napi::Env env)
|
|
|
2247
2269
|
|
|
2248
2270
|
static Napi::Object InitModule(Napi::Env env, Napi::Object exports)
|
|
2249
2271
|
{
|
|
2250
|
-
InstanceData *instance = CreateInstance(
|
|
2272
|
+
InstanceData *instance = CreateInstance();
|
|
2251
2273
|
RG_CRITICAL(instance, "Failed to initialize Koffi");
|
|
2252
2274
|
|
|
2253
2275
|
env.SetInstanceData(instance);
|
package/src/koffi/src/ffi.hh
CHANGED
|
@@ -104,8 +104,9 @@ class CallData;
|
|
|
104
104
|
typedef void DisposeFunc (Napi::Env env, const TypeInfo *type, const void *ptr);
|
|
105
105
|
|
|
106
106
|
enum class TypeFlag {
|
|
107
|
-
|
|
108
|
-
|
|
107
|
+
IsIncomplete = 1 << 0,
|
|
108
|
+
HasTypedArray = 1 << 1,
|
|
109
|
+
IsCharLike = 1 << 2
|
|
109
110
|
};
|
|
110
111
|
|
|
111
112
|
enum class ArrayHint {
|
package/src/koffi/src/util.cc
CHANGED
|
@@ -120,7 +120,9 @@ const TypeInfo *ResolveType(Napi::Value value, int *out_directions)
|
|
|
120
120
|
const TypeInfo *type = ResolveType(env, str.c_str(), out_directions);
|
|
121
121
|
|
|
122
122
|
if (!type) {
|
|
123
|
-
|
|
123
|
+
if (!env.IsExceptionPending()) {
|
|
124
|
+
ThrowError<Napi::TypeError>(env, "Unknown or invalid type name '%1'", str.c_str());
|
|
125
|
+
}
|
|
124
126
|
return nullptr;
|
|
125
127
|
}
|
|
126
128
|
|
|
@@ -299,6 +301,11 @@ const TypeInfo *ResolveType(Napi::Env env, Span<const char> str, int *out_direct
|
|
|
299
301
|
RG_ASSERT(type);
|
|
300
302
|
}
|
|
301
303
|
|
|
304
|
+
if (type->flags & (int)TypeFlag::IsIncomplete) [[unlikely]] {
|
|
305
|
+
ThrowError<Napi::TypeError>(env, "Cannot directly use incomplete type");
|
|
306
|
+
return nullptr;
|
|
307
|
+
}
|
|
308
|
+
|
|
302
309
|
return type;
|
|
303
310
|
}
|
|
304
311
|
|
package/src/koffi/src/win32.cc
CHANGED