From e54ef9620f25dd88d15b528666e498e5eaa488ef Mon Sep 17 00:00:00 2001 From: ValKmjolnir Date: Wed, 9 Mar 2022 22:54:54 +0800 Subject: [PATCH] change nasal_ref value option functions' output types from pointers to references --- README.md | 29 +++--- nasal_builtin.h | 249 ++++++++++++++++++++++++------------------------ nasal_gc.h | 53 ++++++----- nasal_vm.h | 162 +++++++++++++++---------------- 4 files changed, 248 insertions(+), 245 deletions(-) diff --git a/README.md b/README.md index a6d708c..c408693 100644 --- a/README.md +++ b/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<print(); break; - case vm_hash: i.hash()->print(); break; + case vm_str: std::cout<"; 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& 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]; } ``` diff --git a/nasal_builtin.h b/nasal_builtin.h index afa2ecc..af93dc7 100644 --- a/nasal_builtin.h +++ b/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<print(); break; - case vm_hash: i.hash()->print(); break; + case vm_str: std::cout<"; 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<& vec=gc.top[0].vec()->elems; + std::vector& vec=gc.top[0].vec().elems; if(!delimeter_len) { for(int i=0;ielems.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()->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>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>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;ielems.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_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; } diff --git a/nasal_gc.h b/nasal_gc.h index ca4fa5c..dda1859 100644 --- a/nasal_gc.h +++ b/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<str());break; - case vm_vec: this->vec()->print(); break; - case vm_hash: this->hash()->print(); break; + case vm_str: std::cout<"; 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& s) { + // initiaize function register funcr=nil; for(uint8_t i=0;i& 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() diff --git a/nasal_vm.h b/nasal_vm.h index 3e05986..ede4f91 100644 --- a/nasal_vm.h +++ b/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< %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):\n",(uint64_t)localr,localr-gc.stack); for(uint32_t i=0;iupvalue.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[%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& ref=gc.top[-1].vec()->elems; + std::vector& 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(argclocal[argc+1].type==vm_none) + uint32_t psize=func.psize-1; // parameter size is func->psize-1, 1 is reserved for "me" + if(argclsize; - 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;ielems.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;ilsize;++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=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;ilsize;++i) - local[i]=func->local[i]; + gc.top+=func.lsize; + for(uint32_t i=0;ikeys) + 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& ref=gc.top[-1].vec()->elems; - std::vector& aim=gc.top[0].vec()->elems; + std::vector& ref=gc.top[-1].vec().elems; + std::vector& 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