ENABLE_DEBUG_INFO=1
C_FILES="onyx astnodes builtins checker clone doc entities errors lex parser symres types utils wasm_emit wasm_runtime "
-LIBS="-L$CORE_DIR/lib -l$RUNTIME_LIBRARY -Wl,-rpath=$CORE_DIR/lib:./ -lpthread -ldl -lm"
-INCLUDES="-I./include -I../shared/include"
+LIBS="-L$CORE_DIR/lib -l$RUNTIME_LIBRARY -Wl,-rpath=$CORE_DIR/lib:./ -lpthread -ldl -lm -ldyncall_s"
+INCLUDES="-I./include -I../shared/include -I../shared/include/dyncall"
WARNINGS='-Wimplicit -Wmisleading-indentation -Wparentheses -Wsequence-point -Wreturn-type -Wshift-negative-value -Wunused-but-set-parameter -Wunused-but-set-variable -Wunused-function -Wunused-label -Wmaybe-uninitialized -Wsign-compare -Wstrict-overflow -Wduplicated-branches -Wduplicated-cond -Wtrigraphs -Waddress -Wlogical-op'
#include "astnodes.h"
#include "wasm.h"
#include "onyx_library.h"
+#include "dyncall.h"
#ifndef USE_OVM_DEBUGGER
#include "wasmer.h"
wasm_module_t* wasm_module;
wasm_memory_t* wasm_memory;
+// @Temporary
+static DCCallVM *dcCallVM;
+
OnyxRuntime wasm_runtime;
b32 wasm_name_equals(const wasm_name_t* name1, const wasm_name_t* name2) {
return !strncmp(name1->data, name2, name1->size);
}
+b32 wasm_name_starts_with(const wasm_name_t* name, const char *prefix) {
+ u32 prefix_size = strlen(prefix);
+ if (name->size < prefix_size) return 0;
+ return !strncmp(name->data, prefix, prefix_size);
+}
+
wasm_extern_t* wasm_extern_lookup_by_name(wasm_module_t* module, wasm_instance_t* instance, const char* name) {
i32 name_len = strlen(name);
return exports.data[idx];
}
+typedef struct LinkLibraryContext {
+ bh_buffer wasm_bytes;
+ bh_arr(char *) library_paths;
+} LinkLibraryContext;
-typedef void *(*LibraryLinker)(OnyxRuntime *runtime);
+static void *locate_symbol_in_dynamic_library(LinkLibraryContext *ctx, char *libname, char *sym) {
+ #ifdef _BH_LINUX
+ char *library_name = bh_lookup_file(libname, ".", ".so", 1, (const char **) ctx->library_paths, 1);
+ void* handle = dlopen(library_name, RTLD_LAZY);
+ if (handle == NULL) {
+ return NULL;
+ }
-typedef struct LibraryLinkContext {
- bh_buffer wasm_bytes;
- bh_arr(char *) library_paths;
-} LibraryLinkContext;
+ return dlsym(handle, sym);
+ #endif
+
+ #ifdef _BH_WINDOWS
+ char *library_name = bh_lookup_file(libname, ".", ".dll", 1, (const char **) ctx->library_paths, 1);
+ HMODULE handle = LoadLibraryA(library_name);
+ if (handle == NULL) {
+ return NULL;
+ }
-static WasmFuncDefinition** onyx_load_library(LibraryLinkContext *ctx, char *name) {
+ return GetProcAddress(handle, sym);
+ #endif
+
+ return NULL;
+}
+
+typedef void *(*LinkLibraryer)(OnyxRuntime *runtime);
+
+static WasmFuncDefinition** onyx_load_library(LinkLibraryContext *ctx, char *name) {
#ifdef _BH_LINUX
#define DIR_SEPARATOR '/'
#endif
char *library_load_name_tmp = bh_bprintf("onyx_library_%s", library);
char *library_load_name = alloca(strlen(library_load_name_tmp) + 1);
strcpy(library_load_name, library_load_name_tmp);
- LibraryLinker library_load;
-
- #ifdef _BH_LINUX
- char *library_name = bh_lookup_file(name, ".", ".so", 1, (const char **) ctx->library_paths, 1);
- void* handle = dlopen(library_name, RTLD_LAZY);
- if (handle == NULL) {
- printf("ERROR LOADING LIBRARY %s: %s\n", name, dlerror());
- return NULL;
- }
- library_load = (LibraryLinker) dlsym(handle, library_load_name);
+ LinkLibraryer library_load = locate_symbol_in_dynamic_library(ctx, name, library_load_name);
if (library_load == NULL) {
printf("ERROR RESOLVING '%s': %s\n", library_load_name, dlerror());
return NULL;
}
- #endif
-
- #ifdef _BH_WINDOWS
- char *library_name = bh_lookup_file(name, ".", ".dll", 1, (const char **) ctx->library_paths, 1);
- HMODULE handle = LoadLibraryA(library_name);
- if (handle == NULL) {
- printf("ERROR LOADING LIBRARY %s: %d\n", name, GetLastError());
- return NULL;
- }
-
- library_load = (LibraryLinker) GetProcAddress(handle, library_load_name);
- if (library_load == NULL) {
- printf("ERROR RESOLVING '%s': %d\n", library_load_name, GetLastError());
- return NULL;
- }
- #endif
return library_load(runtime);
}
-static void lookup_and_load_custom_libraries(LibraryLinkContext *ctx, bh_arr(WasmFuncDefinition **)* p_out) {
+static void lookup_and_load_custom_libraries(LinkLibraryContext *ctx, bh_arr(WasmFuncDefinition **)* p_out) {
bh_arr(WasmFuncDefinition **) out = *p_out;
bh_buffer wasm_bytes = ctx->wasm_bytes;
*p_out = out;
}
+
+typedef struct DynCallContext {
+ void (*func)();
+ char types[64];
+} DynCallContext;
+
+static wasm_trap_t *__wasm_dyncall(void *env, const wasm_val_vec_t *args, wasm_val_vec_t *res) {
+ DynCallContext *ctx = env;
+ dcReset(dcCallVM);
+
+ int arg_idx = 0;
+ for (int i = 1; i < 64; i++) {
+ switch (ctx->types[i]) {
+ case '\0': goto arguments_placed;
+ case 'i': dcArgInt(dcCallVM, args->data[arg_idx++].of.i32); break;
+ case 'l': dcArgLongLong(dcCallVM, args->data[arg_idx++].of.i64); break;
+ case 'f': dcArgFloat(dcCallVM, args->data[arg_idx++].of.f32); break;
+ case 'd': dcArgFloat(dcCallVM, args->data[arg_idx++].of.f64); break;
+ case 'p': dcArgPointer(dcCallVM, ONYX_PTR(args->data[arg_idx++].of.i32)); break;
+ case 'v': break;
+ case 's':
+ dcArgPointer(dcCallVM, ONYX_PTR(args->data[arg_idx++].of.i32));
+ dcArgInt(dcCallVM, args->data[arg_idx++].of.i32);
+ break;
+ default: assert(("bad dynamic call type", 0));
+ }
+ }
+
+ arguments_placed:
+ switch (ctx->types[0]) {
+ case 'i': res->data[0] = WASM_I32_VAL(dcCallInt(dcCallVM, ctx->func)); break;
+ case 'l': res->data[0] = WASM_I64_VAL(dcCallLongLong(dcCallVM, ctx->func)); break;
+ case 'f': res->data[0] = WASM_F32_VAL(dcCallFloat(dcCallVM, ctx->func)); break;
+ case 'd': res->data[0] = WASM_F64_VAL(dcCallDouble(dcCallVM, ctx->func)); break;
+ case 'p': res->data[0] = WASM_I64_VAL((u64) dcCallPointer(dcCallVM, ctx->func)); break;
+ case 'v': dcCallVoid(dcCallVM, ctx->func);
+ }
+
+ return NULL;
+}
+
+static wasm_func_t *link_and_prepare_dyncall_function(
+ wasm_externtype_t* type,
+ LinkLibraryContext *lib_ctx,
+ wasm_name_t library_name,
+ wasm_name_t function_name)
+{
+ //
+ // When using any dynamic functions, a DCCallVM has to be created.
+ if (!dcCallVM) {
+ dcCallVM = dcNewCallVM(4096);
+ dcMode(dcCallVM, DC_CALL_C_DEFAULT);
+ }
+
+ char lib_name[256];
+ strncpy(lib_name, library_name.data, bh_min(256, library_name.size));
+
+ u32 index;
+ char func_name[256];
+ for (index = 0; index < function_name.size; index++) {
+ if (function_name.data[index] == ':') break;
+ func_name[index] = function_name.data[index];
+ }
+ func_name[index++] = '\0';
+
+ char dynamic_types[64];
+ for (; index < function_name.size; index++) {
+ dynamic_types[index] = function_name.data[index];
+ }
+ dynamic_types[index] = '\0';
+
+ void (*func)() = locate_symbol_in_dynamic_library(lib_ctx, lib_name, func_name);
+ if (!func) return NULL;
+
+ wasm_functype_t *functype = wasm_externtype_as_functype(type);
+
+ DynCallContext* dcc = bh_alloc_item(bh_heap_allocator(), DynCallContext);
+ dcc->func = func;
+ memcpy(&dcc->types, dynamic_types, 64);
+
+ wasm_func_t *wasm_func = wasm_func_new_with_env(wasm_store, functype, &__wasm_dyncall, dcc, NULL);
+ return wasm_func;
+}
+
static void onyx_print_trap(wasm_trap_t* trap) {
wasm_message_t msg;
wasm_trap_message(trap, &msg);
//
// This could be cleaned up a bit, as this function directly modifies various global variables.
// Those being wasm_memory and wasm_imports.
-static b32 link_wasm_imports(bh_arr(WasmFuncDefinition **) linkable_functions, wasm_module_t *wasm_module) {
+static b32 link_wasm_imports(
+ bh_arr(WasmFuncDefinition **) linkable_functions,
+ LinkLibraryContext *lib_ctx,
+ wasm_module_t *wasm_module)
+{
wasm_importtype_vec_t module_imports;
wasm_module_imports(wasm_module, &module_imports);
}
}
+ if (wasm_name_starts_with(module_name, "dyncall:")) {
+ wasm_name_t library_name = *module_name;
+ library_name.data += 8;
+ library_name.size -= 8;
+
+ wasm_name_t function_name = *import_name;
+
+ wasm_func_t *wasm_func = link_and_prepare_dyncall_function(
+ (wasm_externtype_t *) wasm_importtype_type(module_imports.data[i]),
+ lib_ctx,
+ library_name,
+ function_name
+ );
+
+ if (!wasm_func) {
+ goto bad_import;
+ }
+
+ import = wasm_func_as_extern(wasm_func);
+ goto import_found;
+ }
+
bh_arr_each(WasmFuncDefinition **, library_funcs, linkable_functions) {
WasmFuncDefinition **pcurrent_function = *library_funcs;
while (*pcurrent_function != NULL) {
bh_arr(WasmFuncDefinition **) linkable_functions = NULL;
bh_arr_new(bh_heap_allocator(), linkable_functions, 4);
- {
- LibraryLinkContext lib_ctx;
- lib_ctx.wasm_bytes = wasm_bytes;
- lib_ctx.library_paths = NULL;
- lookup_and_load_custom_libraries(&lib_ctx, &linkable_functions);
-
- bh_arr_free(lib_ctx.library_paths);
- }
+ LinkLibraryContext lib_ctx;
+ lib_ctx.wasm_bytes = wasm_bytes;
+ lib_ctx.library_paths = NULL;
+ lookup_and_load_custom_libraries(&lib_ctx, &linkable_functions);
wasm_byte_vec_t wasm_data;
wasm_data.size = wasm_bytes.length;
}
wasm_imports = (wasm_extern_vec_t) WASM_EMPTY_VEC;
- if (!link_wasm_imports(linkable_functions, wasm_module)) {
+ if (!link_wasm_imports(linkable_functions, &lib_ctx, wasm_module)) {
return 0;
}
+ bh_arr_free(lib_ctx.library_paths);
+
wasm_trap_t* traps = NULL;
wasm_instance = wasm_instance_new(wasm_store, wasm_module, &wasm_imports, &traps);
--- /dev/null
+/*
+
+ Package: dyncall
+ Library: dyncall
+ File: dyncall/dyncall.h
+ Description: public header for library dyncall
+ License:
+
+ Copyright (c) 2007-2022 Daniel Adler <dadler@uni-goettingen.de>,
+ Tassilo Philipp <tphilipp@potion-studios.com>
+
+ Permission to use, copy, modify, and distribute this software for any
+ purpose with or without fee is hereby granted, provided that the above
+ copyright notice and this permission notice appear in all copies.
+
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+*/
+
+
+#ifndef DYNCALL_H
+#define DYNCALL_H
+
+#include "dyncall_types.h"
+#include "dyncall_signature.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct DCCallVM_ DCCallVM;
+typedef struct DCaggr_ DCaggr;
+
+/* Supported Calling Convention Modes */
+
+/* default */
+#define DC_CALL_C_DEFAULT 0 /* C default (platform native) */
+#define DC_CALL_C_DEFAULT_THIS 99 /* for C++ calls where first param is hidden this ptr (platform native) */
+#define DC_CALL_C_ELLIPSIS 100 /* to be set for vararg calls' non-hidden (e.g. C++ this ptr), named arguments */
+#define DC_CALL_C_ELLIPSIS_VARARGS 101 /* to be set for vararg calls' non-hidden (e.g. C++ this ptr), variable arguments (in ... part) */
+/* platform specific */
+#define DC_CALL_C_X86_CDECL 1
+#define DC_CALL_C_X86_WIN32_STD 2
+#define DC_CALL_C_X86_WIN32_FAST_MS 3
+#define DC_CALL_C_X86_WIN32_FAST_GNU 4
+#define DC_CALL_C_X86_WIN32_THIS_MS 5
+#define DC_CALL_C_X86_WIN32_THIS_GNU DC_CALL_C_X86_CDECL /* alias - identical to cdecl (w/ this-ptr as 1st arg) */
+#define DC_CALL_C_X64_WIN64 7
+#define DC_CALL_C_X64_WIN64_THIS 70 /* only needed when using aggregate by value as return type */
+#define DC_CALL_C_X64_SYSV 8
+#define DC_CALL_C_X64_SYSV_THIS DC_CALL_C_X64_SYSV /* alias */
+#define DC_CALL_C_PPC32_DARWIN 9
+#define DC_CALL_C_PPC32_OSX DC_CALL_C_PPC32_DARWIN /* alias */
+#define DC_CALL_C_ARM_ARM_EABI 10
+#define DC_CALL_C_ARM_THUMB_EABI 11
+#define DC_CALL_C_ARM_ARMHF 30
+#define DC_CALL_C_MIPS32_EABI 12
+#define DC_CALL_C_MIPS32_PSPSDK DC_CALL_C_MIPS32_EABI /* alias - deprecated. */
+#define DC_CALL_C_PPC32_SYSV 13
+#define DC_CALL_C_PPC32_LINUX DC_CALL_C_PPC32_SYSV /* alias */
+#define DC_CALL_C_ARM_ARM 14
+#define DC_CALL_C_ARM_THUMB 15
+#define DC_CALL_C_MIPS32_O32 16
+#define DC_CALL_C_MIPS64_N32 17
+#define DC_CALL_C_MIPS64_N64 18
+#define DC_CALL_C_X86_PLAN9 19
+#define DC_CALL_C_SPARC32 20
+#define DC_CALL_C_SPARC64 21
+#define DC_CALL_C_ARM64 22
+#define DC_CALL_C_PPC64 23
+#define DC_CALL_C_PPC64_LINUX DC_CALL_C_PPC64 /* alias */
+/* syscalls, default */
+#define DC_CALL_SYS_DEFAULT 200
+/* syscalls, platform specific */
+#define DC_CALL_SYS_X86_INT80H_LINUX 201
+#define DC_CALL_SYS_X86_INT80H_BSD 202
+#define DC_CALL_SYS_X64_SYSCALL_SYSV 204
+#define DC_CALL_SYS_PPC32 210
+#define DC_CALL_SYS_PPC64 211
+
+/* Error codes. */
+
+#define DC_ERROR_NONE 0
+#define DC_ERROR_UNSUPPORTED_MODE -1
+
+DC_API DCCallVM* dcNewCallVM (DCsize size);
+DC_API void dcFree (DCCallVM* vm);
+DC_API void dcReset (DCCallVM* vm);
+
+DC_API void dcMode (DCCallVM* vm, DCint mode);
+
+DC_API void dcBeginCallAggr (DCCallVM* vm, const DCaggr* ag);
+
+DC_API void dcArgBool (DCCallVM* vm, DCbool value);
+DC_API void dcArgChar (DCCallVM* vm, DCchar value);
+DC_API void dcArgShort (DCCallVM* vm, DCshort value);
+DC_API void dcArgInt (DCCallVM* vm, DCint value);
+DC_API void dcArgLong (DCCallVM* vm, DClong value);
+DC_API void dcArgLongLong (DCCallVM* vm, DClonglong value);
+DC_API void dcArgFloat (DCCallVM* vm, DCfloat value);
+DC_API void dcArgDouble (DCCallVM* vm, DCdouble value);
+DC_API void dcArgPointer (DCCallVM* vm, DCpointer value);
+DC_API void dcArgAggr (DCCallVM* vm, const DCaggr* ag, const void* value);
+
+DC_API void dcCallVoid (DCCallVM* vm, DCpointer funcptr);
+DC_API DCbool dcCallBool (DCCallVM* vm, DCpointer funcptr);
+DC_API DCchar dcCallChar (DCCallVM* vm, DCpointer funcptr);
+DC_API DCshort dcCallShort (DCCallVM* vm, DCpointer funcptr);
+DC_API DCint dcCallInt (DCCallVM* vm, DCpointer funcptr);
+DC_API DClong dcCallLong (DCCallVM* vm, DCpointer funcptr);
+DC_API DClonglong dcCallLongLong (DCCallVM* vm, DCpointer funcptr);
+DC_API DCfloat dcCallFloat (DCCallVM* vm, DCpointer funcptr);
+DC_API DCdouble dcCallDouble (DCCallVM* vm, DCpointer funcptr);
+DC_API DCpointer dcCallPointer (DCCallVM* vm, DCpointer funcptr);
+DC_API DCpointer dcCallAggr (DCCallVM* vm, DCpointer funcptr, const DCaggr* ag, DCpointer ret); /* retval is written to *ret, returns ret */
+
+DC_API DCint dcGetError (DCCallVM* vm);
+
+DC_API DCaggr* dcNewAggr (DCsize maxFieldCount, DCsize size);
+DC_API void dcFreeAggr (DCaggr* ag);
+/* if type == DC_SIGCHAR_AGGREGATE, pass DCaggr* of nested struct/union in ... */
+DC_API void dcAggrField (DCaggr* ag, DCsigchar type, DCint offset, DCsize array_len, ...);
+DC_API void dcCloseAggr (DCaggr* ag); /* to indicate end of struct definition, required */
+
+
+/* helpers */
+
+/* returns respective mode for callconv sig char (w/o checking if mode exists */
+/* on current platform), or DC_ERROR_UNSUPPORTED_MODE if char isn't a sigchar */
+DC_API DCint dcGetModeFromCCSigChar(DCsigchar sig_char);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* DYNCALL_H */
+
--- /dev/null
+/*
+
+ Package: dyncall
+ Library: dyncall
+ File: dyncall/dyncall_config.h
+ Description: Macro configuration file for non-standard C types
+ License:
+
+ Copyright (c) 2007-2018 Daniel Adler <dadler@uni-goettingen.de>,
+ Tassilo Philipp <tphilipp@potion-studios.com>
+
+ Permission to use, copy, modify, and distribute this software for any
+ purpose with or without fee is hereby granted, provided that the above
+ copyright notice and this permission notice appear in all copies.
+
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+*/
+
+
+
+/*
+
+ dyncall type configuration
+
+ REVISION
+ 2007/12/11 initial
+
+*/
+
+#ifndef DYNCALL_CONFIG_H
+#define DYNCALL_CONFIG_H
+
+#include "dyncall_macros.h"
+
+#define DC_BOOL int
+#define DC_LONG_LONG long long
+#define DC_POINTER void*
+
+#endif /* DYNCALL_CONFIG_H */
+
--- /dev/null
+/*
+
+ Package: dyncall
+ Library: dyncall
+ File: dyncall/dyncall_macros.h
+ Description: Platform detection macros
+ License:
+
+ Copyright (c) 2007-2018 Daniel Adler <dadler@uni-goettingen.de>,
+ Tassilo Philipp <tphilipp@potion-studios.com>
+
+ Permission to use, copy, modify, and distribute this software for any
+ purpose with or without fee is hereby granted, provided that the above
+ copyright notice and this permission notice appear in all copies.
+
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+*/
+
+
+
+/*
+
+ dyncall macros
+
+ Platform detection, specific defines and configuration.
+ The purpose of this file is to provide coherent platform and compiler
+ specific defines. So instead of defines like WIN32, _OpenBSD_ or
+ __GNUC__, one should use DC__OS_Win32, DC__OS_OpenBSD or DC__C_GNU,
+ respectively.
+
+ REVISION
+ 2007/12/11 initial
+
+*/
+
+
+#ifndef DYNCALL_MACROS_H
+#define DYNCALL_MACROS_H
+
+
+
+/* -- Platform specific #defines ------------------------------------ */
+
+/* MS Windows XP x64/Vista64 or later. */
+#if defined(WIN64) || defined(_WIN64) || defined(__WIN64__)
+# define DC__OS_Win64
+
+/* MS Windows NT/95/98/ME/2000/XP/Vista32. */
+#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) || defined(__WINDOWS__) || defined(_WINDOWS)
+# define DC__OS_Win32
+
+/* All the OS' based on Darwin OS (MacOS X, OpenDarwin). Note that '__APPLE__' may be defined for classic MacOS, too. */
+/* __MACOSX__ is not defined in gcc assembler mode (switch: -S) */
+#elif defined(__APPLE__) || defined(__Darwin__)
+# define DC__OS_Darwin
+# if defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__)
+# define DC__OS_IPhone
+# else /* defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) */
+# define DC__OS_MacOSX
+# endif
+
+/* The most popular open source Unix-like OS - Linux. */
+#elif defined(__linux__) || defined(__linux) || defined(__gnu_linux__)
+# define DC__OS_Linux
+
+/* The most powerful open source Unix-like OS - FreeBSD. */
+#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) /* latter is (also) used by systems using FreeBSD kernel, e.g. Debian/kFreeBSD, which could be detected specifically by also checking for __GLIBC__ */
+# define DC__OS_FreeBSD
+
+/* The most secure open source Unix-like OS - OpenBSD. */
+#elif defined(__OpenBSD__)
+# define DC__OS_OpenBSD
+
+/* The most portable open source Unix-like OS - NetBSD. */
+#elif defined(__NetBSD__)
+# define DC__OS_NetBSD
+
+/* The FreeBSD fork having heavy clusterization in mind - DragonFlyBSD. */
+#elif defined(__DragonFly__)
+# define DC__OS_DragonFlyBSD
+
+/* Sun's Unix-like OS - SunOS / Solaris. */
+#elif defined(__sun__) || defined(__sun) || defined(sun)
+# define DC__OS_SunOS
+
+/* The Nintendo DS (homebrew) using devkitpro. */
+#elif defined(__nds__)
+# define DC__OS_NDS
+
+/* The PlayStation Portable (homebrew) SDK. */
+#elif defined(__psp__) || defined(PSP)
+# define DC__OS_PSP
+
+/* Haiku (BeOS alike). */
+#elif defined(__HAIKU__)
+# define DC__OS_BeOS
+
+/* The Unix successor - Plan9 from Bell Labs */
+#elif defined(Plan9) || defined(__Plan9__)
+# define DC__OS_Plan9
+
+/* Digital's Unix-like OS - VMS */
+#elif defined(__vms)
+# define DC__OS_VMS
+
+/* Tanenbaum's Microkernel OS - Minix */
+#elif defined(__minix)
+# define DC__OS_Minix
+
+/* Unable to determine OS, which is probably ok (e.g. baremetal stuff, etc.). */
+#else
+# define DC__OS_UNKNOWN
+
+#endif
+
+
+/* windows sub envs */
+#if defined(DC__OS_Win32) || defined(DC__OS_Win64)
+
+/* The "Linux-like environment for Windows" - Cygwin. */
+# if defined(__CYGWIN__)
+# define DC__OS_Cygwin
+
+/* The "Minimalist GNU for Windows" - MinGW. */
+# elif defined(__MINGW32__) || defined(__MINGW64__)
+# define DC__OS_MinGW
+# endif
+
+#endif
+
+
+
+/* -- Compiler specific #defines ------------------------------------ */
+
+/* Don't change the order, b/c some compilers use same #defines compatibility */
+
+/* Intel's C/C++ compiler. */
+#if defined(__INTEL_COMPILER)
+# define DC__C_Intel
+
+/* MS C/C++ compiler. */
+#elif defined(_MSC_VER)
+# define DC__C_MSVC
+
+/* LLVM clang. */
+#elif defined(__clang__) || defined(__llvm__)
+# define DC__C_CLANG
+
+/* The GNU Compiler Collection - GCC. */
+#elif defined(__GNUC__)
+# define DC__C_GNU
+
+/* Watcom compiler. */
+#elif defined(__WATCOMC__)
+# define DC__C_WATCOM
+
+/* Portable C Compiler. */
+#elif defined(__PCC__)
+# define DC__C_PCC
+
+/* Sun Pro C. */
+#elif defined(__SUNPRO_C)
+# define DC__C_SUNPRO
+
+/* Undetected C Compiler. */
+#else
+# define DC__C_UNKNOWN
+#endif
+
+
+
+/* -- Architecture -------------------------------------------------- */
+
+/* Check architecture. */
+#if defined(_M_X64_) || defined(_M_AMD64) || defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64)
+# define DC__Arch_AMD64
+#elif defined(_M_IX86) || defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__) || defined(__386__) || defined(__i386)
+# define DC__Arch_Intel_x86
+#elif defined(_M_IA64) || defined(__ia64__)
+# define DC__Arch_Itanium
+#elif defined(_M_PPC) || defined(__powerpc__) || defined(__powerpc) || defined(__POWERPC__) || defined(__ppc__) || defined(__power__)
+# if defined(__ppc64__) || defined(_ARCH_PPC64) || defined(__power64__) || defined(__powerpc64__)
+# define DC__Arch_PPC64
+# else
+# define DC__Arch_PPC32
+# endif
+#elif defined(__mips64__) || defined(__mips64)
+# define DC__Arch_MIPS64
+#elif defined(_M_MRX000) || defined(__mips__) || defined(__mips) || defined(_mips)
+# define DC__Arch_MIPS
+#elif defined(__arm__)
+# define DC__Arch_ARM
+#elif defined(_M_ARM64) || defined(__aarch64__) || defined(__arm64) || defined(__arm64__)
+# define DC__Arch_ARM64
+#elif defined(__sh__)
+# define DC__Arch_SuperH
+#elif defined(__sparc) || defined(__sparc__)
+# if defined(__sparcv9) || defined(__sparc_v9__) || defined(__sparc64__) || defined(__arch64__)
+# define DC__Arch_Sparc64
+# else
+# define DC__Arch_Sparc
+# endif
+#endif
+
+
+
+/* -- Runtime ------------------------------------------------------- */
+
+#if defined(__MSVCRT__)
+# define DC__RT_MSVCRT
+#endif
+
+
+/* -- Rough OS classification --------------------------------------- */
+
+#if defined(DC__OS_Win32) || defined(DC__OS_Win64)
+# define DC_WINDOWS
+#elif defined(DC__OS_Plan9)
+# define DC_PLAN9
+#elif defined(DC__OS_NDS) || defined(DC__OS_PSP)
+# define DC_OTHER
+#else
+# define DC_UNIX
+#endif
+
+
+
+/* -- Misc machine-dependent modes, ABIs, etc. ---------------------- */
+
+#if defined(__arm__) && !defined(__thumb__)
+# define DC__Arch_ARM_ARM
+#elif defined(__arm__) && defined(__thumb__)
+# define DC__Arch_ARM_THUMB
+#endif
+
+#if defined(DC__Arch_ARM_ARM) || defined(DC__Arch_ARM_THUMB)
+# if defined(__ARM_EABI__) || defined(DC__OS_NDS)
+# if defined (__ARM_PCS_VFP) && (__ARM_PCS_VFP == 1)
+# define DC__ABI_ARM_HF
+# else
+# define DC__ABI_ARM_EABI
+# endif
+# elif defined(__APCS_32__)
+# define DC__ABI_ARM_OABI
+# endif
+#endif /* ARM */
+
+#if defined(DC__Arch_MIPS) || defined(DC__Arch_MIPS64)
+# if defined(_ABIO32) || defined(__mips_o32) || defined(_MIPS_ARCH_MIPS1) || defined(_MIPS_ARCH_MIPS2)
+# define DC__ABI_MIPS_O32
+# elif defined(_ABI64) || defined(__mips_n64)
+# define DC__ABI_MIPS_N64
+# elif defined(_ABIN32)
+# define DC__ABI_MIPS_N32
+# else
+# define DC__ABI_MIPS_EABI
+# endif
+/* Set extra flag to know if FP hardware ABI, default to yes, if unsure */
+# if (defined(__mips_hard_float) && (__mips_hard_float == 1)) || !defined(__mips_soft_float) || (__mips_soft_float != 1)
+# define DC__ABI_HARDFLOAT /* @@@ make this general for all archs? */
+# else
+# define DC__ABI_SOFTFLOAT
+# endif
+#endif /* MIPS */
+
+#if defined(DC__Arch_PPC64)
+# if defined(_CALL_ELF)
+# define DC__ABI_PPC64_ELF_V _CALL_ELF
+# else
+# define DC__ABI_PPC64_ELF_V 0 /* 0 means not explicitly set, otherwise this is 1 (big endian) and 2 (little endian) */
+# endif
+#endif /* PPC64 */
+
+
+
+/* -- Endianness detection ------------------------------------------ */
+
+#if defined(DC__Arch_Intel_x86) || defined(DC__Arch_AMD64) /* always little */
+# define DC__Endian_LITTLE
+#elif defined(DC__Arch_Sparc) /* always purely big until v9 */
+# define DC__Endian_BIG
+#else /* all others are bi-endian */
+/* @@@check flags used on following bi-endianness archs:
+DC__Arch_Itanium
+DC__Arch_PPC32
+DC__Arch_PPC64
+DC__Arch_SuperH
+*/
+# if (defined(DC__Arch_PPC64) && (DC__ABI_PPC64_ELF_V == 1)) || defined(MIPSEB) || defined(_MIPSEB) || defined(__MIPSEB) || defined(__MIPSEB__) || defined(__ARMEB__) || defined(__AARCH64EB__)
+# define DC__Endian_BIG
+# elif (defined(DC__Arch_PPC64) && (DC__ABI_PPC64_ELF_V == 2)) || defined(MIPSEL) || defined(_MIPSEL) || defined(__MIPSEL) || defined(__MIPSEL__) || defined(__ARMEL__) || defined(__AARCH64EL__)
+# define DC__Endian_LITTLE
+# elif defined(DC__Arch_Sparc64) && !defined(__BYTE_ORDER__) /* Sparc64 default is big-endian, except if explicitly defined */
+# define DC__Endian_BIG
+# elif defined(BYTE_ORDER) || defined(_BYTE_ORDER) || defined(__BYTE_ORDER__) /* explicitly set byte order, either through compiler or platform specific endian.h */
+# if (defined(BIG_ENDIAN) && (BYTE_ORDER == BIG_ENDIAN)) || (defined(_BIG_ENDIAN) && (_BYTE_ORDER == _BIG_ENDIAN)) || (defined(__ORDER_BIG_ENDIAN__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))
+# define DC__Endian_BIG
+# elif (defined(LITTLE_ENDIAN) && (BYTE_ORDER == LITTLE_ENDIAN)) || (defined(_LITTLE_ENDIAN) && (_BYTE_ORDER == _LITTLE_ENDIAN)) || (defined(__ORDER_LITTLE_ENDIAN__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__))
+# define DC__Endian_LITTLE
+# endif
+# elif (defined(_BIG_ENDIAN) && (_BIG_ENDIAN == 1)) || (defined(__BIG_ENDIAN__) && (__BIG_ENDIAN__ == 1)) /* explicitly set as on/off */
+# define DC__Endian_BIG
+# elif (defined(_LITTLE_ENDIAN) && (_LITTLE_ENDIAN == 1)) || (defined(__LITTLE_ENDIAN__) && (__LITTLE_ENDIAN__ == 1)) /* explicitly set as on/off */
+# define DC__Endian_LITTLE
+# endif /* no else, leave unset if not sure */
+#endif
+
+
+
+/* -- Internal macro/tag -------------------------------------------- */
+
+#if !defined(DC_API)
+# define DC_API
+#endif
+
+
+
+/* -- Library feature support macors -------------------------------- */
+
+/* macros for specifying lesser used feature support (main features like basic
+ call and callback support are required for a platform implementation */
+
+/* syscalls */
+#if (defined(DC__Arch_Intel_x86) || (defined(DC__Arch_AMD64) && defined(DC_UNIX)) || defined(DC__Arch_PPC32) || defined(DC__Arch_PPC64)) && \
+ !defined(DC__OS_MacOSX) && !defined(DC__OS_Plan9) && !defined(DC__OS_NDS) && !defined(DC__OS_PSP) && !defined(DC__OS_Minix) && !defined(DC__OS_SunOS) && !defined(DC__OS_BeOS)
+# define DC__Feature_Syscall
+#endif
+
+/* aggregate (struct, union) by value */
+#if defined(DC__Arch_AMD64)
+# define DC__Feature_AggrByVal
+#endif
+
+
+#endif /* DYNCALL_MACROS_H */
+
--- /dev/null
+/*
+
+ Package: dyncall
+ Library: dyncall
+ File: dyncall/dyncall_signature.h
+ Description: Type and calling-convention signature character defines
+ License:
+
+ Copyright (c) 2007-2022 Daniel Adler <dadler@uni-goettingen.de>,
+ Tassilo Philipp <tphilipp@potion-studios.com>
+
+ Permission to use, copy, modify, and distribute this software for any
+ purpose with or without fee is hereby granted, provided that the above
+ copyright notice and this permission notice appear in all copies.
+
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+*/
+
+
+#ifndef DYNCALL_SIGNATURE_H
+#define DYNCALL_SIGNATURE_H
+
+typedef char DCsigchar;
+
+#define DC_SIGCHAR_VOID 'v'
+#define DC_SIGCHAR_BOOL 'B'
+#define DC_SIGCHAR_CHAR 'c'
+#define DC_SIGCHAR_UCHAR 'C'
+#define DC_SIGCHAR_SHORT 's'
+#define DC_SIGCHAR_USHORT 'S'
+#define DC_SIGCHAR_INT 'i'
+#define DC_SIGCHAR_UINT 'I'
+#define DC_SIGCHAR_LONG 'j'
+#define DC_SIGCHAR_ULONG 'J'
+#define DC_SIGCHAR_LONGLONG 'l'
+#define DC_SIGCHAR_ULONGLONG 'L'
+#define DC_SIGCHAR_FLOAT 'f'
+#define DC_SIGCHAR_DOUBLE 'd'
+#define DC_SIGCHAR_POINTER 'p' /* also used for arrays, as such args decay to ptrs */
+#define DC_SIGCHAR_STRING 'Z' /* in theory same as 'p', but convenient to disambiguate */
+#define DC_SIGCHAR_AGGREGATE 'A' /* aggregate (struct/union described out-of-band via DCaggr) */
+#define DC_SIGCHAR_ENDARG ')'
+
+/* calling convention / mode signatures */
+
+#define DC_SIGCHAR_CC_PREFIX '_' /* announces next char to be one of the below calling convention mode chars */
+#define DC_SIGCHAR_CC_DEFAULT ':' /* default calling conv (platform native) */
+#define DC_SIGCHAR_CC_THISCALL '*' /* C++ this calls (platform native) */
+#define DC_SIGCHAR_CC_ELLIPSIS 'e'
+#define DC_SIGCHAR_CC_ELLIPSIS_VARARGS '.'
+#define DC_SIGCHAR_CC_CDECL 'c' /* x86 specific */
+#define DC_SIGCHAR_CC_STDCALL 's' /* x86 specific */
+#define DC_SIGCHAR_CC_FASTCALL_MS 'F' /* x86 specific */
+#define DC_SIGCHAR_CC_FASTCALL_GNU 'f' /* x86 specific */
+#define DC_SIGCHAR_CC_THISCALL_MS '+' /* x86 specific, MS C++ this calls */
+#define DC_SIGCHAR_CC_THISCALL_GNU '#' /* x86 specific, GNU C++ this calls are cdecl, but keep specific sig char for clarity */
+#define DC_SIGCHAR_CC_ARM_ARM 'A'
+#define DC_SIGCHAR_CC_ARM_THUMB 'a'
+#define DC_SIGCHAR_CC_SYSCALL '$'
+
+#endif /* DYNCALL_SIGNATURE_H */
+
--- /dev/null
+/*
+
+ Package: dyncall
+ Library: dyncall
+ File: dyncall/dyncall_types.h
+ Description: Typedefs
+ License:
+
+ Copyright (c) 2007-2018 Daniel Adler <dadler@uni-goettingen.de>,
+ Tassilo Philipp <tphilipp@potion-studios.com>
+
+ Permission to use, copy, modify, and distribute this software for any
+ purpose with or without fee is hereby granted, provided that the above
+ copyright notice and this permission notice appear in all copies.
+
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+*/
+
+
+
+/*
+
+ dyncall argument- and return-types
+
+ REVISION
+ 2007/12/11 initial
+
+*/
+
+#ifndef DYNCALL_TYPES_H
+#define DYNCALL_TYPES_H
+
+#include <stddef.h>
+
+#include "dyncall_config.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void DCvoid;
+typedef DC_BOOL DCbool;
+typedef char DCchar;
+typedef unsigned char DCuchar;
+typedef short DCshort;
+typedef unsigned short DCushort;
+typedef int DCint;
+typedef unsigned int DCuint;
+typedef long DClong;
+typedef unsigned long DCulong;
+typedef DC_LONG_LONG DClonglong;
+typedef unsigned DC_LONG_LONG DCulonglong;
+typedef float DCfloat;
+typedef double DCdouble;
+typedef DC_POINTER DCpointer;
+typedef const char* DCstring;
+typedef size_t DCsize;
+
+#define DC_TRUE 1
+#define DC_FALSE 0
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* DYNCALL_TYPES_H */
+