+added stack tracing; +added an mb_debug_get_stack_trace function and an MB_ENABLE_STACK_TRACE macro; *polished document.
This commit is contained in:
parent
468df58c6f
commit
d0913e2735
2
HISTORY
2
HISTORY
@ -1,4 +1,6 @@
|
|||||||
Jan. 4 2016
|
Jan. 4 2016
|
||||||
|
Added stack tracing
|
||||||
|
Added an mb_debug_get_stack_trace function and an MB_ENABLE_STACK_TRACE macro
|
||||||
Added support to duplicate a class instance by NEW statement with an identifier string
|
Added support to duplicate a class instance by NEW statement with an identifier string
|
||||||
Fixed a string value copy issue in mb_pop_value
|
Fixed a string value copy issue in mb_pop_value
|
||||||
|
|
||||||
|
Binary file not shown.
@ -264,6 +264,7 @@ static const char* _ERR_DESC[] = {
|
|||||||
"Invalid iterator",
|
"Invalid iterator",
|
||||||
"Empty collection",
|
"Empty collection",
|
||||||
"Referenced type expected",
|
"Referenced type expected",
|
||||||
|
"Stack trace disabled",
|
||||||
/** Extended abort */
|
/** Extended abort */
|
||||||
"Extended abort"
|
"Extended abort"
|
||||||
};
|
};
|
||||||
@ -619,6 +620,9 @@ typedef struct mb_interpreter_t {
|
|||||||
int last_error_pos;
|
int last_error_pos;
|
||||||
unsigned short last_error_row;
|
unsigned short last_error_row;
|
||||||
unsigned short last_error_col;
|
unsigned short last_error_col;
|
||||||
|
#ifdef MB_ENABLE_STACK_TRACE
|
||||||
|
_ls_node_t* stack_frames;
|
||||||
|
#endif /* MB_ENABLE_STACK_TRACE */
|
||||||
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;
|
||||||
@ -2761,7 +2765,13 @@ _array:
|
|||||||
} else if(c->type == _DT_FUNC) {
|
} else if(c->type == _DT_FUNC) {
|
||||||
ast = ast->prev;
|
ast = ast->prev;
|
||||||
if(_IS_UNARY_FUNC(c)) {
|
if(_IS_UNARY_FUNC(c)) {
|
||||||
|
#ifdef MB_ENABLE_STACK_TRACE
|
||||||
|
_ls_pushback(s->stack_frames, c->data.func->name);
|
||||||
|
#endif /* MB_ENABLE_STACK_TRACE */
|
||||||
result = (c->data.func->pointer)(s, (void**)&ast);
|
result = (c->data.func->pointer)(s, (void**)&ast);
|
||||||
|
#ifdef MB_ENABLE_STACK_TRACE
|
||||||
|
_ls_popback(s->stack_frames);
|
||||||
|
#endif /* MB_ENABLE_STACK_TRACE */
|
||||||
} else {
|
} else {
|
||||||
int calc_depth = running->calc_depth;
|
int calc_depth = running->calc_depth;
|
||||||
running->calc_depth = _INFINITY_CALC_DEPTH;
|
running->calc_depth = _INFINITY_CALC_DEPTH;
|
||||||
@ -3089,6 +3099,10 @@ int _eval_routine(mb_interpreter_t* s, _ls_node_t** l, mb_value_t* va, unsigned
|
|||||||
/* Evaluate a routine */
|
/* Evaluate a routine */
|
||||||
int result = MB_FUNC_OK;
|
int result = MB_FUNC_OK;
|
||||||
|
|
||||||
|
#ifdef MB_ENABLE_STACK_TRACE
|
||||||
|
_ls_pushback(s->stack_frames, r->name);
|
||||||
|
#endif /* MB_ENABLE_STACK_TRACE */
|
||||||
|
|
||||||
if(r->is_basic && r->func.basic.entry) {
|
if(r->is_basic && r->func.basic.entry) {
|
||||||
result = _eval_script_routine(s, l, va, ca, r, has_arg, pop_arg);
|
result = _eval_script_routine(s, l, va, ca, r, has_arg, pop_arg);
|
||||||
} else if(!r->is_basic && r->func.native.entry) {
|
} else if(!r->is_basic && r->func.native.entry) {
|
||||||
@ -3098,6 +3112,10 @@ int _eval_routine(mb_interpreter_t* s, _ls_node_t** l, mb_value_t* va, unsigned
|
|||||||
}
|
}
|
||||||
|
|
||||||
_exit:
|
_exit:
|
||||||
|
#ifdef MB_ENABLE_STACK_TRACE
|
||||||
|
_ls_popback(s->stack_frames);
|
||||||
|
#endif /* MB_ENABLE_STACK_TRACE */
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -7138,7 +7156,13 @@ int _execute_statement(mb_interpreter_t* s, _ls_node_t** l) {
|
|||||||
_retry:
|
_retry:
|
||||||
switch(obj->type) {
|
switch(obj->type) {
|
||||||
case _DT_FUNC:
|
case _DT_FUNC:
|
||||||
|
#ifdef MB_ENABLE_STACK_TRACE
|
||||||
|
_ls_pushback(s->stack_frames, obj->data.func->name);
|
||||||
|
#endif /* MB_ENABLE_STACK_TRACE */
|
||||||
result = (obj->data.func->pointer)(s, (void**)&ast);
|
result = (obj->data.func->pointer)(s, (void**)&ast);
|
||||||
|
#ifdef MB_ENABLE_STACK_TRACE
|
||||||
|
_ls_popback(s->stack_frames);
|
||||||
|
#endif /* MB_ENABLE_STACK_TRACE */
|
||||||
if(result == MB_FUNC_IGNORE) {
|
if(result == MB_FUNC_IGNORE) {
|
||||||
result = MB_FUNC_OK;
|
result = MB_FUNC_OK;
|
||||||
obj = (_object_t*)ast->data;
|
obj = (_object_t*)ast->data;
|
||||||
@ -7843,17 +7867,21 @@ int mb_open(struct mb_interpreter_t** s) {
|
|||||||
(*s)->temp_values = _ls_create();
|
(*s)->temp_values = _ls_create();
|
||||||
(*s)->lazy_destroy_objects = _ls_create();
|
(*s)->lazy_destroy_objects = _ls_create();
|
||||||
|
|
||||||
|
#ifdef MB_ENABLE_GC
|
||||||
|
(*s)->gc.table = _ht_create(0, _ht_cmp_ref, _ht_hash_ref, _do_nothing_on_object);
|
||||||
|
(*s)->gc.recursive_table = _ht_create(0, _ht_cmp_ref, _ht_hash_ref, _do_nothing_on_object);
|
||||||
|
(*s)->gc.collected_table = _ht_create(0, _ht_cmp_ref, _ht_hash_ref, _do_nothing_on_object);
|
||||||
|
#endif /* MB_ENABLE_GC */
|
||||||
|
|
||||||
running = _create_running_context();
|
running = _create_running_context();
|
||||||
running->meta = _SCOPE_META_ROOT;
|
running->meta = _SCOPE_META_ROOT;
|
||||||
(*s)->running_context = running;
|
(*s)->running_context = running;
|
||||||
global_scope = _ht_create(0, _ht_cmp_string, _ht_hash_string, 0);
|
global_scope = _ht_create(0, _ht_cmp_string, _ht_hash_string, 0);
|
||||||
running->var_dict = global_scope;
|
running->var_dict = global_scope;
|
||||||
|
|
||||||
#ifdef MB_ENABLE_GC
|
#ifdef MB_ENABLE_STACK_TRACE
|
||||||
(*s)->gc.table = _ht_create(0, _ht_cmp_ref, _ht_hash_ref, _do_nothing_on_object);
|
(*s)->stack_frames = _ls_create();
|
||||||
(*s)->gc.recursive_table = _ht_create(0, _ht_cmp_ref, _ht_hash_ref, _do_nothing_on_object);
|
#endif /* MB_ENABLE_STACK_TRACE */
|
||||||
(*s)->gc.collected_table = _ht_create(0, _ht_cmp_ref, _ht_hash_ref, _do_nothing_on_object);
|
|
||||||
#endif /* MB_ENABLE_GC */
|
|
||||||
|
|
||||||
(*s)->sub_stack = _ls_create();
|
(*s)->sub_stack = _ls_create();
|
||||||
|
|
||||||
@ -7892,6 +7920,10 @@ int mb_close(struct mb_interpreter_t** s) {
|
|||||||
|
|
||||||
_ls_destroy((*s)->sub_stack);
|
_ls_destroy((*s)->sub_stack);
|
||||||
|
|
||||||
|
#ifdef MB_ENABLE_STACK_TRACE
|
||||||
|
_ls_destroy((*s)->stack_frames);
|
||||||
|
#endif /* MB_ENABLE_STACK_TRACE */
|
||||||
|
|
||||||
_tidy_scope_chain(*s);
|
_tidy_scope_chain(*s);
|
||||||
_dispose_scope_chain(*s);
|
_dispose_scope_chain(*s);
|
||||||
|
|
||||||
@ -7965,6 +7997,10 @@ int mb_reset(struct mb_interpreter_t** s, bool_t clrf/* = false*/) {
|
|||||||
_ls_foreach(ast, _destroy_object);
|
_ls_foreach(ast, _destroy_object);
|
||||||
_ls_clear(ast);
|
_ls_clear(ast);
|
||||||
|
|
||||||
|
#ifdef MB_ENABLE_STACK_TRACE
|
||||||
|
_ls_clear((*s)->stack_frames);
|
||||||
|
#endif /* MB_ENABLE_STACK_TRACE */
|
||||||
|
|
||||||
_clear_scope_chain(*s);
|
_clear_scope_chain(*s);
|
||||||
|
|
||||||
if(clrf) {
|
if(clrf) {
|
||||||
@ -9398,6 +9434,39 @@ int mb_debug_set(struct mb_interpreter_t* s, const char* n, mb_value_t val) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int mb_debug_get_stack_trace(struct mb_interpreter_t* s, void** l, char** fs, unsigned fc) {
|
||||||
|
/* Get stack frame names of an interpreter instance */
|
||||||
|
#ifdef MB_ENABLE_STACK_TRACE
|
||||||
|
int result = MB_FUNC_OK;
|
||||||
|
_ls_node_t* f = 0;
|
||||||
|
unsigned i = 0;
|
||||||
|
mb_unrefvar(l);
|
||||||
|
|
||||||
|
mb_assert(s);
|
||||||
|
|
||||||
|
if(fs && fc) {
|
||||||
|
f = s->stack_frames->prev;
|
||||||
|
while(f && f->data && i < fc) {
|
||||||
|
fs[i++] = (char*)f->data;
|
||||||
|
f = f->prev;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while(i < fc)
|
||||||
|
fs[i++] = 0;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
#else /* MB_ENABLE_STACK_TRACE */
|
||||||
|
int result = MB_FUNC_OK;
|
||||||
|
mb_unrefvar(fs);
|
||||||
|
mb_unrefvar(fc);
|
||||||
|
|
||||||
|
_handle_error_on_obj(s, SE_RN_STACK_TRACE_DISABLED, 0, TON(l), MB_FUNC_ERR, _exit, result);
|
||||||
|
|
||||||
|
_exit:
|
||||||
|
return result;
|
||||||
|
#endif /* MB_ENABLE_STACK_TRACE */
|
||||||
|
}
|
||||||
|
|
||||||
int mb_debug_set_stepped_handler(struct mb_interpreter_t* s, mb_debug_stepped_handler_t h) {
|
int mb_debug_set_stepped_handler(struct mb_interpreter_t* s, mb_debug_stepped_handler_t h) {
|
||||||
/* Set a stepped handler to an interpreter instance */
|
/* Set a stepped handler to an interpreter instance */
|
||||||
int result = MB_FUNC_OK;
|
int result = MB_FUNC_OK;
|
||||||
|
@ -62,6 +62,10 @@ extern "C" {
|
|||||||
# define MB_ENABLE_SOURCE_TRACE
|
# define MB_ENABLE_SOURCE_TRACE
|
||||||
#endif /* MB_ENABLE_SOURCE_TRACE */
|
#endif /* MB_ENABLE_SOURCE_TRACE */
|
||||||
|
|
||||||
|
#ifndef MB_ENABLE_STACK_TRACE
|
||||||
|
# define MB_ENABLE_STACK_TRACE
|
||||||
|
#endif /* MB_ENABLE_STACK_TRACE */
|
||||||
|
|
||||||
#ifndef MB_ENABLE_UNICODE
|
#ifndef MB_ENABLE_UNICODE
|
||||||
# define MB_ENABLE_UNICODE
|
# define MB_ENABLE_UNICODE
|
||||||
#endif /* MB_ENABLE_UNICODE */
|
#endif /* MB_ENABLE_UNICODE */
|
||||||
@ -327,6 +331,7 @@ typedef enum mb_error_e {
|
|||||||
SE_RN_INVALID_ITERATOR,
|
SE_RN_INVALID_ITERATOR,
|
||||||
SE_RN_EMPTY_COLLECTION,
|
SE_RN_EMPTY_COLLECTION,
|
||||||
SE_RN_REFERENCED_EXPECTED,
|
SE_RN_REFERENCED_EXPECTED,
|
||||||
|
SE_RN_STACK_TRACE_DISABLED,
|
||||||
/** Extended abort */
|
/** Extended abort */
|
||||||
SE_EA_EXTENDED_ABORT,
|
SE_EA_EXTENDED_ABORT,
|
||||||
/** Extra */
|
/** Extra */
|
||||||
@ -472,6 +477,7 @@ MBAPI int mb_schedule_suspend(struct mb_interpreter_t* s, int t);
|
|||||||
|
|
||||||
MBAPI int mb_debug_get(struct mb_interpreter_t* s, const char* n, mb_value_t* val);
|
MBAPI int mb_debug_get(struct mb_interpreter_t* s, const char* n, mb_value_t* val);
|
||||||
MBAPI int mb_debug_set(struct mb_interpreter_t* s, const char* n, mb_value_t val);
|
MBAPI int mb_debug_set(struct mb_interpreter_t* s, const char* n, mb_value_t val);
|
||||||
|
MBAPI int mb_debug_get_stack_trace(struct mb_interpreter_t* s, void** l, char** fs, unsigned fc);
|
||||||
MBAPI int mb_debug_set_stepped_handler(struct mb_interpreter_t* s, mb_debug_stepped_handler_t h);
|
MBAPI int mb_debug_set_stepped_handler(struct mb_interpreter_t* s, mb_debug_stepped_handler_t h);
|
||||||
|
|
||||||
MBAPI const char* mb_get_type_string(mb_data_e t);
|
MBAPI const char* mb_get_type_string(mb_data_e t);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user