🚀 change module function parameter format to avoid warnings
This commit is contained in:
parent
3ef8effe9a
commit
c705b75513
19
README.md
19
README.md
|
@ -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.
|
||||||
|
|
|
@ -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`编译成动态库。
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
|
@ -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;
|
||||||
}
|
}
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
|
@ -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)
|
||||||
|
|
26
nasal_gc.h
26
nasal_gc.h
|
@ -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
|
|
@ -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();
|
||||||
|
|
|
@ -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{
|
||||||
|
|
|
@ -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 ");
|
||||||
|
|
Loading…
Reference in New Issue