+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:
paladin-t 2016-01-04 14:57:14 +08:00
parent 468df58c6f
commit d0913e2735
4 changed files with 82 additions and 5 deletions

View File

@ -1,4 +1,6 @@
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
Fixed a string value copy issue in mb_pop_value

Binary file not shown.

View File

@ -264,6 +264,7 @@ static const char* _ERR_DESC[] = {
"Invalid iterator",
"Empty collection",
"Referenced type expected",
"Stack trace disabled",
/** Extended abort */
"Extended abort"
};
@ -619,6 +620,9 @@ typedef struct mb_interpreter_t {
int last_error_pos;
unsigned short last_error_row;
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_error_handler_t error_handler;
mb_print_func_t printer;
@ -2761,7 +2765,13 @@ _array:
} else if(c->type == _DT_FUNC) {
ast = ast->prev;
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);
#ifdef MB_ENABLE_STACK_TRACE
_ls_popback(s->stack_frames);
#endif /* MB_ENABLE_STACK_TRACE */
} else {
int calc_depth = running->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 */
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) {
result = _eval_script_routine(s, l, va, ca, r, has_arg, pop_arg);
} 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:
#ifdef MB_ENABLE_STACK_TRACE
_ls_popback(s->stack_frames);
#endif /* MB_ENABLE_STACK_TRACE */
return result;
}
@ -7138,7 +7156,13 @@ int _execute_statement(mb_interpreter_t* s, _ls_node_t** l) {
_retry:
switch(obj->type) {
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);
#ifdef MB_ENABLE_STACK_TRACE
_ls_popback(s->stack_frames);
#endif /* MB_ENABLE_STACK_TRACE */
if(result == MB_FUNC_IGNORE) {
result = MB_FUNC_OK;
obj = (_object_t*)ast->data;
@ -7843,17 +7867,21 @@ int mb_open(struct mb_interpreter_t** s) {
(*s)->temp_values = _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->meta = _SCOPE_META_ROOT;
(*s)->running_context = running;
global_scope = _ht_create(0, _ht_cmp_string, _ht_hash_string, 0);
running->var_dict = global_scope;
#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 */
#ifdef MB_ENABLE_STACK_TRACE
(*s)->stack_frames = _ls_create();
#endif /* MB_ENABLE_STACK_TRACE */
(*s)->sub_stack = _ls_create();
@ -7892,6 +7920,10 @@ int mb_close(struct mb_interpreter_t** s) {
_ls_destroy((*s)->sub_stack);
#ifdef MB_ENABLE_STACK_TRACE
_ls_destroy((*s)->stack_frames);
#endif /* MB_ENABLE_STACK_TRACE */
_tidy_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_clear(ast);
#ifdef MB_ENABLE_STACK_TRACE
_ls_clear((*s)->stack_frames);
#endif /* MB_ENABLE_STACK_TRACE */
_clear_scope_chain(*s);
if(clrf) {
@ -9398,6 +9434,39 @@ int mb_debug_set(struct mb_interpreter_t* s, const char* n, mb_value_t val) {
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) {
/* Set a stepped handler to an interpreter instance */
int result = MB_FUNC_OK;

View File

@ -62,6 +62,10 @@ extern "C" {
# define 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
# define MB_ENABLE_UNICODE
#endif /* MB_ENABLE_UNICODE */
@ -327,6 +331,7 @@ typedef enum mb_error_e {
SE_RN_INVALID_ITERATOR,
SE_RN_EMPTY_COLLECTION,
SE_RN_REFERENCED_EXPECTED,
SE_RN_STACK_TRACE_DISABLED,
/** Extended abort */
SE_EA_EXTENDED_ABORT,
/** 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_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 const char* mb_get_type_string(mb_data_e t);