mirror of
https://github.com/janet-lang/janet
synced 2024-11-24 17:27:18 +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]
|
[& 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 */
|
||||||
|
Loading…
Reference in New Issue
Block a user