diff --git a/include/cyclone/runtime.h b/include/cyclone/runtime.h index f62cd9f6..706275ef 100644 --- a/include/cyclone/runtime.h +++ b/include/cyclone/runtime.h @@ -649,6 +649,16 @@ object find_or_add_symbol(const char *name); char *_strdup(const char *s); /**@}*/ +/** + * \defgroup prim_glo Library table + * + * @brief A table of scheme libraries that are loaded. + */ +/**@{*/ +object is_library_loaded(const char *name); +object register_library(const char *name); +/**@}*/ + /** * \defgroup prim_glo Global table * diff --git a/runtime.c b/runtime.c index d4316f00..945d3b1d 100644 --- a/runtime.c +++ b/runtime.c @@ -148,6 +148,7 @@ char **_cyc_argv = NULL; static symbol_type __EOF = { {0}, eof_tag, ""}; // symbol_type in lieu of custom type const object Cyc_EOF = &__EOF; +static ck_hs_t lib_table; static ck_hs_t symbol_table; static int symbol_table_initial_size = 4096; static pthread_mutex_t symbol_table_lock; @@ -265,6 +266,13 @@ static bool set_insert(ck_hs_t * hs, const void *value) */ void gc_init_heap(long heap_size) { + if (!ck_hs_init(&lib_table, + CK_HS_MODE_OBJECT | CK_HS_MODE_SPMC, + hs_hash, hs_compare, + &my_allocator, 32, 43423)) { + fprintf(stderr, "Unable to initialize library table\n"); + exit(1); + } if (!ck_hs_init(&symbol_table, CK_HS_MODE_OBJECT | CK_HS_MODE_SPMC, hs_hash, hs_compare, @@ -386,6 +394,30 @@ object find_or_add_symbol(const char *name) /* END symbol table */ +/* Library table */ +object is_library_loaded(const char *name) +{ + symbol_type tmp = { {0}, symbol_tag, name}; + object result = set_get(&symbol_table, &tmp); + if (result) + return boolean_t; + return boolean_f; +} + +object register_library(const char *name) +{ + symbol_type sym = { {0}, symbol_tag, _strdup(name)}; + symbol_type *psym = malloc(sizeof(symbol_type)); + memcpy(psym, &sym, sizeof(symbol_type)); + // Reuse mutex since lib inserts will be rare + pthread_mutex_lock(&symbol_table_lock); // Only 1 "writer" allowed + set_insert(&lib_table, psym); + pthread_mutex_unlock(&symbol_table_lock); + return psym; +} +/* END Library table */ + + /* Global table */ list global_table = NULL; diff --git a/scheme/cyclone/cgen.sld b/scheme/cyclone/cgen.sld index 5bfc26fe..f092b223 100644 --- a/scheme/cyclone/cgen.sld +++ b/scheme/cyclone/cgen.sld @@ -1421,6 +1421,9 @@ (emit* "}") (emit* "void c_" (lib:name->string lib-name) "_entry_pt(data, argc, cont,value) void *data; int argc; closure cont; object value;{ ") + (emit* " register_library(\"" + (lib:name->unique-string lib-name) + "\");") (if (null? lib-pass-thru-exports) (emit* " c_" (lib:name->string lib-name) "_entry_pt_first_lambda(data, argc, cont,value);") ; GC to ensure objects are moved when exporting exports. diff --git a/scheme/cyclone/libraries.sld b/scheme/cyclone/libraries.sld index a3650373..da183664 100644 --- a/scheme/cyclone/libraries.sld +++ b/scheme/cyclone/libraries.sld @@ -25,6 +25,7 @@ lib:name lib:name->string lib:name->symbol + lib:name->unique-string lib:result lib:exports lib:rename-exports @@ -119,6 +120,16 @@ (define (lib:name->string name) (apply string-append (map mangle (lib:import->library-name name)))) +;; Convert name (as list of symbols) to a mangled string guaranteed to be unique +(define (lib:name->unique-string name) + (foldl + (lambda (s acc) + (if (> (string-length acc) 0) + (string-append acc "_" s) + s)) + "" + (map mangle (lib:import->library-name name)))) + ;; Convert library name to a unique symbol (define (lib:name->symbol name) (string->symbol diff --git a/scheme/eval.sld b/scheme/eval.sld index 09a507e9..1583e80f 100644 --- a/scheme/eval.sld +++ b/scheme/eval.sld @@ -437,8 +437,8 @@ (define (analyze-import exp env) (lambda (env) - ;; TODO: allow %import to take env - (write `(%import ,(cdr exp))) + ;; FUTURE: allow %import to take env? + ;(write `(%import ,(cdr exp))) (apply %import (cdr exp)) 'ok))