optimize code.

This commit is contained in:
ValKmjolnir 2022-07-08 23:00:36 +08:00
parent 11e9567b55
commit 9890b46f02
5 changed files with 116 additions and 127 deletions

14
nasal.h
View File

@ -112,19 +112,19 @@ inline double dec_to_double(const char* str)
} }
double str2num(const char* str) double str2num(const char* str)
{ {
bool is_negative=false; bool negative=false;
double ret_num=0; double res=0;
if(*str=='-' || *str=='+') if(*str=='-' || *str=='+')
is_negative=(*str++=='-'); negative=(*str++=='-');
if(!*str) if(!*str)
return nan(""); return nan("");
if(str[0]=='0' && str[1]=='x') if(str[0]=='0' && str[1]=='x')
ret_num=hex_to_double(str+2); res=hex_to_double(str+2);
else if(str[0]=='0' && str[1]=='o') else if(str[0]=='0' && str[1]=='o')
ret_num=oct_to_double(str+2); res=oct_to_double(str+2);
else else
ret_num=dec_to_double(str); res=dec_to_double(str);
return is_negative?-ret_num:ret_num; return negative?-res:res;
} }
int utf8_hdchk(const char head) int utf8_hdchk(const char head)

View File

@ -1174,8 +1174,8 @@ nasal_ref builtin_dlcall(nasal_ref* local,nasal_gc& gc)
nasal_ref args=local[2]; nasal_ref args=local[2];
if(!funcptr.objchk(nasal_obj::faddr)) if(!funcptr.objchk(nasal_obj::faddr))
return builtin_err("dlcall","\"funcptr\" is not a valid function pointer"); return builtin_err("dlcall","\"funcptr\" is not a valid function pointer");
typedef nasal_ref (*extern_func)(std::vector<nasal_ref>&,nasal_gc&); typedef nasal_ref (*externs)(std::vector<nasal_ref>&,nasal_gc&);
extern_func func=(extern_func)funcptr.obj().ptr; externs func=(externs)funcptr.obj().ptr;
return func(args.vec().elems,gc); return func(args.vec().elems,gc);
} }
nasal_ref builtin_platform(nasal_ref* local,nasal_gc& gc) nasal_ref builtin_platform(nasal_ref* local,nasal_gc& gc)

View File

