optimize code & replace all `printf` with `std::cout`.

This commit is contained in:
ValKmjolnir 2022-07-09 23:36:14 +08:00
parent 2ed20f6362
commit bcdc55a652
7 changed files with 172 additions and 174 deletions

View File

@ -1,7 +1,7 @@
# lib.nas # lib.nas
# print is used to print all things in nasal, try and see how it works. # 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...){ var print=func(elems...){
return __print(elems); return __print(elems);
} }

View File

@ -6,6 +6,7 @@ libfib.so: fib.cpp
libfib.dll: fib.cpp libfib.dll: fib.cpp
g++ -c -O3 fib.cpp -fPIC -o fib.o g++ -c -O3 fib.cpp -fPIC -o fib.o
g++ -shared -o libfib.dll fib.o g++ -shared -o libfib.dll fib.o
del fib.o
libkey.so: keyboard.cpp libkey.so: keyboard.cpp
clang++ -c -O3 keyboard.cpp -fPIC -o keyboard.o clang++ -c -O3 keyboard.cpp -fPIC -o keyboard.o
@ -14,6 +15,7 @@ libkey.so: keyboard.cpp
libkey.dll: keyboard.cpp libkey.dll: keyboard.cpp
g++ -c -O3 keyboard.cpp -fPIC -o keyboard.o -static g++ -c -O3 keyboard.cpp -fPIC -o keyboard.o -static
g++ -shared -o libkey.dll keyboard.o -static g++ -shared -o libkey.dll keyboard.o -static
del keyboard.o
libnasock.so: nasocket.cpp libnasock.so: nasocket.cpp
clang++ -c -O3 nasocket.cpp -fPIC -o nasocket.o clang++ -c -O3 nasocket.cpp -fPIC -o nasocket.o
@ -22,9 +24,10 @@ libnasock.so: nasocket.cpp
libnasock.dll: nasocket.cpp libnasock.dll: nasocket.cpp
g++ -c -O3 nasocket.cpp -fPIC -o nasocket.o -lwsock32 -static g++ -c -O3 nasocket.cpp -fPIC -o nasocket.o -lwsock32 -static
g++ -shared -o libnasock.dll nasocket.o -lwsock32 -static g++ -shared -o libnasock.dll nasocket.o -lwsock32 -static
del nasocket.o
clean: clean:
rm *.o *.so *.dll *.dylib rm *.so *.dll *.dylib
all: libfib.so libkey.so libnasock.so all: libfib.so libkey.so libnasock.so
@ echo "build done" @ echo "build done"
mingw-all: libfib.dll libkey.dll libnasock.dll mingw-all: libfib.dll libkey.dll libnasock.dll

11
nasal.h
View File

@ -8,6 +8,7 @@
#include <cstdlib> #include <cstdlib>
#include <cstdio> #include <cstdio>
#include <iostream> #include <iostream>
#include <iomanip>
#include <fstream> #include <fstream>
#include <sstream> #include <sstream>
#include <algorithm> #include <algorithm>
@ -35,16 +36,6 @@
#include <sys/wait.h> #include <sys/wait.h>
#endif #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; const uint32_t STACK_DEPTH=2048;
inline double hex_to_double(const char* str) inline double hex_to_double(const char* str)

View File

