*fixed bugs with lambda; *fixed a multiple disposing bug with string expression; *fixed some other bugs with lambda.
This commit is contained in:
parent
f4ce66dedf
commit
9e790bce1e
5
HISTORY
5
HISTORY
@ -1,5 +1,10 @@
|
|||||||
Jan. 12 2016
|
Jan. 12 2016
|
||||||
Fixed a routine evaluation bug when it's stored in a variable
|
Fixed a routine evaluation bug when it's stored in a variable
|
||||||
|
Fixed a disposing issue with collection iterators
|
||||||
|
Fixed some memory leak with lambda
|
||||||
|
Fixed a multiple disposing bug with string expression calculation
|
||||||
|
Improved GC with outer scopes of lambda
|
||||||
|
Fixed some other minor bugs with lambda
|
||||||
|
|
||||||
Jan. 11 2016
|
Jan. 11 2016
|
||||||
Fixed a crash bug when a DO-UNTIL statement is the end of a program
|
Fixed a crash bug when a DO-UNTIL statement is the end of a program
|
||||||
|
@ -1211,11 +1211,19 @@ static char* _extract_string(_object_t* obj);
|
|||||||
case _DT_DICT_IT: \
|
case _DT_DICT_IT: \
|
||||||
_destroy_dict_it(obj->data.dict_it); \
|
_destroy_dict_it(obj->data.dict_it); \
|
||||||
break;
|
break;
|
||||||
|
# define _ADDGC_COLL_IT(__o, __g) \
|
||||||
|
case _DT_LIST_IT: \
|
||||||
|
_destroy_list_it(obj->data.list_it); \
|
||||||
|
break; \
|
||||||
|
case _DT_DICT_IT: \
|
||||||
|
_destroy_dict_it(obj->data.dict_it); \
|
||||||
|
break;
|
||||||
#else /* MB_ENABLE_COLLECTION_LIB */
|
#else /* MB_ENABLE_COLLECTION_LIB */
|
||||||
# define _REF_COLL(__o) ((void)(__o));
|
# define _REF_COLL(__o) ((void)(__o));
|
||||||
# define _UNREF_COLL(__o) ((void)(__o));
|
# define _UNREF_COLL(__o) ((void)(__o));
|
||||||
# define _ADDGC_COLL(__o, __g) ((void)(__o)); ((void)(__g));
|
# define _ADDGC_COLL(__o, __g) ((void)(__o)); ((void)(__g));
|
||||||
# define _UNREF_COLL_IT(__o) ((void)(__o));
|
# define _UNREF_COLL_IT(__o) ((void)(__o));
|
||||||
|
# define _ADDGC_COLL_IT(__o, __g) ((void)(__o)); ((void)(__g));
|
||||||
#endif /* MB_ENABLE_COLLECTION_LIB */
|
#endif /* MB_ENABLE_COLLECTION_LIB */
|
||||||
#ifdef MB_ENABLE_CLASS
|
#ifdef MB_ENABLE_CLASS
|
||||||
# define _REF_CLASS(__o) \
|
# define _REF_CLASS(__o) \
|
||||||
@ -1292,6 +1300,7 @@ static char* _extract_string(_object_t* obj);
|
|||||||
_ADDGC_USERTYPE_REF(__o, __g) \
|
_ADDGC_USERTYPE_REF(__o, __g) \
|
||||||
_ADDGC_ARRAY(__o, __g) \
|
_ADDGC_ARRAY(__o, __g) \
|
||||||
_ADDGC_COLL(__o, __g) \
|
_ADDGC_COLL(__o, __g) \
|
||||||
|
_ADDGC_COLL_IT(__o, __g) \
|
||||||
_ADDGC_CLASS(__o, __g) \
|
_ADDGC_CLASS(__o, __g) \
|
||||||
_ADDGC_ROUTINE(__o, __g) \
|
_ADDGC_ROUTINE(__o, __g) \
|
||||||
_ADDGC_STRING(__o) \
|
_ADDGC_STRING(__o) \
|
||||||
@ -1317,6 +1326,10 @@ static int _gc_destroy_garbage_in_dict(void* data, void* extra, void* gc);
|
|||||||
#ifdef MB_ENABLE_CLASS
|
#ifdef MB_ENABLE_CLASS
|
||||||
static int _gc_destroy_garbage_in_class(void* data, void* extra, void* gc);
|
static int _gc_destroy_garbage_in_class(void* data, void* extra, void* gc);
|
||||||
#endif /* MB_ENABLE_CLASS */
|
#endif /* MB_ENABLE_CLASS */
|
||||||
|
#ifdef MB_ENABLE_LAMBDA
|
||||||
|
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);
|
||||||
|
#endif /* MB_ENABLE_LAMBDA */
|
||||||
static int _gc_destroy_garbage(void* data, void* extra);
|
static int _gc_destroy_garbage(void* data, void* extra);
|
||||||
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);
|
||||||
@ -2969,12 +2982,11 @@ _routine:
|
|||||||
);
|
);
|
||||||
if(cs) {
|
if(cs) {
|
||||||
c = (_object_t*)cs->data;
|
c = (_object_t*)cs->data;
|
||||||
if(c && c->type == _DT_ROUTINE) {
|
if(c && c->type == _DT_VAR && c->data.variable->data->type == _DT_ROUTINE)
|
||||||
goto _routine;
|
|
||||||
} else if(c && c->type == _DT_VAR && c->data.variable->data->type == _DT_ROUTINE) {
|
|
||||||
c = c->data.variable->data;
|
c = c->data.variable->data;
|
||||||
|
if(ast && ast && _IS_FUNC(ast->data, _core_open_bracket)) {
|
||||||
goto _routine;
|
if(c && c->type == _DT_ROUTINE)
|
||||||
|
goto _routine;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(ast) {
|
if(ast) {
|
||||||
@ -4800,6 +4812,42 @@ int _gc_destroy_garbage_in_class(void* data, void* extra, void* gc) {
|
|||||||
}
|
}
|
||||||
#endif /* MB_ENABLE_CLASS */
|
#endif /* MB_ENABLE_CLASS */
|
||||||
|
|
||||||
|
#ifdef MB_ENABLE_LAMBDA
|
||||||
|
int _gc_destroy_garbage_in_lambda(void* data, void* extra, void* gc) {
|
||||||
|
/* Destroy only the capsule (wrapper) of an object, leave the data behind, deal with extra as well, and add it to GC if possible */
|
||||||
|
int result = _OP_RESULT_NORMAL;
|
||||||
|
_object_t* obj = 0;
|
||||||
|
_gc_t* _gc = (_gc_t*)gc;
|
||||||
|
mb_unrefvar(extra);
|
||||||
|
|
||||||
|
mb_assert(data);
|
||||||
|
|
||||||
|
obj = (_object_t*)data;
|
||||||
|
if(obj->type == _DT_VAR) {
|
||||||
|
_gc_destroy_garbage_in_lambda(obj->data.variable->data, 0, gc);
|
||||||
|
safe_free(obj->data.variable->name);
|
||||||
|
safe_free(obj->data.variable);
|
||||||
|
} else {
|
||||||
|
_ADDGC(obj, _gc);
|
||||||
|
}
|
||||||
|
safe_free(obj);
|
||||||
|
|
||||||
|
result = _OP_RESULT_DEL_NODE;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _gc_destroy_garbage_in_outer_scope(_running_context_ref_t* p, _gc_t* gc) {
|
||||||
|
/* Collect garbage of outer scopes */
|
||||||
|
while(p) {
|
||||||
|
_running_context_ref_t* scope = p;
|
||||||
|
p = p->prev;
|
||||||
|
_HT_FOREACH(scope->scope->var_dict, _do_nothing_on_object, _gc_destroy_garbage_in_lambda, gc);
|
||||||
|
_ht_clear(scope->scope->var_dict);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* MB_ENABLE_LAMBDA */
|
||||||
|
|
||||||
int _gc_destroy_garbage(void* data, void* extra) {
|
int _gc_destroy_garbage(void* data, void* extra) {
|
||||||
/* Destroy a garbage */
|
/* Destroy a garbage */
|
||||||
int result = _OP_RESULT_NORMAL;
|
int result = _OP_RESULT_NORMAL;
|
||||||
@ -4813,6 +4861,9 @@ int _gc_destroy_garbage(void* data, void* extra) {
|
|||||||
#ifdef MB_ENABLE_CLASS
|
#ifdef MB_ENABLE_CLASS
|
||||||
_class_t* instance = 0;
|
_class_t* instance = 0;
|
||||||
#endif /* MB_ENABLE_CLASS */
|
#endif /* MB_ENABLE_CLASS */
|
||||||
|
#ifdef MB_ENABLE_LAMBDA
|
||||||
|
_routine_t* routine = 0;
|
||||||
|
#endif /* MB_ENABLE_LAMBDA */
|
||||||
|
|
||||||
mb_assert(data && extra);
|
mb_assert(data && extra);
|
||||||
|
|
||||||
@ -4848,9 +4899,26 @@ int _gc_destroy_garbage(void* data, void* extra) {
|
|||||||
_HT_FOREACH(instance->scope->var_dict, _do_nothing_on_object, _gc_destroy_garbage_in_class, gc);
|
_HT_FOREACH(instance->scope->var_dict, _do_nothing_on_object, _gc_destroy_garbage_in_class, gc);
|
||||||
_ht_clear(instance->scope->var_dict);
|
_ht_clear(instance->scope->var_dict);
|
||||||
_ls_clear(instance->meta_list);
|
_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;
|
break;
|
||||||
#endif /* MB_ENABLE_CLASS */
|
#endif /* MB_ENABLE_CLASS */
|
||||||
|
#ifdef MB_ENABLE_LAMBDA
|
||||||
|
case _DT_ROUTINE:
|
||||||
|
routine = (_routine_t*)data;
|
||||||
|
if(routine->type == _IT_LAMBDA) {
|
||||||
|
_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);
|
||||||
|
_gc_destroy_garbage_in_outer_scope(routine->func.lambda.outer_scope, gc);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
#endif /* MB_ENABLE_LAMBDA */
|
||||||
default: /* Do nothing */
|
default: /* Do nothing */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -5870,6 +5938,12 @@ void _destroy_class(_class_t* c) {
|
|||||||
_ht_foreach(c->scope->var_dict, _destroy_object);
|
_ht_foreach(c->scope->var_dict, _destroy_object);
|
||||||
_ht_destroy(c->scope->var_dict);
|
_ht_destroy(c->scope->var_dict);
|
||||||
}
|
}
|
||||||
|
#ifdef MB_ENABLE_LAMBDA
|
||||||
|
if(c->scope->refered_lambdas) {
|
||||||
|
_ls_destroy(c->scope->refered_lambdas);
|
||||||
|
c->scope->refered_lambdas = 0;
|
||||||
|
}
|
||||||
|
#endif /* MB_ENABLE_LAMBDA */
|
||||||
safe_free(c->scope);
|
safe_free(c->scope);
|
||||||
_destroy_ref(&c->ref);
|
_destroy_ref(&c->ref);
|
||||||
safe_free(c->name);
|
safe_free(c->name);
|
||||||
@ -6286,9 +6360,9 @@ void _destroy_outer_scope(_running_context_ref_t* p) {
|
|||||||
|
|
||||||
while(p) {
|
while(p) {
|
||||||
_running_context_ref_t* scope = p;
|
_running_context_ref_t* scope = p;
|
||||||
|
p = p->prev;
|
||||||
_destroy_scope(scope->ref.s, scope->scope);
|
_destroy_scope(scope->ref.s, scope->scope);
|
||||||
_destroy_ref(&scope->ref);
|
_destroy_ref(&scope->ref);
|
||||||
p = p->prev;
|
|
||||||
mb_free(scope);
|
mb_free(scope);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -6424,8 +6498,12 @@ bool_t _is_valid_lambda_body_node(mb_interpreter_t* s, _lambda_t* lambda, _objec
|
|||||||
return
|
return
|
||||||
!_IS_FUNC(obj, _core_def) &&
|
!_IS_FUNC(obj, _core_def) &&
|
||||||
!_IS_FUNC(obj, _core_enddef) &&
|
!_IS_FUNC(obj, _core_enddef) &&
|
||||||
|
#ifdef MB_ENABLE_CLASS
|
||||||
!_IS_FUNC(obj, _core_class) &&
|
!_IS_FUNC(obj, _core_class) &&
|
||||||
!_IS_FUNC(obj, _core_endclass);
|
!_IS_FUNC(obj, _core_endclass) &&
|
||||||
|
#endif /* MB_ENABLE_CLASS */
|
||||||
|
true
|
||||||
|
;
|
||||||
}
|
}
|
||||||
#endif /* MB_ENABLE_LAMBDA */
|
#endif /* MB_ENABLE_LAMBDA */
|
||||||
|
|
||||||
@ -6905,7 +6983,7 @@ int _clone_object(mb_interpreter_t* s, _object_t* obj, _object_t* tgt) {
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
case _DT_LIST_IT:
|
case _DT_LIST_IT:
|
||||||
tgt->data.list_it = _create_list_it(obj->data.list_it->list, false);
|
tgt->data.list_it = _create_list_it(obj->data.list_it->list, true);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case _DT_DICT:
|
case _DT_DICT:
|
||||||
@ -6915,7 +6993,7 @@ int _clone_object(mb_interpreter_t* s, _object_t* obj, _object_t* tgt) {
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
case _DT_DICT_IT:
|
case _DT_DICT_IT:
|
||||||
tgt->data.dict_it = _create_dict_it(obj->data.dict_it->dict, false);
|
tgt->data.dict_it = _create_dict_it(obj->data.dict_it->dict, true);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
#endif /* MB_ENABLE_COLLECTION_LIB */
|
#endif /* MB_ENABLE_COLLECTION_LIB */
|
||||||
@ -7329,6 +7407,7 @@ int _public_value_to_internal_object(mb_value_t* pbl, _object_t* itn) {
|
|||||||
case MB_DT_STRING:
|
case MB_DT_STRING:
|
||||||
itn->type = _DT_STRING;
|
itn->type = _DT_STRING;
|
||||||
itn->data.string = pbl->value.string;
|
itn->data.string = pbl->value.string;
|
||||||
|
itn->ref = true;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case MB_DT_USERTYPE:
|
case MB_DT_USERTYPE:
|
||||||
|
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user