🚀 change module function parameter format to avoid warnings

This commit is contained in:
ValKmjolnir 2022-10-24 01:12:25 +08:00
parent 3ef8effe9a
commit c705b75513
11 changed files with 199 additions and 99 deletions

View File

@ -615,9 +615,8 @@ double fibonaci(double x){
return x; return x;
return fibonaci(x-1)+fibonaci(x-2); return fibonaci(x-1)+fibonaci(x-2);
} }
// remember to use extern "C", // module functions' parameter list example
// so you could search the symbol quickly var fib(var* args,usize size,gc* ngc){
extern "C" var fib(std::vector<var>& args,gc& ngc){
// the arguments are generated into a vm_vec: args // the arguments are generated into a vm_vec: args
// get values from the vector that must be used here // get values from the vector that must be used here
var num=args[0]; var num=args[0];
@ -627,10 +626,22 @@ extern "C" var fib(std::vector<var>& args,gc& ngc){
if(num.type!=vm_num) if(num.type!=vm_num)
return nas_err("extern_fib","\"num\" must be number"); return nas_err("extern_fib","\"num\" must be number");
// ok, you must know that vm_num now is not managed by gc // ok, you must know that vm_num now is not managed by gc
// if want to return a gc object, use ngc.alloc(type) // if want to return a gc object, use ngc->alloc(type)
// usage of gc is the same as adding a native function // usage of gc is the same as adding a native function
return {vm_num,fibonaci(num.tonum())}; return {vm_num,fibonaci(num.tonum())};
} }
// must write this function, this will help nasal to
// get the function pointer by name
// the reason why using this way to get function pointer
// is because `var` has constructors, which is not compatiable in C
// so "extern "C" var fib" may get compilation warnings
extern "C" mod get(const char* n){
string name=n;
if(name=="fib")
return fib;
return nullptr;
}
``` ```
Next, compile this `fib.cpp` into dynamic lib. Next, compile this `fib.cpp` into dynamic lib.

View File

@ -590,19 +590,30 @@ double fibonaci(double x){
return x; return x;
return fibonaci(x-1)+fibonaci(x-2); return fibonaci(x-1)+fibonaci(x-2);
} }
// 记得用extern "C"
// 这样找符号会更加快速便捷不要在意编译时的warning // 模块函数的参数列表一律以这个为准
extern "C" var fib(std::vector<var>& args,gc& ngc){ var fib(var* args,usize size,gc* ngc){
// 传参会被送到一个vm_vec类型中送过来而不是上文中那种指针直接指向局部作用域 // 传参会给予一个var指针指向一个vm_vec的data()
var num=args[0]; var num=args[0];
// 如果你想让这个函数有更强的稳定性,那么一定要进行合法性检查 // 如果你想让这个函数有更强的稳定性,那么一定要进行合法性检查
// builtin_err会输出错误信息并返回错误类型让虚拟机终止执行 // nas_err会输出错误信息并返回错误类型让虚拟机终止执行
if(num.type!=vm_num) if(num.type!=vm_num)
return nas_err("extern_fib","\"num\" must be number"); return nas_err("extern_fib","\"num\" must be number");
// vm_num作为普通的数字类型不是内存管理的对象所以无需申请 // vm_num作为普通的数字类型不是内存管理的对象所以无需申请
// 如果需要返回内存管理的对象请使用ngc.alloc(type) // 如果需要返回内存管理的对象请使用ngc->alloc(type)
return {vm_num,fibonaci(num.tonum())}; return {vm_num,fibonaci(num.tonum())};
} }
// 必须实现这个函数, 这样nasal可以通过字符串名字获得函数指针
// 之所以用这种方式来获取函数指针, 是因为`var`是有构造函数的
// 有构造函数的类型作为返回值, 和C是不兼容的, 这导致
// 类似 "extern "C" var fib" 的写法会得到编译错误
extern "C" mod get(const char* n){
string name=n;
if(name=="fib")
return fib;
return nullptr;
}
``` ```
接着我们把`fib.cpp`编译成动态库。 接着我们把`fib.cpp`编译成动态库。

View File

@ -6,18 +6,20 @@ double fibonaci(double x){
return x; return x;
return fibonaci(x-1)+fibonaci(x-2); return fibonaci(x-1)+fibonaci(x-2);
} }
extern "C" var fib(std::vector<var>& args,gc& ngc){
var fib(var* args,usize size,gc* ngc){
std::cout<<"[mod] this is the first test module of nasal\n"; std::cout<<"[mod] this is the first test module of nasal\n";
if(!args.size()) if(!size)
return nas_err("fib","lack arguments"); return nas_err("fib","lack arguments");
var num=args[0]; var num=args[0];
if(num.type!=vm_num) if(num.type!=vm_num)
return nas_err("extern_fib","\"num\" must be number"); return nas_err("extern_fib","\"num\" must be number");
return {vm_num,fibonaci(num.tonum())}; return {vm_num,fibonaci(num.tonum())};
} }
extern "C" var quick_fib(std::vector<var>& args,gc& ngc){
var quick_fib(var* args,usize size,gc* ngc){
std::cout<<"[mod] this is the first test module of nasal\n"; std::cout<<"[mod] this is the first test module of nasal\n";
if(!args.size()) if(!size)
return nas_err("fib","lack arguments"); return nas_err("fib","lack arguments");
var num=args[0]; var num=args[0];
if(num.type!=vm_num) if(num.type!=vm_num)
@ -31,4 +33,13 @@ extern "C" var quick_fib(std::vector<var>& args,gc& ngc){
b=res; b=res;
} }
return {vm_num,res}; return {vm_num,res};
}
extern "C" mod get(const char* n){
string name=n;
if(name=="fib")
return fib;
else if(name=="quick_fib")
return quick_fib;
return nullptr;
} }

View File

@ -71,14 +71,25 @@ public:
}; };
noecho_input this_window; noecho_input this_window;
extern "C" var nas_getch(std::vector<var>& args,gc& ngc){ var nas_getch(var* args,usize size,gc* ngc){
return {vm_num,(double)this_window.noecho_getch()}; return {vm_num,(double)this_window.noecho_getch()};
} }
extern "C" var nas_kbhit(std::vector<var>& args,gc& ngc){ var nas_kbhit(var* args,usize size,gc* ngc){
return {vm_num,(double)this_window.noecho_kbhit()}; return {vm_num,(double)this_window.noecho_kbhit()};
} }
extern "C" var nas_noblock(std::vector<var>& args,gc& ngc){ var nas_noblock(var* args,usize size,gc* ngc){
if(this_window.noecho_kbhit()) if(this_window.noecho_kbhit())
return {vm_num,(double)this_window.noecho_getch()}; return {vm_num,(double)this_window.noecho_getch()};
return nil; return nil;
}
extern "C" mod get(const char* n){
string name=n;
if(name=="nas_getch")
return nas_getch;
else if(name=="nas_kbhit")
return nas_kbhit;
else if(name=="nas_noblock")
return nas_noblock;
return nullptr;
} }

View File

@ -3,36 +3,41 @@
STD=14 STD=14
libfib.so: fib.cpp libfib.so: fib.cpp
$(CXX) -std=c++$(STD) -c -O3 fib.cpp -fPIC -o fib.o @ echo "[build] libfib.so"
$(CXX) -shared -o libfib.so fib.o @ $(CXX) -std=c++$(STD) -c -O3 fib.cpp -fPIC -o fib.o
rm fib.o @ $(CXX) -shared -o libfib.so fib.o
@ rm fib.o
libfib.dll: fib.cpp libfib.dll: fib.cpp
$(CXX) -std=c++$(STD) -c -O3 fib.cpp -fPIC -o fib.o @ echo [build] libfib.dll
$(CXX) -shared -o libfib.dll fib.o @ $(CXX) -std=c++$(STD) -c -O3 fib.cpp -fPIC -o fib.o
del fib.o @ $(CXX) -shared -o libfib.dll fib.o
@ del fib.o
libkey.so: keyboard.cpp libkey.so: keyboard.cpp
$(CXX) -std=c++$(STD) -c -O3 keyboard.cpp -fPIC -o keyboard.o @ echo "[build] libkey.so"
$(CXX) -shared -o libkey.so keyboard.o @ $(CXX) -std=c++$(STD) -c -O3 keyboard.cpp -fPIC -o keyboard.o
rm keyboard.o @ $(CXX) -shared -o libkey.so keyboard.o
@ rm keyboard.o
libkey.dll: keyboard.cpp libkey.dll: keyboard.cpp
$(CXX) -std=c++$(STD) -c -O3 keyboard.cpp -fPIC -o keyboard.o -static @ echo [build] libkey.dll
$(CXX) -shared -o libkey.dll keyboard.o -static @ $(CXX) -std=c++$(STD) -c -O3 keyboard.cpp -fPIC -o keyboard.o -static
del keyboard.o @ $(CXX) -shared -o libkey.dll keyboard.o -static
@ del keyboard.o
libnasock.so: nasocket.cpp libnasock.so: nasocket.cpp
$(CXX) -std=c++$(STD) -c -O3 nasocket.cpp -fPIC -o nasocket.o @ echo "[build] libnasock.so"
$(CXX) -shared -o libnasock.so nasocket.o @ $(CXX) -std=c++$(STD) -c -O3 nasocket.cpp -fPIC -o nasocket.o
rm nasocket.o @ $(CXX) -shared -o libnasock.so nasocket.o
@ rm nasocket.o
libnasock.dll: nasocket.cpp libnasock.dll: nasocket.cpp
$(CXX) -std=c++$(STD) -c -O3 nasocket.cpp -fPIC -o nasocket.o -lwsock32 -static @ echo [build] libnasock.dll
$(CXX) -shared -o libnasock.dll nasocket.o -lwsock32 -static @ $(CXX) -std=c++$(STD) -c -O3 nasocket.cpp -fPIC -o nasocket.o -lwsock32 -static
del nasocket.o @ $(CXX) -shared -o libnasock.dll nasocket.o -lwsock32 -static
@ del nasocket.o
clean: clean:
-@ rm *.so *.dll *.dylib -@ rm *.so *.dll *.dylib
@ echo "done"
all: libfib.so libkey.so libnasock.so all: libfib.so libkey.so libnasock.so
@ echo "build done" @ echo "[build] done"
mingw-all: libfib.dll libkey.dll libnasock.dll mingw-all: libfib.dll libkey.dll libnasock.dll
@ echo build done @ echo [build] done

View File

