+added fork functions.

This commit is contained in:
Wang Renxin 2017-05-08 20:59:28 +08:00
parent e0312fa4af
commit e21aad249b
4 changed files with 143 additions and 13 deletions

View File

@ -1,4 +1,5 @@
May. 8 2017
Added fork functions
Added a global alive object checker
May. 7 2017

Binary file not shown.

View File

@ -819,6 +819,10 @@ typedef struct _tuple3_t {
typedef struct mb_interpreter_t {
/** Fundamental */
#ifdef MB_ENABLE_FORK
struct mb_interpreter_t* from;
_running_context_t* forked_context;
#endif /* MB_ENABLE_FORK */
bool_t valid;
void* userdata;
_ls_node_t* ast;
@ -6079,9 +6083,18 @@ static bool_t _weak_unref(_ref_t* weak) {
/* Create a reference stub, initialize the reference count with zero */
static void _create_ref(_ref_t* ref, _unref_func_t dtor, _data_e t, mb_interpreter_t* s) {
#ifdef MB_ENABLE_FORK
mb_interpreter_t* src = 0;
#endif /* MB_ENABLE_FORK */
if(ref->count)
return;
#ifdef MB_ENABLE_FORK
while(mb_get_forked_from(s, &src) == MB_FUNC_OK)
s = src;
#endif /* MB_ENABLE_FORK */
ref->count = (_ref_count_t*)mb_malloc(sizeof(_ref_count_t));
*ref->count = _NONE_REF;
ref->weak_count = (_ref_count_t*)mb_malloc(sizeof(_ref_count_t));
@ -6294,7 +6307,7 @@ static int _gc_destroy_garbage_in_list(void* data, void* extra, _gc_t* gc) {
mb_assert(data);
obj = (_object_t*)data;
_ADDGC(obj, gc);
_ADDGC(obj, gc)
safe_free(obj);
return result;
@ -6308,11 +6321,11 @@ static int _gc_destroy_garbage_in_dict(void* data, void* extra, _gc_t* gc) {
mb_assert(data);
obj = (_object_t*)data;
_ADDGC(obj, gc);
_ADDGC(obj, gc)
safe_free(obj);
obj = (_object_t*)extra;
_ADDGC(obj, gc);
_ADDGC(obj, gc)
safe_free(obj);
return result;
@ -6333,7 +6346,7 @@ static int _gc_destroy_garbage_in_class(void* data, void* extra, _gc_t* gc) {
safe_free(obj->data.variable->name);
safe_free(obj->data.variable);
} else {
_ADDGC(obj, gc);
_ADDGC(obj, gc)
}
safe_free(obj);
@ -6364,7 +6377,7 @@ static int _gc_destroy_garbage_in_lambda(void* data, void* extra, _gc_t* gc) {
safe_free(obj->data.variable->name);
safe_free(obj->data.variable);
} else {
_ADDGC(obj, gc);
_ADDGC(obj, gc)
}
safe_free(obj);
@ -9904,7 +9917,7 @@ static void _destroy_var_arg(void* data, void* extra, _gc_t* gc) {
mb_assert(data);
obj = (_object_t*)data;
_UNREF(obj);
_UNREF(obj)
safe_free(obj);
}
@ -11242,11 +11255,16 @@ int mb_open(struct mb_interpreter_t** s) {
int mb_close(struct mb_interpreter_t** s) {
_ht_node_t* local_scope = 0;
_ht_node_t* global_scope = 0;
_ls_node_t* ast;
_ls_node_t* ast = 0;
if(!s || !(*s))
return MB_FUNC_ERR;
#ifdef MB_ENABLE_FORK
if((*s)->from)
return mb_close_forked(s);
#endif /* MB_ENABLE_FORK */
(*s)->valid = false;
#ifdef MB_ENABLE_COLLECTION_LIB
@ -11370,6 +11388,109 @@ int mb_reset(struct mb_interpreter_t** s, bool_t clrf) {
return result;
}
/* Fork a new MY-BASIC environment */
int mb_fork(struct mb_interpreter_t** s, struct mb_interpreter_t* r) {
#ifdef MB_ENABLE_FORK
int result = MB_FUNC_OK;
_running_context_t* running = 0;
if(!s || !r)
return MB_FUNC_ERR;
*s = (mb_interpreter_t*)mb_malloc(sizeof(mb_interpreter_t));
memcpy(*s, r, sizeof(mb_interpreter_t));
(*s)->edge_destroy_objects = _ls_create();
(*s)->lazy_destroy_objects = _ls_create();
running = _create_running_context(true);
running->meta = _SCOPE_META_ROOT;
(*s)->forked_context = (*s)->running_context = running;
running->prev = r->running_context;
(*s)->var_args = 0;
#ifdef MB_ENABLE_STACK_TRACE
(*s)->stack_frames = _ls_create();
#endif /* MB_ENABLE_STACK_TRACE */
#ifdef _MULTILINE_STATEMENT
(*s)->multiline_enabled = _ls_create();
#endif /* _MULTILINE_STATEMENT */
(*s)->from = r;
mb_assert(MB_FUNC_OK == result);
return result;
#else /* MB_ENABLE_FORK */
mb_unrefvar(s);
mb_unrefvar(r);
return MB_FUNC_ERR;
#endif /* MB_ENABLE_FORK */
}
/* Close a forked MY-BASIC environment */
int mb_close_forked(struct mb_interpreter_t** s) {
#ifdef MB_ENABLE_FORK
int result = MB_FUNC_OK;
mb_interpreter_t* src = 0;
if(!s || !(*s) || !(*s)->from)
return MB_FUNC_ERR;
(*s)->valid = false;
#ifdef MB_ENABLE_STACK_TRACE
_ls_destroy((*s)->stack_frames);
#endif /* MB_ENABLE_STACK_TRACE */
#ifdef _MULTILINE_STATEMENT
_ls_destroy((*s)->multiline_enabled);
#endif /* _MULTILINE_STATEMENT */
src = *s;
while(mb_get_forked_from(src, &src) == MB_FUNC_OK) { }
if(!src->valid)
(*s)->running_context = (*s)->forked_context;
(*s)->running_context->prev = 0;
_dispose_scope_chain(*s);
_ls_foreach((*s)->edge_destroy_objects, _destroy_object);
_ls_destroy((*s)->edge_destroy_objects);
_ls_foreach((*s)->lazy_destroy_objects, _destroy_object);
_ls_destroy((*s)->lazy_destroy_objects);
safe_free(*s);
return result;
#else /* MB_ENABLE_FORK */
mb_unrefvar(s);
return MB_FUNC_ERR;
#endif /* MB_ENABLE_FORK */
}
/* Get the source MY-BASIC environment of a forked one */
int mb_get_forked_from(struct mb_interpreter_t* s, struct mb_interpreter_t** src) {
#ifdef MB_ENABLE_FORK
int result = MB_FUNC_OK;
if(!s || !src)
result = MB_FUNC_ERR;
else if(s->from == 0)
result = MB_FUNC_ERR;
else
*src = s->from;
return result;
#else /* MB_ENABLE_FORK */
mb_unrefvar(s);
mb_unrefvar(src);
return MB_FUNC_ERR;
#endif /* MB_ENABLE_FORK */
}
/* Register an API function to a MY-BASIC environment */
int mb_register_func(struct mb_interpreter_t* s, const char* n, mb_func_t f) {
if(!s || !n || !f) return MB_FUNC_ERR;
@ -12690,7 +12811,7 @@ int mb_ref_value(struct mb_interpreter_t* s, void** l, mb_value_t val) {
) {
_handle_error_on_obj(s, SE_RN_REFERENCED_TYPE_EXPECTED, s->source_file, DON2(l), MB_FUNC_ERR, _exit, result);
}
_REF(&obj);
_REF(&obj)
_exit:
return result;
@ -12724,7 +12845,7 @@ int mb_unref_value(struct mb_interpreter_t* s, void** l, mb_value_t val) {
) {
_handle_error_on_obj(s, SE_RN_REFERENCED_TYPE_EXPECTED, s->source_file, DON2(l), MB_FUNC_ERR, _exit, result);
}
_UNREF(&obj);
_UNREF(&obj)
_exit:
return result;
@ -12976,7 +13097,7 @@ int mb_eval_routine(struct mb_interpreter_t* s, void** l, mb_value_t val, mb_val
_assign_public_value(ret, &running->intermediate_value);
_MAKE_NIL(&obj);
_public_value_to_internal_object(ret, &obj);
_ADDGC(&obj, &s->gc);
_ADDGC(&obj, &s->gc)
}
_exit:
@ -15202,7 +15323,7 @@ static int _core_args(mb_interpreter_t* s, void** l) {
mb_make_nil(arg);
_internal_object_to_public_value(obj, &arg);
mb_check(mb_push_value(s, l, arg));
_UNREF(obj);
_UNREF(obj)
pushed = true;
_destroy_object_capsule_only(obj, 0);
}
@ -16849,8 +16970,8 @@ static int _std_print(mb_interpreter_t* s, void** l) {
case _DT_FUNC: /* Fall through */
case _DT_ROUTINE:
result = _calc_expression(s, &ast, &val_ptr);
_REF(val_ptr);
_UNREF(val_ptr);
_REF(val_ptr)
_UNREF(val_ptr)
_print:
if(val_ptr->type == _DT_NIL) {
_get_printer(s)(MB_NIL);

View File

@ -149,6 +149,10 @@ extern "C" {
# endif
#endif /* MB_ENABLE_UNICODE_ID */
#ifndef MB_ENABLE_FORK
# define MB_ENABLE_FORK
#endif /* MB_ENABLE_FORK */
#ifndef MB_GC_GARBAGE_THRESHOLD
# define MB_GC_GARBAGE_THRESHOLD 16
#endif /* MB_GC_GARBAGE_THRESHOLD */
@ -579,6 +583,10 @@ MBAPI int mb_open(struct mb_interpreter_t** s);
MBAPI int mb_close(struct mb_interpreter_t** s);
MBAPI int mb_reset(struct mb_interpreter_t** s, bool_t clrf/* = false*/);
MBAPI int mb_fork(struct mb_interpreter_t** s, struct mb_interpreter_t* r);
MBAPI int mb_close_forked(struct mb_interpreter_t** s);
MBAPI int mb_get_forked_from(struct mb_interpreter_t* s, struct mb_interpreter_t** src);
MBAPI int mb_register_func(struct mb_interpreter_t* s, const char* n, mb_func_t f);
MBAPI int mb_remove_func(struct mb_interpreter_t* s, const char* n);
MBAPI int mb_remove_reserved_func(struct mb_interpreter_t* s, const char* n);