⚡ add new ways of calling dylib function
This commit is contained in:
parent
ca527ec931
commit
97b3cefe75
13
README.md
13
README.md
|
@ -674,10 +674,21 @@ dylib.dlclose(dlhandle);
|
|||
|
||||
`dylib.dlsym` is used to get the function address.
|
||||
|
||||
`dylib.dlcall` is used to call the function, the first argument is the function address, make sure this argument is vm_obj and type=obj_extern.
|
||||
`dylib.dlcall` is used to call the function, the first argument is the function address, make sure this argument is `vm_obj` and `type=obj_extern`.
|
||||
|
||||
`dylib.dlclose` is used to unload the library, at the moment that you call the function, all the function addresses that got from it are invalid.
|
||||
|
||||
`dylib.limitcall` is used to get `dlcall` function that has limited parameter size, this function will prove the performance of your code because it does not use `vm_vec` to store the arguments, instead it uses local scope to store them, so this could avoid frequently garbage collecting. And the code above could also be written like this:
|
||||
|
||||
```javascript
|
||||
var dlhandle=dylib.dlopen("libfib."~(os.platform()=="windows"?"dll":"so"));
|
||||
var fib=dylib.dlsym(dlhandle,"fib");
|
||||
var invoke=dylib.limitcall(1); # this means the called function has only one parameter
|
||||
for(var i=1;i<30;i+=1)
|
||||
println(invoke(fib,i));
|
||||
dylib.dlclose(dlhandle);
|
||||
```
|
||||
|
||||
If get this, Congratulations!
|
||||
|
||||
```bash
|
||||
|
|
|
@ -647,10 +647,21 @@ dylib.dlclose(dlhandle);
|
|||
|
||||
`dylib.dlsym`通过符号从动态库中获得函数地址。
|
||||
|
||||
`dylib.dlcall`用于调用函数,第一个参数是动态库函数的地址,这是个特殊类型,一定要保证这个参数是vm_obj类型并且type=obj_extern。
|
||||
`dylib.dlcall`用于调用函数,第一个参数是动态库函数的地址,这是个特殊类型,一定要保证这个参数是`vm_obj`类型并且`type=obj_extern`。
|
||||
|
||||
`dylib.dlclose`用于卸载动态库,当然,在这个函数调用之后,所有从该库中获取的函数都作废。
|
||||
|
||||
`dylib.limitcall`用于获取使用固定长度传参的 `dlcall` 函数,这种函数可以提高你的程序运行效率,因为它不需要用 `vm_vec` 来存储传入参数,而是使用局部作用域来直接存储,从而避免了频繁调用可能导致的频繁垃圾收集。所以上面展示的代码同样可以这样写:
|
||||
|
||||
```javascript
|
||||
var dlhandle=dylib.dlopen("libfib."~(os.platform()=="windows"?"dll":"so"));
|
||||
var fib=dylib.dlsym(dlhandle,"fib");
|
||||
var invoke=dylib.limitcall(1); # 这说明我们要调用的函数只有一个参数
|
||||
for(var i=1;i<30;i+=1)
|
||||
println(invoke(fib,i));
|
||||
dylib.dlclose(dlhandle);
|
||||
```
|
||||
|
||||
如果接下来你看到了这个运行结果,恭喜你!
|
||||
|
||||
```bash
|
||||
|
|
39
lib.nas
39
lib.nas
|
@ -280,8 +280,7 @@ var md5=func(str){
|
|||
return __md5(str);
|
||||
}
|
||||
|
||||
var io=
|
||||
{
|
||||
var io={
|
||||
SEEK_SET:0,
|
||||
SEEK_CUR:1,
|
||||
SEEK_END:2,
|
||||
|
@ -333,8 +332,7 @@ var fstat=func(filename){
|
|||
|
||||
# functions that do bitwise calculation.
|
||||
# carefully use it, all the calculations are based on integer.
|
||||
var bits=
|
||||
{
|
||||
var bits={
|
||||
# i32 xor
|
||||
i32_xor: func(a,b){return __i32xor(a,b); },
|
||||
# i32 and
|
||||
|
@ -378,8 +376,7 @@ var bits=
|
|||
};
|
||||
|
||||
# mostly used math functions and special constants, you know.
|
||||
var math=
|
||||
{
|
||||
var math={
|
||||
e: 2.7182818284590452354,
|
||||
pi: 3.14159265358979323846264338327950288,
|
||||
D2R: 2.7182818284590452354/180,
|
||||
|
@ -402,8 +399,7 @@ var math=
|
|||
min: func(x,y){return x<y?x:y; }
|
||||
};
|
||||
|
||||
var unix=
|
||||
{
|
||||
var unix={
|
||||
pipe: func(){return __pipe;},
|
||||
fork: func(){return __fork;},
|
||||
dup2: func(fd0,fd1){die("not supported yet");},
|
||||
|
@ -425,8 +421,7 @@ var unix=
|
|||
|
||||
# dylib is the core hashmap for developers to load their own library.
|
||||
# for safe using dynamic library, you could use 'module' in stl/module.nas
|
||||
var dylib=
|
||||
{
|
||||
var dylib={
|
||||
# open dynamic lib.
|
||||
dlopen: func(libname){
|
||||
# find dynamic lib from local dir first
|
||||
|
@ -451,22 +446,34 @@ var dylib=
|
|||
dlsym: func(lib,sym){return __dlsym; },
|
||||
# close dynamic lib, this operation will make all the symbols loaded from it invalid.
|
||||
dlclose: func(lib){return __dlclose; },
|
||||
# call the loaded symbol.
|
||||
dlcall: func(ptr,args...){return __dlcall}
|
||||
# call the loaded symbol, with infinite parameters:
|
||||
# Caution: this may cause garbage collection process, be aware of the performance.
|
||||
dlcall: func(ptr,args...){return __dlcallv},
|
||||
# get dlcall function with limited parameter list
|
||||
limitcall: func(arg_size=0){
|
||||
if(arg_size==0){return func(ptr){return __dlcall};}
|
||||
else if(arg_size==1){return func(ptr,_0){return __dlcall};}
|
||||
else if(arg_size==2){return func(ptr,_0,_1){return __dlcall};}
|
||||
else if(arg_size==3){return func(ptr,_0,_1,_2){return __dlcall};}
|
||||
else if(arg_size==4){return func(ptr,_0,_1,_2,_3){return __dlcall};}
|
||||
else if(arg_size==5){return func(ptr,_0,_1,_2,_3,_4){return __dlcall};}
|
||||
else if(arg_size==6){return func(ptr,_0,_1,_2,_3,_4,_5){return __dlcall};}
|
||||
else if(arg_size==7){return func(ptr,_0,_1,_2,_3,_4,_5,_6){return __dlcall};}
|
||||
else if(arg_size==8){return func(ptr,_0,_1,_2,_3,_4,_5,_6,_7){return __dlcall};}
|
||||
else{return func(ptr,args...){return __dlcallv};}
|
||||
}
|
||||
};
|
||||
|
||||
# os is used to use or get some os-related info/functions.
|
||||
# windows/macOS/linux are supported.
|
||||
var os=
|
||||
{
|
||||
var os={
|
||||
# get a string that tell which os it runs on.
|
||||
platform: func(){return __platform;},
|
||||
time: func(){return __logtime; }
|
||||
};
|
||||
|
||||
# runtime gives us some functions that we could manage it manually.
|
||||
var runtime=
|
||||
{
|
||||
var runtime={
|
||||
# command line arguments
|
||||
argv: func(){return __sysargv;}
|
||||
};
|
||||
|
|
|
@ -8,26 +8,20 @@ double fibonaci(double x){
|
|||
}
|
||||
|
||||
var fib(var* args,usize size,gc* ngc){
|
||||
std::cout<<"[mod] this is the first test module of nasal\n";
|
||||
if(!size)
|
||||
return nas_err("fib","lack arguments");
|
||||
var num=args[0];
|
||||
if(num.type!=vm_num)
|
||||
return nas_err("extern_fib","\"num\" must be number");
|
||||
return {vm_num,fibonaci(num.tonum())};
|
||||
}
|
||||
|
||||
var quick_fib(var* args,usize size,gc* ngc){
|
||||
std::cout<<"[mod] this is the first test module of nasal\n";
|
||||
if(!size)
|
||||
return nas_err("fib","lack arguments");
|
||||
var num=args[0];
|
||||
if(num.type!=vm_num)
|
||||
return nas_err("extern_quick_fib","\"num\" must be number");
|
||||
if(num.num()<2)
|
||||
return num;
|
||||
return nas_err("quick_fib","lack arguments");
|
||||
double num=args[0].tonum();
|
||||
if(num<2)
|
||||
return {vm_num,num};
|
||||
double a=1,b=1,res=0;
|
||||
for(double i=1;i<num.num();i+=1){
|
||||
for(double i=1;i<num;i+=1){
|
||||
res=a+b;
|
||||
a=b;
|
||||
b=res;
|
||||
|
|
|
@ -2,7 +2,7 @@ var libfib=func(){
|
|||
var dl=dylib.dlopen("libfib."~(os.platform()=="windows"?"dll":"so"));
|
||||
var fib=dylib.dlsym(dl,"fib");
|
||||
var qfib=dylib.dlsym(dl,"quick_fib");
|
||||
var call=dylib.dlcall;
|
||||
var call=dylib.limitcall(1);
|
||||
return {
|
||||
fib: func(x){return call(fib,x)},
|
||||
qfib:func(x){return call(qfib,x)}
|
||||
|
|
|
@ -3,7 +3,7 @@ var libkey=func(){
|
|||
var kb=dylib.dlsym(lib,"nas_kbhit");
|
||||
var gt=dylib.dlsym(lib,"nas_getch");
|
||||
var nb=dylib.dlsym(lib,"nas_noblock");
|
||||
var call=dylib.dlcall;
|
||||
var call=dylib.limitcall(0);
|
||||
return {
|
||||
kbhit:func(){return call(kb);},
|
||||
getch:func(){return call(gt);},
|
||||
|
|
|
@ -27,32 +27,36 @@ var libmat=func(){
|
|||
dylib.dlsym(dl,"nas_rotate_y"),
|
||||
dylib.dlsym(dl,"nas_rotate_z")
|
||||
);
|
||||
var call=dylib.dlcall;
|
||||
var (invoke_i,invoke_ii,invoke_iii)=(
|
||||
dylib.limitcall(1),
|
||||
dylib.limitcall(2),
|
||||
dylib.limitcall(3)
|
||||
);
|
||||
return {
|
||||
vec2:{
|
||||
new:func(x,y){return call(vec2,x,y);},
|
||||
add:func(v0,v1){return call(vec2add,v0,v1);},
|
||||
sub:func(v0,v1){return call(vec2sub,v0,v1);},
|
||||
mul:func(v0,v1){return call(vec2mul,v0,v1);},
|
||||
div:func(v0,v1){return call(vec2div,v0,v1);},
|
||||
neg:func(v0){return call(vec2neg,v0);},
|
||||
norm:func(v0){return call(vec2norm,v0);},
|
||||
len:func(v0){return call(vec2len,v0);},
|
||||
dot:func(v0,v1){return call(vec2dot,v0,v1);}
|
||||
new: func(x,y){return invoke_ii(vec2,x,y);},
|
||||
add: func(v0,v1){return invoke_ii(vec2add,v0,v1);},
|
||||
sub: func(v0,v1){return invoke_ii(vec2sub,v0,v1);},
|
||||
mul: func(v0,v1){return invoke_ii(vec2mul,v0,v1);},
|
||||
div: func(v0,v1){return invoke_ii(vec2div,v0,v1);},
|
||||
neg: func(v0){return invoke_i(vec2neg,v0);},
|
||||
norm: func(v0){return invoke_i(vec2norm,v0);},
|
||||
len: func(v0){return invoke_i(vec2len,v0);},
|
||||
dot: func(v0,v1){return invoke_ii(vec2dot,v0,v1);}
|
||||
},
|
||||
vec3:{
|
||||
new:func(x,y,z){return call(vec3,x,y,z);},
|
||||
add:func(v0,v1){return call(vec3add,v0,v1);},
|
||||
sub:func(v0,v1){return call(vec3sub,v0,v1);},
|
||||
mul:func(v0,v1){return call(vec3mul,v0,v1);},
|
||||
div:func(v0,v1){return call(vec3div,v0,v1);},
|
||||
neg:func(v0){return call(vec3neg,v0);},
|
||||
norm:func(v0){return call(vec3norm,v0);},
|
||||
len:func(v0){return call(vec3len,v0);},
|
||||
rx:func(v0,angle){return call(rotate_x,v0,angle);},
|
||||
ry:func(v0,angle){return call(rotate_y,v0,angle);},
|
||||
rz:func(v0,angle){return call(rotate_z,v0,angle);},
|
||||
dot:func(v0,v1){return call(vec3dot,v0,v1);}
|
||||
new: func(x,y,z){return invoke_iii(vec3,x,y,z);},
|
||||
add: func(v0,v1){return invoke_ii(vec3add,v0,v1);},
|
||||
sub: func(v0,v1){return invoke_ii(vec3sub,v0,v1);},
|
||||
mul: func(v0,v1){return invoke_ii(vec3mul,v0,v1);},
|
||||
div: func(v0,v1){return invoke_ii(vec3div,v0,v1);},
|
||||
neg: func(v0){return invoke_i(vec3neg,v0);},
|
||||
norm: func(v0){return invoke_i(vec3norm,v0);},
|
||||
len: func(v0){return invoke_i(vec3len,v0);},
|
||||
rx: func(v0,angle){return invoke_ii(rotate_x,v0,angle);},
|
||||
ry: func(v0,angle){return invoke_ii(rotate_y,v0,angle);},
|
||||
rz: func(v0,angle){return invoke_ii(rotate_z,v0,angle);},
|
||||
dot: func(v0,v1){return invoke_ii(vec3dot,v0,v1);}
|
||||
}
|
||||
};
|
||||
}();
|
|
@ -1,5 +1,6 @@
|
|||
var socket=func(){
|
||||
var lib=dylib.dlopen("libnasock"~(os.platform()=="windows"?".dll":".so"));
|
||||
|
||||
var sock=dylib.dlsym(lib,"nas_socket");
|
||||
var closesocket=dylib.dlsym(lib,"nas_closesocket");
|
||||
var shutdown=dylib.dlsym(lib,"nas_shutdown");
|
||||
|
@ -12,17 +13,46 @@ var socket=func(){
|
|||
var recv=dylib.dlsym(lib,"nas_recv");
|
||||
var recvfrom=dylib.dlsym(lib,"nas_recvfrom");
|
||||
var errno=dylib.dlsym(lib,"nas_errno");
|
||||
var call=dylib.dlcall;
|
||||
|
||||
var (invoke,invoke_i,invoke_ii,invoke_iii,invoke_iiii,invoke_iiiii)=(
|
||||
dylib.limitcall(0),
|
||||
dylib.limitcall(1),
|
||||
dylib.limitcall(2),
|
||||
dylib.limitcall(3),
|
||||
dylib.limitcall(4),
|
||||
dylib.limitcall(5),
|
||||
);
|
||||
return {
|
||||
AF_UNSPEC:0,AF_UNIX:1,AF_INET:2,AF_IMPLINK:3,
|
||||
AF_PUP:4,AF_CHAOS:5,AF_IPX:6,AF_NS:6,
|
||||
AF_ISO:7,AF_OSI:7,AF_ECMA:8,AF_DATAKIT:9,
|
||||
AF_CCITT:10,AF_SNA:11,AF_DECnet:12,AF_DLI:13,
|
||||
AF_LAT:14,AF_HYLINK:15,AF_APPLETALK:16,AF_NETBIOS:17,
|
||||
AF_VOICEVIEW:18,AF_FIREFOX:19,AF_UNKNOWN1:20,AF_BAN:21,
|
||||
AF_UNSPEC:0,
|
||||
AF_UNIX:1,
|
||||
AF_INET:2,
|
||||
AF_IMPLINK:3,
|
||||
AF_PUP:4,
|
||||
AF_CHAOS:5,
|
||||
AF_IPX:6,
|
||||
AF_NS:6,
|
||||
AF_ISO:7,
|
||||
AF_OSI:7,
|
||||
AF_ECMA:8,
|
||||
AF_DATAKIT:9,
|
||||
AF_CCITT:10,
|
||||
AF_SNA:11,
|
||||
AF_DECnet:12,
|
||||
AF_DLI:13,
|
||||
AF_LAT:14,
|
||||
AF_HYLINK:15,
|
||||
AF_APPLETALK:16,
|
||||
AF_NETBIOS:17,
|
||||
AF_VOICEVIEW:18,
|
||||
AF_FIREFOX:19,
|
||||
AF_UNKNOWN1:20,
|
||||
AF_BAN:21,
|
||||
AF_MAX:22,
|
||||
|
||||
SOCK_STREAM:1,SOCK_DGRAM:2,SOCK_RAW:3,SOCK_RDM:4,
|
||||
SOCK_STREAM:1,
|
||||
SOCK_DGRAM:2,
|
||||
SOCK_RAW:3,
|
||||
SOCK_RDM:4,
|
||||
SOCK_SEQPACKET:5,
|
||||
|
||||
IPPROTO_IP:0,IPPROTO_ICMP:1,IPPROTO_IGMP:2,IPPROTO_GGP:3,
|
||||
|
@ -46,40 +76,40 @@ var socket=func(){
|
|||
MSG_DONTROUTE:0x4,
|
||||
|
||||
socket:func(af,type,proto){
|
||||
return call(sock,af,type,proto);
|
||||
return invoke_iii(sock,af,type,proto);
|
||||
},
|
||||
closesocket:func(sd){
|
||||
return call(closesocket,sd);
|
||||
return invoke_i(closesocket,sd);
|
||||
},
|
||||
shutdown: func(sd,how){
|
||||
return call(shutdown,sd,how);
|
||||
return invoke_ii(shutdown,sd,how);
|
||||
},
|
||||
bind: func(sd,ip,port){
|
||||
return call(bind,sd,ip,port);
|
||||
return invoke_iii(bind,sd,ip,port);
|
||||
},
|
||||
listen: func(sd,backlog){
|
||||
return call(listen,sd,backlog);
|
||||
return invoke_ii(listen,sd,backlog);
|
||||
},
|
||||
connect: func(sd,hostname,port){
|
||||
return call(connect,sd,hostname,port);
|
||||
return invoke_iii(connect,sd,hostname,port);
|
||||
},
|
||||
accept: func(sd){
|
||||
return call(accept,sd);
|
||||
return invoke_i(accept,sd);
|
||||
},
|
||||
send: func(sd,buff,flags=0){
|
||||
return call(send,sd,buff,flags);
|
||||
return invoke_iii(send,sd,buff,flags);
|
||||
},
|
||||
sendto: func(sd,hostname,port,buff,flags=0){
|
||||
return call(sendto,sd,hostname,port,buff,flags);
|
||||
return invoke_iiiii(sendto,sd,hostname,port,buff,flags);
|
||||
},
|
||||
recv: func(sd,len,flags=0){
|
||||
return call(recv,sd,len,flags);
|
||||
return invoke_iii(recv,sd,len,flags);
|
||||
},
|
||||
recvfrom: func(sd,len,flags=0){
|
||||
return call(recvfrom,sd,len,flags);
|
||||
return invoke_iii(recvfrom,sd,len,flags);
|
||||
},
|
||||
errno: func(){
|
||||
return call(errno);
|
||||
return invoke(errno);
|
||||
}
|
||||
};
|
||||
}();
|
|
@ -5,6 +5,11 @@ dynamic_libs_dll=libfib.dll libkey.dll libnasock.dll libmat.dll
|
|||
|
||||
STD=c++14
|
||||
|
||||
all: $(dynamic_libs_so)
|
||||
@ echo "[Compiling] done"
|
||||
winall: $(dynamic_libs_dll)
|
||||
@ echo [Compiling] done
|
||||
|
||||
libfib.so: fib.cpp
|
||||
@ echo "[Compiling] libfib.so"
|
||||
@ $(CXX) -std=$(STD) -c -O3 fib.cpp -fPIC -o fib.o
|
||||
|
@ -54,8 +59,3 @@ clean:
|
|||
-@ rm $(dynamic_libs_so)
|
||||
@ echo "[clean] dll"
|
||||
-@ rm $(dynamic_libs_dll)
|
||||
|
||||
all: $(dynamic_libs_so)
|
||||
@ echo "[Compiling] done"
|
||||
winall: $(dynamic_libs_dll)
|
||||
@ echo [Compiling] done
|
||||
|
|
|
@ -964,7 +964,7 @@ var builtin_dlclose(var* local,gc& ngc)
|
|||
return nil;
|
||||
}
|
||||
|
||||
var builtin_dlcall(var* local,gc& ngc)
|
||||
var builtin_dlcallv(var* local,gc& ngc)
|
||||
{
|
||||
var fp=local[1];
|
||||
var args=local[2];
|
||||
|
@ -974,6 +974,15 @@ var builtin_dlcall(var* local,gc& ngc)
|
|||
return ((mod)fp.obj().ptr)(vec.data(),vec.size(),&ngc);
|
||||
}
|
||||
|
||||
var builtin_dlcall(var* local,gc& ngc)
|
||||
{
|
||||
var fp=local[1];
|
||||
if(!fp.objchk(nas_obj::faddr))
|
||||
return nas_err("dlcall","\"ptr\" is not a valid function pointer");
|
||||
// arguments' stored place begins at local +2
|
||||
return ((mod)fp.obj().ptr)(local+2,ngc.top-local-2,&ngc);
|
||||
}
|
||||
|
||||
var builtin_platform(var* local,gc& ngc)
|
||||
{
|
||||
#if defined _WIN32 || defined _WIN64
|
||||
|
@ -1282,6 +1291,7 @@ struct
|
|||
{"__dlopen", builtin_dlopen },
|
||||
{"__dlsym", builtin_dlsym },
|
||||
{"__dlclose", builtin_dlclose },
|
||||
{"__dlcallv", builtin_dlcallv },
|
||||
{"__dlcall", builtin_dlcall },
|
||||
{"__platform",builtin_platform},
|
||||
{"__md5", builtin_md5 },
|
||||
|
|
|
@ -706,11 +706,8 @@ inline void vm::o_callfv()
|
|||
for(u32 i=psize;i<argc;++i)
|
||||
dynamic.vec().elems.push_back(local[i]);
|
||||
}
|
||||
#ifdef _MSC_VER
|
||||
u32 min_size=(std::min)(psize,argc);
|
||||
#else
|
||||
u32 min_size=std::min(psize,argc);
|
||||
#endif
|
||||
|
||||
u32 min_size=(std::min)(psize,argc); // avoid error in MSVC
|
||||
for(u32 i=min_size;i>=1;--i)// load arguments
|
||||
local[i]=local[i-1];
|
||||
local[0]=func.local[0];// load "me"
|
||||
|
|
39
stl/lib.nas
39
stl/lib.nas
|
@ -280,8 +280,7 @@ var md5=func(str){
|
|||
return __md5(str);
|
||||
}
|
||||
|
||||
var io=
|
||||
{
|
||||
var io={
|
||||
SEEK_SET:0,
|
||||
SEEK_CUR:1,
|
||||
SEEK_END:2,
|
||||
|
@ -333,8 +332,7 @@ var fstat=func(filename){
|
|||
|
||||
# functions that do bitwise calculation.
|
||||
# carefully use it, all the calculations are based on integer.
|
||||
var bits=
|
||||
{
|
||||
var bits={
|
||||
# i32 xor
|
||||
i32_xor: func(a,b){return __i32xor(a,b); },
|
||||
# i32 and
|
||||
|
@ -378,8 +376,7 @@ var bits=
|
|||
};
|
||||
|
||||
# mostly used math functions and special constants, you know.
|
||||
var math=
|
||||
{
|
||||
var math={
|
||||
e: 2.7182818284590452354,
|
||||
pi: 3.14159265358979323846264338327950288,
|
||||
D2R: 2.7182818284590452354/180,
|
||||
|
@ -402,8 +399,7 @@ var math=
|
|||
min: func(x,y){return x<y?x:y; }
|
||||
};
|
||||
|
||||
var unix=
|
||||
{
|
||||
var unix={
|
||||
pipe: func(){return __pipe;},
|
||||
fork: func(){return __fork;},
|
||||
dup2: func(fd0,fd1){die("not supported yet");},
|
||||
|
@ -425,8 +421,7 @@ var unix=
|
|||
|
||||
# dylib is the core hashmap for developers to load their own library.
|
||||
# for safe using dynamic library, you could use 'module' in stl/module.nas
|
||||
var dylib=
|
||||
{
|
||||
var dylib={
|
||||
# open dynamic lib.
|
||||
dlopen: func(libname){
|
||||
# find dynamic lib from local dir first
|
||||
|
@ -451,22 +446,34 @@ var dylib=
|
|||
dlsym: func(lib,sym){return __dlsym; },
|
||||
# close dynamic lib, this operation will make all the symbols loaded from it invalid.
|
||||
dlclose: func(lib){return __dlclose; },
|
||||
# call the loaded symbol.
|
||||
dlcall: func(ptr,args...){return __dlcall}
|
||||
# call the loaded symbol, with infinite parameters:
|
||||
# Caution: this may cause garbage collection process, be aware of the performance.
|
||||
dlcall: func(ptr,args...){return __dlcallv},
|
||||
# get dlcall function with limited parameter list
|
||||
limitcall: func(arg_size=0){
|
||||
if(arg_size==0){return func(ptr){return __dlcall};}
|
||||
else if(arg_size==1){return func(ptr,_0){return __dlcall};}
|
||||
else if(arg_size==2){return func(ptr,_0,_1){return __dlcall};}
|
||||
else if(arg_size==3){return func(ptr,_0,_1,_2){return __dlcall};}
|
||||
else if(arg_size==4){return func(ptr,_0,_1,_2,_3){return __dlcall};}
|
||||
else if(arg_size==5){return func(ptr,_0,_1,_2,_3,_4){return __dlcall};}
|
||||
else if(arg_size==6){return func(ptr,_0,_1,_2,_3,_4,_5){return __dlcall};}
|
||||
else if(arg_size==7){return func(ptr,_0,_1,_2,_3,_4,_5,_6){return __dlcall};}
|
||||
else if(arg_size==8){return func(ptr,_0,_1,_2,_3,_4,_5,_6,_7){return __dlcall};}
|
||||
else{return func(ptr,args...){return __dlcallv};}
|
||||
}
|
||||
};
|
||||
|
||||
# os is used to use or get some os-related info/functions.
|
||||
# windows/macOS/linux are supported.
|
||||
var os=
|
||||
{
|
||||
var os={
|
||||
# get a string that tell which os it runs on.
|
||||
platform: func(){return __platform;},
|
||||
time: func(){return __logtime; }
|
||||
};
|
||||
|
||||
# runtime gives us some functions that we could manage it manually.
|
||||
var runtime=
|
||||
{
|
||||
var runtime={
|
||||
# command line arguments
|
||||
argv: func(){return __sysargv;}
|
||||
};
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
# all the invalid functions cannot be called
|
||||
|
||||
var module_call_func=func(fptr,args){
|
||||
return __dlcall;
|
||||
return __dlcallv;
|
||||
}
|
||||
var extern={
|
||||
new: func(fptr){
|
||||
|
@ -14,9 +14,7 @@ var extern={
|
|||
return {
|
||||
close:func(){isopen=0;},
|
||||
call:func(args...){
|
||||
return (!isopen)?
|
||||
nil:
|
||||
module_call_func(fptr,args);
|
||||
return isopen?module_call_func(fptr,args):nil;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
var libfib=func(){
|
||||
var (dd,fib,qfib)=(nil,nil,nil);
|
||||
var invoke=dylib.limitcall(1);
|
||||
return {
|
||||
open:func(){
|
||||
if(dd==nil){
|
||||
|
@ -20,13 +21,13 @@ var libfib=func(){
|
|||
},
|
||||
fib:func(x){
|
||||
if(fib!=nil)
|
||||
return dylib.dlcall(fib,x);
|
||||
return invoke(fib,x);
|
||||
println("[error ] cannot call fib.");
|
||||
return nil;
|
||||
},
|
||||
qfib:func(x){
|
||||
if(qfib!=nil)
|
||||
return dylib.dlcall(qfib,x);
|
||||
return invoke(qfib,x);
|
||||
println("[error ] cannot call qfib.");
|
||||
return nil;
|
||||
}
|
||||
|
@ -36,9 +37,33 @@ var libfib=func(){
|
|||
println("[keys ] ",keys(libfib));
|
||||
libfib.open();
|
||||
libfib.open();
|
||||
var tm=maketimestamp();
|
||||
tm.stamp();
|
||||
println("[result] ",libfib.fib(40));
|
||||
println("[time ] ",tm.elapsedMSec()," ms");
|
||||
tm.stamp();
|
||||
println("[result] ",libfib.qfib(40));
|
||||
println("[time ] ",tm.elapsedMSec()," ms");
|
||||
libfib.close();
|
||||
println("[result] ",libfib.fib(40));
|
||||
println("[result] ",libfib.qfib(40));
|
||||
libfib.close();
|
||||
libfib.close();
|
||||
|
||||
var speed_test=func(){
|
||||
var d=dylib.dlopen("libfib."~(os.platform()=="windows"?"dll":"so"));
|
||||
var fd=dylib.dlsym(d,"quick_fib");
|
||||
var vec_call=dylib.dlcall;
|
||||
var invoke=dylib.limitcall(1);
|
||||
|
||||
var tm=maketimestamp();
|
||||
tm.stamp();
|
||||
for(var i=0;i<1e7;i+=1)
|
||||
invoke(fd,40);
|
||||
println("[time ] limited call: ",tm.elapsedMSec()," ms");
|
||||
tm.stamp();
|
||||
for(var i=0;i<1e7;i+=1)
|
||||
vec_call(fd,40);
|
||||
println("[time ] dynamic call: ",tm.elapsedMSec()," ms");
|
||||
}
|
||||
|
||||
speed_test();
|
Loading…
Reference in New Issue