+added a checking step for alive objects in all forked environment.
This commit is contained in:
parent
46a450da20
commit
18b00672ed
3
HISTORY
3
HISTORY
@ -1,3 +1,6 @@
|
|||||||
|
Nov. 15 2017
|
||||||
|
Added a checking step for alive objects in all forked environment
|
||||||
|
|
||||||
Nov. 13 2017
|
Nov. 13 2017
|
||||||
Fixed an extended abort issue
|
Fixed an extended abort issue
|
||||||
Fixed a crash bug with routine
|
Fixed a crash bug with routine
|
||||||
|
Binary file not shown.
148
core/my_basic.c
148
core/my_basic.c
@ -221,13 +221,13 @@ extern "C" {
|
|||||||
#define _OP_RESULT_NORMAL 0
|
#define _OP_RESULT_NORMAL 0
|
||||||
#define _OP_RESULT_DEL_NODE -1
|
#define _OP_RESULT_DEL_NODE -1
|
||||||
|
|
||||||
typedef int (* _common_compare)(void*, void*);
|
typedef int (* _common_compare_t)(void*, void*);
|
||||||
typedef int (* _common_operation)(void*, void*);
|
typedef int (* _common_operation_t)(void*, void*);
|
||||||
|
|
||||||
/** List */
|
/** List */
|
||||||
|
|
||||||
typedef _common_compare _ls_compare;
|
typedef _common_compare_t _ls_compare_t;
|
||||||
typedef _common_operation _ls_operation;
|
typedef _common_operation_t _ls_operation_t;
|
||||||
|
|
||||||
typedef struct _ls_node_t {
|
typedef struct _ls_node_t {
|
||||||
void* data;
|
void* data;
|
||||||
@ -238,14 +238,14 @@ typedef struct _ls_node_t {
|
|||||||
|
|
||||||
/** Dictionary */
|
/** Dictionary */
|
||||||
|
|
||||||
typedef unsigned (* _ht_hash)(void*, void*);
|
typedef unsigned (* _ht_hash_t)(void*, void*);
|
||||||
typedef _common_compare _ht_compare;
|
typedef _common_compare_t _ht_compare_t;
|
||||||
typedef _common_operation _ht_operation;
|
typedef _common_operation_t _ht_operation_t;
|
||||||
|
|
||||||
typedef struct _ht_node_t {
|
typedef struct _ht_node_t {
|
||||||
_ls_operation free_extra;
|
_ls_operation_t free_extra;
|
||||||
_ht_compare compare;
|
_ht_compare_t compare;
|
||||||
_ht_hash hash;
|
_ht_hash_t hash;
|
||||||
unsigned array_size;
|
unsigned array_size;
|
||||||
unsigned count;
|
unsigned count;
|
||||||
_ls_node_t** array;
|
_ls_node_t** array;
|
||||||
@ -445,7 +445,7 @@ typedef struct _usertype_ref_t {
|
|||||||
mb_cmp_func_t cmp;
|
mb_cmp_func_t cmp;
|
||||||
mb_fmt_func_t fmt;
|
mb_fmt_func_t fmt;
|
||||||
#ifdef MB_ENABLE_ALIVE_CHECKING_ON_USERTYPE_REF
|
#ifdef MB_ENABLE_ALIVE_CHECKING_ON_USERTYPE_REF
|
||||||
mb_alive_value_checker alive_checker;
|
mb_alive_value_checker_t alive_checker;
|
||||||
#endif /* MB_ENABLE_ALIVE_CHECKING_ON_USERTYPE_REF */
|
#endif /* MB_ENABLE_ALIVE_CHECKING_ON_USERTYPE_REF */
|
||||||
_calculation_operator_info_t* calc_operators;
|
_calculation_operator_info_t* calc_operators;
|
||||||
mb_meta_func_t coll_func;
|
mb_meta_func_t coll_func;
|
||||||
@ -861,6 +861,7 @@ typedef struct mb_interpreter_t {
|
|||||||
#ifdef MB_ENABLE_FORK
|
#ifdef MB_ENABLE_FORK
|
||||||
struct mb_interpreter_t* forked_from;
|
struct mb_interpreter_t* forked_from;
|
||||||
_running_context_t* forked_context;
|
_running_context_t* forked_context;
|
||||||
|
_ls_node_t* all_forked;
|
||||||
#endif /* MB_ENABLE_FORK */
|
#endif /* MB_ENABLE_FORK */
|
||||||
bool_t valid _PACK1;
|
bool_t valid _PACK1;
|
||||||
void* userdata;
|
void* userdata;
|
||||||
@ -913,7 +914,7 @@ typedef struct mb_interpreter_t {
|
|||||||
unsigned short last_error_row;
|
unsigned short last_error_row;
|
||||||
unsigned short last_error_col;
|
unsigned short last_error_col;
|
||||||
/** Handlers */
|
/** Handlers */
|
||||||
mb_alive_checker alive_check_handler;
|
mb_alive_checker_t alive_check_handler;
|
||||||
mb_debug_stepped_handler_t debug_stepped_handler;
|
mb_debug_stepped_handler_t debug_stepped_handler;
|
||||||
mb_error_handler_t error_handler;
|
mb_error_handler_t error_handler;
|
||||||
mb_print_func_t printer;
|
mb_print_func_t printer;
|
||||||
@ -1220,17 +1221,17 @@ static int _ls_cmp_module_func(void* node, void* info);
|
|||||||
|
|
||||||
static _ls_node_t* _ls_create_node(void* data);
|
static _ls_node_t* _ls_create_node(void* data);
|
||||||
static _ls_node_t* _ls_create(void);
|
static _ls_node_t* _ls_create(void);
|
||||||
static _ls_node_t* _ls_find(_ls_node_t* list, void* data, _ls_compare cmp, int* idx);
|
static _ls_node_t* _ls_find(_ls_node_t* list, void* data, _ls_compare_t cmp, int* idx);
|
||||||
static _ls_node_t* _ls_back(_ls_node_t* node);
|
static _ls_node_t* _ls_back(_ls_node_t* node);
|
||||||
static _ls_node_t* _ls_pushback(_ls_node_t* list, void* data);
|
static _ls_node_t* _ls_pushback(_ls_node_t* list, void* data);
|
||||||
static void* _ls_popback(_ls_node_t* list);
|
static void* _ls_popback(_ls_node_t* list);
|
||||||
static _ls_node_t* _ls_front(_ls_node_t* node);
|
static _ls_node_t* _ls_front(_ls_node_t* node);
|
||||||
static void* _ls_popfront(_ls_node_t* list);
|
static void* _ls_popfront(_ls_node_t* list);
|
||||||
static _ls_node_t* _ls_insert_at(_ls_node_t* list, int index, void* data);
|
static _ls_node_t* _ls_insert_at(_ls_node_t* list, int index, void* data);
|
||||||
static unsigned _ls_remove(_ls_node_t* list, _ls_node_t* node, _ls_operation op);
|
static unsigned _ls_remove(_ls_node_t* list, _ls_node_t* node, _ls_operation_t op);
|
||||||
static unsigned _ls_try_remove(_ls_node_t* list, void* info, _ls_compare cmp, _ls_operation op);
|
static unsigned _ls_try_remove(_ls_node_t* list, void* info, _ls_compare_t cmp, _ls_operation_t op);
|
||||||
static unsigned _ls_foreach(_ls_node_t* list, _ls_operation op);
|
static unsigned _ls_foreach(_ls_node_t* list, _ls_operation_t op);
|
||||||
static _ls_node_t* _ls_sort(_ls_node_t* _mb_unaligned * list, _ls_compare cmp);
|
static _ls_node_t* _ls_sort(_ls_node_t* _mb_unaligned * list, _ls_compare_t cmp);
|
||||||
static unsigned _ls_count(_ls_node_t* list);
|
static unsigned _ls_count(_ls_node_t* list);
|
||||||
static bool_t _ls_empty(_ls_node_t* list);
|
static bool_t _ls_empty(_ls_node_t* list);
|
||||||
static void _ls_clear(_ls_node_t* list);
|
static void _ls_clear(_ls_node_t* list);
|
||||||
@ -1275,11 +1276,11 @@ static int _ht_cmp_string(void* d1, void* d2);
|
|||||||
static int _ht_cmp_intptr(void* d1, void* d2);
|
static int _ht_cmp_intptr(void* d1, void* d2);
|
||||||
static int _ht_cmp_ref(void* d1, void* d2);
|
static int _ht_cmp_ref(void* d1, void* d2);
|
||||||
|
|
||||||
static _ht_node_t* _ht_create(unsigned size, _ht_compare cmp, _ht_hash hs, _ls_operation freeextra);
|
static _ht_node_t* _ht_create(unsigned size, _ht_compare_t cmp, _ht_hash_t hs, _ls_operation_t freeextra);
|
||||||
static _ls_node_t* _ht_find(_ht_node_t* ht, void* key);
|
static _ls_node_t* _ht_find(_ht_node_t* ht, void* key);
|
||||||
static unsigned _ht_set_or_insert(_ht_node_t* ht, void* key, void* value);
|
static unsigned _ht_set_or_insert(_ht_node_t* ht, void* key, void* value);
|
||||||
static unsigned _ht_remove(_ht_node_t* ht, void* key, _ls_compare cmp);
|
static unsigned _ht_remove(_ht_node_t* ht, void* key, _ls_compare_t cmp);
|
||||||
static unsigned _ht_foreach(_ht_node_t* ht, _ht_operation op);
|
static unsigned _ht_foreach(_ht_node_t* ht, _ht_operation_t op);
|
||||||
static unsigned _ht_count(_ht_node_t* ht);
|
static unsigned _ht_count(_ht_node_t* ht);
|
||||||
static void _ht_clear(_ht_node_t* ht);
|
static void _ht_clear(_ht_node_t* ht);
|
||||||
static void _ht_destroy(_ht_node_t* ht);
|
static void _ht_destroy(_ht_node_t* ht);
|
||||||
@ -1720,7 +1721,10 @@ static void _gc_add(_ref_t* ref, void* data, _gc_t* gc);
|
|||||||
static void _gc_remove(_ref_t* ref, void* data, _gc_t* gc);
|
static void _gc_remove(_ref_t* ref, void* data, _gc_t* gc);
|
||||||
static int _gc_add_reachable(void* data, void* extra, void* h);
|
static int _gc_add_reachable(void* data, void* extra, void* h);
|
||||||
static int _gc_add_reachable_both(void* data, void* extra, void* h);
|
static int _gc_add_reachable_both(void* data, void* extra, void* h);
|
||||||
static void _gc_get_reachable(mb_interpreter_t* s, _ht_node_t* ht);
|
#ifdef MB_ENABLE_FORK
|
||||||
|
static int _gc_get_reachable_in_forked(void* data, void* extra, _ht_node_t* valid);
|
||||||
|
#endif /* MB_ENABLE_FORK */
|
||||||
|
static void _gc_get_reachable(mb_interpreter_t* s, _ht_node_t* ht, _running_context_t* end);
|
||||||
static void _gc_alive_marker(mb_interpreter_t* s, void* h, mb_value_t val);
|
static void _gc_alive_marker(mb_interpreter_t* s, void* h, mb_value_t val);
|
||||||
static int _gc_destroy_garbage_in_list(void* data, void* extra, _gc_t* gc);
|
static int _gc_destroy_garbage_in_list(void* data, void* extra, _gc_t* gc);
|
||||||
static int _gc_destroy_garbage_in_dict(void* data, void* extra, _gc_t* gc);
|
static int _gc_destroy_garbage_in_dict(void* data, void* extra, _gc_t* gc);
|
||||||
@ -1804,14 +1808,14 @@ static int _copy_keys_to_value_array(void* data, void* extra, _keys_helper_t* h)
|
|||||||
#endif /* MB_ENABLE_COLLECTION_LIB */
|
#endif /* MB_ENABLE_COLLECTION_LIB */
|
||||||
|
|
||||||
#ifdef MB_ENABLE_CLASS
|
#ifdef MB_ENABLE_CLASS
|
||||||
typedef int (* _class_scope_walker)(void*, void*, void*);
|
typedef int (* _class_scope_walker_t)(void*, void*, void*);
|
||||||
typedef bool_t (* _class_meta_walker)(_class_t*, void*, void*);
|
typedef bool_t (* _class_meta_walker_t)(_class_t*, void*, void*);
|
||||||
static void _init_class(mb_interpreter_t* s, _class_t* instance, char* n);
|
static void _init_class(mb_interpreter_t* s, _class_t* instance, char* n);
|
||||||
static void _begin_class(mb_interpreter_t* s);
|
static void _begin_class(mb_interpreter_t* s);
|
||||||
static bool_t _end_class(mb_interpreter_t* s);
|
static bool_t _end_class(mb_interpreter_t* s);
|
||||||
static void _unref_class(_ref_t* ref, void* data);
|
static void _unref_class(_ref_t* ref, void* data);
|
||||||
static void _destroy_class(_class_t* c);
|
static void _destroy_class(_class_t* c);
|
||||||
static bool_t _traverse_class(_class_t* c, _class_scope_walker scope_walker, _class_meta_walker meta_walker, unsigned meta_depth, bool_t meta_walk_on_self, void* extra_data, void* ret);
|
static bool_t _traverse_class(_class_t* c, _class_scope_walker_t scope_walker, _class_meta_walker_t meta_walker, unsigned meta_depth, bool_t meta_walk_on_self, void* extra_data, void* ret);
|
||||||
static bool_t _link_meta_class(mb_interpreter_t* s, _class_t* derived, _class_t* base);
|
static bool_t _link_meta_class(mb_interpreter_t* s, _class_t* derived, _class_t* base);
|
||||||
static void _unlink_meta_class(mb_interpreter_t* s, _class_t* derived);
|
static void _unlink_meta_class(mb_interpreter_t* s, _class_t* derived);
|
||||||
static int _unlink_meta_instance(void* data, void* extra, _class_t* derived);
|
static int _unlink_meta_instance(void* data, void* extra, _class_t* derived);
|
||||||
@ -2338,7 +2342,7 @@ static _ls_node_t* _ls_create(void) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static _ls_node_t* _ls_find(_ls_node_t* list, void* data, _ls_compare cmp, int* idx) {
|
static _ls_node_t* _ls_find(_ls_node_t* list, void* data, _ls_compare_t cmp, int* idx) {
|
||||||
_ls_node_t* result = 0;
|
_ls_node_t* result = 0;
|
||||||
|
|
||||||
mb_assert(list && data && cmp);
|
mb_assert(list && data && cmp);
|
||||||
@ -2463,7 +2467,7 @@ static _ls_node_t* _ls_insert_at(_ls_node_t* list, int index, void* data) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned _ls_remove(_ls_node_t* list, _ls_node_t* node, _ls_operation op) {
|
static unsigned _ls_remove(_ls_node_t* list, _ls_node_t* node, _ls_operation_t op) {
|
||||||
unsigned result = 0;
|
unsigned result = 0;
|
||||||
|
|
||||||
mb_assert(list && node);
|
mb_assert(list && node);
|
||||||
@ -2485,7 +2489,7 @@ static unsigned _ls_remove(_ls_node_t* list, _ls_node_t* node, _ls_operation op)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned _ls_try_remove(_ls_node_t* list, void* info, _ls_compare cmp, _ls_operation op) {
|
static unsigned _ls_try_remove(_ls_node_t* list, void* info, _ls_compare_t cmp, _ls_operation_t op) {
|
||||||
unsigned result = 0;
|
unsigned result = 0;
|
||||||
_ls_node_t* tmp = 0;
|
_ls_node_t* tmp = 0;
|
||||||
|
|
||||||
@ -2516,7 +2520,7 @@ static unsigned _ls_try_remove(_ls_node_t* list, void* info, _ls_compare cmp, _l
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned _ls_foreach(_ls_node_t* list, _ls_operation op) {
|
static unsigned _ls_foreach(_ls_node_t* list, _ls_operation_t op) {
|
||||||
unsigned idx = 0;
|
unsigned idx = 0;
|
||||||
int opresult = _OP_RESULT_NORMAL;
|
int opresult = _OP_RESULT_NORMAL;
|
||||||
_ls_node_t* node = 0;
|
_ls_node_t* node = 0;
|
||||||
@ -2543,7 +2547,7 @@ static unsigned _ls_foreach(_ls_node_t* list, _ls_operation op) {
|
|||||||
return idx;
|
return idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
static _ls_node_t* _ls_sort(_ls_node_t* _mb_unaligned * list, _ls_compare cmp) {
|
static _ls_node_t* _ls_sort(_ls_node_t* _mb_unaligned * list, _ls_compare_t cmp) {
|
||||||
/* Copyright 2001 Simon Tatham, http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.c */
|
/* Copyright 2001 Simon Tatham, http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.c */
|
||||||
bool_t is_circular = false, is_double = true;
|
bool_t is_circular = false, is_double = true;
|
||||||
_ls_node_t* p, * q, * e, * tail, * oldhead;
|
_ls_node_t* p, * q, * e, * tail, * oldhead;
|
||||||
@ -2940,7 +2944,7 @@ static int _ht_cmp_ref(void* d1, void* d2) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static _ht_node_t* _ht_create(unsigned size, _ht_compare cmp, _ht_hash hs, _ls_operation freeextra) {
|
static _ht_node_t* _ht_create(unsigned size, _ht_compare_t cmp, _ht_hash_t hs, _ls_operation_t freeextra) {
|
||||||
const unsigned array_size = size ? size : _HT_ARRAY_SIZE_DEFAULT;
|
const unsigned array_size = size ? size : _HT_ARRAY_SIZE_DEFAULT;
|
||||||
_ht_node_t* result = 0;
|
_ht_node_t* result = 0;
|
||||||
unsigned ul = 0;
|
unsigned ul = 0;
|
||||||
@ -3025,7 +3029,7 @@ static unsigned _ht_set_or_insert(_ht_node_t* ht, void* key, void* value) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned _ht_remove(_ht_node_t* ht, void* key, _ls_compare cmp) {
|
static unsigned _ht_remove(_ht_node_t* ht, void* key, _ls_compare_t cmp) {
|
||||||
unsigned result = 0;
|
unsigned result = 0;
|
||||||
unsigned hash_code = 0;
|
unsigned hash_code = 0;
|
||||||
_ls_node_t* bucket = 0;
|
_ls_node_t* bucket = 0;
|
||||||
@ -3046,7 +3050,7 @@ static unsigned _ht_remove(_ht_node_t* ht, void* key, _ls_compare cmp) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned _ht_foreach(_ht_node_t* ht, _ht_operation op) {
|
static unsigned _ht_foreach(_ht_node_t* ht, _ht_operation_t op) {
|
||||||
unsigned result = 0;
|
unsigned result = 0;
|
||||||
_ls_node_t* bucket = 0;
|
_ls_node_t* bucket = 0;
|
||||||
unsigned ul = 0;
|
unsigned ul = 0;
|
||||||
@ -4845,7 +4849,7 @@ static char* _load_file(mb_interpreter_t* s, const char* f, const char* prefix,
|
|||||||
|
|
||||||
context = (_parsing_context_t*)s->parsing_context;
|
context = (_parsing_context_t*)s->parsing_context;
|
||||||
|
|
||||||
if(_ls_find(context->imported, (void*)f, (_ls_compare)_ht_cmp_string, 0)) {
|
if(_ls_find(context->imported, (void*)f, (_ls_compare_t)_ht_cmp_string, 0)) {
|
||||||
buf = (char*)f;
|
buf = (char*)f;
|
||||||
} else {
|
} else {
|
||||||
fp = fopen(f, "rb");
|
fp = fopen(f, "rb");
|
||||||
@ -5427,7 +5431,7 @@ static _data_e _get_symbol_type(mb_interpreter_t* s, char* sym, _raw_t* value) {
|
|||||||
#ifdef MB_ENABLE_MODULE
|
#ifdef MB_ENABLE_MODULE
|
||||||
char* ns = mb_strdup(sym + 2, strlen(sym + 2) + 1);
|
char* ns = mb_strdup(sym + 2, strlen(sym + 2) + 1);
|
||||||
mb_strupr(ns);
|
mb_strupr(ns);
|
||||||
if(_ls_find(s->using_modules, ns, (_ls_compare)_ht_cmp_string, 0)) {
|
if(_ls_find(s->using_modules, ns, (_ls_compare_t)_ht_cmp_string, 0)) {
|
||||||
safe_free(ns);
|
safe_free(ns);
|
||||||
} else {
|
} else {
|
||||||
_ls_pushback(s->using_modules, ns);
|
_ls_pushback(s->using_modules, ns);
|
||||||
@ -5452,7 +5456,7 @@ static _data_e _get_symbol_type(mb_interpreter_t* s, char* sym, _raw_t* value) {
|
|||||||
_post_import(s, lf, &pos, &row, &col);
|
_post_import(s, lf, &pos, &row, &col);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(!_ls_find(context->imported, (void*)(sym + 1), (_ls_compare)_ht_cmp_string, 0)) {
|
if(!_ls_find(context->imported, (void*)(sym + 1), (_ls_compare_t)_ht_cmp_string, 0)) {
|
||||||
if(s->import_handler) {
|
if(s->import_handler) {
|
||||||
_object_t* sep = 0;
|
_object_t* sep = 0;
|
||||||
char* lf = 0;
|
char* lf = 0;
|
||||||
@ -6446,20 +6450,37 @@ static int _gc_add_reachable_both(void* data, void* extra, void* h) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MB_ENABLE_FORK
|
||||||
|
/* Get reachable objects in a forked environment */
|
||||||
|
static int _gc_get_reachable_in_forked(void* data, void* extra, _ht_node_t* valid) {
|
||||||
|
int result = _OP_RESULT_NORMAL;
|
||||||
|
mb_interpreter_t* s = 0;
|
||||||
|
_running_context_t* root = 0;
|
||||||
|
mb_unrefvar(extra);
|
||||||
|
|
||||||
|
mb_assert(data);
|
||||||
|
|
||||||
|
s = (mb_interpreter_t*)data;
|
||||||
|
root = _get_root_scope(s->running_context);
|
||||||
|
_gc_get_reachable(s, valid, root);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
#endif /* MB_ENABLE_FORK */
|
||||||
|
|
||||||
/* Get all reachable referenced objects */
|
/* Get all reachable referenced objects */
|
||||||
static void _gc_get_reachable(mb_interpreter_t* s, _ht_node_t* ht) {
|
static void _gc_get_reachable(mb_interpreter_t* s, _ht_node_t* ht, _running_context_t* end) {
|
||||||
_running_context_t* running = 0;
|
_running_context_t* running = 0;
|
||||||
_ht_node_t* global_scope = 0;
|
_ht_node_t* scope = 0;
|
||||||
|
|
||||||
mb_assert(s && ht);
|
mb_assert(s && ht);
|
||||||
|
|
||||||
running = s->running_context;
|
running = s->running_context;
|
||||||
while(running) {
|
while(running && running != end) {
|
||||||
global_scope = running->var_dict;
|
scope = running->var_dict;
|
||||||
if(global_scope) {
|
if(scope) {
|
||||||
_HT_FOREACH(global_scope, _do_nothing_on_object, _gc_add_reachable, ht);
|
_HT_FOREACH(scope, _do_nothing_on_object, _gc_add_reachable, ht);
|
||||||
}
|
}
|
||||||
|
|
||||||
running = running->prev;
|
running = running->prev;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -6787,7 +6808,10 @@ static void _gc_collect_garbage(mb_interpreter_t* s, int depth) {
|
|||||||
valid = _ht_create(0, _ht_cmp_ref, _ht_hash_ref, _do_nothing_on_object);
|
valid = _ht_create(0, _ht_cmp_ref, _ht_hash_ref, _do_nothing_on_object);
|
||||||
if(depth != -1)
|
if(depth != -1)
|
||||||
gc->valid_table = valid;
|
gc->valid_table = valid;
|
||||||
_gc_get_reachable(s, valid);
|
_gc_get_reachable(s, valid, 0);
|
||||||
|
#ifdef MB_ENABLE_FORK
|
||||||
|
_LS_FOREACH(s->all_forked, _do_nothing_on_object, _gc_get_reachable_in_forked, valid);
|
||||||
|
#endif /* MB_ENABLE_FORK */
|
||||||
if(s->alive_check_handler)
|
if(s->alive_check_handler)
|
||||||
s->alive_check_handler(s, valid, _gc_alive_marker);
|
s->alive_check_handler(s, valid, _gc_alive_marker);
|
||||||
|
|
||||||
@ -7745,7 +7769,7 @@ static bool_t _find_list(_list_t* coll, mb_value_t* val, int* idx) {
|
|||||||
_fill_ranged(coll);
|
_fill_ranged(coll);
|
||||||
|
|
||||||
_create_internal_object_from_public_value(val, &oarg);
|
_create_internal_object_from_public_value(val, &oarg);
|
||||||
result = !!_ls_find(coll->list, oarg, (_ls_compare)_ht_cmp_object, idx);
|
result = !!_ls_find(coll->list, oarg, (_ls_compare_t)_ht_cmp_object, idx);
|
||||||
_destroy_object(oarg, 0);
|
_destroy_object(oarg, 0);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@ -7769,7 +7793,7 @@ static void _clear_list(_list_t* coll) {
|
|||||||
static void _sort_list(_list_t* coll) {
|
static void _sort_list(_list_t* coll) {
|
||||||
mb_assert(coll);
|
mb_assert(coll);
|
||||||
|
|
||||||
_ls_sort(&coll->list, (_ls_compare)_ht_cmp_object);
|
_ls_sort(&coll->list, (_ls_compare_t)_ht_cmp_object);
|
||||||
|
|
||||||
_write_on_ref_object(&coll->lock, &coll->ref, coll);
|
_write_on_ref_object(&coll->lock, &coll->ref, coll);
|
||||||
_invalidate_list_cache(coll);
|
_invalidate_list_cache(coll);
|
||||||
@ -8164,7 +8188,7 @@ static void _destroy_class(_class_t* c) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Traverse all fields of a class instance, and its meta class instances recursively as well */
|
/* Traverse all fields of a class instance, and its meta class instances recursively as well */
|
||||||
static bool_t _traverse_class(_class_t* c, _class_scope_walker scope_walker, _class_meta_walker meta_walker, unsigned meta_depth, bool_t meta_walk_on_self, void* extra_data, void* ret) {
|
static bool_t _traverse_class(_class_t* c, _class_scope_walker_t scope_walker, _class_meta_walker_t meta_walker, unsigned meta_depth, bool_t meta_walk_on_self, void* extra_data, void* ret) {
|
||||||
bool_t result = true;
|
bool_t result = true;
|
||||||
_ls_node_t* node = 0;
|
_ls_node_t* node = 0;
|
||||||
_class_t* meta = 0;
|
_class_t* meta = 0;
|
||||||
@ -8209,7 +8233,7 @@ _exit:
|
|||||||
static bool_t _link_meta_class(mb_interpreter_t* s, _class_t* derived, _class_t* base) {
|
static bool_t _link_meta_class(mb_interpreter_t* s, _class_t* derived, _class_t* base) {
|
||||||
mb_assert(s && derived && base);
|
mb_assert(s && derived && base);
|
||||||
|
|
||||||
if(_ls_find(derived->meta_list, base, (_ls_compare)_ht_cmp_intptr, 0)) {
|
if(_ls_find(derived->meta_list, base, (_ls_compare_t)_ht_cmp_intptr, 0)) {
|
||||||
_handle_error_now(s, SE_RN_WRONG_META_CLASS, s->source_file, MB_FUNC_ERR);
|
_handle_error_now(s, SE_RN_WRONG_META_CLASS, s->source_file, MB_FUNC_ERR);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -8774,7 +8798,7 @@ static void _mark_upvalue(mb_interpreter_t* s, _lambda_t* lambda, _object_t* obj
|
|||||||
if(scp && found_in_scope) {
|
if(scp && found_in_scope) {
|
||||||
if(!found_in_scope->refered_lambdas)
|
if(!found_in_scope->refered_lambdas)
|
||||||
found_in_scope->refered_lambdas = _ls_create();
|
found_in_scope->refered_lambdas = _ls_create();
|
||||||
if(!_ls_find(found_in_scope->refered_lambdas, lambda, (_ls_compare)_ht_cmp_intptr, 0))
|
if(!_ls_find(found_in_scope->refered_lambdas, lambda, (_ls_compare_t)_ht_cmp_intptr, 0))
|
||||||
_ls_pushback(found_in_scope->refered_lambdas, lambda);
|
_ls_pushback(found_in_scope->refered_lambdas, lambda);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -11629,7 +11653,7 @@ static _ls_node_t* _find_func(mb_interpreter_t* s, char* n, bool_t* mod) {
|
|||||||
result = result->next;
|
result = result->next;
|
||||||
while(result) {
|
while(result) {
|
||||||
mp = (_module_func_t*)result->data;
|
mp = (_module_func_t*)result->data;
|
||||||
if(_ls_find(s->using_modules, mp->module, (_ls_compare)_ht_cmp_string, 0))
|
if(_ls_find(s->using_modules, mp->module, (_ls_compare_t)_ht_cmp_string, 0))
|
||||||
break;
|
break;
|
||||||
result = result->next;
|
result = result->next;
|
||||||
}
|
}
|
||||||
@ -11854,6 +11878,10 @@ int mb_open(struct mb_interpreter_t** s) {
|
|||||||
|
|
||||||
(*s)->parsing_context = _reset_parsing_context((*s)->parsing_context);
|
(*s)->parsing_context = _reset_parsing_context((*s)->parsing_context);
|
||||||
|
|
||||||
|
#ifdef MB_ENABLE_FORK
|
||||||
|
(*s)->all_forked = _ls_create();
|
||||||
|
#endif /* MB_ENABLE_FORK */
|
||||||
|
|
||||||
(*s)->edge_destroy_objects = _ls_create();
|
(*s)->edge_destroy_objects = _ls_create();
|
||||||
(*s)->lazy_destroy_objects = _ls_create();
|
(*s)->lazy_destroy_objects = _ls_create();
|
||||||
|
|
||||||
@ -11941,6 +11969,11 @@ int mb_close(struct mb_interpreter_t** s) {
|
|||||||
(*s)->gc.recursive_table = 0;
|
(*s)->gc.recursive_table = 0;
|
||||||
(*s)->gc.collected_table = 0;
|
(*s)->gc.collected_table = 0;
|
||||||
|
|
||||||
|
#ifdef MB_ENABLE_FORK
|
||||||
|
mb_assert(_ls_count((*s)->all_forked) == 0);
|
||||||
|
_ls_destroy((*s)->all_forked);
|
||||||
|
#endif /* MB_ENABLE_FORK */
|
||||||
|
|
||||||
_ls_foreach((*s)->edge_destroy_objects, _destroy_object);
|
_ls_foreach((*s)->edge_destroy_objects, _destroy_object);
|
||||||
_ls_destroy((*s)->edge_destroy_objects);
|
_ls_destroy((*s)->edge_destroy_objects);
|
||||||
_ls_foreach((*s)->lazy_destroy_objects, _destroy_object);
|
_ls_foreach((*s)->lazy_destroy_objects, _destroy_object);
|
||||||
@ -12015,6 +12048,11 @@ int mb_reset(struct mb_interpreter_t** s, bool_t clrf) {
|
|||||||
_tidy_scope_chain(*s);
|
_tidy_scope_chain(*s);
|
||||||
_clear_scope_chain(*s);
|
_clear_scope_chain(*s);
|
||||||
|
|
||||||
|
#ifdef MB_ENABLE_FORK
|
||||||
|
mb_assert(_ls_count((*s)->all_forked) == 0);
|
||||||
|
_ls_clear((*s)->all_forked);
|
||||||
|
#endif /* MB_ENABLE_FORK */
|
||||||
|
|
||||||
(*s)->parsing_context = _reset_parsing_context((*s)->parsing_context);
|
(*s)->parsing_context = _reset_parsing_context((*s)->parsing_context);
|
||||||
|
|
||||||
if(clrf) {
|
if(clrf) {
|
||||||
@ -12038,7 +12076,7 @@ int mb_reset(struct mb_interpreter_t** s, bool_t clrf) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Fork a new MY-BASIC environment */
|
/* Fork a new MY-BASIC environment */
|
||||||
int mb_fork(struct mb_interpreter_t** s, struct mb_interpreter_t* r) {
|
int mb_fork(struct mb_interpreter_t** s, struct mb_interpreter_t* r, bool_t cklv) {
|
||||||
#ifdef MB_ENABLE_FORK
|
#ifdef MB_ENABLE_FORK
|
||||||
int result = MB_FUNC_OK;
|
int result = MB_FUNC_OK;
|
||||||
_running_context_t* running = 0;
|
_running_context_t* running = 0;
|
||||||
@ -12072,12 +12110,16 @@ int mb_fork(struct mb_interpreter_t** s, struct mb_interpreter_t* r) {
|
|||||||
|
|
||||||
(*s)->forked_from = r;
|
(*s)->forked_from = r;
|
||||||
|
|
||||||
|
if(cklv)
|
||||||
|
_ls_pushback(r->all_forked, *s);
|
||||||
|
|
||||||
mb_assert(MB_FUNC_OK == result);
|
mb_assert(MB_FUNC_OK == result);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
#else /* MB_ENABLE_FORK */
|
#else /* MB_ENABLE_FORK */
|
||||||
mb_unrefvar(s);
|
mb_unrefvar(s);
|
||||||
mb_unrefvar(r);
|
mb_unrefvar(r);
|
||||||
|
mb_unrefvar(cklv);
|
||||||
|
|
||||||
return MB_FUNC_ERR;
|
return MB_FUNC_ERR;
|
||||||
#endif /* MB_ENABLE_FORK */
|
#endif /* MB_ENABLE_FORK */
|
||||||
@ -12113,6 +12155,8 @@ int mb_join(struct mb_interpreter_t** s) {
|
|||||||
_ls_foreach((*s)->lazy_destroy_objects, _destroy_object);
|
_ls_foreach((*s)->lazy_destroy_objects, _destroy_object);
|
||||||
_ls_destroy((*s)->lazy_destroy_objects);
|
_ls_destroy((*s)->lazy_destroy_objects);
|
||||||
|
|
||||||
|
_ls_try_remove((*s)->all_forked, *s, _ls_cmp_data, 0);
|
||||||
|
|
||||||
safe_free(*s);
|
safe_free(*s);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@ -13614,7 +13658,7 @@ _exit:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Set the global alive checker */
|
/* Set the global alive checker */
|
||||||
int mb_set_alive_checker(struct mb_interpreter_t* s, mb_alive_checker f) {
|
int mb_set_alive_checker(struct mb_interpreter_t* s, mb_alive_checker_t f) {
|
||||||
int result = MB_FUNC_OK;
|
int result = MB_FUNC_OK;
|
||||||
|
|
||||||
if(!s)
|
if(!s)
|
||||||
@ -13626,7 +13670,7 @@ int mb_set_alive_checker(struct mb_interpreter_t* s, mb_alive_checker f) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Set the alive checker of a value */
|
/* Set the alive checker of a value */
|
||||||
int mb_set_alive_checker_of_value(struct mb_interpreter_t* s, void** l, mb_value_t val, mb_alive_value_checker f) {
|
int mb_set_alive_checker_of_value(struct mb_interpreter_t* s, void** l, mb_value_t val, mb_alive_value_checker_t f) {
|
||||||
#ifdef MB_ENABLE_ALIVE_CHECKING_ON_USERTYPE_REF
|
#ifdef MB_ENABLE_ALIVE_CHECKING_ON_USERTYPE_REF
|
||||||
int result = MB_FUNC_OK;
|
int result = MB_FUNC_OK;
|
||||||
_object_t obj;
|
_object_t obj;
|
||||||
|
@ -587,9 +587,9 @@ typedef void* (* mb_clone_func_t)(struct mb_interpreter_t*, void*);
|
|||||||
typedef unsigned (* mb_hash_func_t)(struct mb_interpreter_t*, void*);
|
typedef unsigned (* mb_hash_func_t)(struct mb_interpreter_t*, void*);
|
||||||
typedef int (* mb_cmp_func_t)(struct mb_interpreter_t*, void*, void*);
|
typedef int (* mb_cmp_func_t)(struct mb_interpreter_t*, void*, void*);
|
||||||
typedef int (* mb_fmt_func_t)(struct mb_interpreter_t*, void*, char*, unsigned);
|
typedef int (* mb_fmt_func_t)(struct mb_interpreter_t*, void*, char*, unsigned);
|
||||||
typedef void (* mb_alive_marker)(struct mb_interpreter_t*, void*, mb_value_t);
|
typedef void (* mb_alive_marker_t)(struct mb_interpreter_t*, void*, mb_value_t);
|
||||||
typedef void (* mb_alive_checker)(struct mb_interpreter_t*, void*, mb_alive_marker);
|
typedef void (* mb_alive_checker_t)(struct mb_interpreter_t*, void*, mb_alive_marker_t);
|
||||||
typedef void (* mb_alive_value_checker)(struct mb_interpreter_t*, void*, mb_value_t, mb_alive_marker);
|
typedef void (* mb_alive_value_checker_t)(struct mb_interpreter_t*, void*, mb_value_t, mb_alive_marker_t);
|
||||||
typedef int (* mb_meta_operator_t)(struct mb_interpreter_t*, void**, mb_value_t*, mb_value_t*, mb_value_t*);
|
typedef int (* mb_meta_operator_t)(struct mb_interpreter_t*, void**, mb_value_t*, mb_value_t*, mb_value_t*);
|
||||||
typedef mb_meta_status_e (* mb_meta_func_t)(struct mb_interpreter_t*, void**, mb_value_t*, const char*);
|
typedef mb_meta_status_e (* mb_meta_func_t)(struct mb_interpreter_t*, void**, mb_value_t*, const char*);
|
||||||
typedef char* (* mb_memory_allocate_func_t)(unsigned);
|
typedef char* (* mb_memory_allocate_func_t)(unsigned);
|
||||||
@ -604,7 +604,7 @@ MBAPI int mb_open(struct mb_interpreter_t** s);
|
|||||||
MBAPI int mb_close(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_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_fork(struct mb_interpreter_t** s, struct mb_interpreter_t* r, bool_t cklv/* = true*/);
|
||||||
MBAPI int mb_join(struct mb_interpreter_t** s);
|
MBAPI int mb_join(struct mb_interpreter_t** s);
|
||||||
MBAPI int mb_get_forked_from(struct mb_interpreter_t* s, struct mb_interpreter_t** src);
|
MBAPI int mb_get_forked_from(struct mb_interpreter_t* s, struct mb_interpreter_t** src);
|
||||||
|
|
||||||
@ -655,8 +655,8 @@ MBAPI int mb_make_ref_value(struct mb_interpreter_t* s, void* val, mb_value_t* o
|
|||||||
MBAPI int mb_get_ref_value(struct mb_interpreter_t* s, void** l, mb_value_t val, void** out);
|
MBAPI int mb_get_ref_value(struct mb_interpreter_t* s, void** l, mb_value_t val, void** out);
|
||||||
MBAPI int mb_ref_value(struct mb_interpreter_t* s, void** l, mb_value_t val);
|
MBAPI int mb_ref_value(struct mb_interpreter_t* s, void** l, mb_value_t val);
|
||||||
MBAPI int mb_unref_value(struct mb_interpreter_t* s, void** l, mb_value_t val);
|
MBAPI int mb_unref_value(struct mb_interpreter_t* s, void** l, mb_value_t val);
|
||||||
MBAPI int mb_set_alive_checker(struct mb_interpreter_t* s, mb_alive_checker f);
|
MBAPI int mb_set_alive_checker(struct mb_interpreter_t* s, mb_alive_checker_t f);
|
||||||
MBAPI int mb_set_alive_checker_of_value(struct mb_interpreter_t* s, void** l, mb_value_t val, mb_alive_value_checker f);
|
MBAPI int mb_set_alive_checker_of_value(struct mb_interpreter_t* s, void** l, mb_value_t val, mb_alive_value_checker_t f);
|
||||||
MBAPI int mb_override_value(struct mb_interpreter_t* s, void** l, mb_value_t val, mb_meta_func_e m, void* f);
|
MBAPI int mb_override_value(struct mb_interpreter_t* s, void** l, mb_value_t val, mb_meta_func_e m, void* f);
|
||||||
MBAPI int mb_dispose_value(struct mb_interpreter_t* s, mb_value_t val);
|
MBAPI int mb_dispose_value(struct mb_interpreter_t* s, mb_value_t val);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user