From bbee31ea55beb93fc9d2ce29019d9d215b97721f Mon Sep 17 00:00:00 2001 From: ValKmjolnir Date: Sun, 17 Oct 2021 22:57:45 +0800 Subject: [PATCH] add detail crash info --- main.cpp | 12 ++++-- makefile | 5 +++ nasal.h | 19 --------- nasal_vm.h | 122 +++++++++++++++++++++++++++++++++++------------------ 4 files changed, 93 insertions(+), 65 deletions(-) create mode 100644 makefile diff --git a/main.cpp b/main.cpp index 4012cd6..8ecdabd 100644 --- a/main.cpp +++ b/main.cpp @@ -5,6 +5,7 @@ constexpr uint32_t VM_CODEINFO =4; constexpr uint32_t VM_EXECTIME =8; constexpr uint32_t VM_OPCALLNUM=16; constexpr uint32_t VM_EXEC =32; +constexpr uint32_t VM_DBGINFO =64; void help() { std::cout @@ -25,6 +26,7 @@ void help() <<" -c, --code | view bytecode.\n" <<" -t, --time | execute and get the running time.\n" <<" -o, --opcnt | count operands while running.\n" + <<" -d, --detail | get detail crash info.\n" <<"file:\n" <<" input file name to execute script file.\n"; } @@ -59,7 +61,7 @@ void err() std::exit(1); } -void execute(const std::string& file,const uint16_t cmd) +void execute(const std::string& file,const uint32_t cmd) { nasal_lexer lexer; nasal_parse parse; @@ -96,11 +98,11 @@ void execute(const std::string& file,const uint16_t cmd) if(cmd&VM_EXECTIME) { clock_t t=clock(); - vm.run(gen,linker,cmd&VM_OPCALLNUM); + vm.run(gen,linker,cmd&VM_OPCALLNUM,cmd&VM_DBGINFO); std::cout<<"process exited after "<<((double)(clock()-t))/CLOCKS_PER_SEC<<"s.\n"; } else if(cmd&VM_EXEC) - vm.run(gen,linker,cmd&VM_OPCALLNUM); + vm.run(gen,linker,cmd&VM_OPCALLNUM,cmd&VM_DBGINFO); } int main(int argc,const char* argv[]) @@ -113,7 +115,7 @@ int main(int argc,const char* argv[]) execute(argv[1],VM_EXEC); else if(argc>=3) { - uint16_t cmd=0; + uint32_t cmd=0; for(int i=1;i #include -class nasal_err -{ -private: - uint32_t error; - std::string stage; -public: - nasal_err( - const uint32_t _error, - const std::string _stage - ):error(_error),stage(_stage){} - void unwarp(const std::string& error_file) - { - if(!error) - return; - std::cout<<"["<: error(s) occurred,stop.\n"; - std::exit(1); - } -}; - /* check if a string can be converted to a number if this string cannot be converted to a number,it will return nan diff --git a/nasal_vm.h b/nasal_vm.h index 1c19a93..6e7aa93 100644 --- a/nasal_vm.h +++ b/nasal_vm.h @@ -27,11 +27,14 @@ private: const std::vector&); void clear(); /* debug functions */ + bool detail_info; + void valinfo(nasal_ref&); void bytecodeinfo(const uint32_t); void traceback(); void stackinfo(const uint32_t); + void detail(); + void opcallsort(const uint64_t*); void die(std::string); - void stackoverflow(); /* vm calculation functions*/ bool condition(nasal_ref); void opr_nop(); @@ -115,7 +118,11 @@ private: public: nasal_vm():stack_top(gc.stack_top){} ~nasal_vm(){clear();} - void run(const nasal_codegen&,const nasal_import&,const bool); + void run( + const nasal_codegen&, + const nasal_import&, + const bool, + const bool); }; void nasal_vm::init( @@ -136,6 +143,22 @@ void nasal_vm::clear() while(!counter.empty()) counter.pop(); str_table.clear(); + imm.clear(); +} +void nasal_vm::valinfo(nasal_ref& val) +{ + const nasal_val* ptr=val.value.gcobj; + switch(val.type) + { + case vm_none: printf("\tnull |\n");break; + case vm_nil: printf("\tnil |\n");break; + case vm_num: printf("\tnum | %lf\n",val.num());break; + case vm_str: printf("\tstr | <%p> %s\n",ptr,raw_string(*val.str()).c_str());break; + case vm_func: printf("\tfunc | <%p> func{entry=0x%x}\n",ptr,val.func()->entry);break; + case vm_vec: printf("\tvec | <%p> [%lu val]\n",ptr,val.vec()->elems.size());break; + case vm_hash: printf("\thash | <%p> {%lu member}\n",ptr,val.hash()->elems.size());break; + case vm_obj: printf("\tobj | <%p>\n",ptr);break; + } } void nasal_vm::bytecodeinfo(const uint32_t p) { @@ -143,10 +166,12 @@ void nasal_vm::bytecodeinfo(const uint32_t p) printf("\t0x%.8x: %s 0x%x",p,code_table[code.op].name,code.num); if(code.op==op_callb) printf(" <%s>",builtin_func[code.num].name); - printf(" (%s line %d)\n",files[code.fidx].c_str(),code.line); + printf(" (<%s> line %d)\n",files[code.fidx].c_str(),code.line); } void nasal_vm::traceback() { + // push pc to ret stack to store the position program crashed + ret.push(pc); printf("trace back:\n"); uint32_t same_cnt=0,last_point=0xffffffff; for(uint32_t point=0;!ret.empty();last_point=point,ret.pop()) @@ -185,36 +210,58 @@ void nasal_vm::stackinfo(const uint32_t limit) same_cnt=0; } last_ptr=stack_top[0]; - const nasal_val* ptr=stack_top[0].value.gcobj; - switch(stack_top[0].type) - { - case vm_none: printf("\tnull |\n");break; - case vm_nil: printf("\tnil |\n");break; - case vm_num: printf("\tnum | %lf\n",stack_top[0].num());break; - case vm_str: printf("\tstr | <%p> %s\n",ptr,raw_string(*stack_top[0].str()).c_str());break; - case vm_func: printf("\tfunc | <%p> func{entry=0x%x}\n",ptr,stack_top[0].func()->entry);break; - case vm_vec: printf("\tvec | <%p> [%lu val]\n",ptr,stack_top[0].vec()->elems.size());break; - case vm_hash: printf("\thash | <%p> {%lu member}\n",ptr,stack_top[0].hash()->elems.size());break; - case vm_obj: printf("\tobj | <%p>\n",ptr);break; - } + valinfo(stack_top[0]); } if(same_cnt) printf("\t... | %d same value(s)\n",same_cnt); } +void nasal_vm::detail() +{ + printf("mcall address: %p\n",mem_addr); + printf("global value:\n"); + // bytecode[0] is op_intg + for(uint32_t i=0;ielems; + for(uint32_t i=0;i op; + std::vector opcall; + for(uint32_t i=0;i<=op_exit;++i) + opcall.push_back({i,arr[i]}); + std::sort( + opcall.begin(), + opcall.end(), + [](op& a,op& b){return a.second>b.second;} + ); + std::cout<<'\n'; + for(auto& i:opcall) + { + if(!i.second) + break; + std::cout<maxnum) - { - index=j; - maxnum=count[j]; - } - std::cout<