@ -25,14 +25,14 @@ static WSAmanager win;
#include <netinet/in.h> #include <netinet/in.h>
#endif #endif
extern "C" var nas_socket(std::vector<var>& args,gc& ngc){ var nas_socket(var* args,usize size,gc* ngc){
if(args[0].type!=vm_num || args[1].type!=vm_num || args[2].type!=vm_num) if(args[0].type!=vm_num || args[1].type!=vm_num || args[2].type!=vm_num)
return nas_err("socket","\"af\", \"type\", \"protocol\" should be number"); return nas_err("socket","\"af\", \"type\", \"protocol\" should be number");
int sd=socket(args[0].num(),args[1].num(),args[2].num()); int sd=socket(args[0].num(),args[1].num(),args[2].num());
return {vm_num,(double)sd}; return {vm_num,(double)sd};
} }
extern "C" var nas_closesocket(std::vector<var>& args,gc& ngc){ var nas_closesocket(var* args,usize size,gc* ngc){
if(args[0].type!=vm_num) if(args[0].type!=vm_num)
return nas_err("closesocket","\"\" should be number"); return nas_err("closesocket","\"\" should be number");
#ifdef _WIN32 #ifdef _WIN32
@ -42,7 +42,7 @@ extern "C" var nas_closesocket(std::vector<var>& args,gc& ngc){
#endif #endif
} }
extern "C" var nas_shutdown(std::vector<var>& args,gc& ngc){ var nas_shutdown(var* args,usize size,gc* ngc){
if(args[0].type!=vm_num) if(args[0].type!=vm_num)
return nas_err("shutdown","\"sd\" must be a number"); return nas_err("shutdown","\"sd\" must be a number");
if(args[1].type!=vm_num) if(args[1].type!=vm_num)
@ -50,7 +50,7 @@ extern "C" var nas_shutdown(std::vector<var>& args,gc& ngc){
return {vm_num,(double)shutdown(args[0].num(),args[1].num())}; return {vm_num,(double)shutdown(args[0].num(),args[1].num())};
} }
extern "C" var nas_bind(std::vector<var>& args,gc& ngc){ var nas_bind(var* args,usize size,gc* ngc){
if(args[0].type!=vm_num) if(args[0].type!=vm_num)
return nas_err("bind","\"sd\" muse be a number"); return nas_err("bind","\"sd\" muse be a number");
if(args[1].type!=vm_str) if(args[1].type!=vm_str)
@ -65,7 +65,7 @@ extern "C" var nas_bind(std::vector<var>& args,gc& ngc){
return {vm_num,(double)bind(args[0].num(),(sockaddr*)&server,sizeof(server))}; return {vm_num,(double)bind(args[0].num(),(sockaddr*)&server,sizeof(server))};
} }
extern "C" var nas_listen(std::vector<var>& args,gc& ngc){ var nas_listen(var* args,usize size,gc* ngc){
if(args[0].type!=vm_num) if(args[0].type!=vm_num)
return nas_err("listen","\"sd\" must be a number"); return nas_err("listen","\"sd\" must be a number");
if(args[1].type!=vm_num) if(args[1].type!=vm_num)
@ -73,7 +73,7 @@ extern "C" var nas_listen(std::vector<var>& args,gc& ngc){
return{vm_num,(double)listen(args[0].num(),args[1].num())}; return{vm_num,(double)listen(args[0].num(),args[1].num())};
} }
extern "C" var nas_connect(std::vector<var>& args,gc& ngc){ var nas_connect(var* args,usize size,gc* ngc){
if(args[0].type!=vm_num) if(args[0].type!=vm_num)
return nas_err("connect","\"sd\" must be a number"); return nas_err("connect","\"sd\" must be a number");
if(args[1].type!=vm_str) if(args[1].type!=vm_str)
@ -89,7 +89,7 @@ extern "C" var nas_connect(std::vector<var>& args,gc& ngc){
return {vm_num,(double)connect(args[0].num(),(sockaddr*)&addr,sizeof(sockaddr_in))}; return {vm_num,(double)connect(args[0].num(),(sockaddr*)&addr,sizeof(sockaddr_in))};
} }
extern "C" var nas_accept(std::vector<var>& args,gc& ngc){ var nas_accept(var* args,usize size,gc* ngc){
if(args[0].type!=vm_num) if(args[0].type!=vm_num)
return nas_err("accept","\"sd\" must be a number"); return nas_err("accept","\"sd\" must be a number");
sockaddr_in client; sockaddr_in client;
@ -99,15 +99,15 @@ extern "C" var nas_accept(std::vector<var>& args,gc& ngc){
#else #else
int client_sd=accept(args[0].num(),(sockaddr*)&client,(socklen_t*)&socklen); int client_sd=accept(args[0].num(),(sockaddr*)&client,(socklen_t*)&socklen);
#endif #endif
var res=ngc.temp=ngc.alloc(vm_hash); var res=ngc->temp=ngc->alloc(vm_hash);
auto& hash=res.hash().elems; auto& hash=res.hash().elems;
hash["sd"]={vm_num,(double)client_sd}; hash["sd"]={vm_num,(double)client_sd};
hash["ip"]=ngc.newstr(inet_ntoa(client.sin_addr)); hash["ip"]=ngc->newstr(inet_ntoa(client.sin_addr));
ngc.temp=nil; ngc->temp=nil;
return res; return res;
} }
extern "C" var nas_send(std::vector<var>& args,gc& ngc){ var nas_send(var* args,usize size,gc* ngc){
if(args[0].type!=vm_num) if(args[0].type!=vm_num)
return nas_err("send","\"sd\" must be a number"); return nas_err("send","\"sd\" must be a number");
if(args[1].type!=vm_str) if(args[1].type!=vm_str)
@ -117,7 +117,7 @@ extern "C" var nas_send(std::vector<var>& args,gc& ngc){
return {vm_num,(double)send(args[0].num(),args[1].str().c_str(),args[1].str().length(),args[2].num())}; return {vm_num,(double)send(args[0].num(),args[1].str().c_str(),args[1].str().length(),args[2].num())};
} }
extern "C" var nas_sendto(std::vector<var>& args,gc& ngc){ var nas_sendto(var* args,usize size,gc* ngc){
if(args[0].type!=vm_num) if(args[0].type!=vm_num)
return nas_err("sendto","\"sd\" must be a number"); return nas_err("sendto","\"sd\" must be a number");
if(args[1].type!=vm_str) if(args[1].type!=vm_str)
@ -137,7 +137,7 @@ extern "C" var nas_sendto(std::vector<var>& args,gc& ngc){
return {vm_num,(double)sendto(args[0].num(),args[3].str().c_str(),args[3].str().length(),args[4].num(),(sockaddr*)&addr,sizeof(sockaddr_in))}; return {vm_num,(double)sendto(args[0].num(),args[3].str().c_str(),args[3].str().length(),args[4].num(),(sockaddr*)&addr,sizeof(sockaddr_in))};
} }
extern "C" var nas_recv(std::vector<var>& args,gc& ngc){ var nas_recv(var* args,usize size,gc* ngc){
if(args[0].type!=vm_num) if(args[0].type!=vm_num)
return nas_err("recv","\"sd\" must be a number"); return nas_err("recv","\"sd\" must be a number");
if(args[1].type!=vm_num) if(args[1].type!=vm_num)
@ -146,17 +146,17 @@ extern "C" var nas_recv(std::vector<var>& args,gc& ngc){
return nas_err("recv","\"len\" out of range"); return nas_err("recv","\"len\" out of range");
if(args[2].type!=vm_num) if(args[2].type!=vm_num)
return nas_err("recv","\"flags\" muse be a number"); return nas_err("recv","\"flags\" muse be a number");
var res=ngc.temp=ngc.alloc(vm_hash); var res=ngc->temp=ngc->alloc(vm_hash);
auto& hash=res.hash().elems; auto& hash=res.hash().elems;
char* buf=new char[(int)args[1].num()]; char* buf=new char[(int)args[1].num()];
hash["size"]={vm_num,(double)recv(args[0].num(),buf,args[1].num(),args[2].num())}; hash["size"]={vm_num,(double)recv(args[0].num(),buf,args[1].num(),args[2].num())};
hash["str"]=ngc.newstr(buf); hash["str"]=ngc->newstr(buf);
delete[] buf; delete[] buf;
ngc.temp=nil; ngc->temp=nil;
return res; return res;
} }
extern "C" var nas_recvfrom(std::vector<var>& args,gc& ngc){ var nas_recvfrom(var* args,usize size,gc* ngc){
if(args[0].type!=vm_num) if(args[0].type!=vm_num)
return nas_err("recvfrom","\"sd\" must be a number"); return nas_err("recvfrom","\"sd\" must be a number");
if(args[1].type!=vm_num) if(args[1].type!=vm_num)
@ -167,7 +167,7 @@ extern "C" var nas_recvfrom(std::vector<var>& args,gc& ngc){
return nas_err("recvfrom","\"flags\" muse be a number"); return nas_err("recvfrom","\"flags\" muse be a number");
sockaddr_in addr; sockaddr_in addr;
int socklen=sizeof(sockaddr_in); int socklen=sizeof(sockaddr_in);
var res=ngc.temp=ngc.alloc(vm_hash); var res=ngc->temp=ngc->alloc(vm_hash);
auto& hash=res.hash().elems; auto& hash=res.hash().elems;
char* buf=new char[(int)args[1].num()+1]; char* buf=new char[(int)args[1].num()+1];
#ifdef _WIN32 #ifdef _WIN32
@ -176,13 +176,42 @@ extern "C" var nas_recvfrom(std::vector<var>& args,gc& ngc){
hash["size"]={vm_num,(double)recvfrom(args[0].num(),buf,args[1].num(),args[2].num(),(sockaddr*)&addr,(socklen_t*)&socklen)}; hash["size"]={vm_num,(double)recvfrom(args[0].num(),buf,args[1].num(),args[2].num(),(sockaddr*)&addr,(socklen_t*)&socklen)};
#endif #endif
buf[(int)hash["size"].num()]=0; buf[(int)hash["size"].num()]=0;
hash["str"]=ngc.newstr(buf); hash["str"]=ngc->newstr(buf);
delete[] buf; delete[] buf;
hash["fromip"]=ngc.newstr(inet_ntoa(addr.sin_addr)); hash["fromip"]=ngc->newstr(inet_ntoa(addr.sin_addr));
ngc.temp=nil; ngc->temp=nil;
return res; return res;
} }
extern "C" var nas_errno(std::vector<var>& args,gc& ngc){ var nas_errno(var* args,usize size,gc* ngc){
return ngc.newstr(strerror(errno)); return ngc->newstr(strerror(errno));
}
extern "C" mod get(const char* n){
string name=n;
if(name=="nas_socket")
return nas_socket;
else if(name=="nas_closesocket")
return nas_closesocket;
else if(name=="nas_shutdown")
return nas_shutdown;
else if(name=="nas_bind")
return nas_bind;
else if(name=="nas_listen")
return nas_listen;
else if(name=="nas_connect")
return nas_connect;
else if(name=="nas_accept")
return nas_accept;
else if(name=="nas_send")
return nas_send;
else if(name=="nas_sendto")
return nas_sendto;
else if(name=="nas_recv")
return nas_recv;
else if(name=="nas_recvfrom")
return nas_recvfrom;
else if(name=="nas_errno")
return nas_errno;
return nullptr;
} }

View File

@ -130,7 +130,7 @@ var builtin_split(var* local,gc& ngc)
// avoid being sweeped // avoid being sweeped
var res=ngc.temp=ngc.alloc(vm_vec); var res=ngc.temp=ngc.alloc(vm_vec);
std::vector<var>& vec=res.vec().elems; auto& vec=res.vec().elems;
if(!deli.length()) if(!deli.length())
{ {
@ -850,7 +850,7 @@ var builtin_getenv(var* local,gc& ngc)
char* res=getenv(envvar.str().c_str()); char* res=getenv(envvar.str().c_str());
return res?ngc.newstr(res):nil; return res?ngc.newstr(res):nil;
} }
void obj_dylib_dtor(void* ptr) void dylib_dtor(void* ptr)
{ {
#ifdef _WIN32 #ifdef _WIN32
FreeLibrary((HMODULE)ptr); FreeLibrary((HMODULE)ptr);
@ -869,7 +869,7 @@ var builtin_dlopen(var* local,gc& ngc)
return nas_err("dlopen","malloc failed"); return nas_err("dlopen","malloc failed");
memset(str,0,sizeof(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); mbstowcs(str,dlname.str().c_str(),dlname.str().size()+1);
void* ptr=LoadLibraryW(str); void* ptr=LoadLibraryA(dlname.str().c_str());
delete []str; delete []str;
#else #else
void* ptr=dlopen(dlname.str().c_str(),RTLD_LOCAL|RTLD_LAZY); void* ptr=dlopen(dlname.str().c_str(),RTLD_LOCAL|RTLD_LAZY);
@ -877,7 +877,7 @@ var builtin_dlopen(var* local,gc& ngc)
if(!ptr) if(!ptr)
return nas_err("dlopen","cannot open dynamic lib <"+dlname.str()+">"); return nas_err("dlopen","cannot open dynamic lib <"+dlname.str()+">");
var ret=ngc.alloc(vm_obj); var ret=ngc.alloc(vm_obj);
ret.obj().set(nas_obj::dylib,ptr,obj_dylib_dtor); ret.obj().set(nas_obj::dylib,ptr,dylib_dtor);
return ret; return ret;
} }
var builtin_dlsym(var* local,gc& ngc) var builtin_dlsym(var* local,gc& ngc)
@ -888,15 +888,20 @@ var builtin_dlsym(var* local,gc& ngc)
return nas_err("dlsym","\"lib\" is not a valid dynamic lib"); return nas_err("dlsym","\"lib\" is not a valid dynamic lib");
if(sym.type!=vm_str) if(sym.type!=vm_str)
return nas_err("dlsym","\"sym\" must be string"); return nas_err("dlsym","\"sym\" must be string");
// "get" function
#ifdef _WIN32 #ifdef _WIN32
void* func=(void*)GetProcAddress((HMODULE)lib.obj().ptr,sym.str().c_str()); void* func=(void*)GetProcAddress((HMODULE)lib.obj().ptr,"get");
#else #else
void* func=dlsym(lib.obj().ptr,sym.str().c_str()); void* func=dlsym(lib.obj().ptr,"get");
#endif #endif
if(!func) if(!func)
return nas_err("dlsym","cannot find symbol \""+sym.str()+"\""); return nas_err("dlsym","cannot find get function");
// get function pointer by name
void* ptr=(void*)((getptr)func)(sym.str().c_str());
if(!ptr)
return nas_err("dlsym","cannot find function <"+sym.str()+">");
var ret=ngc.alloc(vm_obj); var ret=ngc.alloc(vm_obj);
ret.obj().set(nas_obj::faddr,func); ret.obj().set(nas_obj::faddr,ptr);
return ret; return ret;
} }
var builtin_dlclose(var* local,gc& ngc) var builtin_dlclose(var* local,gc& ngc)
@ -918,9 +923,8 @@ var builtin_dlcall(var* local,gc& ngc)
var args=local[2]; var args=local[2];
if(!fp.objchk(nas_obj::faddr)) if(!fp.objchk(nas_obj::faddr))
return nas_err("dlcall","\"funcptr\" is not a valid function pointer"); return nas_err("dlcall","\"funcptr\" is not a valid function pointer");
typedef var (*externs)(std::vector<var>&,gc&); auto& vec=args.vec().elems;
externs func=(externs)fp.obj().ptr; return ((mod)fp.obj().ptr)(vec.data(),vec.size(),&ngc);
return func(args.vec().elems,ngc);
} }
var builtin_platform(var* local,gc& ngc) var builtin_platform(var* local,gc& ngc)

View File

@ -460,16 +460,18 @@ struct gc
} mctx; } mctx;
/* runtime context */ /* runtime context */
u32& pc; // program counter u32& pc; // program counter
var*& localr;// local scope register var*& localr; // local scope register
var*& memr; // used for mem_call var*& memr; // used for mem_call
var& funcr; // function register var& funcr; // function register
var& upvalr;// upvalue register var& upvalr; // upvalue register
var*& canary;// avoid stackoverflow var*& canary; // avoid stackoverflow
var*& top; // stack top var*& top; // stack top
var* stack; // stack pointer var* stack; // stack pointer
nas_co* cort;// running coroutine nas_co* cort; // running coroutine
var temp; // temporary place used in builtin/module functions
/* native function used */
var temp; // temporary place used in builtin/module functions
/* constants and memory pool */ /* constants and memory pool */
std::vector<var> strs; // reserved address for const vm_str std::vector<var> strs; // reserved address for const vm_str
@ -720,4 +722,8 @@ var nas_err(const string& err_f,const string& info)
std::cerr<<"[vm] "<<err_f<<": "<<info<<"\n"; std::cerr<<"[vm] "<<err_f<<": "<<info<<"\n";
return {vm_none}; return {vm_none};
} }
typedef var (*mod)(var*,usize,gc*); // module function type
typedef mod (*getptr)(const char*); // module function "get" type
#endif #endif

View File

@ -602,7 +602,7 @@ inline void vm::o_findex()
} }
inline void vm::o_feach() inline void vm::o_feach()
{ {
std::vector<var>& ref=top[-1].vec().elems; auto& ref=top[-1].vec().elems;
if((usize)(++top[0].cnt())>=ref.size()) if((usize)(++top[0].cnt())>=ref.size())
{ {
pc=imm[pc]-1; pc=imm[pc]-1;
@ -800,8 +800,8 @@ inline void vm::o_slc2()
{ {
var val2=(top--)[0]; var val2=(top--)[0];
var val1=(top--)[0]; var val1=(top--)[0];
std::vector<var>& ref=top[-1].vec().elems; auto& ref=top[-1].vec().elems;
std::vector<var>& aim=top[0].vec().elems; auto& aim=top[0].vec().elems;
u8 type1=val1.type,type2=val2.type; u8 type1=val1.type,type2=val2.type;
i32 num1=val1.tonum(); i32 num1=val1.tonum();

View File

@ -5,7 +5,10 @@ var http=func(){
return { return {
establish:func(ip,port){ establish:func(ip,port){
sd=socket.socket(socket.AF_INET,socket.SOCK_STREAM,socket.IPPROTO_IP); sd=socket.socket(socket.AF_INET,socket.SOCK_STREAM,socket.IPPROTO_IP);
socket.bind(sd,ip,port); if(socket.bind(sd,ip,port)<0){
println("failed to bind socket "~sd~" at IP: "~ip~" port: "~port~".");
return;
}
socket.listen(sd,1); socket.listen(sd,1);
println("[",os.time(),"] start server at [",ip,":",port,"]"); println("[",os.time(),"] start server at [",ip,":",port,"]");
}, },
@ -40,7 +43,6 @@ var http=func(){
}(); }();
http.establish("127.0.0.1",8080); http.establish("127.0.0.1",8080);
var highlight_style=" var highlight_style="
<style> <style>
body{ body{

View File

@ -16,14 +16,20 @@ var cpu_stat=func(){
}; };
return cpu; return cpu;
} }
var cpu_occupation=func(){ var cpu_occupation=func(){
var cpu0=cpu_stat(); while(1){
unix.sleep(0.5); var cpu0=cpu_stat();
var cpu1=cpu_stat(); for(var i=0;i<5;i+=1){
var t0=cpu0.user+cpu0.nice+cpu0.system+cpu0.idle+cpu0.iowait+cpu0.irq+cpu0.softirq; unix.sleep(0.1);
var t1=cpu1.user+cpu1.nice+cpu1.system+cpu1.idle+cpu1.iowait+cpu1.irq+cpu1.softirq; coroutine.yield(nil);
var interval=cpu1.idle-cpu0.idle; }
return t0==t1?0:(1-interval/(t1-t0))*100; var cpu1=cpu_stat();
var t0=cpu0.user+cpu0.nice+cpu0.system+cpu0.idle+cpu0.iowait+cpu0.irq+cpu0.softirq;
var t1=cpu1.user+cpu1.nice+cpu1.system+cpu1.idle+cpu1.iowait+cpu1.irq+cpu1.softirq;
var interval=cpu1.idle-cpu0.idle;
coroutine.yield(t0==t1?0:(1-interval/(t1-t0))*100);
}
} }
var mem_occupation=func(){ var mem_occupation=func(){
@ -36,20 +42,24 @@ var mem_occupation=func(){
} }
return mem_res; return mem_res;
} }
func(){ func(){
if(os.platform()=="windows"){ if(os.platform()=="windows"){
println("haven't supported yet."); println("haven't supported yet.");
return; return;
} }
var co=coroutine.create(cpu_occupation);
var bar=process_bar.high_resolution_bar(30);
print("\ec"); print("\ec");
while(1){ while(1){
var mem=mem_occupation(); var mem=mem_occupation();
var mem_occ=(mem.MemTotal-mem.MemFree)/mem.MemTotal*100; var mem_occ=(mem.MemTotal-mem.MemFree)/mem.MemTotal*100;
var cpu_occ=cpu_occupation(); var cpu_occ=nil;
var key=libkey.nonblock(); while((cpu_occ=coroutine.resume(co)[0])==nil){
var bar=process_bar.high_resolution_bar(25); var key=libkey.nonblock();
if(key!=nil and chr(key)=="q") if(key!=nil and chr(key)=="q")
break; return;
}
println("\e[1;1H\e[1m Memory total(GB) : \e[0m\e[36m",mem.MemTotal/1024/1024,"\e[0m"); println("\e[1;1H\e[1m Memory total(GB) : \e[0m\e[36m",mem.MemTotal/1024/1024,"\e[0m");
println("\e[2;1H\e[1m Memory free(GB) : \e[0m\e[36m",mem.MemFree/1024/1024,"\e[0m"); println("\e[2;1H\e[1m Memory free(GB) : \e[0m\e[36m",mem.MemFree/1024/1024,"\e[0m");
println("\e[3;1H\e[1m Memory occupation(%): \e[0m",mem_occ>60?"\e[91m":"\e[32m",bar.bar(mem_occ/100)~" ",mem_occ,"\e[0m "); println("\e[3;1H\e[1m Memory occupation(%): \e[0m",mem_occ>60?"\e[91m":"\e[32m",bar.bar(mem_occ/100)~" ",mem_occ,"\e[0m ");