@ -180,8 +180,67 @@ struct opcode
line=tmp.line; line=tmp.line;
return *this; 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 class nasal_codegen
{ {
private: private:
@ -245,10 +304,11 @@ private:
void calc_gen(const nasal_ast&); void calc_gen(const nasal_ast&);
void block_gen(const nasal_ast&); void block_gen(const nasal_ast&);
void ret_gen(const nasal_ast&); void ret_gen(const nasal_ast&);
void singleop(const uint32_t);
public: public:
nasal_codegen(nasal_err& e):fileindex(0),nerr(e),file(nullptr){} nasal_codegen(nasal_err& e):fileindex(0),nerr(e),file(nullptr){}
void compile(const nasal_parse&,const nasal_import&); void compile(const nasal_parse&,const nasal_import&);
void print_op(const uint32_t);
void print(); void print();
const std::vector<std::string>& get_strs() const {return str_res;} const std::vector<std::string>& get_strs() const {return str_res;}
const std::vector<double>& get_nums() const {return num_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(); 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 // print opcode index,opcode name,opcode immediate number
const opcode& c=code[index]; const opcode& c=code[index];
if(!festk.empty() && index==festk.top()) 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 if(code[index].op!=op_newf) // avoid two empty lines
printf("\n"); std::cout<<"\n";
fbstk.pop(); fbstk.pop();
festk.pop(); festk.pop();
} }
if(c.op==op_newf) 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) for(uint32_t i=index;i<code.size();++i)
if(code[i].op==op_jmp) if(code[i].op==op_jmp)
{ {
@ -1260,46 +1320,8 @@ void nasal_codegen::print_op(const uint32_t index)
break; break;
} }
} }
printf(" 0x%.8x: %.2x %.2x %.2x %.2x %.2x %s ", c.print(" ",num_res.data(),str_res.data(),index);
index,c.op, std::cout<<"\n";
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;
}
} }
void nasal_codegen::print() void nasal_codegen::print()
@ -1310,7 +1332,7 @@ void nasal_codegen::print()
std::cout<<" .symbol \""<<rawstr(str)<<"\"\n"; std::cout<<" .symbol \""<<rawstr(str)<<"\"\n";
std::cout<<"\n"; std::cout<<"\n";
for(uint32_t i=0;i<code.size();++i) for(uint32_t i=0;i<code.size();++i)
print_op(i); singleop(i);
} }
#endif #endif

View File

@ -84,16 +84,16 @@ void nasal_dbg::stepinfo()
uint32_t begin,end; uint32_t begin,end;
uint32_t line=bytecode[pc].line==0?0:bytecode[pc].line-1; uint32_t line=bytecode[pc].line==0?0:bytecode[pc].line-1;
src.load(files[bytecode[pc].fidx]); src.load(files[bytecode[pc].fidx]);
printf("\nsource code:\n"); std::cout<<"\nsource code:\n";
begin=(line>>3)==0?0:((line>>3)<<3); begin=(line>>3)==0?0:((line>>3)<<3);
end=(1+(line>>3))<<3; end=(1+(line>>3))<<3;
for(uint32_t i=begin;i<end && i<src.size();++i) for(uint32_t i=begin;i<end && i<src.size();++i)
printf("%s\t%s\n",i==line?"-->":" ",src[i].c_str()); std::cout<<(i==line?"--> ":" ")<<src[i]<<"\n";
printf("next bytecode:\n"); std::cout<<"next bytecode:\n";
begin=(pc>>3)==0?0:((pc>>3)<<3); begin=(pc>>3)==0?0:((pc>>3)<<3);
end=(1+(pc>>3))<<3; end=(1+(pc>>3))<<3;
for(uint32_t i=begin;i<end && bytecode[i].op!=op_exit;++i) 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); stackinfo(10);
} }
@ -119,7 +119,7 @@ void nasal_dbg::interact()
stepinfo(); stepinfo();
while(1) while(1)
{ {
printf(">> "); std::cout<<">> ";
std::getline(std::cin,cmd); std::getline(std::cin,cmd);
auto res=parse(cmd); auto res=parse(cmd);
if(res.size()==1) if(res.size()==1)
@ -132,7 +132,7 @@ void nasal_dbg::interact()
return; return;
else if(res[0]=="f" || res[0]=="file") else if(res[0]=="f" || res[0]=="file")
for(size_t i=0;i<fsize;++i) 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") else if(res[0]=="g" || res[0]=="global")
global_state(); global_state();
else if(res[0]=="l" || res[0]=="local"){ else if(res[0]=="l" || res[0]=="local"){
@ -159,12 +159,12 @@ void nasal_dbg::interact()
bk_fidx=fileindex(res[1]); bk_fidx=fileindex(res[1]);
if(bk_fidx==65535) 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; bk_fidx=0;
} }
int tmp=atoi(res[2].c_str()); int tmp=atoi(res[2].c_str());
if(tmp<=0) if(tmp<=0)
printf("incorrect line number \"%s\"\n",res[2].c_str()); std::cout<<"incorrect line number `"<<res[2]<<"`\n";
else else
bk_line=tmp; bk_line=tmp;
} }
@ -217,7 +217,7 @@ vmexit:
die("stack overflow"); die("stack overflow");
gc.clear(); gc.clear();
imm.clear(); imm.clear();
printf("[debug] debugger exited\n"); std::cout<<"[debug] debugger exited\n";
return; return;
#define dbg(op) {interact();op();if(top<canary)goto *code[++pc];goto vmexit;} #define dbg(op) {interact();op();if(top<canary)goto *code[++pc];goto vmexit;}

