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
# 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);
}

View File

@ -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
View File

@ -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)

View File

@ -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

View File

@ -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;}

View File

@ -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];}

View File

@ -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);
}