change increment arguments to a more efficiency level & change gc.nil, gc.one, gc.zero to constant nil, one, zero
This commit is contained in:
parent
aa301aefc3
commit
c55ce758ed
|
@ -1063,8 +1063,8 @@ nasal_ref builtin_print(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
}
|
}
|
||||||
std::cout<<std::flush;
|
std::cout<<std::flush;
|
||||||
// generate return value,use gc::alloc(type) to make a new value
|
// generate return value,use gc::alloc(type) to make a new value
|
||||||
// or use reserved reference gc.nil/gc.one/gc.zero
|
// or use reserved reference nil/one/zero
|
||||||
return gc.nil;
|
return nil;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
18
main.cpp
18
main.cpp
|
@ -1,14 +1,14 @@
|
||||||
#include "nasal.h"
|
#include "nasal.h"
|
||||||
|
|
||||||
constexpr uint32_t VM_LEXINFO =1;
|
const uint32_t VM_LEXINFO =1;
|
||||||
constexpr uint32_t VM_ASTINFO =2;
|
const uint32_t VM_ASTINFO =2;
|
||||||
constexpr uint32_t VM_CODEINFO =4;
|
const uint32_t VM_CODEINFO =4;
|
||||||
constexpr uint32_t VM_EXECTIME =8;
|
const uint32_t VM_EXECTIME =8;
|
||||||
constexpr uint32_t VM_OPCALLNUM=16;
|
const uint32_t VM_OPCALLNUM=16;
|
||||||
constexpr uint32_t VM_EXEC =32;
|
const uint32_t VM_EXEC =32;
|
||||||
constexpr uint32_t VM_DBGINFO =64;
|
const uint32_t VM_DBGINFO =64;
|
||||||
constexpr uint32_t VM_DEBUG =128;
|
const uint32_t VM_DEBUG =128;
|
||||||
constexpr uint32_t VM_OPTIMIZE =256;
|
const uint32_t VM_OPTIMIZE =256;
|
||||||
|
|
||||||
void help()
|
void help()
|
||||||
{
|
{
|
||||||
|
|
|
@ -189,7 +189,7 @@ nasal_ref builtin_print(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
}
|
}
|
||||||
std::cout<<std::flush;
|
std::cout<<std::flush;
|
||||||
// generate return value
|
// generate return value
|
||||||
return gc.nil;
|
return nil;
|
||||||
}
|
}
|
||||||
nasal_ref builtin_append(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_append(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
|
@ -200,7 +200,7 @@ nasal_ref builtin_append(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
auto& ref_vec=vec.vec()->elems;
|
auto& ref_vec=vec.vec()->elems;
|
||||||
for(auto& i:elem.vec()->elems)
|
for(auto& i:elem.vec()->elems)
|
||||||
ref_vec.push_back(i);
|
ref_vec.push_back(i);
|
||||||
return gc.nil;
|
return nil;
|
||||||
}
|
}
|
||||||
nasal_ref builtin_setsize(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_setsize(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
|
@ -213,8 +213,8 @@ nasal_ref builtin_setsize(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
int num=(int)size.num();
|
int num=(int)size.num();
|
||||||
if(num<0)
|
if(num<0)
|
||||||
return builtin_err("setsize","\"size\" must be greater than -1");
|
return builtin_err("setsize","\"size\" must be greater than -1");
|
||||||
vec.vec()->elems.resize(num,gc.nil);
|
vec.vec()->elems.resize(num,nil);
|
||||||
return gc.nil;
|
return nil;
|
||||||
}
|
}
|
||||||
nasal_ref builtin_system(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_system(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
|
@ -258,7 +258,7 @@ nasal_ref builtin_fout(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
if(fout.fail())
|
if(fout.fail())
|
||||||
return builtin_err("io.fout","cannot open \""+*val.str()+"\"");
|
return builtin_err("io.fout","cannot open \""+*val.str()+"\"");
|
||||||
fout<<*str.str();
|
fout<<*str.str();
|
||||||
return gc.nil;
|
return nil;
|
||||||
}
|
}
|
||||||
nasal_ref builtin_split(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_split(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
|
@ -328,7 +328,7 @@ nasal_ref builtin_rand(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
if(val.type==vm_num)
|
if(val.type==vm_num)
|
||||||
{
|
{
|
||||||
srand((unsigned int)val.num());
|
srand((unsigned int)val.num());
|
||||||
return gc.nil;
|
return nil;
|
||||||
}
|
}
|
||||||
double num=0;
|
double num=0;
|
||||||
for(int i=0;i<5;++i)
|
for(int i=0;i<5;++i)
|
||||||
|
@ -351,7 +351,7 @@ nasal_ref builtin_int(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
nasal_ref val=local[1];
|
nasal_ref val=local[1];
|
||||||
if(val.type!=vm_num)
|
if(val.type!=vm_num)
|
||||||
return gc.nil;
|
return nil;
|
||||||
int number=(int)val.num();
|
int number=(int)val.num();
|
||||||
return {vm_num,(double)number};
|
return {vm_num,(double)number};
|
||||||
}
|
}
|
||||||
|
@ -361,10 +361,10 @@ nasal_ref builtin_num(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
if(val.type==vm_num)
|
if(val.type==vm_num)
|
||||||
return val;
|
return val;
|
||||||
if(val.type!=vm_str)
|
if(val.type!=vm_str)
|
||||||
return gc.nil;
|
return nil;
|
||||||
double res=val.to_number();
|
double res=val.to_number();
|
||||||
if(std::isnan(res))
|
if(std::isnan(res))
|
||||||
return gc.nil;
|
return nil;
|
||||||
return {vm_num,res};
|
return {vm_num,res};
|
||||||
}
|
}
|
||||||
nasal_ref builtin_pop(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_pop(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
|
@ -378,7 +378,7 @@ nasal_ref builtin_pop(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
val.vec()->elems.pop_back();
|
val.vec()->elems.pop_back();
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
return gc.nil;
|
return nil;
|
||||||
}
|
}
|
||||||
nasal_ref builtin_str(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_str(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
|
@ -520,7 +520,7 @@ nasal_ref builtin_atan2(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
nasal_ref builtin_isnan(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_isnan(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
nasal_ref x=local[1];
|
nasal_ref x=local[1];
|
||||||
return (x.type==vm_num && std::isnan(x.num()))?gc.one:gc.zero;
|
return (x.type==vm_num && std::isnan(x.num()))?one:zero;
|
||||||
}
|
}
|
||||||
nasal_ref builtin_time(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_time(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
|
@ -538,7 +538,7 @@ nasal_ref builtin_contains(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
return builtin_err("contains","\"hash\" must be hash");
|
return builtin_err("contains","\"hash\" must be hash");
|
||||||
if(key.type!=vm_str)
|
if(key.type!=vm_str)
|
||||||
return builtin_err("contains","\"key\" must be string");
|
return builtin_err("contains","\"key\" must be string");
|
||||||
return hash.hash()->elems.count(*key.str())?gc.one:gc.zero;
|
return hash.hash()->elems.count(*key.str())?one:zero;
|
||||||
}
|
}
|
||||||
nasal_ref builtin_delete(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_delete(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
|
@ -550,7 +550,7 @@ nasal_ref builtin_delete(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
return builtin_err("delete","\"key\" must be string");
|
return builtin_err("delete","\"key\" must be string");
|
||||||
if(hash.hash()->elems.count(*key.str()))
|
if(hash.hash()->elems.count(*key.str()))
|
||||||
hash.hash()->elems.erase(*key.str());
|
hash.hash()->elems.erase(*key.str());
|
||||||
return gc.nil;
|
return nil;
|
||||||
}
|
}
|
||||||
nasal_ref builtin_keys(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_keys(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
|
@ -729,7 +729,7 @@ nasal_ref builtin_close(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
if(filehandle.type!=vm_obj || filehandle.obj()->type!=obj_file)
|
if(filehandle.type!=vm_obj || filehandle.obj()->type!=obj_file)
|
||||||
return builtin_err("close","not a correct filehandle");
|
return builtin_err("close","not a correct filehandle");
|
||||||
fclose((FILE*)filehandle.obj()->ptr);
|
fclose((FILE*)filehandle.obj()->ptr);
|
||||||
return gc.nil;
|
return nil;
|
||||||
}
|
}
|
||||||
nasal_ref builtin_read(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_read(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
|
@ -803,7 +803,7 @@ nasal_ref builtin_readln(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
}
|
}
|
||||||
if(s.length())
|
if(s.length())
|
||||||
return str;
|
return str;
|
||||||
return gc.nil;
|
return nil;
|
||||||
}
|
}
|
||||||
nasal_ref builtin_stat(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_stat(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
|
@ -913,7 +913,7 @@ nasal_ref builtin_setfld(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
else
|
else
|
||||||
s[i>>3]&=~(1<<(7-(i&7)));
|
s[i>>3]&=~(1<<(7-(i&7)));
|
||||||
}
|
}
|
||||||
return gc.nil;
|
return nil;
|
||||||
}
|
}
|
||||||
nasal_ref builtin_buf(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_buf(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
|
@ -931,7 +931,7 @@ nasal_ref builtin_sleep(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
if(val.type!=vm_num)
|
if(val.type!=vm_num)
|
||||||
return builtin_err("sleep","\"duration\" must be number");
|
return builtin_err("sleep","\"duration\" must be number");
|
||||||
usleep((useconds_t)(val.num()*1e6));
|
usleep((useconds_t)(val.num()*1e6));
|
||||||
return gc.nil;
|
return nil;
|
||||||
}
|
}
|
||||||
nasal_ref builtin_opendir(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_opendir(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
|
@ -953,7 +953,7 @@ nasal_ref builtin_readdir(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
return builtin_err("readdir","not a correct dir handle");
|
return builtin_err("readdir","not a correct dir handle");
|
||||||
dirent* p=readdir((DIR*)handle.obj()->ptr);
|
dirent* p=readdir((DIR*)handle.obj()->ptr);
|
||||||
if(!p)
|
if(!p)
|
||||||
return gc.nil;
|
return nil;
|
||||||
nasal_ref ret=gc.alloc(vm_str);
|
nasal_ref ret=gc.alloc(vm_str);
|
||||||
*ret.str()=p->d_name;
|
*ret.str()=p->d_name;
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -964,7 +964,7 @@ nasal_ref builtin_closedir(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
if(handle.type!=vm_obj || handle.obj()->type!=obj_dir)
|
if(handle.type!=vm_obj || handle.obj()->type!=obj_dir)
|
||||||
return builtin_err("closedir","not a correct dir handle");
|
return builtin_err("closedir","not a correct dir handle");
|
||||||
closedir((DIR*)handle.obj()->ptr);
|
closedir((DIR*)handle.obj()->ptr);
|
||||||
return gc.nil;
|
return nil;
|
||||||
}
|
}
|
||||||
nasal_ref builtin_chdir(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_chdir(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
|
@ -973,7 +973,7 @@ nasal_ref builtin_chdir(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
return builtin_err("chdir","\"path\" must be string");
|
return builtin_err("chdir","\"path\" must be string");
|
||||||
if(chdir(path.str()->c_str())<0)
|
if(chdir(path.str()->c_str())<0)
|
||||||
return builtin_err("chdir","failed to execute chdir");
|
return builtin_err("chdir","failed to execute chdir");
|
||||||
return gc.nil;
|
return nil;
|
||||||
}
|
}
|
||||||
nasal_ref builtin_getcwd(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_getcwd(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
|
@ -990,7 +990,7 @@ nasal_ref builtin_getenv(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
return builtin_err("getenv","\"envvar\" must be string");
|
return builtin_err("getenv","\"envvar\" must be string");
|
||||||
char* res=getenv(envvar.str()->c_str());
|
char* res=getenv(envvar.str()->c_str());
|
||||||
if(!res)
|
if(!res)
|
||||||
return gc.nil;
|
return nil;
|
||||||
nasal_ref str=gc.alloc(vm_str);
|
nasal_ref str=gc.alloc(vm_str);
|
||||||
*str.str()=res;
|
*str.str()=res;
|
||||||
return str;
|
return str;
|
||||||
|
@ -1047,7 +1047,7 @@ nasal_ref builtin_dlclose(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
#else
|
#else
|
||||||
dlclose(libptr.obj()->ptr);
|
dlclose(libptr.obj()->ptr);
|
||||||
#endif
|
#endif
|
||||||
return gc.nil;
|
return nil;
|
||||||
}
|
}
|
||||||
nasal_ref builtin_dlcall(std::vector<nasal_ref>& local,nasal_gc& gc)
|
nasal_ref builtin_dlcall(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
|
|
32
nasal_gc.h
32
nasal_gc.h
|
@ -30,17 +30,17 @@ const uint32_t increment[vm_type_size]=
|
||||||
0, // vm_num
|
0, // vm_num
|
||||||
/* gc object */
|
/* gc object */
|
||||||
512, // vm_str
|
512, // vm_str
|
||||||
512, // vm_func
|
1024,// vm_func
|
||||||
512, // vm_vec
|
4096,// vm_vec
|
||||||
512, // vm_hash
|
256, // vm_hash
|
||||||
64 // vm_obj
|
16 // vm_obj
|
||||||
};
|
};
|
||||||
|
|
||||||
struct nasal_vec;
|
struct nasal_vec;
|
||||||
struct nasal_hash;
|
struct nasal_hash;
|
||||||
struct nasal_func;
|
struct nasal_func;
|
||||||
struct nasal_obj;
|
struct nasal_obj;
|
||||||
struct nasal_val;
|
struct nasal_val; // nasal_val includes gc-managed types
|
||||||
|
|
||||||
struct nasal_ref
|
struct nasal_ref
|
||||||
{
|
{
|
||||||
|
@ -118,9 +118,9 @@ struct nasal_obj
|
||||||
void clear(){ptr=nullptr;}
|
void clear(){ptr=nullptr;}
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr uint8_t GC_UNCOLLECTED=0;
|
const uint8_t GC_UNCOLLECTED=0;
|
||||||
constexpr uint8_t GC_COLLECTED =1;
|
const uint8_t GC_COLLECTED =1;
|
||||||
constexpr uint8_t GC_FOUND =2;
|
const uint8_t GC_FOUND =2;
|
||||||
struct nasal_val
|
struct nasal_val
|
||||||
{
|
{
|
||||||
uint8_t mark;
|
uint8_t mark;
|
||||||
|
@ -316,12 +316,12 @@ inline nasal_hash* nasal_ref::hash(){return value.gcobj->ptr.hash;}
|
||||||
inline nasal_func* nasal_ref::func(){return value.gcobj->ptr.func;}
|
inline nasal_func* nasal_ref::func(){return value.gcobj->ptr.func;}
|
||||||
inline nasal_obj* nasal_ref::obj (){return value.gcobj->ptr.obj; }
|
inline nasal_obj* nasal_ref::obj (){return value.gcobj->ptr.obj; }
|
||||||
|
|
||||||
constexpr uint32_t STACK_MAX_DEPTH=4095;
|
const uint32_t STACK_MAX_DEPTH=4095;
|
||||||
|
const nasal_ref zero={vm_num,(double)0};
|
||||||
|
const nasal_ref one ={vm_num,(double)1};
|
||||||
|
const nasal_ref nil ={vm_nil,nullptr};
|
||||||
struct nasal_gc
|
struct nasal_gc
|
||||||
{
|
{
|
||||||
nasal_ref zero;
|
|
||||||
nasal_ref one;
|
|
||||||
nasal_ref nil;
|
|
||||||
nasal_ref stack[STACK_MAX_DEPTH+1];// 1 reserved to avoid stack overflow
|
nasal_ref stack[STACK_MAX_DEPTH+1];// 1 reserved to avoid stack overflow
|
||||||
nasal_ref* top; // stack top
|
nasal_ref* top; // stack top
|
||||||
std::vector<nasal_ref> strs; // reserved address for const vm_str
|
std::vector<nasal_ref> strs; // reserved address for const vm_str
|
||||||
|
@ -399,13 +399,7 @@ void nasal_gc::init(const std::vector<std::string>& s)
|
||||||
memory.push_back(tmp);
|
memory.push_back(tmp);
|
||||||
free_list[i].push(tmp);
|
free_list[i].push(tmp);
|
||||||
}
|
}
|
||||||
|
top=stack;
|
||||||
top=stack; // set top to stack
|
|
||||||
|
|
||||||
zero={vm_num,(double)0}; // init constant 0
|
|
||||||
one ={vm_num,(double)1}; // init constant 1
|
|
||||||
nil ={vm_nil,nullptr}; // init constant nil
|
|
||||||
|
|
||||||
// init constant strings
|
// init constant strings
|
||||||
strs.resize(s.size());
|
strs.resize(s.size());
|
||||||
for(uint32_t i=0;i<strs.size();++i)
|
for(uint32_t i=0;i<strs.size();++i)
|
||||||
|
|
41
nasal_vm.h
41
nasal_vm.h
|
@ -322,7 +322,7 @@ inline void nasal_vm::opr_intg()
|
||||||
}
|
}
|
||||||
inline void nasal_vm::opr_intl()
|
inline void nasal_vm::opr_intl()
|
||||||
{
|
{
|
||||||
gc.top[0].func()->local.resize(imm[pc],gc.nil);
|
gc.top[0].func()->local.resize(imm[pc],nil);
|
||||||
}
|
}
|
||||||
inline void nasal_vm::opr_loadg()
|
inline void nasal_vm::opr_loadg()
|
||||||
{
|
{
|
||||||
|
@ -403,15 +403,15 @@ inline void nasal_vm::opr_unot()
|
||||||
nasal_ref val=gc.top[0];
|
nasal_ref val=gc.top[0];
|
||||||
switch(val.type)
|
switch(val.type)
|
||||||
{
|
{
|
||||||
case vm_nil:gc.top[0]=gc.one;break;
|
case vm_nil:gc.top[0]=one;break;
|
||||||
case vm_num:gc.top[0]=val.num()?gc.zero:gc.one;break;
|
case vm_num:gc.top[0]=val.num()?zero:one;break;
|
||||||
case vm_str:
|
case vm_str:
|
||||||
{
|
{
|
||||||
double num=str2num(val.str()->c_str());
|
double num=str2num(val.str()->c_str());
|
||||||
if(std::isnan(num))
|
if(std::isnan(num))
|
||||||
gc.top[0]={vm_num,(double)val.str()->empty()};
|
gc.top[0]={vm_num,(double)val.str()->empty()};
|
||||||
else
|
else
|
||||||
gc.top[0]=num?gc.zero:gc.one;
|
gc.top[0]=num?zero:one;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:die("unot: incorrect value type");break;
|
default:die("unot: incorrect value type");break;
|
||||||
|
@ -491,31 +491,31 @@ inline void nasal_vm::opr_eq()
|
||||||
nasal_ref val2=gc.top[0];
|
nasal_ref val2=gc.top[0];
|
||||||
nasal_ref val1=(--gc.top)[0];
|
nasal_ref val1=(--gc.top)[0];
|
||||||
if(val1.type==vm_nil && val2.type==vm_nil)
|
if(val1.type==vm_nil && val2.type==vm_nil)
|
||||||
gc.top[0]=gc.one;
|
gc.top[0]=one;
|
||||||
else if(val1.type==vm_str && val2.type==vm_str)
|
else if(val1.type==vm_str && val2.type==vm_str)
|
||||||
gc.top[0]=(*val1.str()==*val2.str())?gc.one:gc.zero;
|
gc.top[0]=(*val1.str()==*val2.str())?one:zero;
|
||||||
else if(val1.type==vm_num || val2.type==vm_num)
|
else if(val1.type==vm_num || val2.type==vm_num)
|
||||||
gc.top[0]=(val1.to_number()==val2.to_number())?gc.one:gc.zero;
|
gc.top[0]=(val1.to_number()==val2.to_number())?one:zero;
|
||||||
else
|
else
|
||||||
gc.top[0]=(val1==val2)?gc.one:gc.zero;
|
gc.top[0]=(val1==val2)?one:zero;
|
||||||
}
|
}
|
||||||
inline void nasal_vm::opr_neq()
|
inline void nasal_vm::opr_neq()
|
||||||
{
|
{
|
||||||
nasal_ref val2=gc.top[0];
|
nasal_ref val2=gc.top[0];
|
||||||
nasal_ref val1=(--gc.top)[0];
|
nasal_ref val1=(--gc.top)[0];
|
||||||
if(val1.type==vm_nil && val2.type==vm_nil)
|
if(val1.type==vm_nil && val2.type==vm_nil)
|
||||||
gc.top[0]=gc.zero;
|
gc.top[0]=zero;
|
||||||
else if(val1.type==vm_str && val2.type==vm_str)
|
else if(val1.type==vm_str && val2.type==vm_str)
|
||||||
gc.top[0]=(*val1.str()!=*val2.str())?gc.one:gc.zero;
|
gc.top[0]=(*val1.str()!=*val2.str())?one:zero;
|
||||||
else if(val1.type==vm_num || val2.type==vm_num)
|
else if(val1.type==vm_num || val2.type==vm_num)
|
||||||
gc.top[0]=(val1.to_number()!=val2.to_number())?gc.one:gc.zero;
|
gc.top[0]=(val1.to_number()!=val2.to_number())?one:zero;
|
||||||
else
|
else
|
||||||
gc.top[0]=(val1!=val2)?gc.one:gc.zero;
|
gc.top[0]=(val1!=val2)?one:zero;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define op_cmp(type)\
|
#define op_cmp(type)\
|
||||||
--gc.top;\
|
--gc.top;\
|
||||||
gc.top[0]=(gc.top[0].to_number() type gc.top[1].to_number())?gc.one:gc.zero;
|
gc.top[0]=(gc.top[0].to_number() type gc.top[1].to_number())?one:zero;
|
||||||
|
|
||||||
inline void nasal_vm::opr_less(){op_cmp(<);}
|
inline void nasal_vm::opr_less(){op_cmp(<);}
|
||||||
inline void nasal_vm::opr_leq(){op_cmp(<=);}
|
inline void nasal_vm::opr_leq(){op_cmp(<=);}
|
||||||
|
@ -523,7 +523,7 @@ inline void nasal_vm::opr_grt(){op_cmp(>);}
|
||||||
inline void nasal_vm::opr_geq(){op_cmp(>=);}
|
inline void nasal_vm::opr_geq(){op_cmp(>=);}
|
||||||
|
|
||||||
#define op_cmp_const(type)\
|
#define op_cmp_const(type)\
|
||||||
gc.top[0]=(gc.top[0].to_number() type num_table[imm[pc]])?gc.one:gc.zero;
|
gc.top[0]=(gc.top[0].to_number() type num_table[imm[pc]])?one:zero;
|
||||||
|
|
||||||
inline void nasal_vm::opr_lessc(){op_cmp_const(<);}
|
inline void nasal_vm::opr_lessc(){op_cmp_const(<);}
|
||||||
inline void nasal_vm::opr_leqc(){op_cmp_const(<=);}
|
inline void nasal_vm::opr_leqc(){op_cmp_const(<=);}
|
||||||
|
@ -650,17 +650,18 @@ inline void nasal_vm::opr_callfv()
|
||||||
nasal_ref* args=gc.top-args_size+1;
|
nasal_ref* args=gc.top-args_size+1;
|
||||||
if(args[-1].type!=vm_func)
|
if(args[-1].type!=vm_func)
|
||||||
die("callfv: must call a function");
|
die("callfv: must call a function");
|
||||||
// push function and new local scope
|
|
||||||
func_stk.push(args[-1].func());
|
func_stk.push(args[-1].func());// push called function into stack to provide upvalue
|
||||||
auto& func=*args[-1].func();
|
auto& func=*args[-1].func();
|
||||||
gc.local.push_back(gc.alloc(vm_vec));
|
gc.local.push_back(gc.alloc(vm_vec)); // get new vector as local scope
|
||||||
gc.local.back().vec()->elems=func.local;
|
gc.local.back().vec()->elems=func.local;// copy data from func.local to local scope
|
||||||
auto& local=gc.local.back().vec()->elems;
|
auto& local=gc.local.back().vec()->elems;
|
||||||
|
|
||||||
uint32_t para_size=func.keys.size();
|
uint32_t para_size=func.keys.size();
|
||||||
// load arguments
|
// load arguments
|
||||||
// if the first default value is not vm_none,then values after it are not nullptr
|
// if the first default value is not vm_none,then values after it are not nullptr
|
||||||
if(args_size<para_size && func.local[args_size+1/*1 is reserved for 'me'*/].type==vm_none)
|
// args_size+1 is because the first space is reserved for 'me'
|
||||||
|
if(args_size<para_size && local[args_size+1].type==vm_none)
|
||||||
die("callfv: lack argument(s)");
|
die("callfv: lack argument(s)");
|
||||||
// if args_size>para_size,for 0 to args_size will cause corruption
|
// if args_size>para_size,for 0 to args_size will cause corruption
|
||||||
uint32_t min_size=std::min(para_size,args_size);
|
uint32_t min_size=std::min(para_size,args_size);
|
||||||
|
@ -697,7 +698,7 @@ inline void nasal_vm::opr_callfh()
|
||||||
{
|
{
|
||||||
if(hash.count(i.first))
|
if(hash.count(i.first))
|
||||||
local[i.second+1]=hash[i.first];
|
local[i.second+1]=hash[i.first];
|
||||||
else if(func.local[i.second+1/*1 is reserved for 'me'*/].type==vm_none)
|
else if(local[i.second+1].type==vm_none)
|
||||||
die("callfh: lack argument(s): \""+i.first+"\"");
|
die("callfh: lack argument(s): \""+i.first+"\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue