mirror of
				https://github.com/janet-lang/janet
				synced 2025-10-31 15:43:01 +00:00 
			
		
		
		
	Use make-image-dict and load-image-dict in thread/new
Rather than messing with janet_core_dictionary, we instead cache the core enevironment, and pull out the needed tables from there. This is more flexible, more correct, and also exposes janet_resolve_core, which can be easily used from the C API.
This commit is contained in:
		| @@ -2068,17 +2068,6 @@ | ||||
|   [& modules] | ||||
|   ~(do ,;(map (fn [x] ~(,import* ,(string x) :prefix "")) modules))) | ||||
|  | ||||
| ### | ||||
| ### | ||||
| ### Thread Extras | ||||
| ### | ||||
| ### | ||||
|  | ||||
| (defn thread/new | ||||
|   "Create a new thread. Same as (thread/new-ext make-image-dict load-image-dict)." | ||||
|   [] | ||||
|   (thread/new-ext make-image-dict load-image-dict)) | ||||
|  | ||||
| ### | ||||
| ### | ||||
| ### REPL | ||||
|   | ||||
| @@ -983,12 +983,6 @@ static void janet_load_libs(JanetTable *env) { | ||||
|  | ||||
| #ifdef JANET_BOOTSTRAP | ||||
|  | ||||
| JanetTable *janet_core_dictionary(JanetTable *replacements) { | ||||
|     (void) replacements; | ||||
|     janet_panic("not defined in bootstrap"); | ||||
|     return NULL; | ||||
| } | ||||
|  | ||||
| JanetTable *janet_core_env(JanetTable *replacements) { | ||||
|     JanetTable *env = (NULL != replacements) ? replacements : janet_table(0); | ||||
|     janet_quick_asm(env, JANET_FUN_PROP, | ||||
| @@ -1147,41 +1141,43 @@ JanetTable *janet_core_env(JanetTable *replacements) { | ||||
|  | ||||
| #else | ||||
|  | ||||
| JanetTable *janet_core_dictionary(JanetTable *replacements) { | ||||
|     JanetTable *dict; | ||||
|     if (NULL == janet_vm_core_dictionary) { | ||||
|         dict = janet_table(0); | ||||
|         janet_load_libs(dict); | ||||
|         janet_vm_core_dictionary = dict; | ||||
|         janet_gcroot(janet_wrap_table(dict)); | ||||
|         /* do replacements */ | ||||
|         if (NULL != replacements) { | ||||
|             for (int32_t i = 0; i < replacements->capacity; i++) { | ||||
|                 if (!janet_checktype(replacements->data[i].key, JANET_NIL)) { | ||||
|                     const JanetKV *kv = replacements->data + i; | ||||
|                     janet_table_put(dict, kv->key, kv->value); | ||||
|                     if (janet_checktype(kv->value, JANET_CFUNCTION)) { | ||||
|                         janet_table_put(janet_vm_registry, kv->value, kv->key); | ||||
|                     } | ||||
| JanetTable *janet_core_env(JanetTable *replacements) { | ||||
|     /* Memoize core env, ignoring replacements the second time around. */ | ||||
|     if (NULL != janet_vm_core_env) { | ||||
|         return janet_vm_core_env; | ||||
|     } | ||||
|  | ||||
|     /* Load core cfunctions (and some built in janet assembly functions) */ | ||||
|     JanetTable *dict = janet_table(300); | ||||
|     janet_load_libs(dict); | ||||
|  | ||||
|     /* Add replacements */ | ||||
|     if (replacements != NULL) { | ||||
|         for (int32_t i = 0; i < replacements->capacity; i++) { | ||||
|             JanetKV kv = replacements->data[i]; | ||||
|             if (!janet_checktype(kv.key, JANET_NIL)) { | ||||
|                 janet_table_put(dict, kv.key, kv.value); | ||||
|                 if (janet_checktype(kv.value, JANET_CFUNCTION)) { | ||||
|                     janet_table_put(janet_vm_registry, kv.value, kv.key); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } else { | ||||
|         dict = janet_vm_core_dictionary; | ||||
|     } | ||||
|     return dict; | ||||
| } | ||||
|  | ||||
| JanetTable *janet_core_env(JanetTable *replacements) { | ||||
|     JanetTable *dict = janet_core_dictionary(replacements); | ||||
|     /* Unmarshal bytecode */ | ||||
|     Janet marsh_out = janet_unmarshal( | ||||
|                           janet_core_image, | ||||
|                           janet_core_image_size, | ||||
|                           0, | ||||
|                           dict, | ||||
|                           NULL); | ||||
|  | ||||
|     /* Memoize */ | ||||
|     janet_gcroot(marsh_out); | ||||
|     return janet_unwrap_table(marsh_out); | ||||
|     JanetTable *env = janet_unwrap_table(marsh_out); | ||||
|     janet_vm_core_env = env; | ||||
|  | ||||
|     return env; | ||||
| } | ||||
|  | ||||
| #endif | ||||
|   | ||||
| @@ -32,8 +32,8 @@ | ||||
|  * be in it. However, thread local global variables for interpreter | ||||
|  * state should allow easy multi-threading. */ | ||||
|  | ||||
| /* The core dictionary is memoized */ | ||||
| extern JANET_THREAD_LOCAL JanetTable *janet_vm_core_dictionary; | ||||
| /* Cache the core environment */ | ||||
| extern JANET_THREAD_LOCAL JanetTable *janet_vm_core_env; | ||||
|  | ||||
| /* How many VM stacks have been entered */ | ||||
| extern JANET_THREAD_LOCAL int janet_vm_stackn; | ||||
|   | ||||
| @@ -32,6 +32,15 @@ | ||||
| #include <pthread.h> | ||||
| #include <setjmp.h> | ||||
|  | ||||
| static JanetTable *janet_get_core_table(const char *name) { | ||||
|     JanetTable *env = janet_core_env(NULL); | ||||
|     Janet out = janet_wrap_nil(); | ||||
|     JanetBindingType bt = janet_resolve(env, janet_csymbol(name), &out); | ||||
|     if (bt == JANET_BINDING_NONE) return NULL; | ||||
|     if (!janet_checktype(out, JANET_TABLE)) return NULL; | ||||
|     return janet_unwrap_table(out); | ||||
| } | ||||
|  | ||||
| static void janet_channel_init(JanetChannel *channel, size_t initialSize) { | ||||
|     janet_buffer_init(&channel->buf, (int32_t) initialSize); | ||||
|     pthread_mutex_init(&channel->lock, NULL); | ||||
| @@ -212,20 +221,11 @@ static int thread_worker(JanetThreadShared *shared) { | ||||
|     janet_init(); | ||||
|  | ||||
|     /* Get dictionaries */ | ||||
|     JanetTable *decode = janet_core_dictionary(NULL); | ||||
|     JanetTable *encode = janet_table(decode->count); | ||||
|     for (int32_t i = 0; i < decode->capacity; i++) { | ||||
|         JanetKV *kv = decode->data + i; | ||||
|         if (!janet_checktype(kv->key, JANET_NIL)) { | ||||
|             janet_table_put(encode, kv->value, kv->key); | ||||
|         } | ||||
|     } | ||||
|     janet_gcroot(janet_wrap_table(encode)); | ||||
|     JanetTable *decode = janet_get_core_table("load-image-dict"); | ||||
|     JanetTable *encode = janet_get_core_table("make-image-dict"); | ||||
|  | ||||
|     /* Create self thread */ | ||||
|     JanetThread *thread = janet_make_thread(shared, encode, decode, JANET_THREAD_SELF); | ||||
|     thread->encode = encode; | ||||
|     thread->decode = decode; | ||||
|     Janet threadv = janet_wrap_abstract(thread); | ||||
|  | ||||
|     /* Unmarshal the function */ | ||||
| @@ -275,10 +275,14 @@ static void janet_thread_start_child(JanetThread *thread) { | ||||
|  * Cfuns | ||||
|  */ | ||||
|  | ||||
| static Janet cfun_thread_new_ext(int32_t argc, Janet *argv) { | ||||
|     janet_fixarity(argc, 2); | ||||
|     JanetTable *encode = janet_gettable(argv, 0); | ||||
|     JanetTable *decode = janet_gettable(argv, 1); | ||||
| static Janet cfun_thread_new(int32_t argc, Janet *argv) { | ||||
|     janet_arity(argc, 0, 2); | ||||
|     JanetTable *encode = (argc < 1 || janet_checktype(argv[0], JANET_NIL)) | ||||
|                          ? janet_get_core_table("make-image-dict") | ||||
|                          : janet_gettable(argv, 0); | ||||
|     JanetTable *decode = (argc < 2 || janet_checktype(argv[1], JANET_NIL)) | ||||
|                          ? janet_get_core_table("load-image-dict") | ||||
|                          : janet_gettable(argv, 1); | ||||
|     JanetThreadShared *shared = janet_shared_create(0); | ||||
|     JanetThread *thread = janet_make_thread(shared, encode, decode, JANET_THREAD_OTHER); | ||||
|     janet_thread_start_child(thread); | ||||
| @@ -316,8 +320,8 @@ static Janet cfun_thread_receive(int32_t argc, Janet *argv) { | ||||
|  | ||||
| static const JanetReg threadlib_cfuns[] = { | ||||
|     { | ||||
|         "thread/new-ext", cfun_thread_new_ext, | ||||
|         JDOC("(thread/new-ext encode-book decode-book)\n\n" | ||||
|         "thread/new", cfun_thread_new, | ||||
|         JDOC("(thread/new &opt encode-book decode-book)\n\n" | ||||
|              "Start a new thread. The thread will wait for a message containing the function used to start the thread, which should be subsequently " | ||||
|              "sent over after thread creation.") | ||||
|     }, | ||||
|   | ||||
| @@ -370,6 +370,14 @@ JanetBindingType janet_resolve(JanetTable *env, const uint8_t *sym, Janet *out) | ||||
|     return JANET_BINDING_DEF; | ||||
| } | ||||
|  | ||||
| /* Resolve a symbol in the core environment. */ | ||||
| Janet janet_resolve_core(const char *name) { | ||||
|     JanetTable *env = janet_core_env(NULL); | ||||
|     Janet out = janet_wrap_nil(); | ||||
|     janet_resolve(env, janet_csymbol(name), &out); | ||||
|     return out; | ||||
| } | ||||
|  | ||||
| /* Read both tuples and arrays as c pointers + int32_t length. Return 1 if the | ||||
|  * view can be constructed, 0 if an invalid type. */ | ||||
| int janet_indexed_view(Janet seq, const Janet **data, int32_t *len) { | ||||
|   | ||||
| @@ -30,7 +30,7 @@ | ||||
| #endif | ||||
|  | ||||
| /* VM state */ | ||||
| JANET_THREAD_LOCAL JanetTable *janet_vm_core_dictionary; | ||||
| JANET_THREAD_LOCAL JanetTable *janet_vm_core_env; | ||||
| JANET_THREAD_LOCAL JanetTable *janet_vm_registry; | ||||
| JANET_THREAD_LOCAL int janet_vm_stackn = 0; | ||||
| JANET_THREAD_LOCAL JanetFiber *janet_vm_fiber = NULL; | ||||
| @@ -1241,8 +1241,8 @@ int janet_init(void) { | ||||
|     /* Initialize registry */ | ||||
|     janet_vm_registry = janet_table(0); | ||||
|     janet_gcroot(janet_wrap_table(janet_vm_registry)); | ||||
|     /* Core env and dictionary */ | ||||
|     janet_vm_core_dictionary = NULL; | ||||
|     /* Core env */ | ||||
|     janet_vm_core_env = NULL; | ||||
|     /* Seed RNG */ | ||||
|     janet_rng_seed(janet_default_rng(), 0); | ||||
|     return 0; | ||||
| @@ -1257,5 +1257,5 @@ void janet_deinit(void) { | ||||
|     janet_vm_root_count = 0; | ||||
|     janet_vm_root_capacity = 0; | ||||
|     janet_vm_registry = NULL; | ||||
|     janet_vm_core_dictionary = NULL; | ||||
|     janet_vm_core_env = NULL; | ||||
| } | ||||
|   | ||||
| @@ -1126,7 +1126,6 @@ struct JanetCompileResult { | ||||
| JANET_API JanetCompileResult janet_compile(Janet source, JanetTable *env, const uint8_t *where); | ||||
|  | ||||
| /* Get the default environment for janet */ | ||||
| JANET_API JanetTable *janet_core_dictionary(JanetTable *replacements); /* Used for unmarshaling images */ | ||||
| JANET_API JanetTable *janet_core_env(JanetTable *replacements); | ||||
|  | ||||
| JANET_API int janet_dobytes(JanetTable *env, const uint8_t *bytes, int32_t len, const char *sourcePath, Janet *out); | ||||
| @@ -1359,6 +1358,9 @@ JANET_API void janet_cfuns(JanetTable *env, const char *regprefix, const JanetRe | ||||
| JANET_API JanetBindingType janet_resolve(JanetTable *env, const uint8_t *sym, Janet *out); | ||||
| JANET_API void janet_register(const char *name, JanetCFunction cfun); | ||||
|  | ||||
| /* Get values from the core environment. */ | ||||
| JANET_API Janet janet_resolve_core(const char *name); | ||||
|  | ||||
| /* New C API */ | ||||
|  | ||||
| /* Allow setting entry name for static libraries */ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Calvin Rose
					Calvin Rose