if (basic->size <= 4) return WASM_TYPE_INT32;
if (basic->size == 8) return WASM_TYPE_INT64;
}
- if (basic->flags & Basic_Flag_Pointer) return WASM_TYPE_INT32;
+ if (basic->flags & Basic_Flag_Pointer) return WASM_TYPE_PTR;
if (basic->flags & Basic_Flag_Float) {
if (basic->size <= 4) return WASM_TYPE_FLOAT32;
if (basic->size == 8) return WASM_TYPE_FLOAT64;
debug_end_function(mod);
}
+static char encode_type_as_dyncall_symbol(Type *t) {
+ if (t->kind == Type_Kind_Slice) return 's';
+ if (t->kind == Type_Kind_Pointer) return 'p';
+ if (t->kind == Type_Kind_Enum) return encode_type_as_dyncall_symbol(t->Enum.backing);
+ 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_Pointer) return 'p';
+ if (basic->flags & Basic_Flag_Float) {
+ if (basic->size <= 4) return 'f';
+ if (basic->size == 8) return 'd';
+ }
+ if (basic->flags & Basic_Flag_SIMD) return 'v';
+ if (basic->flags & Basic_Flag_Type_Index) return 'i';
+ if (basic->size == 0) return 'v';
+ }
+
+ return 'v';
+}
+
static void emit_foreign_function(OnyxWasmModule* mod, AstFunction* fd) {
if (!should_emit_function(fd)) return;
i32 type_idx = generate_type_idx(mod, fd->type);
+ char *module, *name;
+
+ 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);
+
+ int index = 1;
+ bh_arr_each(AstParam, param, fd->params) {
+ type_encoding[index++] = encode_type_as_dyncall_symbol(param->local->type);
+ }
+
+ name = bh_aprintf(global_heap_allocator, "%b:%s", fd->foreign_name->text, fd->foreign_name->length, type_encoding);
+
+ } else {
+ module = bh_aprintf(global_heap_allocator, "%b", fd->foreign_module->text, fd->foreign_module->length);
+ name = bh_aprintf(global_heap_allocator, "%b", fd->foreign_name->text, fd->foreign_name->length);
+ }
+
WasmImport import = {
.kind = WASM_FOREIGN_FUNCTION,
.idx = type_idx,
- .mod = bh_aprintf(global_heap_allocator, "%b", fd->foreign_module->text, fd->foreign_module->length),
- .name = bh_aprintf(global_heap_allocator, "%b", fd->foreign_name->text, fd->foreign_name->length),
+ .mod = module,
+ .name = name,
};
bh_arr_push(mod->imports, import);
} LinkLibraryContext;
-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);
+static void *locate_symbol_in_dynamic_library_raw(char *libname, char *sym) {
+#ifdef _BH_LINUX
+ void* handle = dlopen(libname, RTLD_LAZY);
if (handle == NULL) {
return NULL;
}
return dlsym(handle, sym);
- #endif
+#endif
- #ifdef _BH_WINDOWS
- char *library_name = bh_lookup_file(libname, ".", ".dll", 1, (const char **) ctx->library_paths, 1);
- HMODULE handle = LoadLibraryA(library_name);
+#ifdef _BH_WINDOWS
+ HMODULE handle = LoadLibraryA(libname);
if (handle == NULL) {
return NULL;
}
return GetProcAddress(handle, sym);
- #endif
+#endif
return NULL;
}
+static void *locate_symbol_in_dynamic_library(LinkLibraryContext *ctx, char *libname, char *sym) {
+ char *library_name;
+
+ #ifdef _BH_LINUX
+ library_name = bh_lookup_file(libname, ".", ".so", 1, (const char **) ctx->library_paths, 1);
+ #endif
+
+ #ifdef _BH_WINDOWS
+ library_name = bh_lookup_file(libname, ".", ".dll", 1, (const char **) ctx->library_paths, 1);
+ #endif
+
+ return locate_symbol_in_dynamic_library_raw(library_name, sym);
+}
+
typedef void *(*LinkLibraryer)(OnyxRuntime *runtime);
static WasmFuncDefinition** onyx_load_library(LinkLibraryContext *ctx, char *name) {
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 'd': dcArgDouble(dcCallVM, args->data[arg_idx++].of.f64); break;
+ case 'p': dcArgPointer(dcCallVM, ONYX_PTR(args->data[arg_idx].of.i32)); arg_idx++; break;
+ case 'v': arg_idx++; break;
case 's':
- dcArgPointer(dcCallVM, ONYX_PTR(args->data[arg_idx++].of.i32));
+ dcArgPointer(dcCallVM, ONYX_PTR(args->data[arg_idx].of.i32));
+ arg_idx++;
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);
+ 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); break;
}
+ dcReset(dcCallVM);
return NULL;
}
dcMode(dcCallVM, DC_CALL_C_DEFAULT);
}
- char lib_name[256];
+ char lib_name[256] = {0};
strncpy(lib_name, library_name.data, bh_min(256, library_name.size));
u32 index;
- char func_name[256];
+ char func_name[256] = {0};
for (index = 0; index < function_name.size; index++) {
- if (function_name.data[index] == ':') break;
+ if (function_name.data[index] == ':') {
+ 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];
+ char dynamic_types[64] = {0};
+ for (u32 write_index = 0; index < function_name.size; write_index++, index++) {
+ dynamic_types[write_index] = function_name.data[index];
}
- dynamic_types[index] = '\0';
- void (*func)() = locate_symbol_in_dynamic_library(lib_ctx, lib_name, func_name);
+ void (*func)() = locate_symbol_in_dynamic_library_raw(lib_name, func_name);
if (!func) return NULL;
wasm_functype_t *functype = wasm_externtype_as_functype(type);