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] |   [& modules] | ||||||
|   ~(do ,;(map (fn [x] ~(,import* ,(string x) :prefix "")) 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 | ### REPL | ||||||
|   | |||||||
| @@ -983,12 +983,6 @@ static void janet_load_libs(JanetTable *env) { | |||||||
|  |  | ||||||
| #ifdef JANET_BOOTSTRAP | #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 *janet_core_env(JanetTable *replacements) { | ||||||
|     JanetTable *env = (NULL != replacements) ? replacements : janet_table(0); |     JanetTable *env = (NULL != replacements) ? replacements : janet_table(0); | ||||||
|     janet_quick_asm(env, JANET_FUN_PROP, |     janet_quick_asm(env, JANET_FUN_PROP, | ||||||
| @@ -1147,41 +1141,43 @@ JanetTable *janet_core_env(JanetTable *replacements) { | |||||||
|  |  | ||||||
| #else | #else | ||||||
|  |  | ||||||
| JanetTable *janet_core_dictionary(JanetTable *replacements) { | JanetTable *janet_core_env(JanetTable *replacements) { | ||||||
|     JanetTable *dict; |     /* Memoize core env, ignoring replacements the second time around. */ | ||||||
|     if (NULL == janet_vm_core_dictionary) { |     if (NULL != janet_vm_core_env) { | ||||||
|         dict = janet_table(0); |         return janet_vm_core_env; | ||||||
|         janet_load_libs(dict); |     } | ||||||
|         janet_vm_core_dictionary = dict; |  | ||||||
|         janet_gcroot(janet_wrap_table(dict)); |     /* Load core cfunctions (and some built in janet assembly functions) */ | ||||||
|         /* do replacements */ |     JanetTable *dict = janet_table(300); | ||||||
|         if (NULL != replacements) { |     janet_load_libs(dict); | ||||||
|             for (int32_t i = 0; i < replacements->capacity; i++) { |  | ||||||
|                 if (!janet_checktype(replacements->data[i].key, JANET_NIL)) { |     /* Add replacements */ | ||||||
|                     const JanetKV *kv = replacements->data + i; |     if (replacements != NULL) { | ||||||
|                     janet_table_put(dict, kv->key, kv->value); |         for (int32_t i = 0; i < replacements->capacity; i++) { | ||||||
|                     if (janet_checktype(kv->value, JANET_CFUNCTION)) { |             JanetKV kv = replacements->data[i]; | ||||||
|                         janet_table_put(janet_vm_registry, kv->value, kv->key); |             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) { |     /* Unmarshal bytecode */ | ||||||
|     JanetTable *dict = janet_core_dictionary(replacements); |  | ||||||
|     Janet marsh_out = janet_unmarshal( |     Janet marsh_out = janet_unmarshal( | ||||||
|                           janet_core_image, |                           janet_core_image, | ||||||
|                           janet_core_image_size, |                           janet_core_image_size, | ||||||
|                           0, |                           0, | ||||||
|                           dict, |                           dict, | ||||||
|                           NULL); |                           NULL); | ||||||
|  |  | ||||||
|  |     /* Memoize */ | ||||||
|     janet_gcroot(marsh_out); |     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 | #endif | ||||||
|   | |||||||
| @@ -32,8 +32,8 @@ | |||||||
|  * be in it. However, thread local global variables for interpreter |  * be in it. However, thread local global variables for interpreter | ||||||
|  * state should allow easy multi-threading. */ |  * state should allow easy multi-threading. */ | ||||||
|  |  | ||||||
| /* The core dictionary is memoized */ | /* Cache the core environment */ | ||||||
| extern JANET_THREAD_LOCAL JanetTable *janet_vm_core_dictionary; | extern JANET_THREAD_LOCAL JanetTable *janet_vm_core_env; | ||||||
|  |  | ||||||
| /* How many VM stacks have been entered */ | /* How many VM stacks have been entered */ | ||||||
| extern JANET_THREAD_LOCAL int janet_vm_stackn; | extern JANET_THREAD_LOCAL int janet_vm_stackn; | ||||||
|   | |||||||
| @@ -32,6 +32,15 @@ | |||||||
| #include <pthread.h> | #include <pthread.h> | ||||||
| #include <setjmp.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) { | static void janet_channel_init(JanetChannel *channel, size_t initialSize) { | ||||||
|     janet_buffer_init(&channel->buf, (int32_t) initialSize); |     janet_buffer_init(&channel->buf, (int32_t) initialSize); | ||||||
|     pthread_mutex_init(&channel->lock, NULL); |     pthread_mutex_init(&channel->lock, NULL); | ||||||
| @@ -212,20 +221,11 @@ static int thread_worker(JanetThreadShared *shared) { | |||||||
|     janet_init(); |     janet_init(); | ||||||
|  |  | ||||||
|     /* Get dictionaries */ |     /* Get dictionaries */ | ||||||
|     JanetTable *decode = janet_core_dictionary(NULL); |     JanetTable *decode = janet_get_core_table("load-image-dict"); | ||||||
|     JanetTable *encode = janet_table(decode->count); |     JanetTable *encode = janet_get_core_table("make-image-dict"); | ||||||
|     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)); |  | ||||||
|  |  | ||||||
|     /* Create self thread */ |     /* Create self thread */ | ||||||
|     JanetThread *thread = janet_make_thread(shared, encode, decode, JANET_THREAD_SELF); |     JanetThread *thread = janet_make_thread(shared, encode, decode, JANET_THREAD_SELF); | ||||||
|     thread->encode = encode; |  | ||||||
|     thread->decode = decode; |  | ||||||
|     Janet threadv = janet_wrap_abstract(thread); |     Janet threadv = janet_wrap_abstract(thread); | ||||||
|  |  | ||||||
|     /* Unmarshal the function */ |     /* Unmarshal the function */ | ||||||
| @@ -275,10 +275,14 @@ static void janet_thread_start_child(JanetThread *thread) { | |||||||
|  * Cfuns |  * Cfuns | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
| static Janet cfun_thread_new_ext(int32_t argc, Janet *argv) { | static Janet cfun_thread_new(int32_t argc, Janet *argv) { | ||||||
|     janet_fixarity(argc, 2); |     janet_arity(argc, 0, 2); | ||||||
|     JanetTable *encode = janet_gettable(argv, 0); |     JanetTable *encode = (argc < 1 || janet_checktype(argv[0], JANET_NIL)) | ||||||
|     JanetTable *decode = janet_gettable(argv, 1); |                          ? 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); |     JanetThreadShared *shared = janet_shared_create(0); | ||||||
|     JanetThread *thread = janet_make_thread(shared, encode, decode, JANET_THREAD_OTHER); |     JanetThread *thread = janet_make_thread(shared, encode, decode, JANET_THREAD_OTHER); | ||||||
|     janet_thread_start_child(thread); |     janet_thread_start_child(thread); | ||||||
| @@ -316,8 +320,8 @@ static Janet cfun_thread_receive(int32_t argc, Janet *argv) { | |||||||
|  |  | ||||||
| static const JanetReg threadlib_cfuns[] = { | static const JanetReg threadlib_cfuns[] = { | ||||||
|     { |     { | ||||||
|         "thread/new-ext", cfun_thread_new_ext, |         "thread/new", cfun_thread_new, | ||||||
|         JDOC("(thread/new-ext encode-book decode-book)\n\n" |         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 " |              "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.") |              "sent over after thread creation.") | ||||||
|     }, |     }, | ||||||
|   | |||||||
| @@ -370,6 +370,14 @@ JanetBindingType janet_resolve(JanetTable *env, const uint8_t *sym, Janet *out) | |||||||
|     return JANET_BINDING_DEF; |     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 | /* Read both tuples and arrays as c pointers + int32_t length. Return 1 if the | ||||||
|  * view can be constructed, 0 if an invalid type. */ |  * view can be constructed, 0 if an invalid type. */ | ||||||
| int janet_indexed_view(Janet seq, const Janet **data, int32_t *len) { | int janet_indexed_view(Janet seq, const Janet **data, int32_t *len) { | ||||||
|   | |||||||
| @@ -30,7 +30,7 @@ | |||||||
| #endif | #endif | ||||||
|  |  | ||||||
| /* VM state */ | /* 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 JanetTable *janet_vm_registry; | ||||||
| JANET_THREAD_LOCAL int janet_vm_stackn = 0; | JANET_THREAD_LOCAL int janet_vm_stackn = 0; | ||||||
| JANET_THREAD_LOCAL JanetFiber *janet_vm_fiber = NULL; | JANET_THREAD_LOCAL JanetFiber *janet_vm_fiber = NULL; | ||||||
| @@ -1241,8 +1241,8 @@ int janet_init(void) { | |||||||
|     /* Initialize registry */ |     /* Initialize registry */ | ||||||
|     janet_vm_registry = janet_table(0); |     janet_vm_registry = janet_table(0); | ||||||
|     janet_gcroot(janet_wrap_table(janet_vm_registry)); |     janet_gcroot(janet_wrap_table(janet_vm_registry)); | ||||||
|     /* Core env and dictionary */ |     /* Core env */ | ||||||
|     janet_vm_core_dictionary = NULL; |     janet_vm_core_env = NULL; | ||||||
|     /* Seed RNG */ |     /* Seed RNG */ | ||||||
|     janet_rng_seed(janet_default_rng(), 0); |     janet_rng_seed(janet_default_rng(), 0); | ||||||
|     return 0; |     return 0; | ||||||
| @@ -1257,5 +1257,5 @@ void janet_deinit(void) { | |||||||
|     janet_vm_root_count = 0; |     janet_vm_root_count = 0; | ||||||
|     janet_vm_root_capacity = 0; |     janet_vm_root_capacity = 0; | ||||||
|     janet_vm_registry = NULL; |     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); | JANET_API JanetCompileResult janet_compile(Janet source, JanetTable *env, const uint8_t *where); | ||||||
|  |  | ||||||
| /* Get the default environment for janet */ | /* 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 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); | 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 JanetBindingType janet_resolve(JanetTable *env, const uint8_t *sym, Janet *out); | ||||||
| JANET_API void janet_register(const char *name, JanetCFunction cfun); | 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 */ | /* New C API */ | ||||||
|  |  | ||||||
| /* Allow setting entry name for static libraries */ | /* Allow setting entry name for static libraries */ | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Calvin Rose
					Calvin Rose