. ../settings.sh
+# Enable Dynamic call
+USE_DYNCALL=1
+
# Temporary flag
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 ../shared/lib/linux_$ARCH/lib/libdyncall_s.a"
+LIBS="-L$CORE_DIR/lib -l$RUNTIME_LIBRARY -Wl,-rpath=$CORE_DIR/lib:./ -lpthread -ldl -lm"
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'
FLAGS="$FLAGS -DENABLE_DEBUG_INFO"
fi
-FLAGS="$FLAGS -DENABLE_RUN_WITH_WASMER -DUSE_DYNCALL"
+FLAGS="$FLAGS -DENABLE_RUN_WITH_WASMER"
+
+if [ "$USE_DYNCALL" = "1" ]; then
+ LIBS="$LIBS ../shared/lib/linux_$ARCH/lib/libdyncall_s.a ../shared/lib/linux_$ARCH/lib/libdyncallback_s.a"
+ FLAGS="$FLAGS -DUSE_DYNCALL"
+fi
sudo mkdir -p "$BIN_DIR"
debug_end_function(mod);
}
-static char encode_type_as_dyncall_symbol(Type *t) {
+static void encode_type_as_dyncall_symbol(char *out, Type *t) {
if (type_struct_is_just_one_basic_value(t)) {
Type *inner = type_struct_is_just_one_basic_value(t);
- return encode_type_as_dyncall_symbol(inner);
+ encode_type_as_dyncall_symbol(out, inner);
}
- if (t->kind == Type_Kind_Slice) return 's';
- if (t->kind == Type_Kind_Pointer) return 'p';
- if (t->kind == Type_Kind_MultiPointer) return 'p';
- if (t->kind == Type_Kind_Enum) return encode_type_as_dyncall_symbol(t->Enum.backing);
- if (t->kind == Type_Kind_Basic) {
+ else if (t->kind == Type_Kind_Slice) strncat(out, "s", 64);
+ else if (t->kind == Type_Kind_Pointer) strncat(out, "p", 64);
+ else if (t->kind == Type_Kind_MultiPointer) strncat(out, "p", 64);
+ else if (t->kind == Type_Kind_Enum) encode_type_as_dyncall_symbol(out, t->Enum.backing);
+ else if (t->kind == Type_Kind_Basic) {
TypeBasic* basic = &t->Basic;
- if (basic->flags & Basic_Flag_Boolean) return 'i';
- if (basic->flags & Basic_Flag_Integer) {
- if (basic->size <= 4) return 'i';
- if (basic->size == 8) return 'l';
+ if (basic->flags & Basic_Flag_Boolean) strncat(out, "i", 64);
+ else if (basic->flags & Basic_Flag_Integer) {
+ if (basic->size <= 4) strncat(out, "i", 64);
+ if (basic->size == 8) strncat(out, "l", 64);
}
- if (basic->flags & Basic_Flag_Pointer) return 'p';
- if (basic->flags & Basic_Flag_Float) {
- if (basic->size <= 4) return 'f';
- if (basic->size == 8) return 'd';
+ else if (basic->flags & Basic_Flag_Pointer) strncat(out, "p", 64);
+ else if (basic->flags & Basic_Flag_Float) {
+ if (basic->size <= 4) strncat(out, "f", 64);
+ if (basic->size == 8) strncat(out, "d", 64);
}
- if (basic->flags & Basic_Flag_SIMD) return 'v';
- if (basic->flags & Basic_Flag_Type_Index) return 'i';
- if (basic->size == 0) return 'v';
+ else if (basic->flags & Basic_Flag_SIMD) strncat(out, "v", 64);
+ else if (basic->flags & Basic_Flag_Type_Index) strncat(out, "i", 64);
+ else strncat(out, "v", 64);
}
-
- if (t->kind == Type_Kind_Distinct) {
- return encode_type_as_dyncall_symbol(t->Distinct.base_type);
+ else if (t->kind == Type_Kind_Distinct) {
+ encode_type_as_dyncall_symbol(out, t->Distinct.base_type);
}
- return 'v';
+ else strncat(out, "v", 64);
}
static void emit_foreign_function(OnyxWasmModule* mod, AstFunction* fd) {
if (fd->is_foreign_dyncall) {
module = bh_aprintf(global_heap_allocator, "dyncall:%b", fd->foreign_module->text, fd->foreign_module->length);
- char type_encoding[64] = {0};
- type_encoding[0] = encode_type_as_dyncall_symbol(fd->type->Function.return_type);
+ char type_encoding[65] = {0};
+ encode_type_as_dyncall_symbol(type_encoding, fd->type->Function.return_type);
- int index = 1;
bh_arr_each(AstParam, param, fd->params) {
- type_encoding[index++] = encode_type_as_dyncall_symbol(param->local->type);
+ encode_type_as_dyncall_symbol(type_encoding, param->local->type);
}
name = bh_aprintf(global_heap_allocator, "%b:%s", fd->foreign_name->text, fd->foreign_name->length, type_encoding);
#ifdef USE_DYNCALL
#include "dyncall.h"
+ #include "dyncall_callback.h"
static DCCallVM *dcCallVM;
#endif
arg_idx++;
dcArgInt(dcCallVM, args->data[arg_idx++].of.i32);
break;
+
default: assert(("bad dynamic call type", 0));
}
}
--- /dev/null
+/*
+
+ Package: dyncall
+ Library: dyncallback
+ File: dyncallback/dyncall_args.h
+ Description: Callback's Arguments VM - Interface
+ 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_ARGS_H
+#define DYNCALL_ARGS_H
+
+/*
+ * dyncall args C API
+ *
+ * dyncall args provides serialized access to arguments of a function call.
+ * related concepts: callback
+ *
+ */
+
+#include "dyncall.h"
+
+#include "dyncall_value.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct DCArgs DCArgs;
+
+/* functions to retrieve callback's params in callback handler */
+DC_API DCbool dcbArgBool (DCArgs* p);
+DC_API DCchar dcbArgChar (DCArgs* p);
+DC_API DCshort dcbArgShort (DCArgs* p);
+DC_API DCint dcbArgInt (DCArgs* p);
+DC_API DClong dcbArgLong (DCArgs* p);
+DC_API DClonglong dcbArgLongLong (DCArgs* p);
+DC_API DCuchar dcbArgUChar (DCArgs* p);
+DC_API DCushort dcbArgUShort (DCArgs* p);
+DC_API DCuint dcbArgUInt (DCArgs* p);
+DC_API DCulong dcbArgULong (DCArgs* p);
+DC_API DCulonglong dcbArgULongLong(DCArgs* p);
+DC_API DCfloat dcbArgFloat (DCArgs* p);
+DC_API DCdouble dcbArgDouble (DCArgs* p);
+DC_API DCpointer dcbArgPointer (DCArgs* p);
+/* for trivial aggrs: 'target' points to space to copy aggr to, returns 'target'
+ for C++ non-trivial aggrs: target is ignored, returns ptr to aggr arg */
+DC_API DCpointer dcbArgAggr (DCArgs* p, DCpointer target);
+
+/* helper func to put a to be returned struct-by-value into the 'result'
+ param of the callback handler; for C++ non-trivial aggrs, pass NULL in
+ 'ret', then copy aggr into result->p */
+DC_API void dcbReturnAggr(DCArgs *args, DCValue *result, DCpointer ret);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* DYNCALL_ARGS_H */
+
--- /dev/null
+/*
+
+ Package: dyncall
+ Library: dyncallback
+ File: dyncallback/dyncall_callback.h
+ Description: Callback - Interface
+ 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_CALLBACK_H
+#define DYNCALL_CALLBACK_H
+
+#include "dyncall_args.h"
+#include "dyncall_signature.h"
+#include "dyncall_value.h"
+
+typedef struct DCCallback DCCallback;
+
+/* callback handler:
+ - handlers return value signature char (see dyncall_signature.h) of callback's return value type
+ - callback return value is written to the corresponding type's field of result
+ - if callback return value is an aggregate (by value), use dcbReturnAggr() as a helper to write to result
+*/
+typedef DCsigchar (DCCallbackHandler)(DCCallback* pcb, DCArgs* args, DCValue* result, void* userdata);
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+DCCallback* dcbNewCallback (const DCsigchar* signature, DCCallbackHandler* funcptr, void* userdata);
+DCCallback* dcbNewCallback2 (const DCsigchar* signature, DCCallbackHandler* funcptr, void* userdata, DCaggr *const * aggrs);
+void dcbInitCallback (DCCallback* pcb, const DCsigchar* signature, DCCallbackHandler* handler, void* userdata);
+void dcbInitCallback2(DCCallback* pcb, const DCsigchar* signature, DCCallbackHandler* handler, void* userdata, DCaggr *const * aggrs);
+void dcbFreeCallback (DCCallback* pcb);
+void* dcbGetUserData (DCCallback* pcb);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* DYNCALL_CALLBACK_H */
+
--- /dev/null
+/*
+
+ Package: dyncall
+ Library: dyncall
+ File: dyncall/dyncall_value.h
+ Description: Value variant type
+ 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 value variant
+
+ a value variant union-type that carries all supported dyncall types.
+
+ REVISION
+ 2007/12/11 initial
+
+*/
+
+#ifndef DYNCALL_VALUE_H
+#define DYNCALL_VALUE_H
+
+#include "dyncall_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef union DCValue_ DCValue;
+
+union DCValue_
+{
+/* dyncallback assembly pulls value directly from DCValue structs, without */
+/* knowledge about types used, so lay it out as needed at compile time, here */
+#if defined(DC__Endian_BIG) && (defined(DC__Arch_PPC32) || defined(DC__Arch_MIPS) || defined(DC__Arch_Sparc))
+ DCbool B;
+ struct { DCchar c_pad[3]; DCchar c; };
+ struct { DCuchar C_pad[3]; DCuchar C; };
+ struct { DCshort s_pad; DCshort s; };
+ struct { DCshort S_pad; DCshort S; };
+ DCint i;
+ DCuint I;
+#elif defined(DC__Endian_BIG) && (defined(DC__Arch_PPC64) || defined(DC__Arch_MIPS64) || defined(DC__Arch_Sparc64))
+ struct { DCbool B_pad; DCbool B; };
+ struct { DCchar c_pad[7]; DCchar c; };
+ struct { DCuchar C_pad[7]; DCuchar C; };
+ struct { DCshort s_pad[3]; DCshort s; };
+ struct { DCshort S_pad[3]; DCshort S; };
+ struct { DCint i_pad; DCint i; };
+ struct { DCint I_pad; DCuint I; };
+#else
+ DCbool B;
+ DCchar c;
+ DCuchar C;
+ DCshort s;
+ DCushort S;
+ DCint i;
+ DCuint I;
+#endif
+ DClong j;
+ DCulong J;
+ DClonglong l;
+ DCulonglong L;
+/* floats on mips are right justified in fp-registers on big endian targets, as they aren't promoted */
+#if defined(DC__Endian_BIG) && (defined(DC__Arch_MIPS) || defined(DC__Arch_MIPS64))
+ struct { DCfloat f_pad; DCfloat f; };
+#else
+ DCfloat f;
+#endif
+ DCdouble d;
+ DCpointer p;
+ DCstring Z;
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* DYNCALL_VALUE_H */
+