@ -86,82 +86,82 @@ struct
const char* name; const char* name;
}code_table[]= }code_table[]=
{ {
{op_exit, "exit "}, {op_exit, "exit "},
{op_intg, "intg "}, {op_intg, "intg "},
{op_intl, "intl "}, {op_intl, "intl "},
{op_loadg, "loadg "}, {op_loadg, "loadg "},
{op_loadl, "loadl "}, {op_loadl, "loadl "},
{op_loadu, "loadu "}, {op_loadu, "loadu "},
{op_pnum, "pnum "}, {op_pnum, "pnum "},
{op_pnil, "pnil "}, {op_pnil, "pnil "},
{op_pstr, "pstr "}, {op_pstr, "pstr "},
{op_newv, "newv "}, {op_newv, "newv "},
{op_newh, "newh "}, {op_newh, "newh "},
{op_newf, "newf "}, {op_newf, "newf "},
{op_happ, "happ "}, {op_happ, "happ "},
{op_para, "para "}, {op_para, "para "},
{op_deft, "def "}, {op_deft, "def "},
{op_dyn, "dyn "}, {op_dyn, "dyn "},
{op_unot, "not "}, {op_unot, "not "},
{op_usub, "usub "}, {op_usub, "usub "},
{op_add, "add "}, {op_add, "add "},
{op_sub, "sub "}, {op_sub, "sub "},
{op_mul, "mult "}, {op_mul, "mult "},
{op_div, "div "}, {op_div, "div "},
{op_lnk, "lnk "}, {op_lnk, "lnk "},
{op_addc, "addc "}, {op_addc, "addc "},
{op_subc, "subc "}, {op_subc, "subc "},
{op_mulc, "multc "}, {op_mulc, "multc "},
{op_divc, "divc "}, {op_divc, "divc "},
{op_lnkc, "lnkc "}, {op_lnkc, "lnkc "},
{op_addeq, "addeq "}, {op_addeq, "addeq "},
{op_subeq, "subeq "}, {op_subeq, "subeq "},
{op_muleq, "muleq "}, {op_muleq, "muleq "},
{op_diveq, "diveq "}, {op_diveq, "diveq "},
{op_lnkeq, "lnkeq "}, {op_lnkeq, "lnkeq "},
{op_addeqc, "addeqc"}, {op_addeqc,"addeqc"},
{op_subeqc, "subeqc"}, {op_subeqc,"subeqc"},
{op_muleqc, "muleqc"}, {op_muleqc,"muleqc"},
{op_diveqc, "diveqc"}, {op_diveqc,"diveqc"},
{op_lnkeqc, "lnkeqc"}, {op_lnkeqc,"lnkeqc"},
{op_meq, "meq "}, {op_meq, "meq "},
{op_eq, "eq "}, {op_eq, "eq "},
{op_neq, "neq "}, {op_neq, "neq "},
{op_less, "less "}, {op_less, "less "},
{op_leq, "leq "}, {op_leq, "leq "},
{op_grt, "grt "}, {op_grt, "grt "},
{op_geq, "geq "}, {op_geq, "geq "},
{op_lessc, "lessc "}, {op_lessc, "lessc "},
{op_leqc, "leqc "}, {op_leqc, "leqc "},
{op_grtc, "grtc "}, {op_grtc, "grtc "},
{op_geqc, "geqc "}, {op_geqc, "geqc "},
{op_pop, "pop "}, {op_pop, "pop "},
{op_jmp, "jmp "}, {op_jmp, "jmp "},
{op_jt, "jt "}, {op_jt, "jt "},
{op_jf, "jf "}, {op_jf, "jf "},
{op_cnt, "cnt "}, {op_cnt, "cnt "},
{op_findex, "findx "}, {op_findex,"findx "},
{op_feach, "feach "}, {op_feach, "feach "},
{op_callg, "callg "}, {op_callg, "callg "},
{op_calll, "calll "}, {op_calll, "calll "},
{op_upval, "upval "}, {op_upval, "upval "},
{op_callv, "callv "}, {op_callv, "callv "},
{op_callvi, "callvi"}, {op_callvi,"callvi"},
{op_callh, "callh "}, {op_callh, "callh "},
{op_callfv, "callfv"}, {op_callfv,"callfv"},
{op_callfh, "callfh"}, {op_callfh,"callfh"},
{op_callb, "callb "}, {op_callb, "callb "},
{op_slcbeg, "slcbeg"}, {op_slcbeg,"slcbeg"},
{op_slcend, "slcend"}, {op_slcend,"slcend"},
{op_slc, "slc "}, {op_slc, "slc "},
{op_slc2, "slc2 "}, {op_slc2, "slc2 "},
{op_mcallg, "mcallg"}, {op_mcallg,"mcallg"},
{op_mcalll, "mcalll"}, {op_mcalll,"mcalll"},
{op_mupval, "mupval"}, {op_mupval,"mupval"},
{op_mcallv, "mcallv"}, {op_mcallv,"mcallv"},
{op_mcallh, "mcallh"}, {op_mcallh,"mcallh"},
{op_ret, "ret "}, {op_ret, "ret "},
{-1, nullptr }, {-1, nullptr },
}; };
struct opcode struct opcode
@ -205,7 +205,7 @@ private:
std::stack<uint32_t> fbstk; std::stack<uint32_t> fbstk;
std::stack<uint32_t> festk; std::stack<uint32_t> festk;
void die(std::string,const uint32_t); void die(const std::string&,const uint32_t);
void regist_num(const double); void regist_num(const double);
void regist_str(const std::string&); void regist_str(const std::string&);
void find_symbol(const nasal_ast&); void find_symbol(const nasal_ast&);
@ -248,14 +248,14 @@ private:
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(uint32_t); 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;}
const std::vector<opcode>& get_code() const {return code;} const std::vector<opcode>& get_code() const {return code;}
}; };
void nasal_codegen::die(std::string info,const uint32_t line) void nasal_codegen::die(const std::string& info,const uint32_t line)
{ {
nerr.load(file[fileindex]); nerr.load(file[fileindex]);
nerr.err("code",line,info); nerr.err("code",line,info);
@ -1237,7 +1237,7 @@ void nasal_codegen::compile(const nasal_parse& parse,const nasal_import& import)
nerr.chkerr(); nerr.chkerr();
} }
void nasal_codegen::print_op(uint32_t index) void nasal_codegen::print_op(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];
@ -1261,12 +1261,9 @@ void nasal_codegen::print_op(uint32_t index)
} }
} }
printf(" 0x%.8x: %.2x %.2x %.2x %.2x %.2x %s ", printf(" 0x%.8x: %.2x %.2x %.2x %.2x %.2x %s ",
index, index,c.op,
c.op, uint8_t((c.num>>24)&0xff),uint8_t((c.num>>16)&0xff),
uint8_t((c.num>>24)&0xff), uint8_t((c.num>>8)&0xff),uint8_t(c.num&0xff),
uint8_t((c.num>>16)&0xff),
uint8_t((c.num>>8)&0xff),
uint8_t(c.num&0xff),
code_table[c.op].name code_table[c.op].name
); );
// print detail info // print detail info
@ -1312,7 +1309,7 @@ void nasal_codegen::print()
for(auto& str:str_res) for(auto& str:str_res)
std::cout<<" .symbol \""<<rawstr(str)<<"\"\n"; std::cout<<" .symbol \""<<rawstr(str)<<"\"\n";
std::cout<<"\n"; std::cout<<"\n";
for(size_t i=0;i<code.size();++i) for(uint32_t i=0;i<code.size();++i)
print_op(i); print_op(i);
} }

