*fixed a multiple disposing bug with outer scopes of lambda.
This commit is contained in:
parent
4b54d931f8
commit
f713c1b9a2
1
HISTORY
1
HISTORY
@ -2,6 +2,7 @@ Feb. 26 2016
|
|||||||
Added a ME keyword to represent a class instance itself
|
Added a ME keyword to represent a class instance itself
|
||||||
Added shallow cloning support
|
Added shallow cloning support
|
||||||
Fixed an overrided function copying issue
|
Fixed an overrided function copying issue
|
||||||
|
Fixed a multiple disposing bug with outer scopes of lambda
|
||||||
|
|
||||||
Feb. 25 2016
|
Feb. 25 2016
|
||||||
Improved importing directory detection
|
Improved importing directory detection
|
||||||
|
@ -1468,6 +1468,9 @@ static int _gc_destroy_garbage_in_lambda(void* data, void* extra, void* gc);
|
|||||||
static void _gc_destroy_garbage_in_outer_scope(_running_context_ref_t* p, _gc_t* gc);
|
static void _gc_destroy_garbage_in_outer_scope(_running_context_ref_t* p, _gc_t* gc);
|
||||||
#endif /* MB_ENABLE_LAMBDA */
|
#endif /* MB_ENABLE_LAMBDA */
|
||||||
static int _gc_destroy_garbage(void* data, void* extra);
|
static int _gc_destroy_garbage(void* data, void* extra);
|
||||||
|
#ifdef MB_ENABLE_CLASS
|
||||||
|
static int _gc_destroy_garbage_class(void* data, void* extra);
|
||||||
|
#endif /* MB_ENABLE_CLASS */
|
||||||
static void _gc_swap_tables(mb_interpreter_t* s);
|
static void _gc_swap_tables(mb_interpreter_t* s);
|
||||||
static void _gc_try_trigger(mb_interpreter_t* s);
|
static void _gc_try_trigger(mb_interpreter_t* s);
|
||||||
static void _gc_collect_garbage(mb_interpreter_t* s, int depth);
|
static void _gc_collect_garbage(mb_interpreter_t* s, int depth);
|
||||||
@ -4527,6 +4530,7 @@ static int _create_symbol(mb_interpreter_t* s, _ls_node_t* l, char* sym, _object
|
|||||||
(*obj)->ref = true;
|
(*obj)->ref = true;
|
||||||
*delsym = true;
|
*delsym = true;
|
||||||
} else {
|
} else {
|
||||||
|
#ifdef MB_ENABLE_CLASS
|
||||||
if(strcmp(sym, _CLASS_ME) == 0) {
|
if(strcmp(sym, _CLASS_ME) == 0) {
|
||||||
_handle_error_now(s, SE_RN_CANNOT_CHANGE_ME, s->source_file, MB_FUNC_ERR);
|
_handle_error_now(s, SE_RN_CANNOT_CHANGE_ME, s->source_file, MB_FUNC_ERR);
|
||||||
(*obj)->ref = true;
|
(*obj)->ref = true;
|
||||||
@ -4534,6 +4538,7 @@ static int _create_symbol(mb_interpreter_t* s, _ls_node_t* l, char* sym, _object
|
|||||||
|
|
||||||
goto _exit;
|
goto _exit;
|
||||||
}
|
}
|
||||||
|
#endif /* MB_ENABLE_CLASS */
|
||||||
tmp.var = (_var_t*)mb_malloc(sizeof(_var_t));
|
tmp.var = (_var_t*)mb_malloc(sizeof(_var_t));
|
||||||
memset(tmp.var, 0, sizeof(_var_t));
|
memset(tmp.var, 0, sizeof(_var_t));
|
||||||
tmp.var->name = sym;
|
tmp.var->name = sym;
|
||||||
@ -5253,7 +5258,7 @@ static bool_t _unref(_ref_t* ref, void* data) {
|
|||||||
|
|
||||||
result = --(*ref->count) == _NONE_REF;
|
result = --(*ref->count) == _NONE_REF;
|
||||||
mb_assert(*ref->count >= _NONE_REF);
|
mb_assert(*ref->count >= _NONE_REF);
|
||||||
_gc_add(ref, data, 0);
|
_gc_add(ref, data, &ref->s->gc);
|
||||||
if(ref->count && *ref->count == _NONE_REF)
|
if(ref->count && *ref->count == _NONE_REF)
|
||||||
_tidy_intermediate_value(ref, data);
|
_tidy_intermediate_value(ref, data);
|
||||||
ref->on_unref(ref, data);
|
ref->on_unref(ref, data);
|
||||||
@ -5330,13 +5335,13 @@ static void _gc_add(_ref_t* ref, void* data, _gc_t* gc) {
|
|||||||
if(gc && _ht_find(gc->collected_table, ref))
|
if(gc && _ht_find(gc->collected_table, ref))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(!ref->s->gc.table)
|
if(!gc->table)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(ref->s->gc.collecting)
|
if(gc->collecting)
|
||||||
table = ref->s->gc.recursive_table;
|
table = gc->recursive_table;
|
||||||
else
|
else
|
||||||
table = ref->s->gc.table;
|
table = gc->table;
|
||||||
|
|
||||||
if(gc && gc->valid_table && _ht_find(gc->valid_table, ref))
|
if(gc && gc->valid_table && _ht_find(gc->valid_table, ref))
|
||||||
_ht_remove(table, ref, 0);
|
_ht_remove(table, ref, 0);
|
||||||
@ -5578,9 +5583,6 @@ static int _gc_destroy_garbage(void* data, void* extra) {
|
|||||||
_list_t* lst = 0;
|
_list_t* lst = 0;
|
||||||
_dict_t* dct = 0;
|
_dict_t* dct = 0;
|
||||||
#endif /* MB_ENABLE_COLLECTION_LIB */
|
#endif /* MB_ENABLE_COLLECTION_LIB */
|
||||||
#ifdef MB_ENABLE_CLASS
|
|
||||||
_class_t* instance = 0;
|
|
||||||
#endif /* MB_ENABLE_CLASS */
|
|
||||||
#ifdef MB_ENABLE_LAMBDA
|
#ifdef MB_ENABLE_LAMBDA
|
||||||
_routine_t* routine = 0;
|
_routine_t* routine = 0;
|
||||||
#endif /* MB_ENABLE_LAMBDA */
|
#endif /* MB_ENABLE_LAMBDA */
|
||||||
@ -5605,28 +5607,14 @@ static int _gc_destroy_garbage(void* data, void* extra) {
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
#endif /* MB_ENABLE_COLLECTION_LIB */
|
#endif /* MB_ENABLE_COLLECTION_LIB */
|
||||||
#ifdef MB_ENABLE_CLASS
|
|
||||||
case _DT_CLASS:
|
|
||||||
instance = (_class_t*)data;
|
|
||||||
_HT_FOREACH(instance->scope->var_dict, _do_nothing_on_object, _gc_destroy_garbage_in_class, gc);
|
|
||||||
_ht_clear(instance->scope->var_dict);
|
|
||||||
_ls_clear(instance->meta_list);
|
|
||||||
#ifdef MB_ENABLE_LAMBDA
|
|
||||||
if(instance->scope->refered_lambdas) {
|
|
||||||
_ls_destroy(instance->scope->refered_lambdas);
|
|
||||||
instance->scope->refered_lambdas = 0;
|
|
||||||
}
|
|
||||||
#endif /* MB_ENABLE_LAMBDA */
|
|
||||||
|
|
||||||
break;
|
|
||||||
#endif /* MB_ENABLE_CLASS */
|
|
||||||
#ifdef MB_ENABLE_LAMBDA
|
#ifdef MB_ENABLE_LAMBDA
|
||||||
case _DT_ROUTINE:
|
case _DT_ROUTINE:
|
||||||
routine = (_routine_t*)data;
|
routine = (_routine_t*)data;
|
||||||
if(routine->type == _IT_LAMBDA) {
|
if(routine->type == _IT_LAMBDA) {
|
||||||
_HT_FOREACH(routine->func.lambda.scope->var_dict, _do_nothing_on_object, _gc_destroy_garbage_in_lambda, gc);
|
_HT_FOREACH(routine->func.lambda.scope->var_dict, _do_nothing_on_object, _gc_destroy_garbage_in_lambda, gc);
|
||||||
_ht_clear(routine->func.lambda.scope->var_dict);
|
_ht_clear(routine->func.lambda.scope->var_dict);
|
||||||
_gc_destroy_garbage_in_outer_scope(routine->func.lambda.outer_scope, gc);
|
if(!routine->func.lambda.outer_scope || !_ht_find(gc->collected_table, &routine->func.lambda.outer_scope->ref))
|
||||||
|
_gc_destroy_garbage_in_outer_scope(routine->func.lambda.outer_scope, gc);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -5646,6 +5634,49 @@ static int _gc_destroy_garbage(void* data, void* extra) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MB_ENABLE_CLASS
|
||||||
|
static int _gc_destroy_garbage_class(void* data, void* extra) {
|
||||||
|
/* Destroy a class instance garbage */
|
||||||
|
int result = _OP_RESULT_NORMAL;
|
||||||
|
_gc_t* gc = 0;
|
||||||
|
_ref_t* ref = 0;
|
||||||
|
bool_t cld = false;
|
||||||
|
_class_t* instance = 0;
|
||||||
|
|
||||||
|
mb_assert(data && extra);
|
||||||
|
|
||||||
|
ref = (_ref_t*)extra;
|
||||||
|
gc = &ref->s->gc;
|
||||||
|
switch(ref->type) {
|
||||||
|
case _DT_CLASS:
|
||||||
|
instance = (_class_t*)data;
|
||||||
|
_HT_FOREACH(instance->scope->var_dict, _do_nothing_on_object, _gc_destroy_garbage_in_class, gc);
|
||||||
|
_ht_clear(instance->scope->var_dict);
|
||||||
|
_ls_clear(instance->meta_list);
|
||||||
|
#ifdef MB_ENABLE_LAMBDA
|
||||||
|
if(instance->scope->refered_lambdas) {
|
||||||
|
_ls_destroy(instance->scope->refered_lambdas);
|
||||||
|
instance->scope->refered_lambdas = 0;
|
||||||
|
}
|
||||||
|
#endif /* MB_ENABLE_LAMBDA */
|
||||||
|
|
||||||
|
break;
|
||||||
|
default: /* Do nothing */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(ref->count) {
|
||||||
|
cld = *ref->count == _NONE_REF + 1;
|
||||||
|
_unref(ref, data);
|
||||||
|
if(cld)
|
||||||
|
_ht_set_or_insert(gc->collected_table, ref, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
result = _OP_RESULT_DEL_NODE;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
#endif /* MB_ENABLE_CLASS */
|
||||||
|
|
||||||
static void _gc_swap_tables(mb_interpreter_t* s) {
|
static void _gc_swap_tables(mb_interpreter_t* s) {
|
||||||
/* Swap active garbage table and recursive table */
|
/* Swap active garbage table and recursive table */
|
||||||
_ht_node_t* tmp = 0;
|
_ht_node_t* tmp = 0;
|
||||||
@ -5683,6 +5714,9 @@ static void _gc_collect_garbage(mb_interpreter_t* s, int depth) {
|
|||||||
_HT_FOREACH(valid, _do_nothing_on_object, _ht_remove_exist, s->gc.table);
|
_HT_FOREACH(valid, _do_nothing_on_object, _ht_remove_exist, s->gc.table);
|
||||||
/* Collect garbage */
|
/* Collect garbage */
|
||||||
do {
|
do {
|
||||||
|
#ifdef MB_ENABLE_CLASS
|
||||||
|
_ht_foreach(s->gc.table, _gc_destroy_garbage_class);
|
||||||
|
#endif /* MB_ENABLE_CLASS */
|
||||||
_ht_foreach(s->gc.table, _gc_destroy_garbage);
|
_ht_foreach(s->gc.table, _gc_destroy_garbage);
|
||||||
_ht_clear(s->gc.table);
|
_ht_clear(s->gc.table);
|
||||||
if(s->gc.collecting > 1)
|
if(s->gc.collecting > 1)
|
||||||
@ -7295,7 +7329,7 @@ static void _destroy_routine(mb_interpreter_t* s, _routine_t* r) {
|
|||||||
safe_free(r->func.lambda.scope);
|
safe_free(r->func.lambda.scope);
|
||||||
if(r->func.lambda.parameters)
|
if(r->func.lambda.parameters)
|
||||||
_ls_destroy(r->func.lambda.parameters);
|
_ls_destroy(r->func.lambda.parameters);
|
||||||
if(r->func.lambda.outer_scope)
|
if(r->func.lambda.outer_scope && !_ht_find(s->gc.collected_table, &r->func.lambda.outer_scope->ref))
|
||||||
_unref(&r->func.lambda.outer_scope->ref, r->func.lambda.outer_scope);
|
_unref(&r->func.lambda.outer_scope->ref, r->func.lambda.outer_scope);
|
||||||
if(r->func.lambda.upvalues)
|
if(r->func.lambda.upvalues)
|
||||||
_ht_destroy(r->func.lambda.upvalues);
|
_ht_destroy(r->func.lambda.upvalues);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user