diff --git a/lib.nas b/lib.nas index f10a161..9a5f952 100644 --- a/lib.nas +++ b/lib.nas @@ -284,6 +284,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= { # open dynamic lib. diff --git a/module/fib.cpp b/module/fib.cpp index 9728b74..a3e2b53 100644 --- a/module/fib.cpp +++ b/module/fib.cpp @@ -8,6 +8,8 @@ double fibonaci(double x){ } extern "C" nasal_ref fib(std::vector& args,nasal_gc& gc){ std::cout<<"[mod] this is the first test module of nasal\n"; + if(!args.size()) + return builtin_err("fib","lack arguments"); nasal_ref num=args[0]; if(num.type!=vm_num) return builtin_err("extern_fib","\"num\" must be number"); @@ -15,6 +17,8 @@ extern "C" nasal_ref fib(std::vector& args,nasal_gc& gc){ } extern "C" nasal_ref quick_fib(std::vector& args,nasal_gc& gc){ std::cout<<"[mod] this is the first test module of nasal\n"; + if(!args.size()) + return builtin_err("fib","lack arguments"); nasal_ref num=args[0]; if(num.type!=vm_num) return builtin_err("extern_quick_fib","\"num\" must be number"); diff --git a/nasal_builtin.h b/nasal_builtin.h index 50f7b24..7004fc9 100644 --- a/nasal_builtin.h +++ b/nasal_builtin.h @@ -5,6 +5,7 @@ #include #define environ (*_NSGetEnviron()) #endif + /* builtin functions must be called inside a function like this: var print=func(elems...){ diff --git a/nasal_gc.h b/nasal_gc.h index 3193922..1a7fe3a 100644 --- a/nasal_gc.h +++ b/nasal_gc.h @@ -137,8 +137,16 @@ struct nasal_obj { uint32_t type; void* ptr; - nasal_obj():ptr(nullptr){} - void clear(){ptr=nullptr;} + void* destructor; + nasal_obj():ptr(nullptr),destructor(nullptr){} + ~nasal_obj(){clear();} + void clear() + { + typedef void (*func)(void*); + if(destructor) + (func(destructor))(ptr); + ptr=nullptr; + } }; const uint8_t GC_UNCOLLECTED=0; diff --git a/stl/lib.nas b/stl/lib.nas index f10a161..9a5f952 100644 --- a/stl/lib.nas +++ b/stl/lib.nas @@ -284,6 +284,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= { # open dynamic lib. diff --git a/stl/module.nas b/stl/module.nas new file mode 100644 index 0000000..e6c8636 --- /dev/null +++ b/stl/module.nas @@ -0,0 +1,45 @@ +# lib module.nas +# ValKmjolnir 2022/3/5 + +# this provides safe usage of dylib +# when dylib is closed, +# all the invalid functions cannot be called +import("lib.nas"); + +var module_call_func=func(fptr,args){ + return __builtin_dlcall; +} +var extern={ + new: func(fptr){ + return { + fptr:fptr, + isopen:1, + parents:[extern] + }; + }, + call: func(args...){ + return (!me.isopen)?nil:module_call_func(me.fptr,args); + } +}; +var module={ + new: func(name){ + return { + name:name, + lib:dylib.dlopen(name), + f:{}, + parents:[module] + }; + }, + get: func(symbol){ + if(contains(me.f,symbol)) + return me.f[symbol]; + var f=extern.new(dylib.dlsym(me.lib,symbol)); + me.f[symbol]=f; + return f; + }, + close: func(){ + foreach(var i;keys(me.f)) + me.f[i].isopen=0; + dylib.dlclose(me.lib); + } +}; \ No newline at end of file