⚡ optimize code & replace all `printf` with `std::cout`.
This commit is contained in:
parent
2ed20f6362
commit
bcdc55a652
2
lib.nas
2
lib.nas
|
@ -1,7 +1,7 @@
|
|||
# lib.nas
|
||||
|
||||
# print is used to print all things in nasal, try and see how it works.
|
||||
# this function uses std::cout/printf to output logs.
|
||||
# this function uses std::cout to output logs.
|
||||
var print=func(elems...){
|
||||
return __print(elems);
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ libfib.so: fib.cpp
|
|||
libfib.dll: fib.cpp
|
||||
g++ -c -O3 fib.cpp -fPIC -o fib.o
|
||||
g++ -shared -o libfib.dll fib.o
|
||||
del fib.o
|
||||
|
||||
libkey.so: keyboard.cpp
|
||||
clang++ -c -O3 keyboard.cpp -fPIC -o keyboard.o
|
||||
|
@ -14,6 +15,7 @@ libkey.so: keyboard.cpp
|
|||
libkey.dll: keyboard.cpp
|
||||
g++ -c -O3 keyboard.cpp -fPIC -o keyboard.o -static
|
||||
g++ -shared -o libkey.dll keyboard.o -static
|
||||
del keyboard.o
|
||||
|
||||
libnasock.so: nasocket.cpp
|
||||
clang++ -c -O3 nasocket.cpp -fPIC -o nasocket.o
|
||||
|
@ -22,9 +24,10 @@ libnasock.so: nasocket.cpp
|
|||
libnasock.dll: nasocket.cpp
|
||||
g++ -c -O3 nasocket.cpp -fPIC -o nasocket.o -lwsock32 -static
|
||||
g++ -shared -o libnasock.dll nasocket.o -lwsock32 -static
|
||||
del nasocket.o
|
||||
|
||||
clean:
|
||||
rm *.o *.so *.dll *.dylib
|
||||
rm *.so *.dll *.dylib
|
||||
all: libfib.so libkey.so libnasock.so
|
||||
@ echo "build done"
|
||||
mingw-all: libfib.dll libkey.dll libnasock.dll
|
||||
|
|
11
nasal.h
11
nasal.h
|
@ -8,6 +8,7 @@
|
|||
#include <cstdlib>
|
||||
#include <cstdio>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
|
@ -35,16 +36,6 @@
|
|||
#include <sys/wait.h>
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
#define PRTHEX64 "%lx"
|
||||
#define PRTHEX64_8 "%.8lx"
|
||||
#define PRTINT64 "%ld"
|
||||
#else
|
||||
#define PRTHEX64 "%llx"
|
||||
#define PRTHEX64_8 "%.8llx"
|
||||
#define PRTINT64 "%lld"
|
||||
#endif
|
||||
|
||||
const uint32_t STACK_DEPTH=2048;
|
||||
|
||||
inline double hex_to_double(const char* str)
|
||||
|
|
114
nasal_codegen.h
114
nasal_codegen.h
|
@ -180,8 +180,67 @@ struct opcode
|
|||
line=tmp.line;
|
||||
return *this;
|
||||
}
|
||||
void print(const char*,
|
||||
const double*,
|
||||
const std::string*,
|
||||
const uint32_t,bool) const;
|
||||
};
|
||||
|
||||
void opcode::print(const char* header,
|
||||
const double* constnum,
|
||||
const std::string* conststr,
|
||||
const uint32_t index,
|
||||
bool deftnum=false) const
|
||||
{
|
||||
std::cout<<header<<std::hex<<"0x"
|
||||
<<std::setw(8)<<std::setfill('0')<<index<<": "
|
||||
<<std::setw(2)<<std::setfill('0')<<(uint32_t)op<<" "
|
||||
<<std::setw(2)<<std::setfill('0')<<((num>>24)&0xff)<<" "
|
||||
<<std::setw(2)<<std::setfill('0')<<((num>>16)&0xff)<<" "
|
||||
<<std::setw(2)<<std::setfill('0')<<((num>>8)&0xff)<<" "
|
||||
<<std::setw(2)<<std::setfill('0')<<(num&0xff)
|
||||
<<" "<<code_table[op].name<<" "<<std::dec;
|
||||
switch(op)
|
||||
{
|
||||
case op_addeq: case op_subeq: case op_muleq: case op_diveq:
|
||||
case op_lnkeq: case op_meq:
|
||||
std::cout<<std::hex<<"0x"<<num<<std::dec
|
||||
<<" sp-"<<num;break;
|
||||
case op_addeqc:case op_subeqc: case op_muleqc:case op_diveqc:
|
||||
std::cout<<std::hex<<"0x"<<(num&0x7fffffff)<<std::dec
|
||||
<<" ("<<constnum[num&0x7fffffff]<<") sp-"
|
||||
<<(num>>31);break;
|
||||
case op_lnkeqc:
|
||||
std::cout<<std::hex<<"0x"<<(num&0x7fffffff)<<std::dec<<" (\""
|
||||
<<rawstr(conststr[num&0x7fffffff],16)<<"\") sp-"
|
||||
<<(num>>31);break;
|
||||
case op_addc: case op_subc: case op_mulc: case op_divc:
|
||||
case op_lessc: case op_leqc: case op_grtc: case op_geqc:
|
||||
case op_pnum:
|
||||
std::cout<<std::hex<<"0x"<<num<<std::dec<<" ("
|
||||
<<constnum[num]<<")";break;
|
||||
case op_callvi:case op_newv: case op_callfv:
|
||||
case op_intg: case op_intl:
|
||||
case op_newf: case op_jmp: case op_jt: case op_jf:
|
||||
case op_callg: case op_mcallg: case op_loadg:
|
||||
case op_calll: case op_mcalll: case op_loadl:
|
||||
std::cout<<std::hex<<"0x"<<num<<std::dec;break;
|
||||
case op_callb:
|
||||
std::cout<<std::hex<<"0x"<<num<<" <"<<builtin[num].name
|
||||
<<"@"<<(void*)builtin[num].func<<std::dec<<">";break;
|
||||
case op_upval: case op_mupval: case op_loadu:
|
||||
std::cout<<std::hex<<"0x"<<((num>>16)&0xffff)
|
||||
<<"[0x"<<(num&0xffff)<<"]"<<std::dec;break;
|
||||
case op_happ: case op_pstr:
|
||||
case op_lnkc:
|
||||
case op_callh: case op_mcallh:
|
||||
case op_para: case op_deft: case op_dyn:
|
||||
std::cout<<std::hex<<"0x"<<num<<std::dec
|
||||
<<" (\""<<rawstr(conststr[num],16)<<"\")";break;
|
||||
default:if(deftnum)std::cout<<std::hex<<"0x"<<num<<std::dec;break;
|
||||
}
|
||||
}
|
||||
|
||||
class nasal_codegen
|
||||
{
|
||||
private:
|
||||
|
@ -245,10 +304,11 @@ private:
|
|||
void calc_gen(const nasal_ast&);
|
||||
void block_gen(const nasal_ast&);
|
||||
void ret_gen(const nasal_ast&);
|
||||
|
||||
void singleop(const uint32_t);
|
||||
public:
|
||||
nasal_codegen(nasal_err& e):fileindex(0),nerr(e),file(nullptr){}
|
||||
void compile(const nasal_parse&,const nasal_import&);
|
||||
void print_op(const uint32_t);
|
||||
void print();
|
||||
const std::vector<std::string>& get_strs() const {return str_res;}
|
||||
const std::vector<double>& get_nums() const {return num_res;}
|
||||
|
@ -1237,21 +1297,21 @@ void nasal_codegen::compile(const nasal_parse& parse,const nasal_import& import)
|
|||
nerr.chkerr();
|
||||
}
|
||||
|
||||
void nasal_codegen::print_op(const uint32_t index)
|
||||
void nasal_codegen::singleop(const uint32_t index)
|
||||
{
|
||||
// print opcode index,opcode name,opcode immediate number
|
||||
const opcode& c=code[index];
|
||||
if(!festk.empty() && index==festk.top())
|
||||
{
|
||||
printf("<0x%x>;\n",fbstk.top());
|
||||
std::cout<<std::hex<<"<0x"<<fbstk.top()<<std::dec<<">;\n";
|
||||
if(code[index].op!=op_newf) // avoid two empty lines
|
||||
printf("\n");
|
||||
std::cout<<"\n";
|
||||
fbstk.pop();
|
||||
festk.pop();
|
||||
}
|
||||
if(c.op==op_newf)
|
||||
{
|
||||
printf("\nfunc <0x%x>:\n",index);
|
||||
std::cout<<std::hex<<"\nfunc <0x"<<index<<std::dec<<">:\n";
|
||||
for(uint32_t i=index;i<code.size();++i)
|
||||
if(code[i].op==op_jmp)
|
||||
{
|
||||
|
@ -1260,46 +1320,8 @@ void nasal_codegen::print_op(const uint32_t index)
|
|||
break;
|
||||
}
|
||||
}
|
||||
printf(" 0x%.8x: %.2x %.2x %.2x %.2x %.2x %s ",
|
||||
index,c.op,
|
||||
uint8_t((c.num>>24)&0xff),uint8_t((c.num>>16)&0xff),
|
||||
uint8_t((c.num>>8)&0xff),uint8_t(c.num&0xff),
|
||||
code_table[c.op].name
|
||||
);
|
||||
// print detail info
|
||||
switch(c.op)
|
||||
{
|
||||
case op_addeq: case op_subeq: case op_muleq: case op_diveq:
|
||||
case op_lnkeq: case op_meq:
|
||||
printf("0x%x sp-%u\n",c.num,c.num);break;
|
||||
case op_addeqc:case op_subeqc: case op_muleqc:case op_diveqc:
|
||||
printf("0x%x (",c.num&0x7fffffff);
|
||||
std::cout<<num_res[c.num&0x7fffffff]<<") sp-"<<(c.num>>31)<<"\n";
|
||||
break;
|
||||
case op_lnkeqc:
|
||||
printf("0x%x (\"%s\") sp-%u\n",c.num&0x7fffffff,rawstr(str_res[c.num&0x7fffffff],16).c_str(),c.num>>31);
|
||||
break;
|
||||
case op_addc: case op_subc: case op_mulc: case op_divc:
|
||||
case op_lessc: case op_leqc: case op_grtc: case op_geqc:
|
||||
case op_pnum:
|
||||
printf("0x%x (",c.num);std::cout<<num_res[c.num]<<")\n";break;
|
||||
case op_callvi:case op_newv: case op_callfv:
|
||||
case op_intg: case op_intl:
|
||||
case op_newf: case op_jmp: case op_jt: case op_jf:
|
||||
case op_callg: case op_mcallg: case op_loadg:
|
||||
case op_calll: case op_mcalll: case op_loadl:
|
||||
printf("0x%x\n",c.num);break;
|
||||
case op_callb:
|
||||
printf("0x%x <%s@0x" PRTHEX64 ">\n",c.num,builtin[c.num].name,(uint64_t)builtin[c.num].func);break;
|
||||
case op_upval:case op_mupval: case op_loadu:
|
||||
printf("0x%x[0x%x]\n",(c.num>>16)&0xffff,c.num&0xffff);break;
|
||||
case op_happ: case op_pstr:
|
||||
case op_lnkc:
|
||||
case op_callh: case op_mcallh:
|
||||
case op_para: case op_deft: case op_dyn:
|
||||
printf("0x%x (\"%s\")\n",c.num,rawstr(str_res[c.num],16).c_str());break;
|
||||
default:printf("\n");break;
|
||||
}
|
||||
c.print(" ",num_res.data(),str_res.data(),index);
|
||||
std::cout<<"\n";
|
||||
}
|
||||
|
||||
void nasal_codegen::print()
|
||||
|
@ -1310,7 +1332,7 @@ void nasal_codegen::print()
|
|||
std::cout<<" .symbol \""<<rawstr(str)<<"\"\n";
|
||||
std::cout<<"\n";
|
||||
for(uint32_t i=0;i<code.size();++i)
|
||||
print_op(i);
|
||||
singleop(i);
|
||||
}
|
||||
|
||||
#endif
|
18
nasal_dbg.h
18
nasal_dbg.h
|
@ -84,16 +84,16 @@ void nasal_dbg::stepinfo()
|
|||
uint32_t begin,end;
|
||||
uint32_t line=bytecode[pc].line==0?0:bytecode[pc].line-1;
|
||||
src.load(files[bytecode[pc].fidx]);
|
||||
printf("\nsource code:\n");
|
||||
std::cout<<"\nsource code:\n";
|
||||
begin=(line>>3)==0?0:((line>>3)<<3);
|
||||
end=(1+(line>>3))<<3;
|
||||
for(uint32_t i=begin;i<end && i<src.size();++i)
|
||||
printf("%s\t%s\n",i==line?"-->":" ",src[i].c_str());
|
||||
printf("next bytecode:\n");
|
||||
std::cout<<(i==line?"--> ":" ")<<src[i]<<"\n";
|
||||
std::cout<<"next bytecode:\n";
|
||||
begin=(pc>>3)==0?0:((pc>>3)<<3);
|
||||
end=(1+(pc>>3))<<3;
|
||||
for(uint32_t i=begin;i<end && bytecode[i].op!=op_exit;++i)
|
||||
bytecodeinfo(i==pc?"-->\t":" \t",i);
|
||||
bytecodeinfo(i==pc?"--> ":" ",i);
|
||||
stackinfo(10);
|
||||
}
|
||||
|
||||
|
@ -119,7 +119,7 @@ void nasal_dbg::interact()
|
|||
stepinfo();
|
||||
while(1)
|
||||
{
|
||||
printf(">> ");
|
||||
std::cout<<">> ";
|
||||
std::getline(std::cin,cmd);
|
||||
auto res=parse(cmd);
|
||||
if(res.size()==1)
|
||||
|
@ -132,7 +132,7 @@ void nasal_dbg::interact()
|
|||
return;
|
||||
else if(res[0]=="f" || res[0]=="file")
|
||||
for(size_t i=0;i<fsize;++i)
|
||||
printf("[%zu] %s\n",i,files[i].c_str());
|
||||
std::cout<<"["<<i<<"] "<<files[i]<<"\n";
|
||||
else if(res[0]=="g" || res[0]=="global")
|
||||
global_state();
|
||||
else if(res[0]=="l" || res[0]=="local"){
|
||||
|
@ -159,12 +159,12 @@ void nasal_dbg::interact()
|
|||
bk_fidx=fileindex(res[1]);
|
||||
if(bk_fidx==65535)
|
||||
{
|
||||
printf("cannot find file named \"%s\"\n",res[1].c_str());
|
||||
std::cout<<"cannot find file named `"<<res[1]<<"`\n";
|
||||
bk_fidx=0;
|
||||
}
|
||||
int tmp=atoi(res[2].c_str());
|
||||
if(tmp<=0)
|
||||
printf("incorrect line number \"%s\"\n",res[2].c_str());
|
||||
std::cout<<"incorrect line number `"<<res[2]<<"`\n";
|
||||
else
|
||||
bk_line=tmp;
|
||||
}
|
||||
|
@ -217,7 +217,7 @@ vmexit:
|
|||
die("stack overflow");
|
||||
gc.clear();
|
||||
imm.clear();
|
||||
printf("[debug] debugger exited\n");
|
||||
std::cout<<"[debug] debugger exited\n";
|
||||
return;
|
||||
#define dbg(op) {interact();op();if(top<canary)goto *code[++pc];goto vmexit;}
|
||||
|
||||
|
|
194
nasal_vm.h
194
nasal_vm.h
|
@ -43,7 +43,7 @@ protected:
|
|||
void upval_state();
|
||||
void detail();
|
||||
void opcallsort(const uint64_t*);
|
||||
void die(std::string);
|
||||
void die(const std::string&);
|
||||
/* vm calculation functions*/
|
||||
bool condition(nasal_ref);
|
||||
/* vm operands */
|
||||
|
@ -154,69 +154,41 @@ void nasal_vm::init(
|
|||
void nasal_vm::valinfo(nasal_ref& val)
|
||||
{
|
||||
const nasal_val* p=val.value.gcobj;
|
||||
printf("\t");
|
||||
std::cout<<"\t";
|
||||
switch(val.type)
|
||||
{
|
||||
case vm_none: printf("| null |\n");break;
|
||||
case vm_ret: printf("| pc | 0x%x\n",val.ret());break;
|
||||
case vm_addr: printf("| addr | 0x" PRTHEX64 "\n",(uint64_t)val.addr());break;
|
||||
case vm_cnt: printf("| cnt | " PRTINT64 "\n",val.cnt());break;
|
||||
case vm_nil: printf("| nil |\n");break;
|
||||
case vm_num: printf("| num | ");std::cout<<val.num()<<'\n';break;
|
||||
case vm_str: printf("| str | <0x" PRTHEX64 "> %s\n",(uint64_t)p,rawstr(val.str(),16).c_str());break;
|
||||
case vm_func: printf("| func | <0x" PRTHEX64 "> entry:0x%x\n",(uint64_t)p,val.func().entry);break;
|
||||
case vm_upval:printf("| upval| <0x" PRTHEX64 "> [%u val]\n",(uint64_t)p,val.upval().size);break;
|
||||
case vm_vec: printf("| vec | <0x" PRTHEX64 "> [%zu val]\n",(uint64_t)p,val.vec().size());break;
|
||||
case vm_hash: printf("| hash | <0x" PRTHEX64 "> {%zu val}\n",(uint64_t)p,val.hash().size());break;
|
||||
case vm_obj: printf("| obj | <0x" PRTHEX64 "> obj:0x" PRTHEX64 "\n",(uint64_t)p,(uint64_t)val.obj().ptr);break;
|
||||
case vm_co: printf("| co | <0x" PRTHEX64 "> coroutine\n",(uint64_t)p);break;
|
||||
default: printf("| err | <0x" PRTHEX64 "> unknown object\n",(uint64_t)p);break;
|
||||
case vm_none: std::cout<<"| null |";break;
|
||||
case vm_ret: std::cout<<"| pc | 0x"<<std::hex
|
||||
<<val.ret()<<std::dec;break;
|
||||
case vm_addr: std::cout<<"| addr | "<<std::hex
|
||||
<<(void*)val.addr()<<std::dec;break;
|
||||
case vm_cnt: std::cout<<"| cnt | "<<val.cnt();break;
|
||||
case vm_nil: std::cout<<"| nil |";break;
|
||||
case vm_num: std::cout<<"| num | "<<val.num();break;
|
||||
case vm_str: std::cout<<"| str | <"<<std::hex<<p<<"> "
|
||||
<<rawstr(val.str(),16)<<std::dec;break;
|
||||
case vm_func: std::cout<<"| func | <"<<std::hex<<p<<"> entry:0x"
|
||||
<<val.func().entry<<std::dec;break;
|
||||
case vm_upval:std::cout<<"| upval| <"<<std::hex<<p<<std::dec<<"> ["
|
||||
<<val.upval().size<<" val]";break;
|
||||
case vm_vec: std::cout<<"| vec | <"<<std::hex<<p<<std::dec<<"> ["
|
||||
<<val.vec().size()<<" val]";break;
|
||||
case vm_hash: std::cout<<"| hash | <"<<std::hex<<p<<std::dec<<"> {"
|
||||
<<val.hash().size()<<" val}";break;
|
||||
case vm_obj: std::cout<<"| obj | <"<<std::hex<<p<<"> obj:0x"
|
||||
<<(uint64_t)val.obj().ptr<<std::dec;break;
|
||||
case vm_co: std::cout<<"| co | <"<<std::hex<<p<<std::dec
|
||||
<<"> coroutine";break;
|
||||
default: std::cout<<"| err | <"<<std::hex<<p<<std::dec
|
||||
<<"> unknown object";break;
|
||||
}
|
||||
std::cout<<"\n";
|
||||
}
|
||||
void nasal_vm::bytecodeinfo(const char* header,const uint32_t p)
|
||||
{
|
||||
const opcode& c=bytecode[p];
|
||||
printf("%s0x%.8x: %.2x %.2x %.2x %.2x %.2x %s ",
|
||||
header,p,c.op,
|
||||
uint8_t((c.num>>24)&0xff),uint8_t((c.num>>16)&0xff),
|
||||
uint8_t((c.num>>8)&0xff),uint8_t(c.num&0xff),
|
||||
code_table[c.op].name
|
||||
);
|
||||
switch(c.op)
|
||||
{
|
||||
case op_addeq: case op_subeq: case op_muleq: case op_diveq:
|
||||
case op_lnkeq: case op_meq:
|
||||
printf("0x%x sp-%u",c.num,c.num);break;
|
||||
case op_addeqc:case op_subeqc: case op_muleqc:case op_diveqc:
|
||||
printf("0x%x (",c.num&0x7fffffff);
|
||||
std::cout<<num_table[c.num&0x7fffffff]<<") sp-"<<(c.num>>31);
|
||||
break;
|
||||
case op_lnkeqc:
|
||||
printf("0x%x (\"%s\") sp-%u",c.num&0x7fffffff,rawstr(str_table[c.num&0x7fffffff],16).c_str(),c.num>>31);
|
||||
break;
|
||||
case op_addc: case op_subc: case op_mulc: case op_divc:
|
||||
case op_lessc: case op_leqc: case op_grtc: case op_geqc:
|
||||
case op_pnum:
|
||||
printf("0x%x (",c.num);std::cout<<num_table[c.num]<<")";break;
|
||||
case op_callvi:case op_newv: case op_callfv:
|
||||
case op_intg: case op_intl:
|
||||
case op_newf: case op_jmp: case op_jt: case op_jf:
|
||||
case op_callg: case op_mcallg: case op_loadg:
|
||||
case op_calll: case op_mcalll: case op_loadl:
|
||||
printf("0x%x",c.num);break;
|
||||
case op_callb:
|
||||
printf("0x%x <%s@0x" PRTHEX64 ">",c.num,builtin[c.num].name,(uint64_t)builtin[c.num].func);break;
|
||||
case op_upval: case op_mupval: case op_loadu:
|
||||
printf("0x%x[0x%x]",(c.num>>16)&0xffff,c.num&0xffff);break;
|
||||
case op_happ: case op_pstr:
|
||||
case op_lnkc:
|
||||
case op_callh: case op_mcallh:
|
||||
case op_para: case op_deft: case op_dyn:
|
||||
printf("0x%x (\"%s\")",c.num,rawstr(str_table[c.num],16).c_str());
|
||||
break;
|
||||
default:printf("0x%x",c.num);break;
|
||||
}
|
||||
printf(" (%s:%u)\n",files[c.fidx].c_str(),c.line);
|
||||
c.print(header,num_table,str_table,p,true);
|
||||
std::cout<<" ("<<files[c.fidx]<<":"<<c.line<<")\n";
|
||||
}
|
||||
void nasal_vm::traceback()
|
||||
{
|
||||
|
@ -229,7 +201,7 @@ void nasal_vm::traceback()
|
|||
ret.push(i->ret());
|
||||
// push pc to ret stack to store the position program crashed
|
||||
ret.push(pc);
|
||||
printf("trace back:\n");
|
||||
std::cout<<"trace back:\n";
|
||||
uint32_t same=0,last=0xffffffff;
|
||||
for(uint32_t point=0;!ret.empty();last=point,ret.pop())
|
||||
{
|
||||
|
@ -239,12 +211,14 @@ void nasal_vm::traceback()
|
|||
continue;
|
||||
}
|
||||
if(same)
|
||||
printf("\t0x%.8x: %u same call(s)\n",last,same);
|
||||
std::cout<<" 0x"<<std::hex<<std::setw(8)<<std::setfill('0')
|
||||
<<last<<std::dec<<": "<<same<<" same call(s)\n";
|
||||
same=0;
|
||||
bytecodeinfo("\t",point);
|
||||
bytecodeinfo(" ",point);
|
||||
}
|
||||
if(same)
|
||||
printf("\t0x%.8x: %u same call(s)\n",last,same);
|
||||
std::cout<<" 0x"<<std::hex<<std::setw(8)<<std::setfill('0')
|
||||
<<last<<std::dec<<": "<<same<<" same call(s)\n";
|
||||
}
|
||||
void nasal_vm::stackinfo(const uint32_t limit=10)
|
||||
{
|
||||
|
@ -252,49 +226,41 @@ void nasal_vm::stackinfo(const uint32_t limit=10)
|
|||
uint32_t gsize=gc.stack==stack?bytecode[0].num:0;
|
||||
nasal_ref* t=top;
|
||||
nasal_ref* bottom=gc.stack+gsize;
|
||||
printf("vm stack(0x" PRTHEX64 "<sp+%u>, limit %u, total ",(uint64_t)bottom,gsize,limit);
|
||||
std::cout<<"vm stack(0x"<<std::hex<<(uint64_t)bottom<<std::dec
|
||||
<<"<sp+"<<gsize<<">, limit "<<limit<<", total "
|
||||
<<(t<bottom? 0:(int64_t)(t-bottom+1))<<")\n";
|
||||
if(t<bottom)
|
||||
{
|
||||
printf("0)\n");
|
||||
return;
|
||||
}
|
||||
printf("" PRTINT64 "):\n",(int64_t)(t-bottom+1));
|
||||
for(uint32_t i=0;i<limit && t>=bottom;++i,--t)
|
||||
{
|
||||
printf(" 0x" PRTHEX64_8 "",(uint64_t)(t-gc.stack));
|
||||
std::cout<<" 0x"<<std::hex
|
||||
<<std::setw(8)<<std::setfill('0')
|
||||
<<(uint64_t)(t-gc.stack)<<std::dec;
|
||||
valinfo(t[0]);
|
||||
}
|
||||
}
|
||||
void nasal_vm::register_info()
|
||||
{
|
||||
printf("registers(%s):\n",gc.coroutine?"coroutine":"main");
|
||||
printf(" [ pc ] | pc | 0x%x\n",pc);
|
||||
printf(" [ global ] | addr | 0x" PRTHEX64 "\n",(uint64_t)stack);
|
||||
printf(" [ localr ] | addr | 0x" PRTHEX64 "\n",(uint64_t)localr);
|
||||
printf(" [ memr ] | addr | 0x" PRTHEX64 "\n",(uint64_t)memr);
|
||||
if(funcr.type==vm_nil)
|
||||
printf(" [ funcr ] | nil |\n");
|
||||
else
|
||||
printf(" [ funcr ] | func | <0x" PRTHEX64 "> entry:0x%x\n",
|
||||
(uint64_t)funcr.value.gcobj,
|
||||
funcr.func().entry);
|
||||
if(upvalr.type==vm_nil)
|
||||
printf(" [ upvalr ] | nil |\n");
|
||||
else
|
||||
printf(" [ upvalr ] | upval| <0x" PRTHEX64 "> [%u val]\n",
|
||||
(uint64_t)upvalr.value.gcobj,
|
||||
upvalr.upval().size);
|
||||
printf(" [ canary ] | addr | 0x" PRTHEX64 "\n",(uint64_t)canary);
|
||||
printf(" [ top ] | addr | 0x" PRTHEX64 "\n",(uint64_t)top);
|
||||
std::cout<<"registers("<<(gc.coroutine?"coroutine":"main")<<")\n"<<std::hex
|
||||
<<" [ pc ] | pc | 0x"<<pc<<"\n"
|
||||
<<" [ global ] | addr | "<<stack<<"\n"
|
||||
<<" [ localr ] | addr | "<<localr<<"\n"
|
||||
<<" [ memr ] | addr | "<<memr<<"\n"
|
||||
<<" [ canary ] | addr | "<<canary<<"\n"
|
||||
<<" [ top ] | addr | "<<top<<"\n"
|
||||
<<std::dec;
|
||||
std::cout<<" [ funcr ]";valinfo(funcr);
|
||||
std::cout<<" [ upvalr ]";valinfo(upvalr);
|
||||
}
|
||||
void nasal_vm::global_state()
|
||||
{
|
||||
if(!bytecode[0].num || stack[0].type==vm_none) // bytecode[0].op is op_intg
|
||||
return;
|
||||
printf("global(0x" PRTHEX64 "<sp+0>):\n",(uint64_t)stack);
|
||||
std::cout<<"global(0x"<<std::hex<<(uint64_t)stack<<"<sp+0>)\n"<<std::dec;
|
||||
for(uint32_t i=0;i<bytecode[0].num;++i)
|
||||
{
|
||||
printf(" 0x%.8x",i);
|
||||
std::cout<<" 0x"<<std::hex<<std::setw(8)
|
||||
<<std::setfill('0')<<i<<std::dec;
|
||||
valinfo(stack[i]);
|
||||
}
|
||||
}
|
||||
|
@ -303,10 +269,12 @@ void nasal_vm::local_state()
|
|||
if(!localr || !funcr.func().lsize)
|
||||
return;
|
||||
const uint32_t lsize=funcr.func().lsize;
|
||||
printf("local(0x" PRTHEX64 "<sp+" PRTINT64 ">):\n",(uint64_t)localr,(int64_t)(localr-gc.stack));
|
||||
std::cout<<"local(0x"<<std::hex<<(uint64_t)localr
|
||||
<<"<sp+"<<(uint64_t)(localr-gc.stack)<<">)\n"<<std::dec;
|
||||
for(uint32_t i=0;i<lsize;++i)
|
||||
{
|
||||
printf(" 0x%.8x",i);
|
||||
std::cout<<" 0x"<<std::hex<<std::setw(8)
|
||||
<<std::setfill('0')<<i<<std::dec;
|
||||
valinfo(localr[i]);
|
||||
}
|
||||
}
|
||||
|
@ -314,15 +282,16 @@ void nasal_vm::upval_state()
|
|||
{
|
||||
if(funcr.type==vm_nil || funcr.func().upvalue.empty())
|
||||
return;
|
||||
printf("upvalue:\n");
|
||||
std::cout<<"upvalue\n";
|
||||
auto& upval=funcr.func().upvalue;
|
||||
for(uint32_t i=0;i<upval.size();++i)
|
||||
{
|
||||
printf(" -> upval[%u]:\n",i);
|
||||
std::cout<<" -> upval["<<i<<"]:\n";
|
||||
auto& uv=upval[i].upval();
|
||||
for(uint32_t j=0;j<uv.size;++j)
|
||||
{
|
||||
printf(" 0x%.8x",j);
|
||||
std::cout<<" 0x"<<std::hex<<std::setw(8)
|
||||
<<std::setfill('0')<<j<<std::dec;
|
||||
valinfo(uv[j]);
|
||||
}
|
||||
}
|
||||
|
@ -353,7 +322,8 @@ void nasal_vm::opcallsort(const uint64_t* arr)
|
|||
{
|
||||
uint64_t rate=i.second*100/total;
|
||||
if(rate)
|
||||
std::cout<<"\n "<<code_table[i.first].name<<" : "<<i.second<<" ("<<rate<<"%)";
|
||||
std::cout<<"\n "<<code_table[i.first].name
|
||||
<<" : "<<i.second<<" ("<<rate<<"%)";
|
||||
else
|
||||
{
|
||||
std::cout<<"\n ...";
|
||||
|
@ -362,9 +332,9 @@ void nasal_vm::opcallsort(const uint64_t* arr)
|
|||
}
|
||||
std::cout<<"\n total : "<<total<<'\n';
|
||||
}
|
||||
void nasal_vm::die(std::string str)
|
||||
void nasal_vm::die(const std::string& str)
|
||||
{
|
||||
printf("[vm] %s\n",str.c_str());
|
||||
std::cout<<"[vm] "<<str<<"\n";
|
||||
traceback();
|
||||
stackinfo();
|
||||
if(detail_info)
|
||||
|
@ -406,7 +376,8 @@ inline void nasal_vm::opr_loadl()
|
|||
}
|
||||
inline void nasal_vm::opr_loadu()
|
||||
{
|
||||
funcr.func().upvalue[(imm[pc]>>16)&0xffff].upval()[imm[pc]&0xffff]=(top--)[0];
|
||||
funcr.func().upvalue[(imm[pc]>>16)&0xffff]
|
||||
.upval()[imm[pc]&0xffff]=(top--)[0];
|
||||
}
|
||||
inline void nasal_vm::opr_pnum()
|
||||
{
|
||||
|
@ -461,14 +432,16 @@ inline void nasal_vm::opr_happ()
|
|||
inline void nasal_vm::opr_para()
|
||||
{
|
||||
nasal_func& func=top[0].func();
|
||||
func.keys[str_table[imm[pc]]]=func.psize;// func->size has 1 place reserved for "me"
|
||||
// func->size has 1 place reserved for "me"
|
||||
func.keys[str_table[imm[pc]]]=func.psize;
|
||||
func.local[func.psize++]={vm_none};
|
||||
}
|
||||
inline void nasal_vm::opr_deft()
|
||||
{
|
||||
nasal_ref val=top[0];
|
||||
nasal_func& func=(--top)[0].func();
|
||||
func.keys[str_table[imm[pc]]]=func.psize;// func->size has 1 place reserved for "me"
|
||||
// func->size has 1 place reserved for "me"
|
||||
func.keys[str_table[imm[pc]]]=func.psize;
|
||||
func.local[func.psize++]=val;
|
||||
}
|
||||
inline void nasal_vm::opr_dyn()
|
||||
|
@ -669,7 +642,8 @@ inline void nasal_vm::opr_calll()
|
|||
}
|
||||
inline void nasal_vm::opr_upval()
|
||||
{
|
||||
(++top)[0]=funcr.func().upvalue[(imm[pc]>>16)&0xffff].upval()[imm[pc]&0xffff];
|
||||
(++top)[0]=funcr.func().upvalue[(imm[pc]>>16)&0xffff]
|
||||
.upval()[imm[pc]&0xffff];
|
||||
}
|
||||
inline void nasal_vm::opr_callv()
|
||||
{
|
||||
|
@ -738,10 +712,11 @@ inline void nasal_vm::opr_callfv()
|
|||
nasal_ref tmp=local[-1];
|
||||
local[-1]=funcr;
|
||||
funcr=tmp;
|
||||
if(top-argc+func.lsize+3>=canary) // top-argc+lsize(local) +1(old pc) +1(old localr) +1(old upvalr)
|
||||
// top-argc+lsize(local) +1(old pc) +1(old localr) +1(old upvalr)
|
||||
if(top-argc+func.lsize+3>=canary)
|
||||
die("stack overflow");
|
||||
|
||||
uint32_t psize=func.psize-1; // parameter size is func->psize-1, 1 is reserved for "me"
|
||||
// parameter size is func->psize-1, 1 is reserved for "me"
|
||||
uint32_t psize=func.psize-1;
|
||||
if(argc<psize && func.local[argc+1].type==vm_none)
|
||||
die("callfv: lack argument(s)");
|
||||
|
||||
|
@ -779,7 +754,8 @@ inline void nasal_vm::opr_callfh()
|
|||
nasal_ref tmp=top[-1];
|
||||
top[-1]=funcr;
|
||||
funcr=tmp;
|
||||
if(top+func.lsize+2>=canary) // top -1(hash) +lsize(local) +1(old pc) +1(old localr) +1(old upvalr)
|
||||
// top -1(hash) +lsize(local) +1(old pc) +1(old localr) +1(old upvalr)
|
||||
if(top+func.lsize+2>=canary)
|
||||
die("stack overflow");
|
||||
if(func.dynpara>=0)
|
||||
die("callfh: special call cannot use dynamic argument");
|
||||
|
@ -901,7 +877,7 @@ inline void nasal_vm::opr_mcallv()
|
|||
if(!memr)
|
||||
die("mcallv: index out of range:"+std::to_string(val.tonum()));
|
||||
}
|
||||
else if(vec.type==vm_hash) // special call of hash, this do mcallh but use the mcallv way
|
||||
else if(vec.type==vm_hash) // do mcallh but use the mcallv way
|
||||
{
|
||||
if(val.type!=vm_str)
|
||||
die("mcallv: must use string as the key");
|
||||
|
@ -1027,7 +1003,13 @@ vmexit:
|
|||
imm.clear();
|
||||
return;
|
||||
// may cause stackoverflow
|
||||
#define exec_operand(op,num) {op();++count[num];if(top<canary)goto *code[++pc];goto vmexit;}
|
||||
#define exec_operand(op,num) {\
|
||||
op();\
|
||||
++count[num];\
|
||||
if(top<canary)\
|
||||
goto *code[++pc];\
|
||||
goto vmexit;\
|
||||
}
|
||||
// do not cause stackoverflow
|
||||
#define exec_opnodie(op,num) {op();++count[num];goto *code[++pc];}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# lib.nas
|
||||
|
||||
# print is used to print all things in nasal, try and see how it works.
|
||||
# this function uses std::cout/printf to output logs.
|
||||
# this function uses std::cout to output logs.
|
||||
var print=func(elems...){
|
||||
return __print(elems);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue