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)
{
bool is_negative=false;
double ret_num=0;
bool negative=false;
double res=0;
if(*str=='-' || *str=='+')
is_negative=(*str++=='-');
negative=(*str++=='-');
if(!*str)
return nan("");
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')
ret_num=oct_to_double(str+2);
res=oct_to_double(str+2);
else
ret_num=dec_to_double(str);
return is_negative?-ret_num:ret_num;
res=dec_to_double(str);
return negative?-res:res;
}
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];
if(!funcptr.objchk(nasal_obj::faddr))
return builtin_err("dlcall","\"funcptr\" is not a valid function pointer");
typedef nasal_ref (*extern_func)(std::vector<nasal_ref>&,nasal_gc&);
extern_func func=(extern_func)funcptr.obj().ptr;
typedef nasal_ref (*externs)(std::vector<nasal_ref>&,nasal_gc&);
externs func=(externs)funcptr.obj().ptr;
return func(args.vec().elems,gc);
}
nasal_ref builtin_platform(nasal_ref* local,nasal_gc& gc)

View File

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

View File

@ -210,8 +210,7 @@ bool nasal_parse::check_func_end(const nasal_ast& node)
}
bool nasal_parse::check_special_call()
{
// special call means like this:
// function_name(a:1,b:2,c:3);
// special call means like this: function_name(a:1,b:2,c:3);
uint32_t check_ptr=ptr,curve=1,bracket=0,brace=0;
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()
{
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* bottom=stack+global_size;
std::stack<uint32_t> ret;
@ -304,7 +304,7 @@ void nasal_vm::local_state()
{
if(!localr || !funcr.func().lsize)
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));
for(uint32_t i=0;i<lsize;++i)
{
@ -355,7 +355,7 @@ void nasal_vm::opcallsort(const uint64_t* arr)
for(auto& i:opcall)
{
uint64_t rate=i.second*100/total;
if(rate>0)
if(rate)
std::cout<<"\n "<<code_table[i.first].name<<" : "<<i.second<<" ("<<rate<<"%)";
else
{
@ -380,7 +380,7 @@ inline bool nasal_vm::condition(nasal_ref val)
return val.num();
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))
return !val.str().empty();
return num;
@ -487,13 +487,12 @@ inline void nasal_vm::opr_unot()
case vm_num:top[0]=val.num()?zero:one;break;
case vm_str:
{
double num=str2num(val.str().c_str());
const double num=str2num(val.str().c_str());
if(std::isnan(num))
top[0]={vm_num,(double)val.str().empty()};
else
top[0]=num?zero:one;
}
break;
}break;
default:die("unot: incorrect value type");break;
}
}
@ -503,8 +502,8 @@ inline void nasal_vm::opr_usub()
}
#define op_calc(type)\
nasal_ref val(vm_num,top[-1].tonum() type top[0].tonum());\
(--top)[0]=val;
top[-1]={vm_num,top[-1].tonum() type top[0].tonum()};\
--top;
inline void nasal_vm::opr_add(){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_lnk()
{
nasal_ref val=gc.newstr(top[-1].tostr()+top[0].tostr());
(--top)[0]=val;
top[-1]=gc.newstr(top[-1].tostr()+top[0].tostr());
--top;
}
#define op_calc_const(type)\
nasal_ref val(vm_num,top[0].tonum() type num_table[imm[pc]]);\
top[0]=val;
top[0]={vm_num,top[0].tonum() type num_table[imm[pc]]};
inline void nasal_vm::opr_addc(){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_lnkc()
{
nasal_ref val=gc.newstr(top[0].tostr()+str_table[imm[pc]]);
top[0]=val;
top[0]=gc.newstr(top[0].tostr()+str_table[imm[pc]]);
}
#define op_calc_eq(type)\
nasal_ref val(vm_num,memr[0].tonum() type top[-1].tonum());\
(--top)[0]=memr[0]=val;\
top[-1]=memr[0]={vm_num,memr[0].tonum() type top[-1].tonum()};\
memr=nullptr;\
top-=imm[pc];
top-=imm[pc]+1;
inline void nasal_vm::opr_addeq(){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_lnkeq()
{
nasal_ref val=gc.newstr(memr[0].tostr()+top[-1].tostr());
(--top)[0]=memr[0]=val;
top[-1]=memr[0]=gc.newstr(memr[0].tostr()+top[-1].tostr());
memr=nullptr;
top-=imm[pc];
top-=imm[pc]+1;
}
#define op_calc_eq_const(type)\
nasal_ref val(vm_num,memr[0].tonum() type num_table[imm[pc]&0x7fffffff]);\
top[0]=memr[0]=val;\
top[0]=memr[0]={vm_num,memr[0].tonum() type num_table[imm[pc]&0x7fffffff]};\
memr=nullptr;\
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_lnkeqc()
{
nasal_ref val=gc.newstr(memr[0].tostr()+str_table[imm[pc]&0x7fffffff]);
top[0]=memr[0]=val;
top[0]=memr[0]=gc.newstr(memr[0].tostr()+str_table[imm[pc]&0x7fffffff]);
memr=nullptr;
top-=(imm[pc]>>31);
}
@ -573,9 +566,9 @@ inline void nasal_vm::opr_meq()
// is that when lnkeq/lnkeqc is called, there will be
// a new gc object vm_str which is returned by gc::alloc
// this may cause gc, so we should temporarily put it on stack
memr[0]=(--top)[0];
memr[0]=top[-1];
memr=nullptr;
top-=imm[pc];
top-=imm[pc]+1;
}
inline void nasal_vm::opr_eq()
{
@ -1037,9 +1030,9 @@ vmexit:
imm.clear();
return;
// 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
#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)
intl: exec_opnodie(opr_intl ,op_intl ); // -0