mirror of
https://github.com/janet-lang/janet
synced 2024-11-28 11:09:54 +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:
parent
212479188a
commit
70c8b6838d
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user