View File

@ -210,8 +210,7 @@ bool nasal_parse::check_func_end(const nasal_ast& node)
} }
bool nasal_parse::check_special_call() bool nasal_parse::check_special_call()
{ {
// special call means like this: // special call means like this: function_name(a:1,b:2,c:3);
// function_name(a:1,b:2,c:3);
uint32_t check_ptr=ptr,curve=1,bracket=0,brace=0; uint32_t check_ptr=ptr,curve=1,bracket=0,brace=0;
while(tokens[++check_ptr].type!=tok_eof && curve) while(tokens[++check_ptr].type!=tok_eof && curve)
{ {

View File

@ -222,7 +222,7 @@ void nasal_vm::bytecodeinfo(const char* header,const uint32_t p)
} }
void nasal_vm::traceback() void nasal_vm::traceback()
{ {
uint32_t global_size=bytecode[0].num; // bytecode[0] is op_intg const uint32_t global_size=bytecode[0].num; // bytecode[0] is op_intg
nasal_ref* t=top; nasal_ref* t=top;
nasal_ref* bottom=stack+global_size; nasal_ref* bottom=stack+global_size;
std::stack<uint32_t> ret; std::stack<uint32_t> ret;
@ -304,7 +304,7 @@ void nasal_vm::local_state()
{ {
if(!localr || !funcr.func().lsize) if(!localr || !funcr.func().lsize)
return; return;
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)); printf("local(0x" PRTHEX64 "<sp+" PRTINT64 ">):\n",(uint64_t)localr,(int64_t)(localr-gc.stack));
for(uint32_t i=0;i<lsize;++i) for(uint32_t i=0;i<lsize;++i)
{ {
@ -355,7 +355,7 @@ void nasal_vm::opcallsort(const uint64_t* arr)
for(auto& i:opcall) for(auto& i:opcall)
{ {
uint64_t rate=i.second*100/total; uint64_t rate=i.second*100/total;
if(rate>0) 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
{ {
@ -380,7 +380,7 @@ inline bool nasal_vm::condition(nasal_ref val)
return val.num(); return val.num();
else if(val.type==vm_str) else if(val.type==vm_str)
{ {
double num=str2num(val.str().c_str()); const double num=str2num(val.str().c_str());
if(std::isnan(num)) if(std::isnan(num))
return !val.str().empty(); return !val.str().empty();
return num; return num;
@ -487,13 +487,12 @@ inline void nasal_vm::opr_unot()
case vm_num:top[0]=val.num()?zero:one;break; case vm_num:top[0]=val.num()?zero:one;break;
case vm_str: case vm_str:
{ {
double num=str2num(val.str().c_str()); const double num=str2num(val.str().c_str());
if(std::isnan(num)) if(std::isnan(num))
top[0]={vm_num,(double)val.str().empty()}; top[0]={vm_num,(double)val.str().empty()};
else else
top[0]=num?zero:one; top[0]=num?zero:one;
} }break;
break;
default:die("unot: incorrect value type");break; default:die("unot: incorrect value type");break;
} }
} }
@ -503,8 +502,8 @@ inline void nasal_vm::opr_usub()
} }
#define op_calc(type)\ #define op_calc(type)\
nasal_ref val(vm_num,top[-1].tonum() type top[0].tonum());\ top[-1]={vm_num,top[-1].tonum() type top[0].tonum()};\
(--top)[0]=val; --top;
inline void nasal_vm::opr_add(){op_calc(+);} inline void nasal_vm::opr_add(){op_calc(+);}
inline void nasal_vm::opr_sub(){op_calc(-);} inline void nasal_vm::opr_sub(){op_calc(-);}
@ -512,13 +511,12 @@ inline void nasal_vm::opr_mul(){op_calc(*);}
inline void nasal_vm::opr_div(){op_calc(/);} inline void nasal_vm::opr_div(){op_calc(/);}
inline void nasal_vm::opr_lnk() inline void nasal_vm::opr_lnk()
{ {
nasal_ref val=gc.newstr(top[-1].tostr()+top[0].tostr()); top[-1]=gc.newstr(top[-1].tostr()+top[0].tostr());
(--top)[0]=val; --top;
} }
#define op_calc_const(type)\ #define op_calc_const(type)\
nasal_ref val(vm_num,top[0].tonum() type num_table[imm[pc]]);\ top[0]={vm_num,top[0].tonum() type num_table[imm[pc]]};
top[0]=val;
inline void nasal_vm::opr_addc(){op_calc_const(+);} inline void nasal_vm::opr_addc(){op_calc_const(+);}
inline void nasal_vm::opr_subc(){op_calc_const(-);} inline void nasal_vm::opr_subc(){op_calc_const(-);}
@ -526,15 +524,13 @@ inline void nasal_vm::opr_mulc(){op_calc_const(*);}
inline void nasal_vm::opr_divc(){op_calc_const(/);} inline void nasal_vm::opr_divc(){op_calc_const(/);}
inline void nasal_vm::opr_lnkc() inline void nasal_vm::opr_lnkc()
{ {
nasal_ref val=gc.newstr(top[0].tostr()+str_table[imm[pc]]); top[0]=gc.newstr(top[0].tostr()+str_table[imm[pc]]);
top[0]=val;
} }
#define op_calc_eq(type)\ #define op_calc_eq(type)\
nasal_ref val(vm_num,memr[0].tonum() type top[-1].tonum());\ top[-1]=memr[0]={vm_num,memr[0].tonum() type top[-1].tonum()};\
(--top)[0]=memr[0]=val;\
memr=nullptr;\ memr=nullptr;\
top-=imm[pc]; top-=imm[pc]+1;
inline void nasal_vm::opr_addeq(){op_calc_eq(+);} inline void nasal_vm::opr_addeq(){op_calc_eq(+);}
inline void nasal_vm::opr_subeq(){op_calc_eq(-);} inline void nasal_vm::opr_subeq(){op_calc_eq(-);}
@ -542,15 +538,13 @@ inline void nasal_vm::opr_muleq(){op_calc_eq(*);}
inline void nasal_vm::opr_diveq(){op_calc_eq(/);} inline void nasal_vm::opr_diveq(){op_calc_eq(/);}
inline void nasal_vm::opr_lnkeq() inline void nasal_vm::opr_lnkeq()
{ {
nasal_ref val=gc.newstr(memr[0].tostr()+top[-1].tostr()); top[-1]=memr[0]=gc.newstr(memr[0].tostr()+top[-1].tostr());
(--top)[0]=memr[0]=val;
memr=nullptr; memr=nullptr;
top-=imm[pc]; top-=imm[pc]+1;
} }
#define op_calc_eq_const(type)\ #define op_calc_eq_const(type)\
nasal_ref val(vm_num,memr[0].tonum() type num_table[imm[pc]&0x7fffffff]);\ top[0]=memr[0]={vm_num,memr[0].tonum() type num_table[imm[pc]&0x7fffffff]};\
top[0]=memr[0]=val;\
memr=nullptr;\ memr=nullptr;\
top-=(imm[pc]>>31); top-=(imm[pc]>>31);
@ -560,8 +554,7 @@ inline void nasal_vm::opr_muleqc(){op_calc_eq_const(*);}
inline void nasal_vm::opr_diveqc(){op_calc_eq_const(/);} inline void nasal_vm::opr_diveqc(){op_calc_eq_const(/);}
inline void nasal_vm::opr_lnkeqc() inline void nasal_vm::opr_lnkeqc()
{ {
nasal_ref val=gc.newstr(memr[0].tostr()+str_table[imm[pc]&0x7fffffff]); top[0]=memr[0]=gc.newstr(memr[0].tostr()+str_table[imm[pc]&0x7fffffff]);
top[0]=memr[0]=val;
memr=nullptr; memr=nullptr;
top-=(imm[pc]>>31); top-=(imm[pc]>>31);
} }
@ -573,9 +566,9 @@ inline void nasal_vm::opr_meq()
// is that when lnkeq/lnkeqc is called, there will be // is that when lnkeq/lnkeqc is called, there will be
// a new gc object vm_str which is returned by gc::alloc // a new gc object vm_str which is returned by gc::alloc
// this may cause gc, so we should temporarily put it on stack // this may cause gc, so we should temporarily put it on stack
memr[0]=(--top)[0]; memr[0]=top[-1];
memr=nullptr; memr=nullptr;
top-=imm[pc]; top-=imm[pc]+1;
} }
inline void nasal_vm::opr_eq() inline void nasal_vm::opr_eq()
{ {
@ -1037,9 +1030,9 @@ vmexit:
imm.clear(); imm.clear();
return; return;
// may cause stackoverflow // may cause stackoverflow
#define exec_operand(op,num) {++count[num];op();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) {++count[num];op();goto *code[++pc];} #define exec_opnodie(op,num) {op();++count[num];goto *code[++pc];}
intg: exec_opnodie(opr_intg ,op_intg ); // +imm[pc] (detected at codegen) intg: exec_opnodie(opr_intg ,op_intg ); // +imm[pc] (detected at codegen)
intl: exec_opnodie(opr_intl ,op_intl ); // -0 intl: exec_opnodie(opr_intl ,op_intl ); // -0