add dylib.dlopen dylib.dlsym dylib.dlclose dylib.dlcall
now you could add your own modules into nasal without changing the source code!
This commit is contained in:
parent
aa191a9feb
commit
9861ecd03e
303
README.md
303
README.md
|
@ -889,7 +889,7 @@ a.set(114514);
|
|||
println(a.get());
|
||||
```
|
||||
|
||||
### __Native Functions(This is for library developers)__
|
||||
### __Native Functions__
|
||||
|
||||
You could add builtin functions of your own
|
||||
(written in C/C++) to help you calculate things more quickly.
|
||||
|
@ -1010,6 +1010,126 @@ nasal_ref builtin_keys(std::vector<nasal_ref>& local,nasal_gc& gc)
|
|||
}
|
||||
```
|
||||
|
||||
### __Modules(This is for library developers)__
|
||||
|
||||
If there is only one way to add your own functions into nasal,
|
||||
that is really inconvenient.
|
||||
|
||||
Luckily, we have developed some useful native-functions to help you add modules that created by you.
|
||||
|
||||
After 2021/12/3, there are some new functions added to `lib.nas`:
|
||||
|
||||
```javascript
|
||||
var dylib=
|
||||
{
|
||||
dlopen: func(libname){return __builtin_dlopen;},
|
||||
dlsym: func(lib,sym){return __builtin_dlsym; },
|
||||
dlclose: func(lib){return __builtin_dlclose; },
|
||||
dlcall: func(funcptr,args...){return __builtin_dlcall}
|
||||
};
|
||||
```
|
||||
|
||||
Aha, as you could see, these functions are used to load dynamic libraries into the nasal runtime and execute.
|
||||
Let's see how they work.
|
||||
|
||||
First, write a cpp file that you want to generate the dynamic lib, take the `fib.cpp` as the example(example codes are in `./module`):
|
||||
|
||||
```C++
|
||||
// add header file nasal.h to get api
|
||||
#include "nasal.h"
|
||||
double fibonaci(double x){
|
||||
if(x<=2)
|
||||
return x;
|
||||
return fibonaci(x-1)+fibonaci(x-2);
|
||||
}
|
||||
// remember to use extern "C",
|
||||
// so you could search the symbol quickly
|
||||
extern "C" nasal_ref fib(std::vector<nasal_ref>& args,nasal_gc& gc){
|
||||
// the arguments are generated into a vm_vec: args
|
||||
// get values from the vector that must be used here
|
||||
nasal_ref num=args[0];
|
||||
// if you want your function safer, try this
|
||||
// builtin_err will print the error info on screen
|
||||
// and return vm_null for runtime to interrupt
|
||||
if(num.type!=vm_num)
|
||||
return builtin_err("extern_fib","\"num\" must be number");
|
||||
// ok, you must know that vm_num now is not managed by gc
|
||||
// if want to return a gc object, use gc.alloc(type)
|
||||
// usage of gc is the same as adding a native function
|
||||
return {vm_num,fibonaci(num.to_number())};
|
||||
}
|
||||
```
|
||||
|
||||
Next, compile this `fib.cpp` into dynamic lib.
|
||||
|
||||
Linux(`.so`):
|
||||
|
||||
`clang++ -c -O3 fib.cpp -fPIC -o fib.o`
|
||||
|
||||
`clang++ -shared -o libfib.so fib.o`
|
||||
|
||||
Mac: same as Linux, but remember to generate `.dylib`
|
||||
|
||||
Windows(`.dll`):
|
||||
|
||||
`g++ -c -O3 fib.cpp -fPIC -o fib.o`
|
||||
|
||||
`g++ -shared -o libfib.dll fib.o`
|
||||
|
||||
Then we write a test nasal file to run this fib function, this example runs on Linux:
|
||||
|
||||
```javascript
|
||||
import("lib.nas");
|
||||
var dlhandle=dylib.dlopen("./module/libfib.so");
|
||||
var fib=dylib.dlsym(dlhandle,"fib");
|
||||
for(var i=1;i<30;i+=1)
|
||||
println(dylib.dlcall(fib,i));
|
||||
dylib.dlclose(dlhandle);
|
||||
```
|
||||
|
||||
`dylib.dlopen` is used to load dynamic library.
|
||||
|
||||
`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.dlclose` is used to unload the library, at the moment that you call the function, all the function addresses that gotten from it are invalid.
|
||||
|
||||
If get this, Congratulations!
|
||||
|
||||
```bash
|
||||
./nasal a.nas
|
||||
1
|
||||
2
|
||||
3
|
||||
5
|
||||
8
|
||||
13
|
||||
21
|
||||
34
|
||||
55
|
||||
89
|
||||
144
|
||||
233
|
||||
377
|
||||
610
|
||||
987
|
||||
1597
|
||||
2584
|
||||
4181
|
||||
6765
|
||||
10946
|
||||
17711
|
||||
28657
|
||||
46368
|
||||
75025
|
||||
121393
|
||||
196418
|
||||
317811
|
||||
514229
|
||||
832040
|
||||
```
|
||||
|
||||
## Difference Between Andy's Nasal Interpreter and This Interpreter
|
||||
|
||||
This interpreter uses more strict syntax to make sure it is easier for you to program and debug.
|
||||
|
@ -1098,22 +1218,17 @@ Function 'die' is used to throw error and crash.
|
|||
```javascript
|
||||
hello
|
||||
[vm] error: error occurred this line
|
||||
[vm] error at 0x0000009b: native function error.
|
||||
[vm] native function error.
|
||||
trace back:
|
||||
0x0000009b: callb 0x22 <__builtin_die> (lib.nas line 85)
|
||||
0x00000182: callfv 0x1 (a.nas line 6)
|
||||
0x00000186: callfv 0x0 (a.nas line 8)
|
||||
vm stack(limit 10):
|
||||
null |
|
||||
func | <0x8b0f50> func{entry=0x9b}
|
||||
func | <0x8b1db0> func{entry=0x17c}
|
||||
num | 57.295780
|
||||
num | 1852.000000
|
||||
num | 1.943800
|
||||
num | 0.000540
|
||||
num | 39.370100
|
||||
num | 3.280800
|
||||
num | 0.453600
|
||||
0x00000088: callb 0x22 <__builtin_die@0x417620> (<lib.nas> line 19)
|
||||
0x000002af: callfv 0x1 (<a.nas> line 5)
|
||||
0x000002b3: callfv 0x0 (<a.nas> line 7)
|
||||
vm stack(limit 10, total 5):
|
||||
| null |
|
||||
| addr | 0x2af
|
||||
| func | <0x6c62c0> func{entry=0x88}
|
||||
| addr | 0x2b3
|
||||
| func | <0x6c8910> func{entry=0x2a9}
|
||||
```
|
||||
|
||||
Here is an example of stack overflow:
|
||||
|
@ -1133,13 +1248,22 @@ And the trace back info:
|
|||
```javascript
|
||||
[vm] stack overflow
|
||||
trace back:
|
||||
0x0000000f: callfv 0x1 (a.nas line 5)
|
||||
0x0000000f: 4090 same call(s) ...
|
||||
0x00000007: callfv 0x1 (a.nas line 2)
|
||||
0x00000013: callfv 0x1 (a.nas line 3)
|
||||
vm stack(limit 10):
|
||||
func | <0xc511e0> func{entry=0xd}
|
||||
... | 9 same value(s)
|
||||
0x0000000d: calll 0x1 (<a.nas> line 5)
|
||||
0x0000000f: callfv 0x1 (<a.nas> line 5)
|
||||
0x0000000f: 2044 same call(s)
|
||||
0x00000007: callfv 0x1 (<a.nas> line 2)
|
||||
0x00000013: callfv 0x1 (<a.nas> line 3)
|
||||
vm stack(limit 10, total 4095):
|
||||
| func | <0x24f1f10> func{entry=0xd}
|
||||
| addr | 0xf
|
||||
| func | <0x24f1f10> func{entry=0xd}
|
||||
| addr | 0xf
|
||||
| func | <0x24f1f10> func{entry=0xd}
|
||||
| addr | 0xf
|
||||
| func | <0x24f1f10> func{entry=0xd}
|
||||
| addr | 0xf
|
||||
| func | <0x24f1f10> func{entry=0xd}
|
||||
| addr | 0xf
|
||||
```
|
||||
|
||||
Error will be thrown if there's a fatal error when executing:
|
||||
|
@ -1153,11 +1277,11 @@ func(){
|
|||
And the trace back info:
|
||||
|
||||
```javascript
|
||||
[vm] error at 0x00000008: callv: must call a vector/hash/string
|
||||
[vm] callv: must call a vector/hash/string
|
||||
trace back:
|
||||
0x00000008: callv 0x0 (a.nas line 3)
|
||||
vm stack(limit 10):
|
||||
num | 0.000000
|
||||
0x00000008: callv 0x0 (<a.nas> line 3)
|
||||
vm stack(limit 10, total 1):
|
||||
| num | 0.000000
|
||||
```
|
||||
|
||||
Use command `-d` or `--detail` the trace back info will be this:
|
||||
|
@ -1167,67 +1291,70 @@ hello world
|
|||
[vm] error: exception test
|
||||
[vm] native function error.
|
||||
trace back:
|
||||
0x0000008f: callb 0x22 <__builtin_die> (<lib.nas> line 20)
|
||||
0x00000214: callfv 0x1 (<test/exception.nas> line 16)
|
||||
0x00000248: callfv 0x0 (<test/exception.nas> line 39)
|
||||
vm stack(limit 10):
|
||||
null |
|
||||
func | <0x23bc3f0> func{entry=0x8f}
|
||||
func | <0x23bdc50> func{entry=0x20e}
|
||||
mcall address: 0x24a4b88
|
||||
0x00000088: callb 0x22 <__builtin_die@0x417620> (<lib.nas> line 19)
|
||||
0x000002d2: callfv 0x1 (<test/exception.nas> line 16)
|
||||
0x00000306: callfv 0x0 (<test/exception.nas> line 39)
|
||||
vm stack(limit 10, total 5):
|
||||
| null |
|
||||
| addr | 0x2d2
|
||||
| func | <0x827750> func{entry=0x88}
|
||||
| addr | 0x306
|
||||
| func | <0x829ee0> func{entry=0x2cc}
|
||||
mcall address: 0x90e498
|
||||
global:
|
||||
[0] func | <0x23d3960> func{entry=0x5}
|
||||
[1] func | <0x23bb8b0> func{entry=0xc}
|
||||
[2] func | <0x23bb950> func{entry=0x14}
|
||||
[3] func | <0x23bb9f0> func{entry=0x1c}
|
||||
[4] func | <0x23bba90> func{entry=0x23}
|
||||
[5] func | <0x23bbb30> func{entry=0x29}
|
||||
[6] func | <0x23bbbd0> func{entry=0x30}
|
||||
[7] func | <0x23bbc70> func{entry=0x38}
|
||||
[8] func | <0x23bbd10> func{entry=0x40}
|
||||
[9] func | <0x23bbdb0> func{entry=0x47}
|
||||
[10] func | <0x23bbe50> func{entry=0x4e}
|
||||
[11] func | <0x23bbef0> func{entry=0x55}
|
||||
[12] func | <0x23bbf90> func{entry=0x5c}
|
||||
[13] func | <0x23bc030> func{entry=0x63}
|
||||
[14] func | <0x23bc0d0> func{entry=0x6a}
|
||||
[15] func | <0x23bc170> func{entry=0x72}
|
||||
[16] func | <0x23bc210> func{entry=0x7a}
|
||||
[17] func | <0x23bc2b0> func{entry=0x81}
|
||||
[18] func | <0x23bc350> func{entry=0x88}
|
||||
[19] func | <0x23bc3f0> func{entry=0x8f}
|
||||
[20] func | <0x23bc490> func{entry=0x96}
|
||||
[21] func | <0x23bc530> func{entry=0x9f}
|
||||
[22] func | <0x23bc5d0> func{entry=0xa7}
|
||||
[23] func | <0x23bc670> func{entry=0xaf}
|
||||
[24] func | <0x23bc710> func{entry=0xb7}
|
||||
[25] func | <0x23bc7b0> func{entry=0xbf}
|
||||
[26] func | <0x23bc850> func{entry=0xc6}
|
||||
[27] func | <0x23bc8f0> func{entry=0xcd}
|
||||
[28] hash | <0x248ae70> {14 member}
|
||||
[29] hash | <0x248aed0> {9 member}
|
||||
[30] hash | <0x248af30> {12 member}
|
||||
[31] num | 0.017453
|
||||
[32] num | 0.592500
|
||||
[33] num | 0.304800
|
||||
[34] num | 3.785400
|
||||
[35] num | 0.025400
|
||||
[36] num | 2.204600
|
||||
[37] num | 1.687800
|
||||
[38] num | 0.514400
|
||||
[39] num | 0.264200
|
||||
[40] num | 0.453600
|
||||
[41] num | 3.280800
|
||||
[42] num | 39.370100
|
||||
[43] num | 0.000540
|
||||
[44] num | 1.943800
|
||||
[45] num | 1852.000000
|
||||
[46] num | 57.295780
|
||||
[47] hash | <0x248af90> {3 member}
|
||||
[48] func | <0x23bdcf0> func{entry=0x21e}
|
||||
[49] func | <0x23bdd90> func{entry=0x22d}
|
||||
[50] func | <0x23bde30> func{entry=0x237}
|
||||
[0x00000000] | func | <0x83da50> func{entry=0x5}
|
||||
[0x00000001] | func | <0x826cb0> func{entry=0xc}
|
||||
[0x00000002] | func | <0x826d50> func{entry=0x14}
|
||||
[0x00000003] | func | <0x826df0> func{entry=0x1c}
|
||||
[0x00000004] | func | <0x826e90> func{entry=0x23}
|
||||
[0x00000005] | func | <0x826f30> func{entry=0x29}
|
||||
[0x00000006] | func | <0x826fd0> func{entry=0x31}
|
||||
[0x00000007] | func | <0x827070> func{entry=0x39}
|
||||
[0x00000008] | func | <0x827110> func{entry=0x40}
|
||||
[0x00000009] | func | <0x8271b0> func{entry=0x47}
|
||||
[0x0000000a] | func | <0x827250> func{entry=0x4e}
|
||||
[0x0000000b] | func | <0x8272f0> func{entry=0x55}
|
||||
[0x0000000c] | func | <0x827390> func{entry=0x5c}
|
||||
[0x0000000d] | func | <0x827430> func{entry=0x63}
|
||||
[0x0000000e] | func | <0x8274d0> func{entry=0x6b}
|
||||
[0x0000000f] | func | <0x827570> func{entry=0x73}
|
||||
[0x00000010] | func | <0x827610> func{entry=0x7a}
|
||||
[0x00000011] | func | <0x8276b0> func{entry=0x81}
|
||||
[0x00000012] | func | <0x827750> func{entry=0x88}
|
||||
[0x00000013] | func | <0x8277f0> func{entry=0x8f}
|
||||
[0x00000014] | func | <0x827890> func{entry=0x98}
|
||||
[0x00000015] | func | <0x827930> func{entry=0xa0}
|
||||
[0x00000016] | func | <0x8279d0> func{entry=0xa8}
|
||||
[0x00000017] | func | <0x827a70> func{entry=0xb0}
|
||||
[0x00000018] | func | <0x827b10> func{entry=0xb8}
|
||||
[0x00000019] | func | <0x827bb0> func{entry=0xbf}
|
||||
[0x0000001a] | func | <0x827c50> func{entry=0xc6}
|
||||
[0x0000001b] | hash | <0x8f4ce0> {14 member}
|
||||
[0x0000001c] | hash | <0x8f4d40> {9 member}
|
||||
[0x0000001d] | hash | <0x8f4da0> {13 member}
|
||||
[0x0000001e] | num | 0.017453
|
||||
[0x0000001f] | num | 0.592500
|
||||
[0x00000020] | num | 0.304800
|
||||
[0x00000021] | num | 3.785400
|
||||
[0x00000022] | num | 0.025400
|
||||
[0x00000023] | num | 2.204600
|
||||
[0x00000024] | num | 1.687800
|
||||
[0x00000025] | num | 0.514400
|
||||
[0x00000026] | num | 0.264200
|
||||
[0x00000027] | num | 0.453600
|
||||
[0x00000028] | num | 3.280800
|
||||
[0x00000029] | num | 39.370100
|
||||
[0x0000002a] | num | 0.000540
|
||||
[0x0000002b] | num | 1.943800
|
||||
[0x0000002c] | num | 1852.000000
|
||||
[0x0000002d] | num | 57.295780
|
||||
[0x0000002e] | hash | <0x8f4e00> {16 member}
|
||||
[0x0000002f] | hash | <0x8f4e60> {4 member}
|
||||
[0x00000030] | hash | <0x8f4ec0> {3 member}
|
||||
[0x00000031] | func | <0x829f80> func{entry=0x2dc}
|
||||
[0x00000032] | func | <0x82a020> func{entry=0x2eb}
|
||||
[0x00000033] | func | <0x82a0c0> func{entry=0x2f5}
|
||||
local:
|
||||
[0] nil |
|
||||
[1] str | <0x249abd0> exception test
|
||||
[0x00000000] | nil |
|
||||
[0x00000001] | str | <0x9057f0> exception test
|
||||
```
|
||||
|
|
12
lib.nas
12
lib.nas
|
@ -65,6 +65,8 @@ var math=
|
|||
{
|
||||
e: 2.7182818284590452354,
|
||||
pi: 3.14159265358979323846264338327950288,
|
||||
inf: 1/0,
|
||||
nan: 0/0,
|
||||
sin: func(x) {return __builtin_sin(x); },
|
||||
cos: func(x) {return __builtin_cos(x); },
|
||||
tan: func(x) {return __builtin_tan(x); },
|
||||
|
@ -73,8 +75,6 @@ var math=
|
|||
ln: func(x) {return __builtin_ln(x); },
|
||||
sqrt: func(x) {return __builtin_sqrt(x); },
|
||||
atan2: func(x,y){return __builtin_atan2(x,y);},
|
||||
inf: 1/0,
|
||||
nan: 0/0,
|
||||
isnan: func(x) {return __builtin_isnan(x); }
|
||||
};
|
||||
var D2R=math.pi/180;
|
||||
|
@ -112,4 +112,12 @@ var unix=
|
|||
environ: func(){die("not supported yet");},
|
||||
getcwd: func(){return __builtin_getcwd();},
|
||||
getenv: func(envvar){return __builtin_getenv(envvar);}
|
||||
};
|
||||
|
||||
var dylib=
|
||||
{
|
||||
dlopen: func(libname){return __builtin_dlopen;},
|
||||
dlsym: func(lib,sym){return __builtin_dlsym; },
|
||||
dlclose: func(lib){return __builtin_dlclose; },
|
||||
dlcall: func(funcptr,args...){return __builtin_dlcall}
|
||||
};
|
2
makefile
2
makefile
|
@ -1,6 +1,6 @@
|
|||
.PHONY=test
|
||||
nasal:main.cpp nasal_ast.h nasal_builtin.h nasal_codegen.h nasal_gc.h nasal_import.h nasal_lexer.h nasal_parse.h nasal_vm.h nasal.h
|
||||
clang++ -std=c++11 -O3 main.cpp -o nasal -fno-exceptions -Wshadow -Wall
|
||||
clang++ -std=c++11 -O3 main.cpp -o nasal -fno-exceptions -ldl -Wshadow -Wall
|
||||
test:nasal
|
||||
./nasal test/ascii-art.nas
|
||||
./nasal -c test/bf.nas
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
#include "../nasal.h"
|
||||
|
||||
double fibonaci(double x){
|
||||
if(x<=2)
|
||||
return x;
|
||||
return fibonaci(x-1)+fibonaci(x-2);
|
||||
}
|
||||
extern "C" nasal_ref fib(std::vector<nasal_ref>& args,nasal_gc& gc){
|
||||
nasal_ref num=args[0];
|
||||
if(num.type!=vm_num)
|
||||
return builtin_err("extern_fib","\"num\" must be number");
|
||||
return {vm_num,fibonaci(num.to_number())};
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
.PHONY=clean
|
||||
libfib.so: fib.cpp
|
||||
clang++ -c -O3 fib.cpp -fPIC -o fib.o
|
||||
clang++ -shared -o libfib.so fib.o
|
||||
clean:
|
||||
rm *.o *.so *.dll *.dylib
|
6
nasal.h
6
nasal.h
|
@ -23,6 +23,12 @@
|
|||
#include <fcntl.h>
|
||||
#include <dirent.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
|
||||
inline double hex_to_double(const char* str)
|
||||
{
|
||||
double ret=0;
|
||||
|
|
|
@ -11,6 +11,8 @@ enum obj_type
|
|||
{
|
||||
obj_file=1,
|
||||
obj_dir,
|
||||
obj_dylib,
|
||||
obj_extern
|
||||
};
|
||||
// declaration of builtin functions
|
||||
// to add new builtin function, declare it here and write the definition below
|
||||
|
@ -77,11 +79,15 @@ nas_native(builtin_closedir);
|
|||
nas_native(builtin_chdir);
|
||||
nas_native(builtin_getcwd);
|
||||
nas_native(builtin_getenv);
|
||||
nas_native(builtin_dlopen);
|
||||
nas_native(builtin_dlsym);
|
||||
nas_native(builtin_dlclose);
|
||||
nas_native(builtin_dlcall);
|
||||
|
||||
nasal_ref builtin_err(const char* func_name,std::string info)
|
||||
{
|
||||
std::cout<<"[vm] "<<func_name<<": "<<info<<".\n";
|
||||
return {vm_none};
|
||||
return {vm_none,nullptr};
|
||||
}
|
||||
|
||||
// register builtin function's name and it's address here in this table below
|
||||
|
@ -154,6 +160,10 @@ struct
|
|||
{"__builtin_chdir", builtin_chdir },
|
||||
{"__builtin_getcwd", builtin_getcwd },
|
||||
{"__builtin_getenv", builtin_getenv },
|
||||
{"__builtin_dlopen", builtin_dlopen },
|
||||
{"__builtin_dlsym", builtin_dlsym },
|
||||
{"__builtin_dlclose", builtin_dlclose },
|
||||
{"__builtin_dlcall", builtin_dlcall },
|
||||
{nullptr, nullptr }
|
||||
};
|
||||
|
||||
|
@ -973,4 +983,69 @@ nasal_ref builtin_getenv(std::vector<nasal_ref>& local,nasal_gc& gc)
|
|||
*str.str()=res;
|
||||
return str;
|
||||
}
|
||||
nasal_ref builtin_dlopen(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||
{
|
||||
nasal_ref dlname=local[1];
|
||||
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);
|
||||
// void* ptr=LoadLibrary(str);
|
||||
// delete []str;
|
||||
void* ptr=LoadLibrary(dlname.str()->c_str());
|
||||
#else
|
||||
void* ptr=dlopen(dlname.str()->c_str(),RTLD_LOCAL|RTLD_LAZY);
|
||||
#endif
|
||||
if(!ptr)
|
||||
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;
|
||||
return ret;
|
||||
}
|
||||
nasal_ref builtin_dlsym(std::vector<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)
|
||||
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");
|
||||
void* func=nullptr;
|
||||
#ifdef _WIN32
|
||||
func=(void*)GetProcAddress((HMODULE)libptr.obj()->ptr,sym.str()->c_str());
|
||||
#else
|
||||
func=dlsym(libptr.obj()->ptr,sym.str()->c_str());
|
||||
#endif
|
||||
if(!func)
|
||||
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;
|
||||
return ret;
|
||||
}
|
||||
nasal_ref builtin_dlclose(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||
{
|
||||
nasal_ref libptr=local[1];
|
||||
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);
|
||||
#else
|
||||
dlclose(libptr.obj()->ptr);
|
||||
#endif
|
||||
return gc.nil;
|
||||
}
|
||||
nasal_ref builtin_dlcall(std::vector<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)
|
||||
return builtin_err("dlcall","\"funcptr\" is not a correct function pointer");
|
||||
typedef nasal_ref (*extern_func)(std::vector<nasal_ref>&,nasal_gc&);
|
||||
extern_func func=(extern_func)funcptr.obj()->ptr;
|
||||
return func(args.vec()->elems,gc);
|
||||
}
|
||||
#endif
|
12
stl/lib.nas
12
stl/lib.nas
|
@ -65,6 +65,8 @@ var math=
|
|||
{
|
||||
e: 2.7182818284590452354,
|
||||
pi: 3.14159265358979323846264338327950288,
|
||||
inf: 1/0,
|
||||
nan: 0/0,
|
||||
sin: func(x) {return __builtin_sin(x); },
|
||||
cos: func(x) {return __builtin_cos(x); },
|
||||
tan: func(x) {return __builtin_tan(x); },
|
||||
|
@ -73,8 +75,6 @@ var math=
|
|||
ln: func(x) {return __builtin_ln(x); },
|
||||
sqrt: func(x) {return __builtin_sqrt(x); },
|
||||
atan2: func(x,y){return __builtin_atan2(x,y);},
|
||||
inf: 1/0,
|
||||
nan: 0/0,
|
||||
isnan: func(x) {return __builtin_isnan(x); }
|
||||
};
|
||||
var D2R=math.pi/180;
|
||||
|
@ -112,4 +112,12 @@ var unix=
|
|||
environ: func(){die("not supported yet");},
|
||||
getcwd: func(){return __builtin_getcwd();},
|
||||
getenv: func(envvar){return __builtin_getenv(envvar);}
|
||||
};
|
||||
|
||||
var dylib=
|
||||
{
|
||||
dlopen: func(libname){return __builtin_dlopen;},
|
||||
dlsym: func(lib,sym){return __builtin_dlsym; },
|
||||
dlclose: func(lib){return __builtin_dlclose; },
|
||||
dlcall: func(funcptr,args...){return __builtin_dlcall}
|
||||
};
|
Loading…
Reference in New Issue