+added MB_ENABLE_USERTYPE_REF and MB_ENABLE_ARRAY_REF macros. *updated doc.

This commit is contained in:
paladin-t 2016-01-15 15:39:23 +08:00
parent 86e79c059d
commit cc93e2ab7c
4 changed files with 90 additions and 22 deletions

View File

@ -1,4 +1,6 @@
Jan. 15 2016 Jan. 15 2016
Added an MB_ENABLE_USERTYPE_REF macro
Added an MB_ENABLE_ARRAY_REF macro
Fixed some crash bugs with invalid syntax Fixed some crash bugs with invalid syntax
Fixed some memory leak with invalid syntax Fixed some memory leak with invalid syntax
Fixed an invalid GC table iteration bug Fixed an invalid GC table iteration bug

Binary file not shown.

View File

@ -353,7 +353,9 @@ typedef struct _usertype_ref_t {
} _usertype_ref_t; } _usertype_ref_t;
typedef struct _array_t { typedef struct _array_t {
#ifdef MB_ENABLE_ARRAY_REF
_ref_t ref; _ref_t ref;
#endif /* MB_ENABLE_ARRAY_REF */
char* name; char* name;
_data_e type; _data_e type;
#ifndef MB_SIMPLE_ARRAY #ifndef MB_SIMPLE_ARRAY
@ -1173,21 +1175,27 @@ static char* _extract_string(_object_t* obj);
case _DT_USERTYPE_REF: \ case _DT_USERTYPE_REF: \
_gc_add(&(__o)->data.usertype_ref->ref, (__o)->data.usertype_ref, (__g)); \ _gc_add(&(__o)->data.usertype_ref->ref, (__o)->data.usertype_ref, (__g)); \
break; break;
#define _REF_ARRAY(__o) \ #ifdef MB_ENABLE_ARRAY_REF
case _DT_ARRAY: \ # define _REF_ARRAY(__o) \
if(!(__o)->ref) \ case _DT_ARRAY: \
_ref(&(__o)->data.array->ref, (__o)->data.array); \ if(!(__o)->ref) \
break; _ref(&(__o)->data.array->ref, (__o)->data.array); \
#define _UNREF_ARRAY(__o) \ break;
case _DT_ARRAY: \ # define _UNREF_ARRAY(__o) \
if(!(__o)->ref) \ case _DT_ARRAY: \
_unref(&(__o)->data.array->ref, (__o)->data.array); \ if(!(__o)->ref) \
break; _unref(&(__o)->data.array->ref, (__o)->data.array); \
#define _ADDGC_ARRAY(__o, __g) \ break;
case _DT_ARRAY: \ # define _ADDGC_ARRAY(__o, __g) \
if(!(__o)->ref) \ case _DT_ARRAY: \
_gc_add(&(__o)->data.array->ref, (__o)->data.array, (__g)); \ if(!(__o)->ref) \
break; _gc_add(&(__o)->data.array->ref, (__o)->data.array, (__g)); \
break;
#else /* MB_ENABLE_ARRAY_REF */
# define _REF_ARRAY(__o) ((void)(__o));
# define _UNREF_ARRAY(__o) ((void)(__o));
# define _ADDGC_ARRAY(__o, __g) ((void)(__o)); ((void)(__g));
#endif /* MB_ENABLE_ARRAY_REF */
#ifdef MB_ENABLE_COLLECTION_LIB #ifdef MB_ENABLE_COLLECTION_LIB
# define _REF_COLL(__o) \ # define _REF_COLL(__o) \
case _DT_LIST: \ case _DT_LIST: \
@ -1342,9 +1350,11 @@ 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);
#endif /* MB_ENABLE_GC */ #endif /* MB_ENABLE_GC */
#ifdef MB_ENABLE_USERTYPE_REF
static _usertype_ref_t* _create_usertype_ref(mb_interpreter_t* s, void* val, mb_dtor_func_t un, mb_clone_func_t cl, mb_hash_func_t hs, mb_cmp_func_t cp, mb_fmt_func_t ft); static _usertype_ref_t* _create_usertype_ref(mb_interpreter_t* s, void* val, mb_dtor_func_t un, mb_clone_func_t cl, mb_hash_func_t hs, mb_cmp_func_t cp, mb_fmt_func_t ft);
static void _destroy_usertype_ref(_usertype_ref_t* c); static void _destroy_usertype_ref(_usertype_ref_t* c);
static void _unref_usertype_ref(_ref_t* ref, void* data); static void _unref_usertype_ref(_ref_t* ref, void* data);
#endif /* MB_ENABLE_USERTYPE_REF */
static _array_t* _create_array(const char* n, _data_e t, mb_interpreter_t* s); static _array_t* _create_array(const char* n, _data_e t, mb_interpreter_t* s);
static void _destroy_array(_array_t* arr); static void _destroy_array(_array_t* arr);
@ -4052,7 +4062,7 @@ int _create_symbol(mb_interpreter_t* s, _ls_node_t* l, char* sym, _object_t** ob
safe_free(sym); safe_free(sym);
break; break;
default: default: /* Do nothing */
break; break;
} }
@ -4671,7 +4681,6 @@ void _gc_add(_ref_t* ref, void* data, _gc_t* gc) {
void _gc_remove(_ref_t* ref, void* data) { void _gc_remove(_ref_t* ref, void* data) {
/* Remove a referenced object from GC */ /* Remove a referenced object from GC */
_ht_node_t* table = 0; _ht_node_t* table = 0;
mb_unrefvar(data);
mb_assert(ref && data); mb_assert(ref && data);
@ -4707,11 +4716,13 @@ int _gc_add_reachable(void* data, void* extra, void* ht) {
_ht_set_or_insert(htable, &obj->data.usertype_ref->ref, obj->data.usertype_ref); _ht_set_or_insert(htable, &obj->data.usertype_ref->ref, obj->data.usertype_ref);
break; break;
#ifdef MB_ENABLE_ARRAY_REF
case _DT_ARRAY: case _DT_ARRAY:
if(!_ht_find(htable, &obj->data.array->ref)) if(!_ht_find(htable, &obj->data.array->ref))
_ht_set_or_insert(htable, &obj->data.array->ref, obj->data.array); _ht_set_or_insert(htable, &obj->data.array->ref, obj->data.array);
break; break;
#endif /* MB_ENABLE_ARRAY_REF */
#ifdef MB_ENABLE_COLLECTION_LIB #ifdef MB_ENABLE_COLLECTION_LIB
case _DT_LIST: case _DT_LIST:
if(!_ht_find(htable, &obj->data.list->ref)) { if(!_ht_find(htable, &obj->data.list->ref)) {
@ -5019,6 +5030,7 @@ void _gc_collect_garbage(mb_interpreter_t* s, int depth) {
} }
#endif /* MB_ENABLE_GC */ #endif /* MB_ENABLE_GC */
#ifdef MB_ENABLE_USERTYPE_REF
_usertype_ref_t* _create_usertype_ref(mb_interpreter_t* s, void* val, mb_dtor_func_t un, mb_clone_func_t cl, mb_hash_func_t hs, mb_cmp_func_t cp, mb_fmt_func_t ft) { _usertype_ref_t* _create_usertype_ref(mb_interpreter_t* s, void* val, mb_dtor_func_t un, mb_clone_func_t cl, mb_hash_func_t hs, mb_cmp_func_t cp, mb_fmt_func_t ft) {
/* Create a referenced usertype */ /* Create a referenced usertype */
_usertype_ref_t* result = (_usertype_ref_t*)mb_malloc(sizeof(_usertype_ref_t)); _usertype_ref_t* result = (_usertype_ref_t*)mb_malloc(sizeof(_usertype_ref_t));
@ -5047,6 +5059,7 @@ void _unref_usertype_ref(_ref_t* ref, void* data) {
if(!(*(ref->count))) if(!(*(ref->count)))
_destroy_usertype_ref((_usertype_ref_t*)data); _destroy_usertype_ref((_usertype_ref_t*)data);
} }
#endif /* MB_ENABLE_USERTYPE_REF */
_array_t* _create_array(const char* n, _data_e t, mb_interpreter_t* s) { _array_t* _create_array(const char* n, _data_e t, mb_interpreter_t* s) {
/* Create an array */ /* Create an array */
@ -5054,8 +5067,12 @@ _array_t* _create_array(const char* n, _data_e t, mb_interpreter_t* s) {
memset(result, 0, sizeof(_array_t)); memset(result, 0, sizeof(_array_t));
result->type = t; result->type = t;
result->name = (char*)n; result->name = (char*)n;
#ifdef MB_ENABLE_ARRAY_REF
_create_ref(&result->ref, _unref_array, _DT_ARRAY, s); _create_ref(&result->ref, _unref_array, _DT_ARRAY, s);
_ref(&result->ref, result); _ref(&result->ref, result);
#else /* MB_ENABLE_ARRAY_REF */
mb_unrefvar(s);
#endif /* MB_ENABLE_ARRAY_REF */
return result; return result;
} }
@ -5073,7 +5090,9 @@ void _destroy_array(_array_t* arr) {
safe_free(arr->types); safe_free(arr->types);
} }
#endif /* MB_SIMPLE_ARRAY */ #endif /* MB_SIMPLE_ARRAY */
#ifdef MB_ENABLE_ARRAY_REF
_destroy_ref(&arr->ref); _destroy_ref(&arr->ref);
#endif /* MB_ENABLE_ARRAY_REF */
safe_free(arr); safe_free(arr);
} }
@ -6281,8 +6300,6 @@ void _unref_routine(_ref_t* ref, void* data) {
void _destroy_routine(mb_interpreter_t* s, _routine_t* r) { void _destroy_routine(mb_interpreter_t* s, _routine_t* r) {
/* Destroy a lambda routine */ /* Destroy a lambda routine */
mb_unrefvar(s);
if(r->name) { if(r->name) {
safe_free(r->name); safe_free(r->name);
} }
@ -6573,8 +6590,7 @@ bool_t _is_valid_lambda_body_node(mb_interpreter_t* s, _lambda_t* lambda, _objec
!_IS_FUNC(obj, _core_class) && !_IS_FUNC(obj, _core_class) &&
!_IS_FUNC(obj, _core_endclass) && !_IS_FUNC(obj, _core_endclass) &&
#endif /* MB_ENABLE_CLASS */ #endif /* MB_ENABLE_CLASS */
true true;
;
} }
#endif /* MB_ENABLE_LAMBDA */ #endif /* MB_ENABLE_LAMBDA */
@ -6663,7 +6679,7 @@ _ls_node_t* _search_identifier_accessor(mb_interpreter_t* s, _running_context_t*
instance = obj->data.instance; instance = obj->data.instance;
break; break;
case _DT_ROUTINE: case _DT_ROUTINE: /* Do nothing */
break; break;
default: default:
mb_assert(0 && "Unsupported."); mb_assert(0 && "Unsupported.");
@ -7034,6 +7050,7 @@ int _clone_object(mb_interpreter_t* s, _object_t* obj, _object_t* tgt) {
tgt->data.string = mb_strdup(obj->data.string, 0); tgt->data.string = mb_strdup(obj->data.string, 0);
break; break;
#ifdef MB_ENABLE_USERTYPE_REF
case _DT_USERTYPE_REF: case _DT_USERTYPE_REF:
tgt->data.usertype_ref = _create_usertype_ref( tgt->data.usertype_ref = _create_usertype_ref(
obj->data.usertype_ref->ref.s, obj->data.usertype_ref->ref.s,
@ -7044,6 +7061,7 @@ int _clone_object(mb_interpreter_t* s, _object_t* obj, _object_t* tgt) {
_ref(&tgt->data.usertype_ref->ref, tgt->data.usertype_ref); _ref(&tgt->data.usertype_ref->ref, tgt->data.usertype_ref);
break; break;
#endif /* MB_ENABLE_USERTYPE_REF */
case _DT_FUNC: case _DT_FUNC:
tgt->data.func->name = mb_strdup(obj->data.func->name, strlen(obj->data.func->name) + 1); tgt->data.func->name = mb_strdup(obj->data.func->name, strlen(obj->data.func->name) + 1);
tgt->data.func->pointer = obj->data.func->pointer; tgt->data.func->pointer = obj->data.func->pointer;
@ -7415,8 +7433,10 @@ _data_e _public_type_to_internal_type(mb_data_e t) {
return _DT_STRING; return _DT_STRING;
case MB_DT_USERTYPE: case MB_DT_USERTYPE:
return _DT_USERTYPE; return _DT_USERTYPE;
#ifdef MB_ENABLE_USERTYPE_REF
case MB_DT_USERTYPE_REF: case MB_DT_USERTYPE_REF:
return _DT_USERTYPE_REF; return _DT_USERTYPE_REF;
#endif /* MB_ENABLE_USERTYPE_REF */
case MB_DT_ARRAY: case MB_DT_ARRAY:
return _DT_ARRAY; return _DT_ARRAY;
#ifdef MB_ENABLE_COLLECTION_LIB #ifdef MB_ENABLE_COLLECTION_LIB
@ -7455,8 +7475,10 @@ mb_data_e _internal_type_to_public_type(_data_e t) {
return MB_DT_STRING; return MB_DT_STRING;
case _DT_USERTYPE: case _DT_USERTYPE:
return MB_DT_USERTYPE; return MB_DT_USERTYPE;
#ifdef MB_ENABLE_USERTYPE_REF
case _DT_USERTYPE_REF: case _DT_USERTYPE_REF:
return MB_DT_USERTYPE_REF; return MB_DT_USERTYPE_REF;
#endif /* MB_ENABLE_USERTYPE_REF */
case _DT_ARRAY: case _DT_ARRAY:
return MB_DT_ARRAY; return MB_DT_ARRAY;
#ifdef MB_ENABLE_COLLECTION_LIB #ifdef MB_ENABLE_COLLECTION_LIB
@ -7520,11 +7542,13 @@ int _public_value_to_internal_object(mb_value_t* pbl, _object_t* itn) {
memcpy(itn->data.raw, pbl->value.bytes, sizeof(mb_val_bytes_t)); memcpy(itn->data.raw, pbl->value.bytes, sizeof(mb_val_bytes_t));
break; break;
#ifdef MB_ENABLE_USERTYPE_REF
case MB_DT_USERTYPE_REF: case MB_DT_USERTYPE_REF:
itn->type = _DT_USERTYPE_REF; itn->type = _DT_USERTYPE_REF;
itn->data.usertype_ref = (_usertype_ref_t*)pbl->value.usertype_ref; itn->data.usertype_ref = (_usertype_ref_t*)pbl->value.usertype_ref;
break; break;
#endif /* MB_ENABLE_USERTYPE_REF */
case MB_DT_ARRAY: case MB_DT_ARRAY:
itn->type = _DT_ARRAY; itn->type = _DT_ARRAY;
itn->data.array = (_array_t*)pbl->value.array; itn->data.array = (_array_t*)pbl->value.array;
@ -7614,11 +7638,13 @@ int _internal_object_to_public_value(_object_t* itn, mb_value_t* pbl) {
memcpy(pbl->value.bytes, itn->data.raw, sizeof(mb_val_bytes_t)); memcpy(pbl->value.bytes, itn->data.raw, sizeof(mb_val_bytes_t));
break; break;
#ifdef MB_ENABLE_USERTYPE_REF
case _DT_USERTYPE_REF: case _DT_USERTYPE_REF:
pbl->type = MB_DT_USERTYPE_REF; pbl->type = MB_DT_USERTYPE_REF;
pbl->value.usertype_ref = itn->data.usertype_ref; pbl->value.usertype_ref = itn->data.usertype_ref;
break; break;
#endif /* MB_ENABLE_USERTYPE_REF */
case _DT_ARRAY: case _DT_ARRAY:
pbl->type = MB_DT_ARRAY; pbl->type = MB_DT_ARRAY;
pbl->value.array = itn->data.array; pbl->value.array = itn->data.array;
@ -9819,6 +9845,7 @@ _exit:
int mb_make_ref_value(struct mb_interpreter_t* s, void* val, mb_value_t* out, mb_dtor_func_t un, mb_clone_func_t cl, mb_hash_func_t hs, mb_cmp_func_t cp, mb_fmt_func_t ft) { int mb_make_ref_value(struct mb_interpreter_t* s, void* val, mb_value_t* out, mb_dtor_func_t un, mb_clone_func_t cl, mb_hash_func_t hs, mb_cmp_func_t cp, mb_fmt_func_t ft) {
/* Create a referenced usertype value */ /* Create a referenced usertype value */
#ifdef MB_ENABLE_USERTYPE_REF
int result = MB_FUNC_OK; int result = MB_FUNC_OK;
_usertype_ref_t* ref = 0; _usertype_ref_t* ref = 0;
@ -9831,10 +9858,23 @@ int mb_make_ref_value(struct mb_interpreter_t* s, void* val, mb_value_t* out, mb
} }
return result; return result;
#else /* MB_ENABLE_USERTYPE_REF */
mb_unrefvar(s);
mb_unrefvar(val);
mb_unrefvar(out);
mb_unrefvar(un);
mb_unrefvar(cl);
mb_unrefvar(hs);
mb_unrefvar(cp);
mb_unrefvar(ft);
return MB_FUNC_ERR;
#endif /* MB_ENABLE_USERTYPE_REF */
} }
int mb_get_ref_value(struct mb_interpreter_t* s, void** l, mb_value_t val, void** out) { int mb_get_ref_value(struct mb_interpreter_t* s, void** l, mb_value_t val, void** out) {
/* Get the data of a referenced usertype value */ /* Get the data of a referenced usertype value */
#ifdef MB_ENABLE_USERTYPE_REF
int result = MB_FUNC_OK; int result = MB_FUNC_OK;
_usertype_ref_t* ref = 0; _usertype_ref_t* ref = 0;
@ -9851,6 +9891,14 @@ int mb_get_ref_value(struct mb_interpreter_t* s, void** l, mb_value_t val, void*
_exit: _exit:
return result; return result;
#else /* MB_ENABLE_USERTYPE_REF */
mb_unrefvar(s);
mb_unrefvar(l);
mb_unrefvar(val);
mb_unrefvar(out);
return MB_FUNC_ERR;
#endif /* MB_ENABLE_USERTYPE_REF */
} }
int mb_ref_value(struct mb_interpreter_t* s, void** l, mb_value_t val) { int mb_ref_value(struct mb_interpreter_t* s, void** l, mb_value_t val) {
@ -10275,8 +10323,10 @@ const char* mb_get_type_string(mb_data_e t) {
return "STRING"; return "STRING";
case MB_DT_USERTYPE: case MB_DT_USERTYPE:
return "USERTYPE"; return "USERTYPE";
#ifdef MB_ENABLE_USERTYPE_REF
case MB_DT_USERTYPE_REF: case MB_DT_USERTYPE_REF:
return "USERTYPE_REF"; return "USERTYPE_REF";
#endif /* MB_ENABLE_USERTYPE_REF */
case MB_DT_ARRAY: case MB_DT_ARRAY:
return "ARRAY"; return "ARRAY";
#ifdef MB_ENABLE_COLLECTION_LIB #ifdef MB_ENABLE_COLLECTION_LIB
@ -11072,7 +11122,9 @@ _proc_extra_var:
} }
} else if(arr && literally) { } else if(arr && literally) {
if(val->type != _DT_UNKNOWN) { if(val->type != _DT_UNKNOWN) {
#ifdef MB_ENABLE_ARRAY_REF
_unref(&arr_obj->data.array->ref, arr_obj->data.array); _unref(&arr_obj->data.array->ref, arr_obj->data.array);
#endif /* MB_ENABLE_ARRAY_REF */
arr_obj->type = val->type; arr_obj->type = val->type;
#ifdef MB_ENABLE_COLLECTION_LIB #ifdef MB_ENABLE_COLLECTION_LIB
if(val->type == _DT_LIST_IT || val->type == _DT_DICT_IT) if(val->type == _DT_LIST_IT || val->type == _DT_DICT_IT)
@ -11174,7 +11226,9 @@ int _core_dim(mb_interpreter_t* s, void** l) {
} }
/* Create or modify raw data */ /* Create or modify raw data */
_clear_array(arr->data.array); _clear_array(arr->data.array);
#ifdef MB_ENABLE_ARRAY_REF
dummy.ref = arr->data.array->ref; dummy.ref = arr->data.array->ref;
#endif /* MB_ENABLE_ARRAY_REF */
*(arr->data.array) = dummy; *(arr->data.array) = dummy;
_init_array(arr->data.array); _init_array(arr->data.array);
if(!arr->data.array->raw) { if(!arr->data.array->raw) {

View File

@ -38,6 +38,10 @@ extern "C" {
# define MB_SIMPLE_ARRAY # define MB_SIMPLE_ARRAY
#endif /* MB_SIMPLE_ARRAY */ #endif /* MB_SIMPLE_ARRAY */
#ifndef MB_ENABLE_ARRAY_REF
# define MB_ENABLE_ARRAY_REF
#endif /* MB_ENABLE_ARRAY_REF */
#ifndef MB_MAX_DIMENSION_COUNT #ifndef MB_MAX_DIMENSION_COUNT
# define MB_MAX_DIMENSION_COUNT 4 # define MB_MAX_DIMENSION_COUNT 4
#endif /* MB_MAX_DIMENSION_COUNT */ #endif /* MB_MAX_DIMENSION_COUNT */
@ -85,6 +89,10 @@ extern "C" {
# define MB_ENABLE_MODULE # define MB_ENABLE_MODULE
#endif /* MB_ENABLE_MODULE */ #endif /* MB_ENABLE_MODULE */
#ifndef MB_ENABLE_USERTYPE_REF
# define MB_ENABLE_USERTYPE_REF
#endif /* MB_ENABLE_USERTYPE_REF */
#ifndef MB_ENABLE_CLASS #ifndef MB_ENABLE_CLASS
# define MB_ENABLE_CLASS # define MB_ENABLE_CLASS
#endif /* MB_ENABLE_CLASS */ #endif /* MB_ENABLE_CLASS */
@ -352,7 +360,9 @@ typedef enum mb_data_e {
MB_DT_NUM = 1 << 5, MB_DT_NUM = 1 << 5,
MB_DT_STRING = 1 << 6, MB_DT_STRING = 1 << 6,
MB_DT_USERTYPE = 1 << 7, MB_DT_USERTYPE = 1 << 7,
#ifdef MB_ENABLE_USERTYPE_REF
MB_DT_USERTYPE_REF = 1 << 8, MB_DT_USERTYPE_REF = 1 << 8,
#endif /* MB_ENABLE_USERTYPE_REF */
MB_DT_ARRAY = 1 << 9, MB_DT_ARRAY = 1 << 9,
#ifdef MB_ENABLE_COLLECTION_LIB #ifdef MB_ENABLE_COLLECTION_LIB
MB_DT_LIST = 1 << 10, MB_DT_LIST = 1 << 10,
@ -374,7 +384,9 @@ typedef union mb_value_u {
real_t float_point; real_t float_point;
char* string; char* string;
void* usertype; void* usertype;
#ifdef MB_ENABLE_USERTYPE_REF
void* usertype_ref; void* usertype_ref;
#endif /* MB_ENABLE_USERTYPE_REF */
void* array; void* array;
#ifdef MB_ENABLE_COLLECTION_LIB #ifdef MB_ENABLE_COLLECTION_LIB
void* list; void* list;