show vm stack top's info when error occurs
This commit is contained in:
parent
7a93f5b89b
commit
61677101e4
60
nasal_vm.h
60
nasal_vm.h
|
@ -8,7 +8,7 @@ private:
|
||||||
nasal_val**& stack_top;// stack top
|
nasal_val**& stack_top;// stack top
|
||||||
/* values of nasal_vm */
|
/* values of nasal_vm */
|
||||||
uint32_t pc; // program counter
|
uint32_t pc; // program counter
|
||||||
std::stack<int> ret; // ptr stack stores address for function to return
|
std::stack<uint32_t> ret; // ptr stack stores address for function to return
|
||||||
std::stack<int> counter; // iterator stack for forindex/foreach
|
std::stack<int> counter; // iterator stack for forindex/foreach
|
||||||
std::vector<double> num_table;// numbers used in process(const calculation)
|
std::vector<double> num_table;// numbers used in process(const calculation)
|
||||||
std::vector<std::string> str_table;// symbols used in process
|
std::vector<std::string> str_table;// symbols used in process
|
||||||
|
@ -132,7 +132,7 @@ void nasal_vm::clear()
|
||||||
}
|
}
|
||||||
void nasal_vm::die(std::string str)
|
void nasal_vm::die(std::string str)
|
||||||
{
|
{
|
||||||
printf(">> [vm] error: %s\ntrace back:\n",str.c_str());
|
printf(">> [vm] error at 0x%.8x: %s\ntrace back:\n",pc,str.c_str());
|
||||||
// add error pc into ret_stack
|
// add error pc into ret_stack
|
||||||
ret.push(pc);
|
ret.push(pc);
|
||||||
// trace back will use ret_stack
|
// trace back will use ret_stack
|
||||||
|
@ -141,13 +141,31 @@ void nasal_vm::die(std::string str)
|
||||||
uint32_t point=ret.top();
|
uint32_t point=ret.top();
|
||||||
ret.pop();
|
ret.pop();
|
||||||
printf(
|
printf(
|
||||||
"\tpc 0x%.8x: %s 0x%.8x (%s line %d)\n",
|
"\t0x%.8x: %s 0x%.8x (%s line %d)\n",
|
||||||
point,
|
point,
|
||||||
code_table[bytecode[point].op].name,
|
code_table[bytecode[point].op].name,
|
||||||
bytecode[point].num,
|
bytecode[point].num,
|
||||||
files[bytecode[point].fidx].c_str(),
|
files[bytecode[point].fidx].c_str(),
|
||||||
bytecode[point].line);
|
bytecode[point].line);
|
||||||
}
|
}
|
||||||
|
printf("vm stack(limit 10):\n");
|
||||||
|
for(int i=0;i<10 && stack_top-i>=gc.val_stack;++i)
|
||||||
|
{
|
||||||
|
printf("\t0x%.p ",stack_top[-i]);
|
||||||
|
if(!stack_top[-i])
|
||||||
|
printf(" nullptr\n");
|
||||||
|
else
|
||||||
|
switch(stack_top[-i]->type)
|
||||||
|
{
|
||||||
|
case vm_nil: printf("nil\n");break;
|
||||||
|
case vm_num: printf("num %lf\n",stack_top[-i]->ptr.num); break;
|
||||||
|
case vm_str: printf("str at %p\n",stack_top[-i]->ptr.str); break;
|
||||||
|
case vm_func: printf("func at %p\n",stack_top[-i]->ptr.func);break;
|
||||||
|
case vm_vec: printf("vec at %p\n",stack_top[-i]->ptr.vec); break;
|
||||||
|
case vm_hash: printf("hash at %p\n",stack_top[-i]->ptr.hash);break;
|
||||||
|
default: printf("unknown\n");break;
|
||||||
|
}
|
||||||
|
}
|
||||||
gc.val_stack[STACK_MAX_DEPTH-1]=(nasal_val*)0xffff;
|
gc.val_stack[STACK_MAX_DEPTH-1]=(nasal_val*)0xffff;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -277,21 +295,21 @@ inline void nasal_vm::opr_dynpara()
|
||||||
inline void nasal_vm::opr_unot()
|
inline void nasal_vm::opr_unot()
|
||||||
{
|
{
|
||||||
nasal_val* val=stack_top[0];
|
nasal_val* val=stack_top[0];
|
||||||
int type=val->type;
|
switch(val->type)
|
||||||
if(type==vm_nil)
|
|
||||||
stack_top[0]=gc.one_addr;
|
|
||||||
else if(type==vm_num)
|
|
||||||
stack_top[0]=val->ptr.num?gc.zero_addr:gc.one_addr;
|
|
||||||
else if(type==vm_str)
|
|
||||||
{
|
{
|
||||||
double num=str2num(val->ptr.str->c_str());
|
case vm_nil:stack_top[0]=gc.one_addr;break;
|
||||||
if(std::isnan(num))
|
case vm_num:stack_top[0]=val->ptr.num?gc.zero_addr:gc.one_addr;break;
|
||||||
stack_top[0]=val->ptr.str->empty()?gc.one_addr:gc.zero_addr;
|
case vm_str:
|
||||||
else
|
{
|
||||||
stack_top[0]=num?gc.zero_addr:gc.one_addr;
|
double num=str2num(val->ptr.str->c_str());
|
||||||
|
if(std::isnan(num))
|
||||||
|
stack_top[0]=val->ptr.str->empty()?gc.one_addr:gc.zero_addr;
|
||||||
|
else
|
||||||
|
stack_top[0]=num?gc.zero_addr:gc.one_addr;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:die("unot: incorrect value type");break;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
die("unot: incorrect value type");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
inline void nasal_vm::opr_usub()
|
inline void nasal_vm::opr_usub()
|
||||||
|
@ -897,7 +915,7 @@ inline void nasal_vm::opr_ret()
|
||||||
}
|
}
|
||||||
void nasal_vm::run(std::vector<opcode>& exec)
|
void nasal_vm::run(std::vector<opcode>& exec)
|
||||||
{
|
{
|
||||||
uint32_t count[op_ret+1]={0};
|
uint64_t count[op_ret+1]={0};
|
||||||
void* opr_table[]=
|
void* opr_table[]=
|
||||||
{
|
{
|
||||||
&&nop, &&intg, &&intl, &&offset,
|
&&nop, &&intg, &&intl, &&offset,
|
||||||
|
@ -929,19 +947,19 @@ void nasal_vm::run(std::vector<opcode>& exec)
|
||||||
imm.push_back(i.num);
|
imm.push_back(i.num);
|
||||||
}
|
}
|
||||||
|
|
||||||
nasal_val** canary=gc.val_stack+STACK_MAX_DEPTH-1;
|
auto& canary=gc.val_stack[STACK_MAX_DEPTH-1];
|
||||||
clock_t begin=clock();
|
clock_t begin=clock();
|
||||||
pc=0;
|
pc=0;
|
||||||
goto *code[pc];
|
goto *code[pc];
|
||||||
|
|
||||||
nop:
|
nop:
|
||||||
if(canary[0] && canary[0]!=(nasal_val*)0xffff)
|
if(canary && canary!=(nasal_val*)0xffff)
|
||||||
die("stack overflow");
|
die("stack overflow");
|
||||||
std::cout<<">> [vm] process exited after "<<((double)(clock()-begin))/CLOCKS_PER_SEC<<"s.\n";
|
std::cout<<">> [vm] process exited after "<<((double)(clock()-begin))/CLOCKS_PER_SEC<<"s.\n";
|
||||||
// debug
|
// debug
|
||||||
// for(int i=0;i<15;++i)
|
// for(int i=0;i<15;++i)
|
||||||
// {
|
// {
|
||||||
// int maxnum=0,index=0;
|
// uint64_t maxnum=0,index=0;
|
||||||
// for(int j=0;j<op_ret+1;++j)
|
// for(int j=0;j<op_ret+1;++j)
|
||||||
// if(count[j]>maxnum)
|
// if(count[j]>maxnum)
|
||||||
// {
|
// {
|
||||||
|
@ -953,7 +971,7 @@ nop:
|
||||||
// }
|
// }
|
||||||
return;
|
return;
|
||||||
//#define exec_operand(op,num) {op();++count[num];if(!canary[0])goto *code[++pc];goto nop;}
|
//#define exec_operand(op,num) {op();++count[num];if(!canary[0])goto *code[++pc];goto nop;}
|
||||||
#define exec_operand(op,num) {op();if(!canary[0])goto *code[++pc];goto nop;}
|
#define exec_operand(op,num) {op();if(!canary)goto *code[++pc];goto nop;}
|
||||||
//#define exec_opnodie(op,num) {op();++count[num];goto *code[++pc];}
|
//#define exec_opnodie(op,num) {op();++count[num];goto *code[++pc];}
|
||||||
#define exec_opnodie(op,num) {op();goto *code[++pc];}
|
#define exec_opnodie(op,num) {op();goto *code[++pc];}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue