change nasal_ref value option functions' output types from pointers to references
This commit is contained in:
parent
d8156e839b
commit
e54ef9620f
29
README.md
29
README.md
|
@ -535,15 +535,15 @@ nasal_ref builtin_print(nasal_ref* local,nasal_gc& gc)
|
|||
// main process
|
||||
// also check number of arguments and type here
|
||||
// if get an error,use builtin_err
|
||||
for(auto i:vec.vec()->elems)
|
||||
for(auto i:vec.vec().elems)
|
||||
switch(i.type)
|
||||
{
|
||||
case vm_none: std::cout<<"undefined"; break;
|
||||
case vm_nil: std::cout<<"nil"; break;
|
||||
case vm_num: std::cout<<i.num(); break;
|
||||
case vm_str: std::cout<<*i.str(); break;
|
||||
case vm_vec: i.vec()->print(); break;
|
||||
case vm_hash: i.hash()->print(); break;
|
||||
case vm_str: std::cout<<i.str(); break;
|
||||
case vm_vec: i.vec().print(); break;
|
||||
case vm_hash: i.hash().print(); break;
|
||||
case vm_func: std::cout<<"func(...){...}"; break;
|
||||
case vm_obj: std::cout<<"<object>"; break;
|
||||
}
|
||||
|
@ -609,21 +609,20 @@ nasal_ref builtin_keys(nasal_ref* local,nasal_gc& gc)
|
|||
{
|
||||
nasal_ref hash=local[1];
|
||||
if(hash.type!=vm_hash)
|
||||
{
|
||||
builtin_err("keys","\"hash\" must be hash");
|
||||
return nasal_ref(vm_none);
|
||||
}
|
||||
|
||||
return builtin_err("keys","\"hash\" must be hash");
|
||||
// push vector into local scope to avoid being sweeped
|
||||
local.push_back(gc.alloc(vm_vec));
|
||||
std::vector<nasal_ref>& vec=local.back().vec()->elems;
|
||||
for(auto& iter:hash.hash()->elems)
|
||||
if(gc.top+1>=gc.stack+STACK_MAX_DEPTH-1)
|
||||
builtin_err("keys","expand temporary space error:stackoverflow");
|
||||
(++gc.top)[0]=gc.alloc(vm_vec);
|
||||
auto& vec=gc.top[0].vec().elems;
|
||||
for(auto& iter:hash.hash().elems)
|
||||
{
|
||||
nasal_ref str=gc.builtin_alloc(vm_str);
|
||||
*str.str()=iter.first;
|
||||
nasal_ref str=gc.alloc(vm_str);
|
||||
str.str()=iter.first;
|
||||
vec.push_back(str);
|
||||
}
|
||||
return local.back();
|
||||
--gc.top;
|
||||
return gc.top[1];
|
||||
}
|
||||
```
|
||||
|
||||
|
|
249
nasal_builtin.h
249
nasal_builtin.h
|
@ -189,15 +189,15 @@ nasal_ref builtin_print(nasal_ref* local,nasal_gc& gc)
|
|||
// local[0] is reserved for 'me'
|
||||
nasal_ref vec=local[1];
|
||||
// main process
|
||||
for(auto& i:vec.vec()->elems)
|
||||
for(auto& i:vec.vec().elems)
|
||||
switch(i.type)
|
||||
{
|
||||
case vm_none: std::cout<<"null"; break;
|
||||
case vm_nil: std::cout<<"nil"; break;
|
||||
case vm_num: std::cout<<i.num(); break;
|
||||
case vm_str: std::cout<<*i.str(); break;
|
||||
case vm_vec: i.vec()->print(); break;
|
||||
case vm_hash: i.hash()->print(); break;
|
||||
case vm_str: std::cout<<i.str(); break;
|
||||
case vm_vec: i.vec().print(); break;
|
||||
case vm_hash: i.hash().print(); break;
|
||||
case vm_func: std::cout<<"func(...){...}"; break;
|
||||
case vm_obj: std::cout<<"<object>"; break;
|
||||
}
|
||||
|
@ -211,8 +211,8 @@ nasal_ref builtin_append(nasal_ref* local,nasal_gc& gc)
|
|||
nasal_ref elem=local[2];
|
||||
if(vec.type!=vm_vec)
|
||||
return builtin_err("append","\"vector\" must be vector");
|
||||
auto& ref_vec=vec.vec()->elems;
|
||||
for(auto& i:elem.vec()->elems)
|
||||
auto& ref_vec=vec.vec().elems;
|
||||
for(auto& i:elem.vec().elems)
|
||||
ref_vec.push_back(i);
|
||||
return nil;
|
||||
}
|
||||
|
@ -227,7 +227,7 @@ nasal_ref builtin_setsize(nasal_ref* local,nasal_gc& gc)
|
|||
int num=(int)size.num();
|
||||
if(num<0)
|
||||
return builtin_err("setsize","\"size\" must be greater than -1");
|
||||
vec.vec()->elems.resize(num,nil);
|
||||
vec.vec().elems.resize(num,nil);
|
||||
return nil;
|
||||
}
|
||||
nasal_ref builtin_system(nasal_ref* local,nasal_gc& gc)
|
||||
|
@ -235,12 +235,12 @@ nasal_ref builtin_system(nasal_ref* local,nasal_gc& gc)
|
|||
nasal_ref str=local[1];
|
||||
if(str.type!=vm_str)
|
||||
return builtin_err("system","\"str\" must be string");
|
||||
return {vm_num,(double)system(str.str()->c_str())};
|
||||
return {vm_num,(double)system(str.str().c_str())};
|
||||
}
|
||||
nasal_ref builtin_input(nasal_ref* local,nasal_gc& gc)
|
||||
{
|
||||
nasal_ref ret=gc.alloc(vm_str);
|
||||
std::cin>>*ret.str();
|
||||
std::cin>>ret.str();
|
||||
return ret;
|
||||
}
|
||||
nasal_ref builtin_fin(nasal_ref* local,nasal_gc& gc)
|
||||
|
@ -248,14 +248,14 @@ nasal_ref builtin_fin(nasal_ref* local,nasal_gc& gc)
|
|||
nasal_ref val=local[1];
|
||||
if(val.type!=vm_str)
|
||||
return builtin_err("io.fin","\"filename\" must be string");
|
||||
std::string& filename=*val.str();
|
||||
std::string& filename=val.str();
|
||||
std::ifstream fin(filename);
|
||||
if(!fin.fail())
|
||||
{
|
||||
nasal_ref ret=gc.alloc(vm_str);
|
||||
std::stringstream rd;
|
||||
rd<<fin.rdbuf();
|
||||
*ret.str()=rd.str();
|
||||
ret.str()=rd.str();
|
||||
return ret;
|
||||
}
|
||||
return builtin_err("io.fin","cannot open \""+filename+"\"");
|
||||
|
@ -268,10 +268,10 @@ nasal_ref builtin_fout(nasal_ref* local,nasal_gc& gc)
|
|||
return builtin_err("io.fout","\"filename\" must be string");
|
||||
if(str.type!=vm_str)
|
||||
return builtin_err("io.fout","\"str\" must be string");
|
||||
std::ofstream fout(*val.str());
|
||||
std::ofstream fout(val.str());
|
||||
if(fout.fail())
|
||||
return builtin_err("io.fout","cannot open \""+*val.str()+"\"");
|
||||
fout<<*str.str();
|
||||
return builtin_err("io.fout","cannot open \""+val.str()+"\"");
|
||||
fout<<str.str();
|
||||
return nil;
|
||||
}
|
||||
nasal_ref builtin_split(nasal_ref* local,nasal_gc& gc)
|
||||
|
@ -282,8 +282,8 @@ nasal_ref builtin_split(nasal_ref* local,nasal_gc& gc)
|
|||
return builtin_err("split","\"separator\" must be string");
|
||||
if(str_val.type!=vm_str)
|
||||
return builtin_err("split","\"str\" must be string");
|
||||
std::string& delimeter=*deli_val.str();
|
||||
std::string& source=*str_val.str();
|
||||
std::string& delimeter=deli_val.str();
|
||||
std::string& source=str_val.str();
|
||||
size_t delimeter_len=delimeter.length();
|
||||
size_t source_len=source.length();
|
||||
|
||||
|
@ -292,13 +292,13 @@ nasal_ref builtin_split(nasal_ref* local,nasal_gc& gc)
|
|||
builtin_err("split","expand temporary space error:stackoverflow");
|
||||
(++gc.top)[0]=gc.alloc(vm_vec);
|
||||
|
||||
std::vector<nasal_ref>& vec=gc.top[0].vec()->elems;
|
||||
std::vector<nasal_ref>& vec=gc.top[0].vec().elems;
|
||||
if(!delimeter_len)
|
||||
{
|
||||
for(int i=0;i<source_len;++i)
|
||||
{
|
||||
vec.push_back(gc.alloc(vm_str));
|
||||
*vec.back().str()=source[i];
|
||||
vec.back().str()=source[i];
|
||||
}
|
||||
--gc.top;
|
||||
return gc.top[1];
|
||||
|
@ -321,7 +321,7 @@ nasal_ref builtin_split(nasal_ref* local,nasal_gc& gc)
|
|||
if(tmp.length())
|
||||
{
|
||||
vec.push_back(gc.alloc(vm_str));
|
||||
*vec.back().str()=tmp;
|
||||
vec.back().str()=tmp;
|
||||
tmp="";
|
||||
}
|
||||
i+=delimeter_len-1;
|
||||
|
@ -332,7 +332,7 @@ nasal_ref builtin_split(nasal_ref* local,nasal_gc& gc)
|
|||
if(tmp.length())
|
||||
{
|
||||
vec.push_back(gc.alloc(vm_str));
|
||||
*vec.back().str()=tmp;
|
||||
vec.back().str()=tmp;
|
||||
tmp="";
|
||||
}
|
||||
--gc.top;
|
||||
|
@ -362,7 +362,7 @@ nasal_ref builtin_id(nasal_ref* local,nasal_gc& gc)
|
|||
sprintf(buf,"%p",val.value.gcobj);
|
||||
else
|
||||
sprintf(buf,"0");
|
||||
*ret.str()=buf;
|
||||
ret.str()=buf;
|
||||
return ret;
|
||||
}
|
||||
nasal_ref builtin_int(nasal_ref* local,nasal_gc& gc)
|
||||
|
@ -390,10 +390,11 @@ nasal_ref builtin_pop(nasal_ref* local,nasal_gc& gc)
|
|||
nasal_ref val=local[1];
|
||||
if(val.type!=vm_vec)
|
||||
return builtin_err("pop","\"vector\" must be vector");
|
||||
if(val.vec()->elems.size())
|
||||
auto& vec=val.vec().elems;
|
||||
if(vec.size())
|
||||
{
|
||||
nasal_ref tmp=val.vec()->elems.back();
|
||||
val.vec()->elems.pop_back();
|
||||
nasal_ref tmp=vec.back();
|
||||
vec.pop_back();
|
||||
return tmp;
|
||||
}
|
||||
return nil;
|
||||
|
@ -407,7 +408,7 @@ nasal_ref builtin_str(nasal_ref* local,nasal_gc& gc)
|
|||
tmp.erase(tmp.find_last_not_of('0')+1,std::string::npos);
|
||||
tmp.erase(tmp.find_last_not_of('.')+1,std::string::npos);
|
||||
nasal_ref ret=gc.alloc(vm_str);
|
||||
*ret.str()=tmp;
|
||||
ret.str()=tmp;
|
||||
return ret;
|
||||
}
|
||||
nasal_ref builtin_size(nasal_ref* local,nasal_gc& gc)
|
||||
|
@ -416,10 +417,10 @@ nasal_ref builtin_size(nasal_ref* local,nasal_gc& gc)
|
|||
double num;
|
||||
switch(val.type)
|
||||
{
|
||||
case vm_num: num=val.num(); break;
|
||||
case vm_str: num=val.str()->length(); break;
|
||||
case vm_vec: num=val.vec()->elems.size(); break;
|
||||
case vm_hash: num=val.hash()->elems.size();break;
|
||||
case vm_num: num=val.num(); break;
|
||||
case vm_str: num=val.str().length(); break;
|
||||
case vm_vec: num=val.vec().elems.size(); break;
|
||||
case vm_hash: num=val.hash().elems.size();break;
|
||||
}
|
||||
return {vm_num,num};
|
||||
}
|
||||
|
@ -559,7 +560,7 @@ nasal_ref builtin_contains(nasal_ref* local,nasal_gc& gc)
|
|||
return builtin_err("contains","\"hash\" must be hash");
|
||||
if(key.type!=vm_str)
|
||||
return builtin_err("contains","\"key\" must be string");
|
||||
return hash.hash()->elems.count(*key.str())?one:zero;
|
||||
return hash.hash().elems.count(key.str())?one:zero;
|
||||
}
|
||||
nasal_ref builtin_delete(nasal_ref* local,nasal_gc& gc)
|
||||
{
|
||||
|
@ -569,8 +570,8 @@ nasal_ref builtin_delete(nasal_ref* local,nasal_gc& gc)
|
|||
return builtin_err("delete","\"hash\" must be hash");
|
||||
if(key.type!=vm_str)
|
||||
return builtin_err("delete","\"key\" must be string");
|
||||
if(hash.hash()->elems.count(*key.str()))
|
||||
hash.hash()->elems.erase(*key.str());
|
||||
if(hash.hash().elems.count(key.str()))
|
||||
hash.hash().elems.erase(key.str());
|
||||
return nil;
|
||||
}
|
||||
nasal_ref builtin_keys(nasal_ref* local,nasal_gc& gc)
|
||||
|
@ -582,11 +583,11 @@ nasal_ref builtin_keys(nasal_ref* local,nasal_gc& gc)
|
|||
if(gc.top+1>=gc.stack+STACK_MAX_DEPTH-1)
|
||||
builtin_err("keys","expand temporary space error:stackoverflow");
|
||||
(++gc.top)[0]=gc.alloc(vm_vec);
|
||||
auto& vec=gc.top[0].vec()->elems;
|
||||
for(auto& iter:hash.hash()->elems)
|
||||
auto& vec=gc.top[0].vec().elems;
|
||||
for(auto& iter:hash.hash().elems)
|
||||
{
|
||||
nasal_ref str=gc.alloc(vm_str);
|
||||
*str.str()=iter.first;
|
||||
str.str()=iter.first;
|
||||
vec.push_back(str);
|
||||
}
|
||||
--gc.top;
|
||||
|
@ -608,7 +609,7 @@ nasal_ref builtin_die(nasal_ref* local,nasal_gc& gc)
|
|||
nasal_ref str=local[1];
|
||||
if(str.type!=vm_str)
|
||||
return builtin_err("die","\"str\" must be string");
|
||||
std::cerr<<"[vm] error: "<<*str.str()<<'\n';
|
||||
std::cerr<<"[vm] error: "<<str.str()<<'\n';
|
||||
return nasal_ref(vm_none);
|
||||
}
|
||||
nasal_ref builtin_type(nasal_ref* local,nasal_gc& gc)
|
||||
|
@ -617,14 +618,14 @@ nasal_ref builtin_type(nasal_ref* local,nasal_gc& gc)
|
|||
nasal_ref ret=gc.alloc(vm_str);
|
||||
switch(val.type)
|
||||
{
|
||||
case vm_none: *ret.str()="undefined";break;
|
||||
case vm_nil: *ret.str()="nil"; break;
|
||||
case vm_num: *ret.str()="num"; break;
|
||||
case vm_str: *ret.str()="str"; break;
|
||||
case vm_vec: *ret.str()="vec"; break;
|
||||
case vm_hash: *ret.str()="hash"; break;
|
||||
case vm_func: *ret.str()="func"; break;
|
||||
case vm_obj: *ret.str()="obj"; break;
|
||||
case vm_none: ret.str()="undefined";break;
|
||||
case vm_nil: ret.str()="nil"; break;
|
||||
case vm_num: ret.str()="num"; break;
|
||||
case vm_str: ret.str()="str"; break;
|
||||
case vm_vec: ret.str()="vec"; break;
|
||||
case vm_hash: ret.str()="hash"; break;
|
||||
case vm_func: ret.str()="func"; break;
|
||||
case vm_obj: ret.str()="obj"; break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
@ -641,19 +642,19 @@ nasal_ref builtin_substr(nasal_ref* local,nasal_gc& gc)
|
|||
return builtin_err("substr","\"length\" must be number");
|
||||
int begin=(int)beg.num();
|
||||
int length=(int)len.num();
|
||||
if(begin>=str.str()->length() || begin+length-1>=str.str()->length())
|
||||
if(begin>=str.str().length() || begin+length-1>=str.str().length())
|
||||
return builtin_err("susbtr","index out of range");
|
||||
if(length<0)
|
||||
length=0;
|
||||
nasal_ref ret=gc.alloc(vm_str);
|
||||
*ret.str()=str.str()->substr(begin,length);
|
||||
ret.str()=str.str().substr(begin,length);
|
||||
return ret;
|
||||
}
|
||||
nasal_ref builtin_streq(nasal_ref* local,nasal_gc& gc)
|
||||
{
|
||||
nasal_ref a=local[1];
|
||||
nasal_ref b=local[2];
|
||||
return {vm_num,double((a.type!=vm_str || b.type!=vm_str)?0:(*a.str()==*b.str()))};
|
||||
return {vm_num,double((a.type!=vm_str || b.type!=vm_str)?0:(a.str()==b.str()))};
|
||||
}
|
||||
nasal_ref builtin_left(nasal_ref* local,nasal_gc& gc)
|
||||
{
|
||||
|
@ -667,7 +668,7 @@ nasal_ref builtin_left(nasal_ref* local,nasal_gc& gc)
|
|||
if(length<0)
|
||||
length=0;
|
||||
nasal_ref ret=gc.alloc(vm_str);
|
||||
*ret.str()=str.str()->substr(0,length);
|
||||
ret.str()=str.str().substr(0,length);
|
||||
return ret;
|
||||
}
|
||||
nasal_ref builtin_right(nasal_ref* local,nasal_gc& gc)
|
||||
|
@ -679,13 +680,13 @@ nasal_ref builtin_right(nasal_ref* local,nasal_gc& gc)
|
|||
if(len.type!=vm_num)
|
||||
return builtin_err("right","\"length\" must be number");
|
||||
int length=(int)len.num();
|
||||
int srclen=str.str()->length();
|
||||
int srclen=str.str().length();
|
||||
if(length>srclen)
|
||||
length=srclen;
|
||||
if(length<0)
|
||||
length=0;
|
||||
nasal_ref ret=gc.alloc(vm_str);
|
||||
*ret.str()=str.str()->substr(srclen-length, srclen);
|
||||
ret.str()=str.str().substr(srclen-length, srclen);
|
||||
return ret;
|
||||
}
|
||||
nasal_ref builtin_cmp(nasal_ref* local,nasal_gc& gc)
|
||||
|
@ -696,7 +697,7 @@ nasal_ref builtin_cmp(nasal_ref* local,nasal_gc& gc)
|
|||
return builtin_err("cmp","\"a\" must be string");
|
||||
if(b.type!=vm_str)
|
||||
return builtin_err("cmp","\"b\" must be string");
|
||||
return {vm_num,(double)strcmp(a.str()->c_str(),b.str()->c_str())};
|
||||
return {vm_num,(double)strcmp(a.str().c_str(),b.str().c_str())};
|
||||
}
|
||||
nasal_ref builtin_chr(nasal_ref* local,nasal_gc& gc)
|
||||
{
|
||||
|
@ -724,11 +725,11 @@ nasal_ref builtin_chr(nasal_ref* local,nasal_gc& gc)
|
|||
nasal_ref ret=gc.alloc(vm_str);
|
||||
int num=code.num();
|
||||
if(0<=num && num<128)
|
||||
*ret.str()=(char)num;
|
||||
ret.str()=(char)num;
|
||||
else if(128<=num && num<256)
|
||||
*ret.str()=extend[num-128];
|
||||
ret.str()=extend[num-128];
|
||||
else
|
||||
*ret.str()=" ";
|
||||
ret.str()=" ";
|
||||
return ret;
|
||||
}
|
||||
nasal_ref builtin_open(nasal_ref* local,nasal_gc& gc)
|
||||
|
@ -739,20 +740,20 @@ nasal_ref builtin_open(nasal_ref* local,nasal_gc& gc)
|
|||
return builtin_err("open","\"filename\" must be string");
|
||||
if(mode.type!=vm_str)
|
||||
return builtin_err("open","\"mode\" must be string");
|
||||
FILE* res=fopen(filename.str()->c_str(),mode.str()->c_str());
|
||||
FILE* res=fopen(filename.str().c_str(),mode.str().c_str());
|
||||
if(!res)
|
||||
return builtin_err("open","failed to open file <"+*filename.str()+"> errno "+std::to_string(errno));
|
||||
return builtin_err("open","failed to open file <"+filename.str()+"> errno "+std::to_string(errno));
|
||||
nasal_ref ret=gc.alloc(vm_obj);
|
||||
ret.obj()->type=obj_file;
|
||||
ret.obj()->ptr=(void*)res;
|
||||
ret.obj().type=obj_file;
|
||||
ret.obj().ptr=(void*)res;
|
||||
return ret;
|
||||
}
|
||||
nasal_ref builtin_close(nasal_ref* local,nasal_gc& gc)
|
||||
{
|
||||
nasal_ref filehandle=local[1];
|
||||
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");
|
||||
fclose((FILE*)filehandle.obj()->ptr);
|
||||
fclose((FILE*)filehandle.obj().ptr);
|
||||
return nil;
|
||||
}
|
||||
nasal_ref builtin_read(nasal_ref* local,nasal_gc& gc)
|
||||
|
@ -760,7 +761,7 @@ nasal_ref builtin_read(nasal_ref* local,nasal_gc& gc)
|
|||
nasal_ref filehandle=local[1];
|
||||
nasal_ref buf=local[2];
|
||||
nasal_ref len=local[3];
|
||||
if(filehandle.type!=vm_obj || filehandle.obj()->type!=obj_file)
|
||||
if(filehandle.type!=vm_obj || filehandle.obj().type!=obj_file)
|
||||
return builtin_err("read","not a correct filehandle");
|
||||
if(buf.type!=vm_str)
|
||||
return builtin_err("read","\"buf\" must be string");
|
||||
|
@ -773,8 +774,8 @@ nasal_ref builtin_read(nasal_ref* local,nasal_gc& gc)
|
|||
char* buff=new char[(size_t)len.num()+1];
|
||||
if(!buff)
|
||||
return builtin_err("read","memory allocation error");
|
||||
double res=fread(buff,1,len.num(),(FILE*)filehandle.obj()->ptr);
|
||||
*buf.str()=buff;
|
||||
double res=fread(buff,1,len.num(),(FILE*)filehandle.obj().ptr);
|
||||
buf.str()=buff;
|
||||
delete []buff;
|
||||
return {vm_num,res};
|
||||
}
|
||||
|
@ -782,11 +783,11 @@ nasal_ref builtin_write(nasal_ref* local,nasal_gc& gc)
|
|||
{
|
||||
nasal_ref filehandle=local[1];
|
||||
nasal_ref str=local[2];
|
||||
if(filehandle.type!=vm_obj || filehandle.obj()->type!=obj_file)
|
||||
if(filehandle.type!=vm_obj || filehandle.obj().type!=obj_file)
|
||||
return builtin_err("write","not a correct filehandle");
|
||||
if(str.type!=vm_str)
|
||||
return builtin_err("write","\"str\" must be string");
|
||||
double res=(double)fwrite(str.str()->c_str(),1,str.str()->length(),(FILE*)filehandle.obj()->ptr);
|
||||
double res=(double)fwrite(str.str().c_str(),1,str.str().length(),(FILE*)filehandle.obj().ptr);
|
||||
return {vm_num,res};
|
||||
}
|
||||
nasal_ref builtin_seek(nasal_ref* local,nasal_gc& gc)
|
||||
|
@ -794,32 +795,32 @@ nasal_ref builtin_seek(nasal_ref* local,nasal_gc& gc)
|
|||
nasal_ref filehandle=local[1];
|
||||
nasal_ref position=local[2];
|
||||
nasal_ref whence=local[3];
|
||||
if(filehandle.type!=vm_obj || filehandle.obj()->type!=obj_file)
|
||||
if(filehandle.type!=vm_obj || filehandle.obj().type!=obj_file)
|
||||
return builtin_err("seek","not a correct filehandle");
|
||||
if(position.type!=vm_num)
|
||||
return builtin_err("seek","\"pos\" must be number");
|
||||
if(whence.type!=vm_num || whence.num()<0 || whence.num()>2)
|
||||
return builtin_err("seek","\"whence\" must be number between 0 and 2");
|
||||
double res=fseek((FILE*)filehandle.obj()->ptr,position.num(),whence.num());
|
||||
double res=fseek((FILE*)filehandle.obj().ptr,position.num(),whence.num());
|
||||
return {vm_num,res};
|
||||
}
|
||||
nasal_ref builtin_tell(nasal_ref* local,nasal_gc& gc)
|
||||
{
|
||||
nasal_ref filehandle=local[1];
|
||||
if(filehandle.type!=vm_obj || filehandle.obj()->type!=obj_file)
|
||||
if(filehandle.type!=vm_obj || filehandle.obj().type!=obj_file)
|
||||
return builtin_err("tell","not a correct filehandle");
|
||||
double res=ftell((FILE*)filehandle.obj()->ptr);
|
||||
double res=ftell((FILE*)filehandle.obj().ptr);
|
||||
return {vm_num,res};
|
||||
}
|
||||
nasal_ref builtin_readln(nasal_ref* local,nasal_gc& gc)
|
||||
{
|
||||
nasal_ref filehandle=local[1];
|
||||
if(filehandle.type!=vm_obj || filehandle.obj()->type!=obj_file)
|
||||
if(filehandle.type!=vm_obj || filehandle.obj().type!=obj_file)
|
||||
return builtin_err("readln","not a correct filehandle");
|
||||
nasal_ref str=gc.alloc(vm_str);
|
||||
auto& s=*str.str();
|
||||
auto& s=str.str();
|
||||
char c;
|
||||
while((c=fgetc((FILE*)filehandle.obj()->ptr))!=EOF)
|
||||
while((c=fgetc((FILE*)filehandle.obj().ptr))!=EOF)
|
||||
{
|
||||
if(c=='\r')
|
||||
continue;
|
||||
|
@ -837,10 +838,10 @@ nasal_ref builtin_stat(nasal_ref* local,nasal_gc& gc)
|
|||
if(filename.type!=vm_str)
|
||||
return builtin_err("stat","\"filename\" must be string");
|
||||
struct stat buf;
|
||||
if(stat(filename.str()->c_str(),&buf)<0)
|
||||
return builtin_err("stat","failed to open file <"+*filename.str()+">");
|
||||
if(stat(filename.str().c_str(),&buf)<0)
|
||||
return builtin_err("stat","failed to open file <"+filename.str()+">");
|
||||
nasal_ref ret=gc.alloc(vm_vec);
|
||||
ret.vec()->elems={
|
||||
ret.vec().elems={
|
||||
{vm_num,(double)buf.st_dev},
|
||||
{vm_num,(double)buf.st_ino},
|
||||
{vm_num,(double)buf.st_mode},
|
||||
|
@ -858,9 +859,9 @@ nasal_ref builtin_stat(nasal_ref* local,nasal_gc& gc)
|
|||
nasal_ref builtin_eof(nasal_ref* local,nasal_gc& gc)
|
||||
{
|
||||
nasal_ref filehandle=local[1];
|
||||
if(filehandle.type!=vm_obj || filehandle.obj()->type!=obj_file)
|
||||
if(filehandle.type!=vm_obj || filehandle.obj().type!=obj_file)
|
||||
return builtin_err("readln","not a correct filehandle");
|
||||
double res=feof((FILE*)filehandle.obj()->ptr);
|
||||
double res=feof((FILE*)filehandle.obj().ptr);
|
||||
return {vm_num,res};
|
||||
}
|
||||
nasal_ref builtin_fld(nasal_ref* local,nasal_gc& gc)
|
||||
|
@ -877,10 +878,10 @@ nasal_ref builtin_fld(nasal_ref* local,nasal_gc& gc)
|
|||
return builtin_err("fld","\"startbit\",\"len\" must be number");
|
||||
uint32_t bit=(uint32_t)startbit.num();
|
||||
uint32_t len=(uint32_t)length.num();
|
||||
if(bit+len>8*str.str()->length())
|
||||
if(bit+len>8*str.str().length())
|
||||
return builtin_err("fld","bitfield out of bounds");
|
||||
uint32_t res=0;
|
||||
auto& s=*str.str();
|
||||
auto& s=str.str();
|
||||
for(uint32_t i=bit;i<bit+len;++i)
|
||||
if(s[i>>3]&(1<<(7-(i&7))))
|
||||
res|=1<<(bit+len-i-1);
|
||||
|
@ -901,10 +902,10 @@ nasal_ref builtin_sfld(nasal_ref* local,nasal_gc& gc)
|
|||
return builtin_err("sfld","\"startbit\",\"len\" must be number");
|
||||
uint32_t bit=(uint32_t)startbit.num();
|
||||
uint32_t len=(uint32_t)length.num();
|
||||
if(bit+len>8*str.str()->length())
|
||||
if(bit+len>8*str.str().length())
|
||||
return builtin_err("sfld","bitfield out of bounds");
|
||||
uint32_t res=0;
|
||||
auto& s=*str.str();
|
||||
auto& s=str.str();
|
||||
for(uint32_t i=bit;i<bit+len;++i)
|
||||
if(s[i>>3]&(1<<(7-(i&7))))
|
||||
res|=1<<(bit+len-i-1);
|
||||
|
@ -929,9 +930,9 @@ nasal_ref builtin_setfld(nasal_ref* local,nasal_gc& gc)
|
|||
uint32_t bit=(uint32_t)startbit.num();
|
||||
uint32_t len=(uint32_t)length.num();
|
||||
uint64_t val=(uint64_t)value.num();
|
||||
if(bit+len>8*str.str()->length())
|
||||
if(bit+len>8*str.str().length())
|
||||
return builtin_err("setfld","bitfield out of bounds");
|
||||
auto& s=*str.str();
|
||||
auto& s=str.str();
|
||||
for(uint32_t i=bit;i<bit+len;++i)
|
||||
{
|
||||
if(val&(1<<(i-bit)))
|
||||
|
@ -947,7 +948,7 @@ nasal_ref builtin_buf(nasal_ref* local,nasal_gc& gc)
|
|||
if(length.type!=vm_num || length.num()<=0)
|
||||
return builtin_err("buf","\"len\" must be a number greater than 9");
|
||||
nasal_ref str=gc.alloc(vm_str);
|
||||
auto& s=*str.str();
|
||||
auto& s=str.str();
|
||||
s.resize(length.num(),'\0');
|
||||
return str;
|
||||
}
|
||||
|
@ -966,8 +967,8 @@ nasal_ref builtin_pipe(nasal_ref* local,nasal_gc& gc)
|
|||
#ifndef _WIN32
|
||||
if(pipe(fd)==-1)
|
||||
return builtin_err("pipe","failed to create pipe");
|
||||
res.vec()->elems.push_back({vm_num,(double)fd[0]});
|
||||
res.vec()->elems.push_back({vm_num,(double)fd[1]});
|
||||
res.vec().elems.push_back({vm_num,(double)fd[0]});
|
||||
res.vec().elems.push_back({vm_num,(double)fd[1]});
|
||||
return res;
|
||||
#endif
|
||||
return builtin_err("pipe","not supported yet");
|
||||
|
@ -984,32 +985,32 @@ nasal_ref builtin_opendir(nasal_ref* local,nasal_gc& gc)
|
|||
nasal_ref path=local[1];
|
||||
if(path.type!=vm_str)
|
||||
return builtin_err("opendir","\"path\" must be string");
|
||||
DIR* p=opendir(path.str()->c_str());
|
||||
DIR* p=opendir(path.str().c_str());
|
||||
if(!p)
|
||||
return builtin_err("opendir","cannot open dir <"+*path.str()+"> errno "+std::to_string(errno));
|
||||
return builtin_err("opendir","cannot open dir <"+path.str()+"> errno "+std::to_string(errno));
|
||||
nasal_ref ret=gc.alloc(vm_obj);
|
||||
ret.obj()->type=obj_dir;
|
||||
ret.obj()->ptr=(void*)p;
|
||||
ret.obj().type=obj_dir;
|
||||
ret.obj().ptr=(void*)p;
|
||||
return ret;
|
||||
}
|
||||
nasal_ref builtin_readdir(nasal_ref* local,nasal_gc& gc)
|
||||
{
|
||||
nasal_ref handle=local[1];
|
||||
if(handle.type!=vm_obj || handle.obj()->type!=obj_dir)
|
||||
if(handle.type!=vm_obj || handle.obj().type!=obj_dir)
|
||||
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)
|
||||
return nil;
|
||||
nasal_ref ret=gc.alloc(vm_str);
|
||||
*ret.str()=p->d_name;
|
||||
ret.str()=p->d_name;
|
||||
return ret;
|
||||
}
|
||||
nasal_ref builtin_closedir(nasal_ref* local,nasal_gc& gc)
|
||||
{
|
||||
nasal_ref handle=local[1];
|
||||
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");
|
||||
closedir((DIR*)handle.obj()->ptr);
|
||||
closedir((DIR*)handle.obj().ptr);
|
||||
return nil;
|
||||
}
|
||||
nasal_ref builtin_chdir(nasal_ref* local,nasal_gc& gc)
|
||||
|
@ -1017,19 +1018,21 @@ nasal_ref builtin_chdir(nasal_ref* local,nasal_gc& gc)
|
|||
nasal_ref path=local[1];
|
||||
if(path.type!=vm_str)
|
||||
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 nil;
|
||||
}
|
||||
nasal_ref builtin_environ(nasal_ref* local,nasal_gc& gc)
|
||||
{
|
||||
char** env=environ;
|
||||
if(gc.top+1>=gc.stack+STACK_MAX_DEPTH-1)
|
||||
builtin_err("environ","expand temporary space error:stackoverflow");
|
||||
(++gc.top)[0]=gc.alloc(vm_vec);
|
||||
auto& vec=gc.top[0].vec()->elems;
|
||||
auto& vec=gc.top[0].vec().elems;
|
||||
while(*env)
|
||||
{
|
||||
auto s=gc.alloc(vm_str);
|
||||
*s.str()=*env;
|
||||
s.str()=*env;
|
||||
vec.push_back(s);
|
||||
++env;
|
||||
}
|
||||
|
@ -1041,7 +1044,7 @@ nasal_ref builtin_getcwd(nasal_ref* local,nasal_gc& gc)
|
|||
char buf[1024];
|
||||
getcwd(buf,sizeof(buf));
|
||||
nasal_ref str=gc.alloc(vm_str);
|
||||
*str.str()=buf;
|
||||
str.str()=buf;
|
||||
return str;
|
||||
}
|
||||
nasal_ref builtin_getenv(nasal_ref* local,nasal_gc& gc)
|
||||
|
@ -1049,11 +1052,11 @@ nasal_ref builtin_getenv(nasal_ref* local,nasal_gc& gc)
|
|||
nasal_ref envvar=local[1];
|
||||
if(envvar.type!=vm_str)
|
||||
return builtin_err("getenv","\"envvar\" must be string");
|
||||
char* res=getenv(envvar.str()->c_str());
|
||||
char* res=getenv(envvar.str().c_str());
|
||||
if(!res)
|
||||
return nil;
|
||||
nasal_ref str=gc.alloc(vm_str);
|
||||
*str.str()=res;
|
||||
str.str()=res;
|
||||
return str;
|
||||
}
|
||||
nasal_ref builtin_dlopen(nasal_ref* local,nasal_gc& gc)
|
||||
|
@ -1062,50 +1065,50 @@ nasal_ref builtin_dlopen(nasal_ref* local,nasal_gc& gc)
|
|||
if(dlname.type!=vm_str)
|
||||
return builtin_err("dlopen","\"libname\" must be string");
|
||||
#ifdef _WIN32
|
||||
wchar_t* str=new wchar_t[dlname.str()->size()+1];
|
||||
memset(str,0,sizeof(wchar_t)*dlname.str()->size()+1);
|
||||
mbstowcs(str,dlname.str()->c_str(),dlname.str()->size()+1);
|
||||
wchar_t* str=new wchar_t[dlname.str().size()+1];
|
||||
memset(str,0,sizeof(wchar_t)*dlname.str().size()+1);
|
||||
mbstowcs(str,dlname.str().c_str(),dlname.str().size()+1);
|
||||
void* ptr=LoadLibraryW(str);
|
||||
delete []str;
|
||||
#else
|
||||
void* ptr=dlopen(dlname.str()->c_str(),RTLD_LOCAL|RTLD_LAZY);
|
||||
void* ptr=dlopen(dlname.str().c_str(),RTLD_LOCAL|RTLD_LAZY);
|
||||
#endif
|
||||
if(!ptr)
|
||||
return builtin_err("dlopen","cannot open dynamic lib <"+*dlname.str()+">");
|
||||
return builtin_err("dlopen","cannot open dynamic lib <"+dlname.str()+">");
|
||||
nasal_ref ret=gc.alloc(vm_obj);
|
||||
ret.obj()->type=obj_dylib;
|
||||
ret.obj()->ptr=ptr;
|
||||
ret.obj().type=obj_dylib;
|
||||
ret.obj().ptr=ptr;
|
||||
return ret;
|
||||
}
|
||||
nasal_ref builtin_dlsym(nasal_ref* local,nasal_gc& gc)
|
||||
{
|
||||
nasal_ref libptr=local[1];
|
||||
nasal_ref sym=local[2];
|
||||
if(libptr.type!=vm_obj || libptr.obj()->type!=obj_dylib)
|
||||
if(libptr.type!=vm_obj || libptr.obj().type!=obj_dylib)
|
||||
return builtin_err("dlsym","\"lib\" is not a correct dynamic lib entry");
|
||||
if(sym.type!=vm_str)
|
||||
return builtin_err("dlsym","\"sym\" must be string");
|
||||
#ifdef _WIN32
|
||||
void* func=(void*)GetProcAddress((HMODULE)libptr.obj()->ptr,sym.str()->c_str());
|
||||
void* func=(void*)GetProcAddress((HMODULE)libptr.obj().ptr,sym.str().c_str());
|
||||
#else
|
||||
void* func=dlsym(libptr.obj()->ptr,sym.str()->c_str());
|
||||
void* func=dlsym(libptr.obj().ptr,sym.str().c_str());
|
||||
#endif
|
||||
if(!func)
|
||||
return builtin_err("dlsym","cannot find symbol \""+*sym.str()+"\"");
|
||||
return builtin_err("dlsym","cannot find symbol \""+sym.str()+"\"");
|
||||
nasal_ref ret=gc.alloc(vm_obj);
|
||||
ret.obj()->type=obj_extern;
|
||||
ret.obj()->ptr=func;
|
||||
ret.obj().type=obj_extern;
|
||||
ret.obj().ptr=func;
|
||||
return ret;
|
||||
}
|
||||
nasal_ref builtin_dlclose(nasal_ref* local,nasal_gc& gc)
|
||||
{
|
||||
nasal_ref libptr=local[1];
|
||||
if(libptr.type!=vm_obj || libptr.obj()->type!=obj_dylib)
|
||||
if(libptr.type!=vm_obj || libptr.obj().type!=obj_dylib)
|
||||
return builtin_err("dlclose","\"lib\" is not a correct dynamic lib entry");
|
||||
#ifdef _WIN32
|
||||
FreeLibrary((HMODULE)libptr.obj()->ptr);
|
||||
FreeLibrary((HMODULE)libptr.obj().ptr);
|
||||
#else
|
||||
dlclose(libptr.obj()->ptr);
|
||||
dlclose(libptr.obj().ptr);
|
||||
#endif
|
||||
return nil;
|
||||
}
|
||||
|
@ -1113,21 +1116,21 @@ nasal_ref builtin_dlcall(nasal_ref* local,nasal_gc& gc)
|
|||
{
|
||||
nasal_ref funcptr=local[1];
|
||||
nasal_ref args=local[2];
|
||||
if(funcptr.type!=vm_obj || funcptr.obj()->type!=obj_extern)
|
||||
if(funcptr.type!=vm_obj || funcptr.obj().type!=obj_extern)
|
||||
return builtin_err("dlcall","\"funcptr\" is not a correct function pointer");
|
||||
typedef nasal_ref (*extern_func)(std::vector<nasal_ref>&,nasal_gc&);
|
||||
extern_func func=(extern_func)funcptr.obj()->ptr;
|
||||
return func(args.vec()->elems,gc);
|
||||
extern_func func=(extern_func)funcptr.obj().ptr;
|
||||
return func(args.vec().elems,gc);
|
||||
}
|
||||
nasal_ref builtin_platform(nasal_ref* local,nasal_gc& gc)
|
||||
{
|
||||
nasal_ref ret=gc.alloc(vm_str);
|
||||
#if defined _WIN32 || defined _WIN64
|
||||
*ret.str()="windows";
|
||||
ret.str()="windows";
|
||||
#elif defined __linux__
|
||||
*ret.str()="linux";
|
||||
ret.str()="linux";
|
||||
#elif defined __APPLE__
|
||||
*ret.str()="macOS";
|
||||
ret.str()="macOS";
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
|
53
nasal_gc.h
53
nasal_gc.h
|
@ -87,13 +87,13 @@ struct nasal_ref
|
|||
inline nasal_ref* addr();
|
||||
inline uint32_t ret ();
|
||||
inline int64_t& cnt ();
|
||||
inline double& num ();
|
||||
inline std::string* str ();
|
||||
inline nasal_vec* vec ();
|
||||
inline nasal_hash* hash();
|
||||
inline nasal_func* func();
|
||||
inline double num ();
|
||||
inline std::string& str ();
|
||||
inline nasal_vec& vec ();
|
||||
inline nasal_hash& hash();
|
||||
inline nasal_func& func();
|
||||
inline nasal_upval& upval();
|
||||
inline nasal_obj* obj ();
|
||||
inline nasal_obj& obj ();
|
||||
};
|
||||
|
||||
struct nasal_vec
|
||||
|
@ -223,10 +223,10 @@ nasal_ref nasal_hash::get_val(const std::string& key)
|
|||
nasal_ref ret(vm_none);
|
||||
nasal_ref val=elems["parents"];
|
||||
if(val.type==vm_vec)
|
||||
for(auto& i:val.vec()->elems)
|
||||
for(auto& i:val.vec().elems)
|
||||
{
|
||||
if(i.type==vm_hash)
|
||||
ret=i.hash()->get_val(key);
|
||||
ret=i.hash().get_val(key);
|
||||
if(ret.type!=vm_none)
|
||||
return ret;
|
||||
}
|
||||
|
@ -242,10 +242,10 @@ nasal_ref* nasal_hash::get_mem(const std::string& key)
|
|||
nasal_ref* addr=nullptr;
|
||||
nasal_ref val=elems["parents"];
|
||||
if(val.type==vm_vec)
|
||||
for(auto& i:val.vec()->elems)
|
||||
for(auto& i:val.vec().elems)
|
||||
{
|
||||
if(i.type==vm_hash)
|
||||
addr=i.hash()->get_mem(key);
|
||||
addr=i.hash().get_mem(key);
|
||||
if(addr)
|
||||
return addr;
|
||||
}
|
||||
|
@ -316,12 +316,12 @@ nasal_val::~nasal_val()
|
|||
}
|
||||
double nasal_ref::to_number()
|
||||
{
|
||||
return type!=vm_str?value.num:str2num(str()->c_str());
|
||||
return type!=vm_str?value.num:str2num(str().c_str());
|
||||
}
|
||||
std::string nasal_ref::to_string()
|
||||
{
|
||||
if(type==vm_str)
|
||||
return *str();
|
||||
return str();
|
||||
else if(type==vm_num)
|
||||
{
|
||||
std::string tmp=std::to_string(num());
|
||||
|
@ -338,9 +338,9 @@ void nasal_ref::print()
|
|||
case vm_none: std::cout<<"undefined"; break;
|
||||
case vm_nil: std::cout<<"nil"; break;
|
||||
case vm_num: std::cout<<value.num; break;
|
||||
case vm_str: std::cout<<*(this->str());break;
|
||||
case vm_vec: this->vec()->print(); break;
|
||||
case vm_hash: this->hash()->print(); break;
|
||||
case vm_str: std::cout<<str(); break;
|
||||
case vm_vec: vec().print(); break;
|
||||
case vm_hash: hash().print(); break;
|
||||
case vm_func: std::cout<<"func(..){..}";break;
|
||||
case vm_obj: std::cout<<"<object>"; break;
|
||||
}
|
||||
|
@ -348,13 +348,13 @@ void nasal_ref::print()
|
|||
inline nasal_ref* nasal_ref::addr (){return value.addr; }
|
||||
inline uint32_t nasal_ref::ret (){return value.ret; }
|
||||
inline int64_t& nasal_ref::cnt (){return value.cnt; }
|
||||
inline double& nasal_ref::num (){return value.num; }
|
||||
inline std::string* nasal_ref::str (){return value.gcobj->ptr.str; }
|
||||
inline nasal_vec* nasal_ref::vec (){return value.gcobj->ptr.vec; }
|
||||
inline nasal_hash* nasal_ref::hash (){return value.gcobj->ptr.hash; }
|
||||
inline nasal_func* nasal_ref::func (){return value.gcobj->ptr.func; }
|
||||
inline double nasal_ref::num (){return value.num; }
|
||||
inline std::string& nasal_ref::str (){return *value.gcobj->ptr.str; }
|
||||
inline nasal_vec& nasal_ref::vec (){return *value.gcobj->ptr.vec; }
|
||||
inline nasal_hash& nasal_ref::hash (){return *value.gcobj->ptr.hash; }
|
||||
inline nasal_func& nasal_ref::func (){return *value.gcobj->ptr.func; }
|
||||
inline nasal_upval& nasal_ref::upval(){return *value.gcobj->ptr.upval;}
|
||||
inline nasal_obj* nasal_ref::obj (){return value.gcobj->ptr.obj; }
|
||||
inline nasal_obj& nasal_ref::obj (){return *value.gcobj->ptr.obj; }
|
||||
|
||||
const uint32_t STACK_MAX_DEPTH=8191;
|
||||
const nasal_ref zero={vm_num,(double)0};
|
||||
|
@ -403,17 +403,17 @@ void nasal_gc::mark()
|
|||
switch(tmp.type)
|
||||
{
|
||||
case vm_vec:
|
||||
for(auto& i:tmp.vec()->elems)
|
||||
for(auto& i:tmp.vec().elems)
|
||||
bfs.push(i);
|
||||
break;
|
||||
case vm_hash:
|
||||
for(auto& i:tmp.hash()->elems)
|
||||
for(auto& i:tmp.hash().elems)
|
||||
bfs.push(i.second);
|
||||
break;
|
||||
case vm_func:
|
||||
for(auto& i:tmp.func()->local)
|
||||
for(auto& i:tmp.func().local)
|
||||
bfs.push(i);
|
||||
for(auto& i:tmp.func()->upvalue)
|
||||
for(auto& i:tmp.func().upvalue)
|
||||
bfs.push(i);
|
||||
break;
|
||||
case vm_upval:
|
||||
|
@ -446,6 +446,7 @@ void nasal_gc::sweep()
|
|||
}
|
||||
void nasal_gc::init(const std::vector<std::string>& s)
|
||||
{
|
||||
// initiaize function register
|
||||
funcr=nil;
|
||||
|
||||
for(uint8_t i=0;i<vm_type_size;++i)
|
||||
|
@ -464,7 +465,7 @@ void nasal_gc::init(const std::vector<std::string>& s)
|
|||
{
|
||||
strs[i]={vm_str,new nasal_val(vm_str)};
|
||||
strs[i].value.gcobj->unmut=1;
|
||||
*strs[i].str()=s[i];
|
||||
strs[i].str()=s[i];
|
||||
}
|
||||
}
|
||||
void nasal_gc::clear()
|
||||
|
|
162
nasal_vm.h
162
nasal_vm.h
|
@ -152,11 +152,11 @@ void nasal_vm::valinfo(nasal_ref& val)
|
|||
case vm_cnt: printf("| cnt | %ld\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%lx> %s\n",(uint64_t)p,rawstr(*val.str()).c_str());break;
|
||||
case vm_func: printf("| func | <0x%lx> entry:0x%x\n",(uint64_t)p,val.func()->entry);break;
|
||||
case vm_vec: printf("| vec | <0x%lx> [%lu val]\n",(uint64_t)p,val.vec()->elems.size());break;
|
||||
case vm_hash: printf("| hash | <0x%lx> {%lu val}\n",(uint64_t)p,val.hash()->elems.size());break;
|
||||
case vm_obj: printf("| obj | <0x%lx> obj:0x%lx\n",(uint64_t)p,(uint64_t)val.obj()->ptr);break;
|
||||
case vm_str: printf("| str | <0x%lx> %s\n",(uint64_t)p,rawstr(val.str()).c_str());break;
|
||||
case vm_func: printf("| func | <0x%lx> entry:0x%x\n",(uint64_t)p,val.func().entry);break;
|
||||
case vm_vec: printf("| vec | <0x%lx> [%lu val]\n",(uint64_t)p,val.vec().elems.size());break;
|
||||
case vm_hash: printf("| hash | <0x%lx> {%lu val}\n",(uint64_t)p,val.hash().elems.size());break;
|
||||
case vm_obj: printf("| obj | <0x%lx> obj:0x%lx\n",(uint64_t)p,(uint64_t)val.obj().ptr);break;
|
||||
default: printf("| err | <0x%lx> unknown object\n",(uint64_t)p);break;
|
||||
}
|
||||
}
|
||||
|
@ -243,9 +243,9 @@ void nasal_vm::global_state()
|
|||
}
|
||||
void nasal_vm::local_state()
|
||||
{
|
||||
if(!localr || !gc.funcr.func()->lsize)
|
||||
if(!localr || !gc.funcr.func().lsize)
|
||||
return;
|
||||
uint32_t lsize=gc.funcr.func()->lsize;
|
||||
uint32_t lsize=gc.funcr.func().lsize;
|
||||
printf("local(0x%lx<sp+%ld>):\n",(uint64_t)localr,localr-gc.stack);
|
||||
for(uint32_t i=0;i<lsize;++i)
|
||||
{
|
||||
|
@ -255,10 +255,10 @@ void nasal_vm::local_state()
|
|||
}
|
||||
void nasal_vm::upval_state()
|
||||
{
|
||||
if(gc.funcr.type==vm_nil || gc.funcr.func()->upvalue.empty())
|
||||
if(gc.funcr.type==vm_nil || gc.funcr.func().upvalue.empty())
|
||||
return;
|
||||
printf("upvalue:\n");
|
||||
auto& upval=gc.funcr.func()->upvalue;
|
||||
auto& upval=gc.funcr.func().upvalue;
|
||||
for(uint32_t i=0;i<upval.size();++i)
|
||||
{
|
||||
printf("-> upval[%u]:\n",i);
|
||||
|
@ -279,7 +279,7 @@ void nasal_vm::detail()
|
|||
else
|
||||
printf("funcr(<0x%lx> entry:0x%x)\n",
|
||||
(uint64_t)gc.funcr.value.gcobj,
|
||||
gc.funcr.func()->entry);
|
||||
gc.funcr.func().entry);
|
||||
global_state();
|
||||
local_state();
|
||||
upval_state();
|
||||
|
@ -320,9 +320,9 @@ inline bool nasal_vm::condition(nasal_ref val)
|
|||
return val.value.num;
|
||||
else if(val.type==vm_str)
|
||||
{
|
||||
double num=str2num(val.str()->c_str());
|
||||
double num=str2num(val.str().c_str());
|
||||
if(std::isnan(num))
|
||||
return !val.str()->empty();
|
||||
return !val.str().empty();
|
||||
return num;
|
||||
}
|
||||
return false;
|
||||
|
@ -336,8 +336,8 @@ inline void nasal_vm::opr_intg()
|
|||
}
|
||||
inline void nasal_vm::opr_intl()
|
||||
{
|
||||
gc.top[0].func()->local.resize(imm[pc],nil);
|
||||
gc.top[0].func()->lsize=imm[pc];
|
||||
gc.top[0].func().local.resize(imm[pc],nil);
|
||||
gc.top[0].func().lsize=imm[pc];
|
||||
}
|
||||
inline void nasal_vm::opr_loadg()
|
||||
{
|
||||
|
@ -349,7 +349,7 @@ inline void nasal_vm::opr_loadl()
|
|||
}
|
||||
inline void nasal_vm::opr_loadu()
|
||||
{
|
||||
gc.funcr.func()->upvalue[(imm[pc]>>16)&0xffff].upval()[imm[pc]&0xffff]=(gc.top--)[0];
|
||||
gc.funcr.func().upvalue[(imm[pc]>>16)&0xffff].upval()[imm[pc]&0xffff]=(gc.top--)[0];
|
||||
}
|
||||
inline void nasal_vm::opr_pnum()
|
||||
{
|
||||
|
@ -366,7 +366,7 @@ inline void nasal_vm::opr_pstr()
|
|||
inline void nasal_vm::opr_newv()
|
||||
{
|
||||
nasal_ref newv=gc.alloc(vm_vec);
|
||||
auto& vec=newv.vec()->elems;
|
||||
auto& vec=newv.vec().elems;
|
||||
vec.resize(imm[pc]);
|
||||
// use top-=imm[pc]-1 here will cause error if imm[pc] is 0
|
||||
gc.top=gc.top-imm[pc]+1;
|
||||
|
@ -381,42 +381,42 @@ inline void nasal_vm::opr_newh()
|
|||
inline void nasal_vm::opr_newf()
|
||||
{
|
||||
(++gc.top)[0]=gc.alloc(vm_func);
|
||||
nasal_func* func=gc.top[0].func();
|
||||
func->entry=imm[pc];
|
||||
func->psize=1;
|
||||
nasal_func& func=gc.top[0].func();
|
||||
func.entry=imm[pc];
|
||||
func.psize=1;
|
||||
|
||||
/* this means you create a new function in local scope */
|
||||
if(localr)
|
||||
{
|
||||
func->upvalue=gc.funcr.func()->upvalue;
|
||||
func.upvalue=gc.funcr.func().upvalue;
|
||||
nasal_ref upval=(gc.upvalue.back().type==vm_nil)?gc.alloc(vm_upval):gc.upvalue.back();
|
||||
upval.upval().size=gc.funcr.func()->lsize;
|
||||
upval.upval().size=gc.funcr.func().lsize;
|
||||
upval.upval().stk=localr;
|
||||
func->upvalue.push_back(upval);
|
||||
func.upvalue.push_back(upval);
|
||||
gc.upvalue.back()=upval;
|
||||
}
|
||||
}
|
||||
inline void nasal_vm::opr_happ()
|
||||
{
|
||||
gc.top[-1].hash()->elems[str_table[imm[pc]]]=gc.top[0];
|
||||
gc.top[-1].hash().elems[str_table[imm[pc]]]=gc.top[0];
|
||||
--gc.top;
|
||||
}
|
||||
inline void nasal_vm::opr_para()
|
||||
{
|
||||
nasal_func* func=gc.top[0].func();
|
||||
func->keys[str_table[imm[pc]]]=func->psize;// func->size has 1 place reserved for "me"
|
||||
func->local[func->psize++]={vm_none};
|
||||
nasal_func& func=gc.top[0].func();
|
||||
func.keys[str_table[imm[pc]]]=func.psize;// func->size has 1 place reserved for "me"
|
||||
func.local[func.psize++]={vm_none};
|
||||
}
|
||||
inline void nasal_vm::opr_defpara()
|
||||
{
|
||||
nasal_ref val=gc.top[0];
|
||||
nasal_func* func=(--gc.top)[0].func();
|
||||
func->keys[str_table[imm[pc]]]=func->psize;// func->size has 1 place reserved for "me"
|
||||
func->local[func->psize++]=val;
|
||||
nasal_func& func=(--gc.top)[0].func();
|
||||
func.keys[str_table[imm[pc]]]=func.psize;// func->size has 1 place reserved for "me"
|
||||
func.local[func.psize++]=val;
|
||||
}
|
||||
inline void nasal_vm::opr_dynpara()
|
||||
{
|
||||
gc.top[0].func()->dynpara=imm[pc];
|
||||
gc.top[0].func().dynpara=imm[pc];
|
||||
}
|
||||
inline void nasal_vm::opr_unot()
|
||||
{
|
||||
|
@ -427,9 +427,9 @@ inline void nasal_vm::opr_unot()
|
|||
case vm_num:gc.top[0]=val.num()?zero:one;break;
|
||||
case vm_str:
|
||||
{
|
||||
double num=str2num(val.str()->c_str());
|
||||
double num=str2num(val.str().c_str());
|
||||
if(std::isnan(num))
|
||||
gc.top[0]={vm_num,(double)val.str()->empty()};
|
||||
gc.top[0]={vm_num,(double)val.str().empty()};
|
||||
else
|
||||
gc.top[0]=num?zero:one;
|
||||
}
|
||||
|
@ -453,7 +453,7 @@ inline void nasal_vm::opr_div(){op_calc(/);}
|
|||
inline void nasal_vm::opr_lnk()
|
||||
{
|
||||
nasal_ref val=gc.alloc(vm_str);
|
||||
*val.str()=gc.top[-1].to_string()+gc.top[0].to_string();
|
||||
val.str()=gc.top[-1].to_string()+gc.top[0].to_string();
|
||||
(--gc.top)[0]=val;
|
||||
}
|
||||
|
||||
|
@ -468,7 +468,7 @@ inline void nasal_vm::opr_divc(){op_calc_const(/);}
|
|||
inline void nasal_vm::opr_lnkc()
|
||||
{
|
||||
nasal_ref val=gc.alloc(vm_str);
|
||||
*val.str()=gc.top[0].to_string()+str_table[imm[pc]];
|
||||
val.str()=gc.top[0].to_string()+str_table[imm[pc]];
|
||||
gc.top[0]=val;
|
||||
}
|
||||
|
||||
|
@ -484,7 +484,7 @@ inline void nasal_vm::opr_diveq(){op_calc_eq(/);}
|
|||
inline void nasal_vm::opr_lnkeq()
|
||||
{
|
||||
nasal_ref val=gc.alloc(vm_str);
|
||||
*val.str()=mem_addr[0].to_string()+gc.top[-1].to_string();
|
||||
val.str()=mem_addr[0].to_string()+gc.top[-1].to_string();
|
||||
(--gc.top)[0]=mem_addr[0]=val;
|
||||
mem_addr=nullptr;
|
||||
}
|
||||
|
@ -501,7 +501,7 @@ inline void nasal_vm::opr_diveqc(){op_calc_eq_const(/);}
|
|||
inline void nasal_vm::opr_lnkeqc()
|
||||
{
|
||||
nasal_ref val=gc.alloc(vm_str);
|
||||
*val.str()=mem_addr[0].to_string()+str_table[imm[pc]];
|
||||
val.str()=mem_addr[0].to_string()+str_table[imm[pc]];
|
||||
gc.top[0]=mem_addr[0]=val;
|
||||
mem_addr=nullptr;
|
||||
}
|
||||
|
@ -518,7 +518,7 @@ inline void nasal_vm::opr_eq()
|
|||
if(val1.type==vm_nil && val2.type==vm_nil)
|
||||
gc.top[0]=one;
|
||||
else if(val1.type==vm_str && val2.type==vm_str)
|
||||
gc.top[0]=(*val1.str()==*val2.str())?one:zero;
|
||||
gc.top[0]=(val1.str()==val2.str())?one:zero;
|
||||
else if(val1.type==vm_num || val2.type==vm_num)
|
||||
gc.top[0]=(val1.to_number()==val2.to_number())?one:zero;
|
||||
else
|
||||
|
@ -531,7 +531,7 @@ inline void nasal_vm::opr_neq()
|
|||
if(val1.type==vm_nil && val2.type==vm_nil)
|
||||
gc.top[0]=zero;
|
||||
else if(val1.type==vm_str && val2.type==vm_str)
|
||||
gc.top[0]=(*val1.str()!=*val2.str())?one:zero;
|
||||
gc.top[0]=(val1.str()!=val2.str())?one:zero;
|
||||
else if(val1.type==vm_num || val2.type==vm_num)
|
||||
gc.top[0]=(val1.to_number()!=val2.to_number())?one:zero;
|
||||
else
|
||||
|
@ -582,7 +582,7 @@ inline void nasal_vm::opr_counter()
|
|||
}
|
||||
inline void nasal_vm::opr_findex()
|
||||
{
|
||||
if(++gc.top[0].cnt()>=gc.top[-1].vec()->elems.size())
|
||||
if(++gc.top[0].cnt()>=gc.top[-1].vec().elems.size())
|
||||
{
|
||||
pc=imm[pc]-1;
|
||||
return;
|
||||
|
@ -592,7 +592,7 @@ inline void nasal_vm::opr_findex()
|
|||
}
|
||||
inline void nasal_vm::opr_feach()
|
||||
{
|
||||
std::vector<nasal_ref>& ref=gc.top[-1].vec()->elems;
|
||||
std::vector<nasal_ref>& ref=gc.top[-1].vec().elems;
|
||||
if(++gc.top[0].cnt()>=ref.size())
|
||||
{
|
||||
pc=imm[pc]-1;
|
||||
|
@ -611,7 +611,7 @@ inline void nasal_vm::opr_calll()
|
|||
}
|
||||
inline void nasal_vm::opr_upval()
|
||||
{
|
||||
(++gc.top)[0]=gc.funcr.func()->upvalue[(imm[pc]>>16)&0xffff].upval()[imm[pc]&0xffff];
|
||||
(++gc.top)[0]=gc.funcr.func().upvalue[(imm[pc]>>16)&0xffff].upval()[imm[pc]&0xffff];
|
||||
}
|
||||
inline void nasal_vm::opr_callv()
|
||||
{
|
||||
|
@ -619,7 +619,7 @@ inline void nasal_vm::opr_callv()
|
|||
nasal_ref vec=(--gc.top)[0];
|
||||
if(vec.type==vm_vec)
|
||||
{
|
||||
gc.top[0]=vec.vec()->get_val(val.to_number());
|
||||
gc.top[0]=vec.vec().get_val(val.to_number());
|
||||
if(gc.top[0].type==vm_none)
|
||||
die("callv: index out of range:"+std::to_string(val.to_number()));
|
||||
}
|
||||
|
@ -627,15 +627,15 @@ inline void nasal_vm::opr_callv()
|
|||
{
|
||||
if(val.type!=vm_str)
|
||||
die("callv: must use string as the key");
|
||||
gc.top[0]=vec.hash()->get_val(*val.str());
|
||||
gc.top[0]=vec.hash().get_val(val.str());
|
||||
if(gc.top[0].type==vm_none)
|
||||
die("callv: cannot find member \""+*val.str()+"\" of this hash");
|
||||
die("callv: cannot find member \""+val.str()+"\" of this hash");
|
||||
if(gc.top[0].type==vm_func)
|
||||
gc.top[0].func()->local[0]=val;// 'me'
|
||||
gc.top[0].func().local[0]=val;// 'me'
|
||||
}
|
||||
else if(vec.type==vm_str)
|
||||
{
|
||||
std::string& str=*vec.str();
|
||||
std::string& str=vec.str();
|
||||
int num=val.to_number();
|
||||
int str_size=str.length();
|
||||
if(num<-str_size || num>=str_size)
|
||||
|
@ -652,7 +652,7 @@ inline void nasal_vm::opr_callvi()
|
|||
die("callvi: must use a vector");
|
||||
|
||||
// cannot use operator[],because this may cause overflow
|
||||
(++gc.top)[0]=val.vec()->get_val(imm[pc]);
|
||||
(++gc.top)[0]=val.vec().get_val(imm[pc]);
|
||||
if(gc.top[0].type==vm_none)
|
||||
die("callvi: index out of range:"+std::to_string(imm[pc]));
|
||||
}
|
||||
|
@ -662,12 +662,12 @@ inline void nasal_vm::opr_callh()
|
|||
if(val.type!=vm_hash)
|
||||
die("callh: must call a hash");
|
||||
|
||||
gc.top[0]=val.hash()->get_val(str_table[imm[pc]]);
|
||||
gc.top[0]=val.hash().get_val(str_table[imm[pc]]);
|
||||
if(gc.top[0].type==vm_none)
|
||||
die("callh: member \""+str_table[imm[pc]]+"\" does not exist");
|
||||
|
||||
if(gc.top[0].type==vm_func)
|
||||
gc.top[0].func()->local[0]=val;// 'me'
|
||||
gc.top[0].func().local[0]=val;// 'me'
|
||||
}
|
||||
inline void nasal_vm::opr_callfv()
|
||||
{
|
||||
|
@ -676,61 +676,61 @@ inline void nasal_vm::opr_callfv()
|
|||
if(local[-1].type!=vm_func)
|
||||
die("callfv: must call a function");
|
||||
|
||||
nasal_func* func=local[-1].func();
|
||||
nasal_func& func=local[-1].func();
|
||||
nasal_ref tmp=local[-1];
|
||||
local[-1]=gc.funcr;
|
||||
gc.funcr=tmp;
|
||||
if(gc.top-argc+func->lsize+2>=canary) // gc.top-argc+lsize(local) +1(old pc) +1(old localr)
|
||||
if(gc.top-argc+func.lsize+2>=canary) // gc.top-argc+lsize(local) +1(old pc) +1(old localr)
|
||||
die("stack overflow");
|
||||
|
||||
uint32_t psize=func->psize-1; // parameter size is func->psize-1, 1 is reserved for "me"
|
||||
if(argc<psize && func->local[argc+1].type==vm_none)
|
||||
uint32_t psize=func.psize-1; // parameter size is func->psize-1, 1 is reserved for "me"
|
||||
if(argc<psize && func.local[argc+1].type==vm_none)
|
||||
die("callfv: lack argument(s)");
|
||||
|
||||
nasal_ref dynamic=nil;
|
||||
gc.top=local+func->lsize;
|
||||
if(func->dynpara>=0)// load dynamic arguments
|
||||
gc.top=local+func.lsize;
|
||||
if(func.dynpara>=0)// load dynamic arguments
|
||||
{
|
||||
dynamic=gc.alloc(vm_vec);
|
||||
for(uint32_t i=psize;i<argc;++i)
|
||||
dynamic.vec()->elems.push_back(local[i]);
|
||||
dynamic.vec().elems.push_back(local[i]);
|
||||
}
|
||||
uint32_t min_size=std::min(psize,argc);
|
||||
for(uint32_t i=min_size;i>=1;--i)// load arguments
|
||||
local[i]=local[i-1];
|
||||
local[0]=func->local[0];// load "me"
|
||||
for(uint32_t i=min_size+1;i<func->lsize;++i)// load local scope & default arguments
|
||||
local[i]=func->local[i];
|
||||
if(func->dynpara>=0)
|
||||
local[0]=func.local[0];// load "me"
|
||||
for(uint32_t i=min_size+1;i<func.lsize;++i)// load local scope & default arguments
|
||||
local[i]=func.local[i];
|
||||
if(func.dynpara>=0)
|
||||
local[psize+1]=dynamic;
|
||||
|
||||
gc.top[0]={vm_addr,localr};
|
||||
(++gc.top)[0]={vm_ret,pc};
|
||||
pc=func->entry-1;
|
||||
pc=func.entry-1;
|
||||
localr=local;
|
||||
gc.upvalue.push_back(nil);
|
||||
}
|
||||
inline void nasal_vm::opr_callfh()
|
||||
{
|
||||
auto& hash=gc.top[0].hash()->elems;
|
||||
auto& hash=gc.top[0].hash().elems;
|
||||
if(gc.top[-1].type!=vm_func)
|
||||
die("callfh: must call a function");
|
||||
|
||||
nasal_func* func=gc.top[-1].func();
|
||||
nasal_func& func=gc.top[-1].func();
|
||||
nasal_ref tmp=gc.top[-1];
|
||||
gc.top[-1]=gc.funcr;
|
||||
gc.funcr=tmp;
|
||||
if(gc.top+func->lsize+1>=canary) // gc.top -1(hash) +lsize(local) +1(old pc) +1(old localr)
|
||||
if(gc.top+func.lsize+1>=canary) // gc.top -1(hash) +lsize(local) +1(old pc) +1(old localr)
|
||||
die("stack overflow");
|
||||
if(func->dynpara>=0)
|
||||
if(func.dynpara>=0)
|
||||
die("callfh: special call cannot use dynamic argument");
|
||||
|
||||
nasal_ref* local=gc.top;
|
||||
gc.top+=func->lsize;
|
||||
for(uint32_t i=0;i<func->lsize;++i)
|
||||
local[i]=func->local[i];
|
||||
gc.top+=func.lsize;
|
||||
for(uint32_t i=0;i<func.lsize;++i)
|
||||
local[i]=func.local[i];
|
||||
|
||||
for(auto& i:func->keys)
|
||||
for(auto& i:func.keys)
|
||||
{
|
||||
if(hash.count(i.first))
|
||||
local[i.second]=hash[i.first];
|
||||
|
@ -740,7 +740,7 @@ inline void nasal_vm::opr_callfh()
|
|||
|
||||
gc.top[0]={vm_addr,localr};
|
||||
(++gc.top)[0]={vm_ret,pc}; // rewrite top with vm_ret
|
||||
pc=func->entry-1;
|
||||
pc=func.entry-1;
|
||||
localr=local;
|
||||
gc.upvalue.push_back(nil);
|
||||
}
|
||||
|
@ -769,17 +769,17 @@ inline void nasal_vm::opr_slcend()
|
|||
inline void nasal_vm::opr_slc()
|
||||
{
|
||||
nasal_ref val=(gc.top--)[0];
|
||||
nasal_ref res=gc.top[-1].vec()->get_val(val.to_number());
|
||||
nasal_ref res=gc.top[-1].vec().get_val(val.to_number());
|
||||
if(res.type==vm_none)
|
||||
die("slc: index out of range:"+std::to_string(val.to_number()));
|
||||
gc.top[0].vec()->elems.push_back(res);
|
||||
gc.top[0].vec().elems.push_back(res);
|
||||
}
|
||||
inline void nasal_vm::opr_slc2()
|
||||
{
|
||||
nasal_ref val2=(gc.top--)[0];
|
||||
nasal_ref val1=(gc.top--)[0];
|
||||
std::vector<nasal_ref>& ref=gc.top[-1].vec()->elems;
|
||||
std::vector<nasal_ref>& aim=gc.top[0].vec()->elems;
|
||||
std::vector<nasal_ref>& ref=gc.top[-1].vec().elems;
|
||||
std::vector<nasal_ref>& aim=gc.top[0].vec().elems;
|
||||
|
||||
uint8_t type1=val1.type,type2=val2.type;
|
||||
int num1=val1.to_number();
|
||||
|
@ -817,7 +817,7 @@ inline void nasal_vm::opr_mcalll()
|
|||
}
|
||||
inline void nasal_vm::opr_mupval()
|
||||
{
|
||||
mem_addr=&(gc.funcr.func()->upvalue[(imm[pc]>>16)&0xffff].upval()[imm[pc]&0xffff]);
|
||||
mem_addr=&(gc.funcr.func().upvalue[(imm[pc]>>16)&0xffff].upval()[imm[pc]&0xffff]);
|
||||
(++gc.top)[0]=mem_addr[0];
|
||||
}
|
||||
inline void nasal_vm::opr_mcallv()
|
||||
|
@ -826,7 +826,7 @@ inline void nasal_vm::opr_mcallv()
|
|||
nasal_ref vec=(--gc.top)[0];
|
||||
if(vec.type==vm_vec)
|
||||
{
|
||||
mem_addr=vec.vec()->get_mem(val.to_number());
|
||||
mem_addr=vec.vec().get_mem(val.to_number());
|
||||
if(!mem_addr)
|
||||
die("mcallv: index out of range:"+std::to_string(val.to_number()));
|
||||
}
|
||||
|
@ -834,8 +834,8 @@ inline void nasal_vm::opr_mcallv()
|
|||
{
|
||||
if(val.type!=vm_str)
|
||||
die("mcallv: must use string as the key");
|
||||
nasal_hash& ref=*vec.hash();
|
||||
std::string& str=*val.str();
|
||||
nasal_hash& ref=vec.hash();
|
||||
std::string& str=val.str();
|
||||
mem_addr=ref.get_mem(str);
|
||||
if(!mem_addr)
|
||||
{
|
||||
|
@ -851,7 +851,7 @@ inline void nasal_vm::opr_mcallh()
|
|||
nasal_ref hash=gc.top[0];
|
||||
if(hash.type!=vm_hash)
|
||||
die("mcallh: must call a hash");
|
||||
nasal_hash& ref=*hash.hash();
|
||||
nasal_hash& ref=hash.hash();
|
||||
const std::string& str=str_table[imm[pc]];
|
||||
mem_addr=ref.get_mem(str);
|
||||
if(!mem_addr) // create a new key
|
||||
|
@ -882,7 +882,7 @@ inline void nasal_vm::opr_ret()
|
|||
localr=gc.top[-2].addr();
|
||||
|
||||
gc.top=local-1;
|
||||
func.func()->local[0]=nil;// get func and set 'me' to nil
|
||||
func.func().local[0]=nil;// get func and set 'me' to nil
|
||||
gc.funcr=gc.top[0];
|
||||
|
||||
gc.top[0]=ret; // rewrite func with returned value
|
||||
|
@ -890,7 +890,7 @@ inline void nasal_vm::opr_ret()
|
|||
if(gc.upvalue.back().type==vm_upval) // synchronize upvalue
|
||||
{
|
||||
auto& upval=gc.upvalue.back().upval();
|
||||
auto size=func.func()->lsize;
|
||||
auto size=func.func().lsize;
|
||||
upval.onstk=false;
|
||||
for(uint32_t i=0;i<size;++i)
|
||||
upval.elems.push_back(local[i]);
|
||||
|
|
Loading…
Reference in New Issue