diff options
author | Leo Tenenbaum <pommicket@gmail.com> | 2020-01-20 22:18:11 -0500 |
---|---|---|
committer | Leo Tenenbaum <pommicket@gmail.com> | 2020-01-20 22:18:11 -0500 |
commit | 8406747331eef16a525f0dbf4d26445d243e19d1 (patch) | |
tree | d20fe308f98e91218e852b1235184be540c0d01a | |
parent | 4a1467810d1cf9498db9507f36f78a0bd385c1e9 (diff) |
only load function pointers once
-rw-r--r-- | foreign.c | 34 | ||||
-rw-r--r-- | test.toc | 32 | ||||
-rw-r--r-- | types.c | 2 | ||||
-rw-r--r-- | types.h | 1 |
4 files changed, 36 insertions, 33 deletions
@@ -223,29 +223,34 @@ static bool arg_list_add(av_alist *arg_list, Value *val, Type *type, Location wh } static bool foreign_call(FnExpr *fn, Type *fn_type, Value *args, Location call_where, Value *ret) { - assert(fn->flags & FN_EXPR_FOREIGN); - const char *lib = fn->foreign.lib; - const char *name = fn->foreign.name; + void (*fn_ptr)() = fn->foreign.fn_ptr; + if (!fn_ptr) { + assert(fn->flags & FN_EXPR_FOREIGN); + const char *lib = fn->foreign.lib; + const char *name = fn->foreign.name; - /* TODO: IMPORTANT: only open libraries once */ - void *handle = dlopen(lib, RTLD_LAZY); - if (!handle) { - err_print(call_where, "Could not open dynamic library: %s.", lib); - return false; - } + /* TODO: IMPORTANT: only open libraries once */ + void *handle = dlopen(lib, RTLD_LAZY); + printf("Load %s\n",lib); + if (!handle) { + err_print(call_where, "Could not open dynamic library: %s.", lib); + return false; + } #ifdef __GNUC__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wpedantic" #endif - void (*fn_ptr)() = dlsym(handle, name); + fn_ptr = dlsym(handle, name); #ifdef __GNUC__ #pragma GCC diagnostic pop #endif - - if (!fn_ptr) { - err_print(call_where, "Could not get function from dynamic library: %s.", name); - return false; + + if (!fn_ptr) { + err_print(call_where, "Could not get function from dynamic library: %s.", name); + return false; + } + fn->foreign.fn_ptr = fn_ptr; } av_alist arg_list; @@ -260,7 +265,6 @@ static bool foreign_call(FnExpr *fn, Type *fn_type, Value *args, Location call_w (void)fn_type; (void)args; - dlclose(handle); return true; } @@ -5,29 +5,25 @@ import ::= fn(x :: []char) &Package { p_ptr }; -puts :: fn(&char) i32 = #foreign "puts", "libc.so.6"; -dprintf :: fn(i32, &char, f64) i32 = #foreign "dprintf", "libc.so.6"; +cputs :: fn(&char) i32 = #foreign "puts", "libc.so.6"; -hw ::= fn() i32 { - s := "Hello, world!\0"; - puts(&s[0]) +puts ::= fn(s: []char) i32 { + cstr := new(char, s.len + 1); + each i := 0..s.len-1 { + cstr[i] = s[i]; + } + cstr[s.len] = '\0'; + ret := cputs(&cstr[0]); + del(cstr); + ret }; - -sqrt :: fn(f64) f64 = #foreign "sqrt", "libm.so.6"; - foo ::= fn() i32 { - x := sqrt(2.0); - s := "sqrt(2) = %f\n\0"; - dprintf(2, &s[0], x) + puts("Hi"); + puts("Hello"); + puts("Hey") }; main ::= fn() { - // io ::= import("std/io"); - // io.puts("Hello, world!"); - // hw(); - x ::= hw(); - y ::= foo(); - sqrt2 ::= sqrt(2.0); - // y ::= abort_1(); + x ::= foo(); };
\ No newline at end of file @@ -2236,11 +2236,13 @@ static bool types_decl(Typer *tr, Declaration *d) { /* make sure no one tries to use these */ d->foreign.name = NULL; d->foreign.lib = NULL; + FnExpr *f = d->val.fn = typer_calloc(tr, 1, sizeof *d->expr.fn); f->flags = FN_EXPR_FOREIGN; f->where = d->expr.where = d->where; f->foreign.name = name_cstr; f->foreign.lib = lib_cstr; + f->foreign.fn_ptr = NULL; d->flags |= DECL_FOUND_VAL; } @@ -620,6 +620,7 @@ typedef struct FnExpr { struct { const char *name; const char *lib; + void (*fn_ptr)(); } foreign; }; HashTable instances; /* for fns with constant parameters. the key is a tuple where |