View File

@ -43,7 +43,7 @@ protected:
void upval_state(); void upval_state();
void detail(); void detail();
void opcallsort(const uint64_t*); void opcallsort(const uint64_t*);
void die(std::string); void die(const std::string&);
/* vm calculation functions*/ /* vm calculation functions*/
bool condition(nasal_ref); bool condition(nasal_ref);
/* vm operands */ /* vm operands */
@ -154,69 +154,41 @@ void nasal_vm::init(
void nasal_vm::valinfo(nasal_ref& val) void nasal_vm::valinfo(nasal_ref& val)
{ {
const nasal_val* p=val.value.gcobj; const nasal_val* p=val.value.gcobj;
printf("\t"); std::cout<<"\t";
switch(val.type) switch(val.type)
{ {
case vm_none: printf("| null |\n");break; case vm_none: std::cout<<"| null |";break;
case vm_ret: printf("| pc | 0x%x\n",val.ret());break; case vm_ret: std::cout<<"| pc | 0x"<<std::hex
case vm_addr: printf("| addr | 0x" PRTHEX64 "\n",(uint64_t)val.addr());break; <<val.ret()<<std::dec;break;
case vm_cnt: printf("| cnt | " PRTINT64 "\n",val.cnt());break; case vm_addr: std::cout<<"| addr | "<<std::hex
case vm_nil: printf("| nil |\n");break; <<(void*)val.addr()<<std::dec;break;
case vm_num: printf("| num | ");std::cout<<val.num()<<'\n';break; case vm_cnt: std::cout<<"| cnt | "<<val.cnt();break;
case vm_str: printf("| str | <0x" PRTHEX64 "> %s\n",(uint64_t)p,rawstr(val.str(),16).c_str());break; case vm_nil: std::cout<<"| nil |";break;
case vm_func: printf("| func | <0x" PRTHEX64 "> entry:0x%x\n",(uint64_t)p,val.func().entry);break; case vm_num: std::cout<<"| num | "<<val.num();break;
case vm_upval:printf("| upval| <0x" PRTHEX64 "> [%u val]\n",(uint64_t)p,val.upval().size);break; case vm_str: std::cout<<"| str | <"<<std::hex<<p<<"> "
case vm_vec: printf("| vec | <0x" PRTHEX64 "> [%zu val]\n",(uint64_t)p,val.vec().size());break; <<rawstr(val.str(),16)<<std::dec;break;
case vm_hash: printf("| hash | <0x" PRTHEX64 "> {%zu val}\n",(uint64_t)p,val.hash().size());break; case vm_func: std::cout<<"| func | <"<<std::hex<<p<<"> entry:0x"
case vm_obj: printf("| obj | <0x" PRTHEX64 "> obj:0x" PRTHEX64 "\n",(uint64_t)p,(uint64_t)val.obj().ptr);break; <<val.func().entry<<std::dec;break;
case vm_co: printf("| co | <0x" PRTHEX64 "> coroutine\n",(uint64_t)p);break; case vm_upval:std::cout<<"| upval| <"<<std::hex<<p<<std::dec<<"> ["
default: printf("| err | <0x" PRTHEX64 "> unknown object\n",(uint64_t)p);break; <<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) void nasal_vm::bytecodeinfo(const char* header,const uint32_t p)
{ {
const opcode& c=bytecode[p]; const opcode& c=bytecode[p];
printf("%s0x%.8x: %.2x %.2x %.2x %.2x %.2x %s ", c.print(header,num_table,str_table,p,true);
header,p,c.op, std::cout<<" ("<<files[c.fidx]<<":"<<c.line<<")\n";
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);
} }
void nasal_vm::traceback() void nasal_vm::traceback()
{ {
@ -229,7 +201,7 @@ void nasal_vm::traceback()
ret.push(i->ret()); ret.push(i->ret());
// push pc to ret stack to store the position program crashed // push pc to ret stack to store the position program crashed
ret.push(pc); ret.push(pc);
printf("trace back:\n"); std::cout<<"trace back:\n";
uint32_t same=0,last=0xffffffff; uint32_t same=0,last=0xffffffff;
for(uint32_t point=0;!ret.empty();last=point,ret.pop()) for(uint32_t point=0;!ret.empty();last=point,ret.pop())
{ {
@ -239,12 +211,14 @@ void nasal_vm::traceback()
continue; continue;
} }
if(same) 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; same=0;
bytecodeinfo("\t",point); bytecodeinfo(" ",point);
} }
if(same) 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) 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; uint32_t gsize=gc.stack==stack?bytecode[0].num:0;
nasal_ref* t=top; nasal_ref* t=top;
nasal_ref* bottom=gc.stack+gsize; 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) if(t<bottom)
{
printf("0)\n");
return; return;
}
printf("" PRTINT64 "):\n",(int64_t)(t-bottom+1));
for(uint32_t i=0;i<limit && t>=bottom;++i,--t) 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]); valinfo(t[0]);
} }
} }
void nasal_vm::register_info() void nasal_vm::register_info()
{ {
printf("registers(%s):\n",gc.coroutine?"coroutine":"main"); std::cout<<"registers("<<(gc.coroutine?"coroutine":"main")<<")\n"<<std::hex
printf(" [ pc ] | pc | 0x%x\n",pc); <<" [ pc ] | pc | 0x"<<pc<<"\n"
printf(" [ global ] | addr | 0x" PRTHEX64 "\n",(uint64_t)stack); <<" [ global ] | addr | "<<stack<<"\n"
printf(" [ localr ] | addr | 0x" PRTHEX64 "\n",(uint64_t)localr); <<" [ localr ] | addr | "<<localr<<"\n"
printf(" [ memr ] | addr | 0x" PRTHEX64 "\n",(uint64_t)memr); <<" [ memr ] | addr | "<<memr<<"\n"
if(funcr.type==vm_nil) <<" [ canary ] | addr | "<<canary<<"\n"
printf(" [ funcr ] | nil |\n"); <<" [ top ] | addr | "<<top<<"\n"
else <<std::dec;
printf(" [ funcr ] | func | <0x" PRTHEX64 "> entry:0x%x\n", std::cout<<" [ funcr ]";valinfo(funcr);
(uint64_t)funcr.value.gcobj, std::cout<<" [ upvalr ]";valinfo(upvalr);
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);
} }
void nasal_vm::global_state() void nasal_vm::global_state()
{ {
if(!bytecode[0].num || stack[0].type==vm_none) // bytecode[0].op is op_intg if(!bytecode[0].num || stack[0].type==vm_none) // bytecode[0].op is op_intg
return; 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) 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]); valinfo(stack[i]);
} }
} }
@ -303,10 +269,12 @@ void nasal_vm::local_state()
if(!localr || !funcr.func().lsize) if(!localr || !funcr.func().lsize)
return; return;
const uint32_t lsize=funcr.func().lsize; 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) 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]); valinfo(localr[i]);
} }
} }
@ -314,15 +282,16 @@ void nasal_vm::upval_state()
{ {
if(funcr.type==vm_nil || funcr.func().upvalue.empty()) if(funcr.type==vm_nil || funcr.func().upvalue.empty())
return; return;
printf("upvalue:\n"); std::cout<<"upvalue\n";
auto& upval=funcr.func().upvalue; auto& upval=funcr.func().upvalue;
for(uint32_t i=0;i<upval.size();++i) for(uint32_t i=0;i<upval.size();++i)
{ {
printf(" -> upval[%u]:\n",i); std::cout<<" -> upval["<<i<<"]:\n";
auto& uv=upval[i].upval(); auto& uv=upval[i].upval();
for(uint32_t j=0;j<uv.size;++j) 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]); valinfo(uv[j]);
} }
} }
@ -353,7 +322,8 @@ void nasal_vm::opcallsort(const uint64_t* arr)
{ {
uint64_t rate=i.second*100/total; uint64_t rate=i.second*100/total;
if(rate) 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 else
{ {
std::cout<<"\n ..."; std::cout<<"\n ...";
@ -362,9 +332,9 @@ void nasal_vm::opcallsort(const uint64_t* arr)
} }
std::cout<<"\n total : "<<total<<'\n'; 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(); traceback();
stackinfo(); stackinfo();
if(detail_info) if(detail_info)
@ -406,7 +376,8 @@ inline void nasal_vm::opr_loadl()
} }
inline void nasal_vm::opr_loadu() 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() inline void nasal_vm::opr_pnum()
{ {
@ -461,14 +432,16 @@ inline void nasal_vm::opr_happ()
inline void nasal_vm::opr_para() inline void nasal_vm::opr_para()
{ {
nasal_func& func=top[0].func(); 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}; func.local[func.psize++]={vm_none};
} }
inline void nasal_vm::opr_deft() inline void nasal_vm::opr_deft()
{ {
nasal_ref val=top[0]; nasal_ref val=top[0];
nasal_func& func=(--top)[0].func(); 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; func.local[func.psize++]=val;
} }
inline void nasal_vm::opr_dyn() inline void nasal_vm::opr_dyn()
@ -669,7 +642,8 @@ inline void nasal_vm::opr_calll()
} }
inline void nasal_vm::opr_upval() 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() inline void nasal_vm::opr_callv()
{ {
@ -738,10 +712,11 @@ inline void nasal_vm::opr_callfv()
nasal_ref tmp=local[-1]; nasal_ref tmp=local[-1];
local[-1]=funcr; local[-1]=funcr;
funcr=tmp; 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"); die("stack overflow");
// parameter size is func->psize-1, 1 is reserved for "me"
uint32_t psize=func.psize-1; // 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) if(argc<psize && func.local[argc+1].type==vm_none)
die("callfv: lack argument(s)"); die("callfv: lack argument(s)");
@ -779,7 +754,8 @@ inline void nasal_vm::opr_callfh()
nasal_ref tmp=top[-1]; nasal_ref tmp=top[-1];
top[-1]=funcr; top[-1]=funcr;
funcr=tmp; 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"); die("stack overflow");
if(func.dynpara>=0) if(func.dynpara>=0)
die("callfh: special call cannot use dynamic argument"); die("callfh: special call cannot use dynamic argument");
@ -901,7 +877,7 @@ inline void nasal_vm::opr_mcallv()
if(!memr) if(!memr)
die("mcallv: index out of range:"+std::to_string(val.tonum())); 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) if(val.type!=vm_str)
die("mcallv: must use string as the key"); die("mcallv: must use string as the key");
@ -1027,7 +1003,13 @@ vmexit:
imm.clear(); imm.clear();
return; return;
// may cause stackoverflow // 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 // do not cause stackoverflow
#define exec_opnodie(op,num) {op();++count[num];goto *code[++pc];} #define exec_opnodie(op,num) {op();++count[num];goto *code[++pc];}

View File

@ -1,7 +1,7 @@
# lib.nas # lib.nas
# print is used to print all things in nasal, try and see how it works. # 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...){ var print=func(elems...){
return __print(elems); return __print(elems);
} }