From 774ad60c420d1b2cd4a8b7807cfc08407c216753 Mon Sep 17 00:00:00 2001 From: ValKmjolnir Date: Wed, 10 May 2023 00:48:04 +0800 Subject: [PATCH 1/6] :sparkles: add global_ghost_type_table for test --- module/fib.cpp | 2 +- module/keyboard.cpp | 2 +- module/matrix.cpp | 2 +- module/nasocket.cpp | 2 +- nasal_builtin.h | 34 +++++----- nasal_gc.h | 149 +++++++++++++++++++++----------------------- test/life.nas | 2 +- 7 files changed, 92 insertions(+), 101 deletions(-) diff --git a/module/fib.cpp b/module/fib.cpp index a65f8d6..b58ab8e 100644 --- a/module/fib.cpp +++ b/module/fib.cpp @@ -39,6 +39,6 @@ mod_func func_tbl[]={ {nullptr, nullptr}, }; -extern "C" mod_func* get() { +extern "C" mod_func* get(ghost_register_table* table) { return func_tbl; } \ No newline at end of file diff --git a/module/keyboard.cpp b/module/keyboard.cpp index 57f7f25..6736385 100644 --- a/module/keyboard.cpp +++ b/module/keyboard.cpp @@ -95,6 +95,6 @@ mod_func func_tbl[]={ {nullptr,nullptr} }; -extern "C" mod_func* get() { +extern "C" mod_func* get(ghost_register_table* table) { return func_tbl; } \ No newline at end of file diff --git a/module/matrix.cpp b/module/matrix.cpp index 9166fdc..d74431c 100644 --- a/module/matrix.cpp +++ b/module/matrix.cpp @@ -291,6 +291,6 @@ mod_func func_tbl[]={ {nullptr,nullptr} }; -extern "C" mod_func* get() { +extern "C" mod_func* get(ghost_register_table* table) { return func_tbl; } \ No newline at end of file diff --git a/module/nasocket.cpp b/module/nasocket.cpp index 3d4fa9b..3935567 100644 --- a/module/nasocket.cpp +++ b/module/nasocket.cpp @@ -206,6 +206,6 @@ mod_func func_tbl[]={ {nullptr,nullptr} }; -extern "C" mod_func* get() { +extern "C" mod_func* get(ghost_register_table* table) { return func_tbl; } \ No newline at end of file diff --git a/nasal_builtin.h b/nasal_builtin.h index e36061b..a1c6c55 100644 --- a/nasal_builtin.h +++ b/nasal_builtin.h @@ -544,13 +544,13 @@ var builtin_open(var* local, gc& ngc) { return nas_err("open", "failed to open file <"+name.str()+">"); } var ret=ngc.alloc(vm_obj); - ret.obj().set(obj_type::file, res); + ret.obj().set(ghost_file, res); return ret; } var builtin_close(var* local, gc& ngc) { var fd=local[1]; - if (!fd.objchk(obj_type::file)) { + if (!fd.objchk(ghost_file)) { return nas_err("close", "not a valid filehandle"); } fd.obj().clear(); @@ -561,7 +561,7 @@ var builtin_read(var* local, gc& ngc) { var fd=local[1]; var buf=local[2]; var len=local[3]; - if (!fd.objchk(obj_type::file)) { + if (!fd.objchk(ghost_file)) { return nas_err("read", "not a valid filehandle"); } if (buf.type!=vm_str || buf.val.gcobj->unmut) { @@ -587,7 +587,7 @@ var builtin_read(var* local, gc& ngc) { var builtin_write(var* local, gc& ngc) { var fd=local[1]; var str=local[2]; - if (!fd.objchk(obj_type::file)) { + if (!fd.objchk(ghost_file)) { return nas_err("write", "not a valid filehandle"); } if (str.type!=vm_str) { @@ -600,7 +600,7 @@ var builtin_seek(var* local, gc& ngc) { var fd=local[1]; var pos=local[2]; var whence=local[3]; - if (!fd.objchk(obj_type::file)) { + if (!fd.objchk(ghost_file)) { return nas_err("seek", "not a valid filehandle"); } return var::num((f64)fseek((FILE*)fd.obj().ptr, pos.num(), whence.num())); @@ -608,7 +608,7 @@ var builtin_seek(var* local, gc& ngc) { var builtin_tell(var* local, gc& ngc) { var fd=local[1]; - if (!fd.objchk(obj_type::file)) { + if (!fd.objchk(ghost_file)) { return nas_err("tell", "not a valid filehandle"); } return var::num((f64)ftell((FILE*)fd.obj().ptr)); @@ -616,7 +616,7 @@ var builtin_tell(var* local, gc& ngc) { var builtin_readln(var* local, gc& ngc) { var fd=local[1]; - if (!fd.objchk(obj_type::file)) { + if (!fd.objchk(ghost_file)) { return nas_err("readln", "not a valid filehandle"); } var str=ngc.alloc(vm_str); @@ -664,7 +664,7 @@ var builtin_stat(var* local, gc& ngc) { var builtin_eof(var* local, gc& ngc) { var fd=local[1]; - if (!fd.objchk(obj_type::file)) { + if (!fd.objchk(ghost_file)) { return nas_err("readln", "not a valid filehandle"); } return var::num((f64)feof((FILE*)fd.obj().ptr)); @@ -849,13 +849,13 @@ var builtin_opendir(var* local, gc& ngc) { } #endif var ret=ngc.alloc(vm_obj); - ret.obj().set(obj_type::dir,p); + ret.obj().set(ghost_dir,p); return ret; } var builtin_readdir(var* local, gc& ngc) { var handle=local[1]; - if (!handle.objchk(obj_type::dir)) { + if (!handle.objchk(ghost_dir)) { return nas_err("readdir", "not a valid dir handle"); } #ifdef _MSC_VER @@ -872,7 +872,7 @@ var builtin_readdir(var* local, gc& ngc) { var builtin_closedir(var* local, gc& ngc) { var handle=local[1]; - if (!handle.objchk(obj_type::dir)) { + if (!handle.objchk(ghost_dir)) { return nas_err("closedir", "not a valid dir handle"); } handle.obj().clear(); @@ -936,7 +936,7 @@ var builtin_dlopen(var* local, gc& ngc) { } var ret=ngc.temp=ngc.alloc(vm_hash); var lib=ngc.alloc(vm_obj); - lib.obj().set(obj_type::dylib, ptr); + lib.obj().set(ghost_dylib, ptr); ret.hash().elems["lib"]=lib; #ifdef _WIN32 @@ -948,14 +948,14 @@ var builtin_dlopen(var* local, gc& ngc) { return nas_err("dlopen", "cannot find function"); } // get function pointer by name - mod_func* tbl=(mod_func*)((getptr)func)(); + mod_func* tbl=(mod_func*)((getptr)func)(&global_ghost_type_table); if (!tbl) { return nas_err("dlopen", "failed to get module functions"); } for(u32 i=0;tbl[i].name;++i) { void* p=(void*)tbl[i].fd; var tmp=ngc.alloc(vm_obj); - tmp.obj().set(obj_type::faddr, p); + tmp.obj().set(ghost_faddr, p); ret.hash().elems[tbl[i].name]=tmp; } @@ -965,7 +965,7 @@ var builtin_dlopen(var* local, gc& ngc) { var builtin_dlclose(var* local, gc& ngc) { var libptr=local[1]; - if (!libptr.objchk(obj_type::dylib)) { + if (!libptr.objchk(ghost_dylib)) { return nas_err("dlclose", "\"lib\" is not a valid dynamic lib"); } libptr.obj().clear(); @@ -975,7 +975,7 @@ var builtin_dlclose(var* local, gc& ngc) { var builtin_dlcallv(var* local, gc& ngc) { var fp=local[1]; var args=local[2]; - if (!fp.objchk(obj_type::faddr)) { + if (!fp.objchk(ghost_faddr)) { return nas_err("dlcall", "\"ptr\" is not a valid function pointer"); } auto& vec=args.vec().elems; @@ -984,7 +984,7 @@ var builtin_dlcallv(var* local, gc& ngc) { var builtin_dlcall(var* local, gc& ngc) { var fp=local[1]; - if (!fp.objchk(obj_type::faddr)) { + if (!fp.objchk(ghost_faddr)) { return nas_err("dlcall", "\"ptr\" is not a valid function pointer"); } diff --git a/nasal_gc.h b/nasal_gc.h index 0374e6b..63f37db 100644 --- a/nasal_gc.h +++ b/nasal_gc.h @@ -43,14 +43,6 @@ enum vm_type:u8 { const u32 gc_type_size=vm_co-vm_str+1; -enum class obj_type:u32 { - null=0, - file=1, - dir, - dylib, - faddr -}; - enum class coroutine_status:u32 { suspended, running, @@ -99,7 +91,7 @@ public: // number and string can be translated to each other f64 tonum(); string tostr(); - bool objchk(obj_type); + bool objchk(usize); // create new var object static var none(); @@ -175,49 +167,76 @@ struct nas_upval { void clear() {onstk=true;elems.clear();size=0;} }; -struct ghost_info { - string name; - void (*destructor)(void*); +void file_dtor(void* ptr) { + if ((FILE*)ptr==stdin) { + return; + } + fclose((FILE*)ptr); +} + +void dir_dtor(void* ptr) { +#ifndef _MSC_VER + closedir((DIR*)ptr); +#else + FindClose(ptr); +#endif +} + +void dylib_dtor(void* ptr) { +#ifdef _WIN32 + FreeLibrary((HMODULE)ptr); +#else + dlclose(ptr); +#endif +} + +void faddr_dtor(void* ptr) {} + +usize ghost_file, ghost_dir, ghost_dylib, ghost_faddr; + +struct ghost_register_table { +private: + using dtor=void (*)(void*); + +private: + std::unordered_map mapper; + std::vector destructors; + +public: + ghost_register_table() { + ghost_file=register_ghost_type("file", file_dtor); + ghost_dir=register_ghost_type("dir", dir_dtor); + ghost_dylib=register_ghost_type("dylib", dylib_dtor); + ghost_faddr=register_ghost_type("faddr", faddr_dtor); + } + + usize register_ghost_type(const std::string& name, dtor ptr) { + if (mapper.count(name)) { + std::cerr<<"ghost type \""< ghost_register_table; +ghost_register_table global_ghost_type_table; + +struct nas_obj { +public: usize type; void* ptr; public: - nas_ghost(): type(0), ptr(nullptr) {} - ~nas_ghost() { - if (!ptr) { return; } - ghost_register_table[type].destructor(ptr); - } - - static usize regist_ghost_type(ghost_info i) { - auto res=ghost_register_table.size(); - ghost_register_table.push_back(i); - return res; - } - - const std::string& name() { - return ghost_register_table[type].name; - } -}; - -struct nas_obj { - obj_type type; - void* ptr; - -private: - /* RAII constructor, new object is initialized when creating */ - void file_dtor(); - void dir_dtor(); - void dylib_dtor(); - -public: - nas_obj(): type(obj_type::null), ptr(nullptr) {} + nas_obj(): type(0), ptr(nullptr) {} ~nas_obj() {clear();} - void set(obj_type, void*); + void set(usize, void*); void clear(); }; @@ -357,47 +376,19 @@ void nas_func::clear() { keys.clear(); } -void nas_obj::set(obj_type t, void* p) { +void nas_obj::set(usize t, void* p) { type=t; ptr=p; } void nas_obj::clear() { - if (!ptr) { + if (!ptr || !type) { return; } - switch(type) { - case obj_type::file: file_dtor(); break; - case obj_type::dir: dir_dtor(); break; - case obj_type::dylib: dylib_dtor();break; - default: break; - } + global_ghost_type_table.destructor(type)(ptr); ptr=nullptr; } -void nas_obj::file_dtor() { - if ((FILE*)ptr==stdin) { - return; - } - fclose((FILE*)ptr); -} - -void nas_obj::dir_dtor() { -#ifndef _MSC_VER - closedir((DIR*)ptr); -#else - FindClose(ptr); -#endif -} - -void nas_obj::dylib_dtor() { -#ifdef _WIN32 - FreeLibrary((HMODULE)ptr); -#else - dlclose(ptr); -#endif -} - void nas_co::clear() { for(u32 i=0;i Date: Thu, 11 May 2023 00:24:35 +0800 Subject: [PATCH 2/6] :sparkles: improve function of ghost_register_table --- CMakeLists.txt | 10 +++- module/fib.cpp | 60 ++++++++++++++++++++--- module/keyboard.cpp | 4 +- module/libfib.nas | 25 ++++++++-- module/matrix.cpp | 4 +- module/nasocket.cpp | 4 +- nasal_builtin.h | 42 ++++++++-------- nasal_gc.h | 113 +++++++++++++++++++++++++------------------- 8 files changed, 178 insertions(+), 84 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 706880d..39e57cd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,6 +9,7 @@ set(CMAKE_CXX_FLAGS_RELEASE_INIT "-Wshadow -Wall") # generate release executables set(CMAKE_BUILD_TYPE "Release") +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/module) add_library(fib SHARED ${CMAKE_SOURCE_DIR}/module/fib.cpp) target_include_directories(fib PRIVATE ${CMAKE_SOURCE_DIR}) @@ -24,4 +25,11 @@ target_include_directories(nasock PRIVATE ${CMAKE_SOURCE_DIR}) add_executable(nasal main.cpp) target_link_libraries(nasal dl) -target_include_directories(nasal PRIVATE ${CMAKE_SOURCE_DIR}) \ No newline at end of file +target_include_directories(nasal PRIVATE ${CMAKE_SOURCE_DIR}) + +add_custom_command( + TARGET nasal POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy + ${CMAKE_SOURCE_DIR}/build/nasal + ${CMAKE_SOURCE_DIR}/nasal +) \ No newline at end of file diff --git a/module/fib.cpp b/module/fib.cpp index b58ab8e..70c2219 100644 --- a/module/fib.cpp +++ b/module/fib.cpp @@ -1,6 +1,10 @@ +// module for test + #include #include "../nasal.h" +namespace nasal_fib_module { + double fibonaci(double x) { if (x<=2) { return x; @@ -33,12 +37,56 @@ var quick_fib(var* args, usize size, gc* ngc) { return var::num(res); } -mod_func func_tbl[]={ - {"fib",fib}, - {"quick_fib",quick_fib}, - {nullptr, nullptr}, +u32 ghost_for_test; + +void ghost_for_test_destructor(void* ptr) { + std::cout<<"delete "<alloc(vm_obj); + res.obj().set(ghost_for_test, new u32); + return res; +} + +var set_new_ghost(var* args, usize size, gc* ngc) { + var res=args[0]; + if (!res.objchk(ghost_for_test)) { + std::cout<<"set_new_ghost: not ghost for test type.\n"; + return nil; + } + std::cout<<"set_new_ghost: successfully set ghost.\n"; + f64 num=args[1].num(); + *((u32*)res.obj().ptr)=static_cast(num); + return nil; +} + +var print_new_ghost(var* args, usize size, gc* ngc) { + var res=args[0]; + if (!res.objchk(ghost_for_test)) { + std::cout<<"print_new_ghost: not ghost for test type.\n"; + return nil; + } + std::cout<<"print_new_ghost: result = "<<*((u32*)res.obj().ptr)<<"\n"; + return nil; +} + +module_func_info func_tbl[]={ + {"fib", fib}, + {"quick_fib", quick_fib}, + {"create_ghost", create_new_ghost}, + {"set_ghost", set_new_ghost}, + {"print_ghost", print_new_ghost}, + {nullptr, nullptr} }; -extern "C" mod_func* get(ghost_register_table* table) { - return func_tbl; +} + +extern "C" module_func_info* get(ghost_register_table* table) { + nasal_fib_module::ghost_for_test=table->register_ghost_type( + "fib_for_test", + nasal_fib_module::ghost_for_test_destructor + ); + return nasal_fib_module::func_tbl; } \ No newline at end of file diff --git a/module/keyboard.cpp b/module/keyboard.cpp index 6736385..f4b798d 100644 --- a/module/keyboard.cpp +++ b/module/keyboard.cpp @@ -88,13 +88,13 @@ var nas_noblock(var* args, usize size, gc* ngc) { return nil; } -mod_func func_tbl[]={ +module_func_info func_tbl[]={ {"nas_getch",nas_getch}, {"nas_kbhit",nas_kbhit}, {"nas_noblock",nas_noblock}, {nullptr,nullptr} }; -extern "C" mod_func* get(ghost_register_table* table) { +extern "C" module_func_info* get(ghost_register_table* table) { return func_tbl; } \ No newline at end of file diff --git a/module/libfib.nas b/module/libfib.nas index b852ec0..7fe2a1c 100644 --- a/module/libfib.nas +++ b/module/libfib.nas @@ -2,9 +2,28 @@ var libfib=func(){ var dl=dylib.dlopen("libfib."~(os.platform()=="windows"?"dll":"so")); var fib=dl.fib; var qfib=dl.quick_fib; + var create_ghost=dl.create_ghost; + var set_ghost=dl.set_ghost; + var print_ghost=dl.print_ghost; + var zero_call=dylib.limitcall(0); var call=dylib.limitcall(1); - return { - fib: func(x){return call(fib,x)}, - qfib:func(x){return call(qfib,x)} + var test_call=dylib.limitcall(2); + var res={ + fib: func(x) {return call(fib,x)}, + qfib: func(x) {return call(qfib,x)}, + create_ghost: func() {return zero_call(create_ghost)}, + set_ghost: func(object, x) {return test_call(set_ghost, object, x)}, + print_ghost: func(object) {return call(print_ghost, object)} }; + + res.test_ghost=func() { + var ghost=res.create_ghost(); + res.print_ghost(nil); # err + res.print_ghost(ghost); # random + res.set_ghost(nil, 114); # err + res.set_ghost(ghost, 114); # success + res.print_ghost(ghost); # 114 + } + + return res; }(); \ No newline at end of file diff --git a/module/matrix.cpp b/module/matrix.cpp index d74431c..05e8454 100644 --- a/module/matrix.cpp +++ b/module/matrix.cpp @@ -266,7 +266,7 @@ var nas_vec3_dot(var* args, usize size, gc* ngc) { return var::num(v0[0].num()*v1[0].num()+v0[1].num()*v1[1].num()+v0[2].num()*v1[2].num()); } -mod_func func_tbl[]={ +module_func_info func_tbl[]={ {"nas_vec2",nas_vec2}, {"nas_vec2_add",nas_vec2_add}, {"nas_vec2_sub",nas_vec2_sub}, @@ -291,6 +291,6 @@ mod_func func_tbl[]={ {nullptr,nullptr} }; -extern "C" mod_func* get(ghost_register_table* table) { +extern "C" module_func_info* get(ghost_register_table* table) { return func_tbl; } \ No newline at end of file diff --git a/module/nasocket.cpp b/module/nasocket.cpp index 3935567..4234b11 100644 --- a/module/nasocket.cpp +++ b/module/nasocket.cpp @@ -190,7 +190,7 @@ var nas_errno(var* args, usize size, gc* ngc) { return ngc->newstr(strerror(errno)); } -mod_func func_tbl[]={ +module_func_info func_tbl[]={ {"nas_socket",nas_socket}, {"nas_closesocket",nas_closesocket}, {"nas_shutdown",nas_shutdown}, @@ -206,6 +206,6 @@ mod_func func_tbl[]={ {nullptr,nullptr} }; -extern "C" mod_func* get(ghost_register_table* table) { +extern "C" module_func_info* get(ghost_register_table* table) { return func_tbl; } \ No newline at end of file diff --git a/nasal_builtin.h b/nasal_builtin.h index a1c6c55..10b3071 100644 --- a/nasal_builtin.h +++ b/nasal_builtin.h @@ -544,13 +544,13 @@ var builtin_open(var* local, gc& ngc) { return nas_err("open", "failed to open file <"+name.str()+">"); } var ret=ngc.alloc(vm_obj); - ret.obj().set(ghost_file, res); + ret.obj().set(global_ghost_type_table.ghost_file, res); return ret; } var builtin_close(var* local, gc& ngc) { var fd=local[1]; - if (!fd.objchk(ghost_file)) { + if (!fd.objchk(global_ghost_type_table.ghost_file)) { return nas_err("close", "not a valid filehandle"); } fd.obj().clear(); @@ -561,7 +561,7 @@ var builtin_read(var* local, gc& ngc) { var fd=local[1]; var buf=local[2]; var len=local[3]; - if (!fd.objchk(ghost_file)) { + if (!fd.objchk(global_ghost_type_table.ghost_file)) { return nas_err("read", "not a valid filehandle"); } if (buf.type!=vm_str || buf.val.gcobj->unmut) { @@ -587,7 +587,7 @@ var builtin_read(var* local, gc& ngc) { var builtin_write(var* local, gc& ngc) { var fd=local[1]; var str=local[2]; - if (!fd.objchk(ghost_file)) { + if (!fd.objchk(global_ghost_type_table.ghost_file)) { return nas_err("write", "not a valid filehandle"); } if (str.type!=vm_str) { @@ -600,7 +600,7 @@ var builtin_seek(var* local, gc& ngc) { var fd=local[1]; var pos=local[2]; var whence=local[3]; - if (!fd.objchk(ghost_file)) { + if (!fd.objchk(global_ghost_type_table.ghost_file)) { return nas_err("seek", "not a valid filehandle"); } return var::num((f64)fseek((FILE*)fd.obj().ptr, pos.num(), whence.num())); @@ -608,7 +608,7 @@ var builtin_seek(var* local, gc& ngc) { var builtin_tell(var* local, gc& ngc) { var fd=local[1]; - if (!fd.objchk(ghost_file)) { + if (!fd.objchk(global_ghost_type_table.ghost_file)) { return nas_err("tell", "not a valid filehandle"); } return var::num((f64)ftell((FILE*)fd.obj().ptr)); @@ -616,7 +616,7 @@ var builtin_tell(var* local, gc& ngc) { var builtin_readln(var* local, gc& ngc) { var fd=local[1]; - if (!fd.objchk(ghost_file)) { + if (!fd.objchk(global_ghost_type_table.ghost_file)) { return nas_err("readln", "not a valid filehandle"); } var str=ngc.alloc(vm_str); @@ -664,7 +664,7 @@ var builtin_stat(var* local, gc& ngc) { var builtin_eof(var* local, gc& ngc) { var fd=local[1]; - if (!fd.objchk(ghost_file)) { + if (!fd.objchk(global_ghost_type_table.ghost_file)) { return nas_err("readln", "not a valid filehandle"); } return var::num((f64)feof((FILE*)fd.obj().ptr)); @@ -849,13 +849,13 @@ var builtin_opendir(var* local, gc& ngc) { } #endif var ret=ngc.alloc(vm_obj); - ret.obj().set(ghost_dir,p); + ret.obj().set(global_ghost_type_table.ghost_dir,p); return ret; } var builtin_readdir(var* local, gc& ngc) { var handle=local[1]; - if (!handle.objchk(ghost_dir)) { + if (!handle.objchk(global_ghost_type_table.ghost_dir)) { return nas_err("readdir", "not a valid dir handle"); } #ifdef _MSC_VER @@ -872,7 +872,7 @@ var builtin_readdir(var* local, gc& ngc) { var builtin_closedir(var* local, gc& ngc) { var handle=local[1]; - if (!handle.objchk(ghost_dir)) { + if (!handle.objchk(global_ghost_type_table.ghost_dir)) { return nas_err("closedir", "not a valid dir handle"); } handle.obj().clear(); @@ -936,7 +936,7 @@ var builtin_dlopen(var* local, gc& ngc) { } var ret=ngc.temp=ngc.alloc(vm_hash); var lib=ngc.alloc(vm_obj); - lib.obj().set(ghost_dylib, ptr); + lib.obj().set(global_ghost_type_table.ghost_dylib, ptr); ret.hash().elems["lib"]=lib; #ifdef _WIN32 @@ -948,14 +948,14 @@ var builtin_dlopen(var* local, gc& ngc) { return nas_err("dlopen", "cannot find function"); } // get function pointer by name - mod_func* tbl=(mod_func*)((getptr)func)(&global_ghost_type_table); + module_func_info* tbl=((get_func_ptr)func)(&global_ghost_type_table); if (!tbl) { return nas_err("dlopen", "failed to get module functions"); } for(u32 i=0;tbl[i].name;++i) { void* p=(void*)tbl[i].fd; var tmp=ngc.alloc(vm_obj); - tmp.obj().set(ghost_faddr, p); + tmp.obj().set(global_ghost_type_table.ghost_faddr, p); ret.hash().elems[tbl[i].name]=tmp; } @@ -965,7 +965,7 @@ var builtin_dlopen(var* local, gc& ngc) { var builtin_dlclose(var* local, gc& ngc) { var libptr=local[1]; - if (!libptr.objchk(ghost_dylib)) { + if (!libptr.objchk(global_ghost_type_table.ghost_dylib)) { return nas_err("dlclose", "\"lib\" is not a valid dynamic lib"); } libptr.obj().clear(); @@ -975,23 +975,27 @@ var builtin_dlclose(var* local, gc& ngc) { var builtin_dlcallv(var* local, gc& ngc) { var fp=local[1]; var args=local[2]; - if (!fp.objchk(ghost_faddr)) { + if (!fp.objchk(global_ghost_type_table.ghost_faddr)) { return nas_err("dlcall", "\"ptr\" is not a valid function pointer"); } auto& vec=args.vec().elems; - return ((mod)fp.obj().ptr)(vec.data(), vec.size(), &ngc); + return ((module_func)fp.obj().ptr)( + vec.data(), + vec.size(), + &ngc + ); } var builtin_dlcall(var* local, gc& ngc) { var fp=local[1]; - if (!fp.objchk(ghost_faddr)) { + if (!fp.objchk(global_ghost_type_table.ghost_faddr)) { return nas_err("dlcall", "\"ptr\" is not a valid function pointer"); } var* local_frame_start=local+2; usize local_frame_size=ngc.rctx->top-local_frame_start; // arguments' stored place begins at local +2 - return ((mod)fp.obj().ptr)( + return ((module_func)fp.obj().ptr)( local_frame_start, local_frame_size, &ngc diff --git a/nasal_gc.h b/nasal_gc.h index 63f37db..65c8414 100644 --- a/nasal_gc.h +++ b/nasal_gc.h @@ -55,13 +55,13 @@ enum class gc_status:u8 { found }; -struct nas_vec; // vector -struct nas_hash; // hashmap(dict) -struct nas_func; // function(lambda) -struct nas_upval;// upvalue -struct nas_obj; // special objects -struct nas_co; // coroutine -struct nas_val; // nas_val includes gc-managed types +struct nas_vec; // vector +struct nas_hash; // hashmap(dict) +struct nas_func; // function(lambda) +struct nas_upval; // upvalue +struct nas_obj; // special objects +struct nas_co; // coroutine +struct nas_val; // nas_val includes gc-managed types struct var { public: @@ -154,6 +154,7 @@ struct nas_func { }; struct nas_upval { +public: /* on stack, use these variables */ bool onstk; u32 size; @@ -162,19 +163,28 @@ struct nas_upval { /* not on stack, use this */ std::vector elems; - nas_upval() {onstk=true;stk=nullptr;size=0;} - var& operator[](usize n) {return onstk? stk[n]:elems[n];} - void clear() {onstk=true;elems.clear();size=0;} +public: + nas_upval(): onstk(true), size(0), stk(nullptr) {} + + var& operator[](usize n) { + return onstk? stk[n]:elems[n]; + } + + void clear() { + onstk=true; + elems.clear(); + size=0; + } }; -void file_dtor(void* ptr) { +void filehandle_destructor(void* ptr) { if ((FILE*)ptr==stdin) { return; } fclose((FILE*)ptr); } -void dir_dtor(void* ptr) { +void dir_entry_destructor(void* ptr) { #ifndef _MSC_VER closedir((DIR*)ptr); #else @@ -182,7 +192,7 @@ void dir_dtor(void* ptr) { #endif } -void dylib_dtor(void* ptr) { +void dylib_destructor(void* ptr) { #ifdef _WIN32 FreeLibrary((HMODULE)ptr); #else @@ -190,9 +200,7 @@ void dylib_dtor(void* ptr) { #endif } -void faddr_dtor(void* ptr) {} - -usize ghost_file, ghost_dir, ghost_dylib, ghost_faddr; +void func_addr_destructor(void* ptr) {} struct ghost_register_table { private: @@ -202,17 +210,25 @@ private: std::unordered_map mapper; std::vector destructors; +public: + // reserved ghost type only for native functions + usize ghost_file; + usize ghost_dir; + usize ghost_dylib; + usize ghost_faddr; + public: ghost_register_table() { - ghost_file=register_ghost_type("file", file_dtor); - ghost_dir=register_ghost_type("dir", dir_dtor); - ghost_dylib=register_ghost_type("dylib", dylib_dtor); - ghost_faddr=register_ghost_type("faddr", faddr_dtor); + ghost_file=register_ghost_type("file", filehandle_destructor); + ghost_dir=register_ghost_type("dir", dir_entry_destructor); + ghost_dylib=register_ghost_type("dylib", dylib_destructor); + ghost_faddr=register_ghost_type("faddr", func_addr_destructor); } usize register_ghost_type(const std::string& name, dtor ptr) { if (mapper.count(name)) { - std::cerr<<"ghost type \""< Date: Thu, 11 May 2023 19:26:34 +0800 Subject: [PATCH 3/6] :zap: optimize ghost table structure --- module/fib.cpp | 15 +++++++++++---- nasal_builtin.h | 34 +++++++++++++++++----------------- nasal_gc.h | 44 ++++++++++++++++++++++++++++++++++---------- 3 files changed, 62 insertions(+), 31 deletions(-) diff --git a/module/fib.cpp b/module/fib.cpp index 70c2219..c7327d0 100644 --- a/module/fib.cpp +++ b/module/fib.cpp @@ -40,13 +40,16 @@ var quick_fib(var* args, usize size, gc* ngc) { u32 ghost_for_test; void ghost_for_test_destructor(void* ptr) { - std::cout<<"delete "<alloc(vm_obj); - res.obj().set(ghost_for_test, new u32); + res.obj().set(ghost_for_test, new u32, &ngc->global_ghost_type_table); return res; } @@ -56,9 +59,9 @@ var set_new_ghost(var* args, usize size, gc* ngc) { std::cout<<"set_new_ghost: not ghost for test type.\n"; return nil; } - std::cout<<"set_new_ghost: successfully set ghost.\n"; f64 num=args[1].num(); *((u32*)res.obj().ptr)=static_cast(num); + std::cout<<"set_new_ghost: successfully set ghost = "<exists("fib_for_test")) { + nasal_fib_module::ghost_for_test=table->get_ghost_type_index("fib_for_test"); + return nasal_fib_module::func_tbl; + } nasal_fib_module::ghost_for_test=table->register_ghost_type( "fib_for_test", nasal_fib_module::ghost_for_test_destructor diff --git a/nasal_builtin.h b/nasal_builtin.h index 10b3071..f8653da 100644 --- a/nasal_builtin.h +++ b/nasal_builtin.h @@ -544,13 +544,13 @@ var builtin_open(var* local, gc& ngc) { return nas_err("open", "failed to open file <"+name.str()+">"); } var ret=ngc.alloc(vm_obj); - ret.obj().set(global_ghost_type_table.ghost_file, res); + ret.obj().set(ngc.global_ghost_type_table.ghost_file, res, &ngc.global_ghost_type_table); return ret; } var builtin_close(var* local, gc& ngc) { var fd=local[1]; - if (!fd.objchk(global_ghost_type_table.ghost_file)) { + if (!fd.objchk(ngc.global_ghost_type_table.ghost_file)) { return nas_err("close", "not a valid filehandle"); } fd.obj().clear(); @@ -561,7 +561,7 @@ var builtin_read(var* local, gc& ngc) { var fd=local[1]; var buf=local[2]; var len=local[3]; - if (!fd.objchk(global_ghost_type_table.ghost_file)) { + if (!fd.objchk(ngc.global_ghost_type_table.ghost_file)) { return nas_err("read", "not a valid filehandle"); } if (buf.type!=vm_str || buf.val.gcobj->unmut) { @@ -587,7 +587,7 @@ var builtin_read(var* local, gc& ngc) { var builtin_write(var* local, gc& ngc) { var fd=local[1]; var str=local[2]; - if (!fd.objchk(global_ghost_type_table.ghost_file)) { + if (!fd.objchk(ngc.global_ghost_type_table.ghost_file)) { return nas_err("write", "not a valid filehandle"); } if (str.type!=vm_str) { @@ -600,7 +600,7 @@ var builtin_seek(var* local, gc& ngc) { var fd=local[1]; var pos=local[2]; var whence=local[3]; - if (!fd.objchk(global_ghost_type_table.ghost_file)) { + if (!fd.objchk(ngc.global_ghost_type_table.ghost_file)) { return nas_err("seek", "not a valid filehandle"); } return var::num((f64)fseek((FILE*)fd.obj().ptr, pos.num(), whence.num())); @@ -608,7 +608,7 @@ var builtin_seek(var* local, gc& ngc) { var builtin_tell(var* local, gc& ngc) { var fd=local[1]; - if (!fd.objchk(global_ghost_type_table.ghost_file)) { + if (!fd.objchk(ngc.global_ghost_type_table.ghost_file)) { return nas_err("tell", "not a valid filehandle"); } return var::num((f64)ftell((FILE*)fd.obj().ptr)); @@ -616,7 +616,7 @@ var builtin_tell(var* local, gc& ngc) { var builtin_readln(var* local, gc& ngc) { var fd=local[1]; - if (!fd.objchk(global_ghost_type_table.ghost_file)) { + if (!fd.objchk(ngc.global_ghost_type_table.ghost_file)) { return nas_err("readln", "not a valid filehandle"); } var str=ngc.alloc(vm_str); @@ -664,7 +664,7 @@ var builtin_stat(var* local, gc& ngc) { var builtin_eof(var* local, gc& ngc) { var fd=local[1]; - if (!fd.objchk(global_ghost_type_table.ghost_file)) { + if (!fd.objchk(ngc.global_ghost_type_table.ghost_file)) { return nas_err("readln", "not a valid filehandle"); } return var::num((f64)feof((FILE*)fd.obj().ptr)); @@ -849,13 +849,13 @@ var builtin_opendir(var* local, gc& ngc) { } #endif var ret=ngc.alloc(vm_obj); - ret.obj().set(global_ghost_type_table.ghost_dir,p); + ret.obj().set(ngc.global_ghost_type_table.ghost_dir, p, &ngc.global_ghost_type_table); return ret; } var builtin_readdir(var* local, gc& ngc) { var handle=local[1]; - if (!handle.objchk(global_ghost_type_table.ghost_dir)) { + if (!handle.objchk(ngc.global_ghost_type_table.ghost_dir)) { return nas_err("readdir", "not a valid dir handle"); } #ifdef _MSC_VER @@ -872,7 +872,7 @@ var builtin_readdir(var* local, gc& ngc) { var builtin_closedir(var* local, gc& ngc) { var handle=local[1]; - if (!handle.objchk(global_ghost_type_table.ghost_dir)) { + if (!handle.objchk(ngc.global_ghost_type_table.ghost_dir)) { return nas_err("closedir", "not a valid dir handle"); } handle.obj().clear(); @@ -936,7 +936,7 @@ var builtin_dlopen(var* local, gc& ngc) { } var ret=ngc.temp=ngc.alloc(vm_hash); var lib=ngc.alloc(vm_obj); - lib.obj().set(global_ghost_type_table.ghost_dylib, ptr); + lib.obj().set(ngc.global_ghost_type_table.ghost_dylib, ptr, &ngc.global_ghost_type_table); ret.hash().elems["lib"]=lib; #ifdef _WIN32 @@ -948,14 +948,14 @@ var builtin_dlopen(var* local, gc& ngc) { return nas_err("dlopen", "cannot find function"); } // get function pointer by name - module_func_info* tbl=((get_func_ptr)func)(&global_ghost_type_table); + module_func_info* tbl=((get_func_ptr)func)(&ngc.global_ghost_type_table); if (!tbl) { return nas_err("dlopen", "failed to get module functions"); } for(u32 i=0;tbl[i].name;++i) { void* p=(void*)tbl[i].fd; var tmp=ngc.alloc(vm_obj); - tmp.obj().set(global_ghost_type_table.ghost_faddr, p); + tmp.obj().set(ngc.global_ghost_type_table.ghost_faddr, p, &ngc.global_ghost_type_table); ret.hash().elems[tbl[i].name]=tmp; } @@ -965,7 +965,7 @@ var builtin_dlopen(var* local, gc& ngc) { var builtin_dlclose(var* local, gc& ngc) { var libptr=local[1]; - if (!libptr.objchk(global_ghost_type_table.ghost_dylib)) { + if (!libptr.objchk(ngc.global_ghost_type_table.ghost_dylib)) { return nas_err("dlclose", "\"lib\" is not a valid dynamic lib"); } libptr.obj().clear(); @@ -975,7 +975,7 @@ var builtin_dlclose(var* local, gc& ngc) { var builtin_dlcallv(var* local, gc& ngc) { var fp=local[1]; var args=local[2]; - if (!fp.objchk(global_ghost_type_table.ghost_faddr)) { + if (!fp.objchk(ngc.global_ghost_type_table.ghost_faddr)) { return nas_err("dlcall", "\"ptr\" is not a valid function pointer"); } auto& vec=args.vec().elems; @@ -988,7 +988,7 @@ var builtin_dlcallv(var* local, gc& ngc) { var builtin_dlcall(var* local, gc& ngc) { var fp=local[1]; - if (!fp.objchk(global_ghost_type_table.ghost_faddr)) { + if (!fp.objchk(ngc.global_ghost_type_table.ghost_faddr)) { return nas_err("dlcall", "\"ptr\" is not a valid function pointer"); } diff --git a/nasal_gc.h b/nasal_gc.h index 65c8414..fe51d8b 100644 --- a/nasal_gc.h +++ b/nasal_gc.h @@ -208,6 +208,7 @@ private: private: std::unordered_map mapper; + std::vector ghost_name; std::vector destructors; public: @@ -225,6 +226,18 @@ public: ghost_faddr=register_ghost_type("faddr", func_addr_destructor); } + bool exists(const string& name) const { + return mapper.count(name); + } + + usize get_ghost_type_index(const string& name) const { + return mapper.at(name); + } + + const string& get_ghost_name(usize index) const { + return ghost_name.at(index); + } + usize register_ghost_type(const std::string& name, dtor ptr) { if (mapper.count(name)) { std::cerr<<"nasal_gc.h: ghost_register_table::register_ghost_type: "; @@ -233,6 +246,7 @@ public: } auto res=destructors.size(); mapper[name]=res; + ghost_name.push_back(name); destructors.push_back(ptr); return res; } @@ -242,18 +256,26 @@ public: } }; -ghost_register_table global_ghost_type_table; - struct nas_obj { public: usize type; void* ptr; +private: + ghost_register_table* ghost_type_table; + public: - nas_obj(): type(0), ptr(nullptr) {} + nas_obj(): type(0), ptr(nullptr), ghost_type_table(nullptr) {} ~nas_obj() {clear();} - void set(usize, void*); + void set(usize, void*, ghost_register_table*); void clear(); + +public: + friend std::ostream& operator<<(std::ostream& out, nas_obj& ghost) { + out<<"get_ghost_name(ghost.type); + out<<" at 0x"<"; + return out; + } }; struct context { @@ -392,16 +414,17 @@ void nas_func::clear() { keys.clear(); } -void nas_obj::set(usize t, void* p) { +void nas_obj::set(usize t, void* p, ghost_register_table* table) { type=t; ptr=p; + ghost_type_table=table; } void nas_obj::clear() { - if (!ptr || !type) { + if (!ptr) { return; } - global_ghost_type_table.destructor(type)(ptr); + ghost_type_table->destructor(type)(ptr); ptr=nullptr; } @@ -486,7 +509,7 @@ std::ostream& operator<<(std::ostream& out, var& ref) { case vm_vec: out<"; break; + case vm_obj: out<"; break; } return out; @@ -541,6 +564,7 @@ const var one =var::num(1); const var nil =var::nil(); struct gc { + ghost_register_table global_ghost_type_table; /* main context temporary storage */ context mctx; @@ -714,7 +738,7 @@ void gc::sweep() { } void gc::extend(u8 type) { - u8 index=type-vm_str; + const u8 index=type-vm_str; size[index]+=incr[index]; for(u32 i=0;i& s, const std::vector& argv) { size[i]=gcnt[i]=acnt[i]=0; } - // coroutine pointer set to nullpre + // coroutine pointer set to nullptr cort=nullptr; // init constant strings From dfb0c6ab5204081c01d42ede58c3cfd270fa7848 Mon Sep 17 00:00:00 2001 From: ValKmjolnir Date: Thu, 11 May 2023 19:41:39 +0800 Subject: [PATCH 4/6] :bug: fix header in module for vs to build --- module/fib.cpp | 196 +++++++-------- module/keyboard.cpp | 202 +++++++-------- module/matrix.cpp | 590 ++++++++++++++++++++++---------------------- module/nasocket.cpp | 423 +++++++++++++++---------------- 4 files changed, 709 insertions(+), 702 deletions(-) diff --git a/module/fib.cpp b/module/fib.cpp index c7327d0..f0a546a 100644 --- a/module/fib.cpp +++ b/module/fib.cpp @@ -1,99 +1,99 @@ -// module for test - -#include -#include "../nasal.h" - -namespace nasal_fib_module { - -double fibonaci(double x) { - if (x<=2) { - return x; - } - return fibonaci(x-1)+fibonaci(x-2); -} - -var fib(var* args, usize size, gc* ngc) { - if (!size) { - return nas_err("fib","lack arguments"); - } - var num=args[0]; - return var::num(fibonaci(num.tonum())); -} - -var quick_fib(var* args, usize size, gc* ngc) { - if (!size) { - return nas_err("quick_fib","lack arguments"); - } - double num=args[0].tonum(); - if (num<2) { - return var::num(num); - } - double a=1,b=1,res=0; - for(double i=1;ialloc(vm_obj); - res.obj().set(ghost_for_test, new u32, &ngc->global_ghost_type_table); - return res; -} - -var set_new_ghost(var* args, usize size, gc* ngc) { - var res=args[0]; - if (!res.objchk(ghost_for_test)) { - std::cout<<"set_new_ghost: not ghost for test type.\n"; - return nil; - } - f64 num=args[1].num(); - *((u32*)res.obj().ptr)=static_cast(num); - std::cout<<"set_new_ghost: successfully set ghost = "<exists("fib_for_test")) { - nasal_fib_module::ghost_for_test=table->get_ghost_type_index("fib_for_test"); - return nasal_fib_module::func_tbl; - } - nasal_fib_module::ghost_for_test=table->register_ghost_type( - "fib_for_test", - nasal_fib_module::ghost_for_test_destructor - ); - return nasal_fib_module::func_tbl; +// module for test + +#include +#include "../nasal.h" + +namespace nasal_fib_module { + +double fibonaci(double x) { + if (x<=2) { + return x; + } + return fibonaci(x-1)+fibonaci(x-2); +} + +var fib(var* args, usize size, gc* ngc) { + if (!size) { + return nas_err("fib","lack arguments"); + } + var num=args[0]; + return var::num(fibonaci(num.tonum())); +} + +var quick_fib(var* args, usize size, gc* ngc) { + if (!size) { + return nas_err("quick_fib","lack arguments"); + } + double num=args[0].tonum(); + if (num<2) { + return var::num(num); + } + double a=1,b=1,res=0; + for(double i=1;ialloc(vm_obj); + res.obj().set(ghost_for_test, new u32, &ngc->global_ghost_type_table); + return res; +} + +var set_new_ghost(var* args, usize size, gc* ngc) { + var res=args[0]; + if (!res.objchk(ghost_for_test)) { + std::cout<<"set_new_ghost: not ghost for test type.\n"; + return nil; + } + f64 num=args[1].num(); + *((u32*)res.obj().ptr)=static_cast(num); + std::cout<<"set_new_ghost: successfully set ghost = "<exists("fib_for_test")) { + nasal_fib_module::ghost_for_test=table->get_ghost_type_index("fib_for_test"); + return nasal_fib_module::func_tbl; + } + nasal_fib_module::ghost_for_test=table->register_ghost_type( + "fib_for_test", + nasal_fib_module::ghost_for_test_destructor + ); + return nasal_fib_module::func_tbl; } \ No newline at end of file diff --git a/module/keyboard.cpp b/module/keyboard.cpp index f4b798d..c3c8e2f 100644 --- a/module/keyboard.cpp +++ b/module/keyboard.cpp @@ -1,100 +1,104 @@ -#include "../nasal.h" -#include -#include -#ifdef _WIN32 -#include -#else -#include -#include -#endif - -class noecho_input { -private: -#ifndef _WIN32 - struct termios init_termios; - struct termios new_termios; - int peek_char=-1; -#endif -public: - noecho_input() { -#ifndef _WIN32 - tcflush(0, TCIOFLUSH); - tcgetattr(0, &init_termios); - new_termios=init_termios; - new_termios.c_lflag&=~(ICANON|ECHO|ECHONL|ECHOE); - // vmin=0 is nonblock input, but in wsl there is a bug that will block input - // so we use fcntl to write the nonblock input - new_termios.c_cc[VMIN]=1; - new_termios.c_cc[VTIME]=0; - tcsetattr(0, TCSANOW, &new_termios); -#endif - } - ~noecho_input() { -#ifndef _WIN32 - tcflush(0, TCIOFLUSH); - tcsetattr(0, TCSANOW, &init_termios); -#endif - } - int noecho_kbhit() { -#ifndef _WIN32 - unsigned char ch=0; - int nread=0; - if (peek_char!=-1) { - return 1; - } - int flag=fcntl(0, F_GETFL); - fcntl(0, F_SETFL,flag|O_NONBLOCK); - nread=read(0, &ch, 1); - fcntl(0, F_SETFL, flag); - if (nread==1) { - peek_char=ch; - return 1; - } - return 0; -#else - return kbhit(); -#endif - } - int noecho_getch() { -#ifndef _WIN32 - int ch=0; - if (peek_char!=-1) { - ch=peek_char; - peek_char=-1; - return ch; - } - ssize_t tmp=read(0, &ch, 1); - return ch; -#else - return getch(); -#endif - } -}; - -noecho_input this_window; - -var nas_getch(var* args, usize size, gc* ngc) { - return var::num((double)this_window.noecho_getch()); -} - -var nas_kbhit(var* args, usize size, gc* ngc) { - return var::num((double)this_window.noecho_kbhit()); -} - -var nas_noblock(var* args, usize size, gc* ngc) { - if (this_window.noecho_kbhit()) { - return var::num((double)this_window.noecho_getch()); - } - return nil; -} - -module_func_info func_tbl[]={ - {"nas_getch",nas_getch}, - {"nas_kbhit",nas_kbhit}, - {"nas_noblock",nas_noblock}, - {nullptr,nullptr} -}; - -extern "C" module_func_info* get(ghost_register_table* table) { - return func_tbl; +#include "../nasal.h" +#include + +#ifndef _MSC_VER +#include +#endif + +#ifdef _WIN32 +#include +#else +#include +#include +#endif + +class noecho_input { +private: +#ifndef _WIN32 + struct termios init_termios; + struct termios new_termios; + int peek_char=-1; +#endif +public: + noecho_input() { +#ifndef _WIN32 + tcflush(0, TCIOFLUSH); + tcgetattr(0, &init_termios); + new_termios=init_termios; + new_termios.c_lflag&=~(ICANON|ECHO|ECHONL|ECHOE); + // vmin=0 is nonblock input, but in wsl there is a bug that will block input + // so we use fcntl to write the nonblock input + new_termios.c_cc[VMIN]=1; + new_termios.c_cc[VTIME]=0; + tcsetattr(0, TCSANOW, &new_termios); +#endif + } + ~noecho_input() { +#ifndef _WIN32 + tcflush(0, TCIOFLUSH); + tcsetattr(0, TCSANOW, &init_termios); +#endif + } + int noecho_kbhit() { +#ifndef _WIN32 + unsigned char ch=0; + int nread=0; + if (peek_char!=-1) { + return 1; + } + int flag=fcntl(0, F_GETFL); + fcntl(0, F_SETFL,flag|O_NONBLOCK); + nread=read(0, &ch, 1); + fcntl(0, F_SETFL, flag); + if (nread==1) { + peek_char=ch; + return 1; + } + return 0; +#else + return kbhit(); +#endif + } + int noecho_getch() { +#ifndef _WIN32 + int ch=0; + if (peek_char!=-1) { + ch=peek_char; + peek_char=-1; + return ch; + } + ssize_t tmp=read(0, &ch, 1); + return ch; +#else + return getch(); +#endif + } +}; + +noecho_input this_window; + +var nas_getch(var* args, usize size, gc* ngc) { + return var::num((double)this_window.noecho_getch()); +} + +var nas_kbhit(var* args, usize size, gc* ngc) { + return var::num((double)this_window.noecho_kbhit()); +} + +var nas_noblock(var* args, usize size, gc* ngc) { + if (this_window.noecho_kbhit()) { + return var::num((double)this_window.noecho_getch()); + } + return nil; +} + +module_func_info func_tbl[]={ + {"nas_getch",nas_getch}, + {"nas_kbhit",nas_kbhit}, + {"nas_noblock",nas_noblock}, + {nullptr,nullptr} +}; + +extern "C" module_func_info* get(ghost_register_table* table) { + return func_tbl; } \ No newline at end of file diff --git a/module/matrix.cpp b/module/matrix.cpp index 05e8454..5bf8939 100644 --- a/module/matrix.cpp +++ b/module/matrix.cpp @@ -1,296 +1,296 @@ -#include "../nasal.h" -#include - -var nas_vec2(var* args, usize size, gc* ngc) { - var res=ngc->alloc(vm_vec); - res.vec().elems.push_back(args[0]); - res.vec().elems.push_back(args[1]); - return res; -} - -var nas_vec3(var* args, usize size, gc* ngc) { - var res=ngc->alloc(vm_vec); - res.vec().elems.push_back(args[0]); - res.vec().elems.push_back(args[1]); - res.vec().elems.push_back(args[2]); - return res; -} - -var nas_vec2_add(var* args, usize size, gc* ngc) { - if (args[0].type!=vm_vec || args[1].type!=vm_vec) - return nil; - auto& v0=args[0].vec().elems; - auto& v1=args[1].vec().elems; - if (v0.size()!=2 || v1.size()!=2) - return nil; - var res=ngc->alloc(vm_vec); - res.vec().elems.push_back(var::num(v0[0].num()+v1[0].num())); - res.vec().elems.push_back(var::num(v0[1].num()+v1[1].num())); - return res; -} - -var nas_vec2_sub(var* args, usize size, gc* ngc) { - if (args[0].type!=vm_vec || args[1].type!=vm_vec) - return nil; - auto& v0=args[0].vec().elems; - auto& v1=args[1].vec().elems; - if (v0.size()!=2 || v1.size()!=2) - return nil; - var res=ngc->alloc(vm_vec); - res.vec().elems.push_back(var::num(v0[0].num()-v1[0].num())); - res.vec().elems.push_back(var::num(v0[1].num()-v1[1].num())); - return res; -} - -var nas_vec2_mult(var* args, usize size, gc* ngc) { - if (args[0].type!=vm_vec || args[1].type!=vm_vec) - return nil; - auto& v0=args[0].vec().elems; - auto& v1=args[1].vec().elems; - if (v0.size()!=2 || v1.size()!=2) - return nil; - var res=ngc->alloc(vm_vec); - res.vec().elems.push_back(var::num(v0[0].num()*v1[0].num())); - res.vec().elems.push_back(var::num(v0[1].num()*v1[1].num())); - return res; -} - -var nas_vec2_div(var* args, usize size, gc* ngc) { - if (args[0].type!=vm_vec || args[1].type!=vm_vec) - return nil; - auto& v0=args[0].vec().elems; - auto& v1=args[1].vec().elems; - if (v0.size()!=2 || v1.size()!=2) - return nil; - var res=ngc->alloc(vm_vec); - res.vec().elems.push_back(var::num(v0[0].num()/v1[0].num())); - res.vec().elems.push_back(var::num(v0[1].num()/v1[1].num())); - return res; -} - -var nas_vec2_neg(var* args, usize size, gc* ngc) { - if (args[0].type!=vm_vec) - return nil; - auto& v0=args[0].vec().elems; - if (v0.size()!=2) - return nil; - var res=ngc->alloc(vm_vec); - res.vec().elems.push_back(var::num(-v0[0].num())); - res.vec().elems.push_back(var::num(-v0[1].num())); - return res; -} - -var nas_vec2_norm(var* args, usize size, gc* ngc) { - if (args[0].type!=vm_vec) - return nil; - auto& v0=args[0].vec().elems; - if (v0.size()!=2) - return nil; - auto x=v0[0].num(); - auto y=v0[1].num(); - auto t=std::sqrt(x*x+y*y); - var res=ngc->alloc(vm_vec); - res.vec().elems.push_back(var::num(x/t)); - res.vec().elems.push_back(var::num(y/t)); - return res; -} - -var nas_vec2_len(var* args, usize size, gc* ngc) { - if (args[0].type!=vm_vec) - return nil; - auto& v0=args[0].vec().elems; - if (v0.size()!=2) - return nil; - auto x=v0[0].num(); - auto y=v0[1].num(); - return var::num(std::sqrt(x*x+y*y)); -} - -var nas_vec2_dot(var* args, usize size, gc* ngc) { - if (args[0].type!=vm_vec || args[1].type!=vm_vec) - return nil; - auto& v0=args[0].vec().elems; - auto& v1=args[1].vec().elems; - if (v0.size()!=2 || v1.size()!=2) - return nil; - return var::num(v0[0].num()*v1[0].num()+v0[1].num()*v1[1].num()); -} - -var nas_vec3_add(var* args, usize size, gc* ngc) { - if (args[0].type!=vm_vec || args[1].type!=vm_vec) - return nil; - auto& v0=args[0].vec().elems; - auto& v1=args[1].vec().elems; - if (v0.size()!=3 || v1.size()!=3) - return nil; - var res=ngc->alloc(vm_vec); - res.vec().elems.push_back(var::num(v0[0].num()+v1[0].num())); - res.vec().elems.push_back(var::num(v0[1].num()+v1[1].num())); - res.vec().elems.push_back(var::num(v0[2].num()+v1[2].num())); - return res; -} - -var nas_vec3_sub(var* args, usize size, gc* ngc) { - if (args[0].type!=vm_vec || args[1].type!=vm_vec) - return nil; - auto& v0=args[0].vec().elems; - auto& v1=args[1].vec().elems; - if (v0.size()!=3 || v1.size()!=3) - return nil; - var res=ngc->alloc(vm_vec); - res.vec().elems.push_back(var::num(v0[0].num()-v1[0].num())); - res.vec().elems.push_back(var::num(v0[1].num()-v1[1].num())); - res.vec().elems.push_back(var::num(v0[2].num()-v1[2].num())); - return res; -} - -var nas_vec3_mult(var* args, usize size, gc* ngc) { - if (args[0].type!=vm_vec || args[1].type!=vm_vec) - return nil; - auto& v0=args[0].vec().elems; - auto& v1=args[1].vec().elems; - if (v0.size()!=3 || v1.size()!=3) - return nil; - var res=ngc->alloc(vm_vec); - res.vec().elems.push_back(var::num(v0[0].num()*v1[0].num())); - res.vec().elems.push_back(var::num(v0[1].num()*v1[1].num())); - res.vec().elems.push_back(var::num(v0[2].num()*v1[2].num())); - return res; -} - -var nas_vec3_div(var* args, usize size, gc* ngc) { - if (args[0].type!=vm_vec || args[1].type!=vm_vec) - return nil; - auto& v0=args[0].vec().elems; - auto& v1=args[1].vec().elems; - if (v0.size()!=3 || v1.size()!=3) - return nil; - var res=ngc->alloc(vm_vec); - res.vec().elems.push_back(var::num(v0[0].num()/v1[0].num())); - res.vec().elems.push_back(var::num(v0[1].num()/v1[1].num())); - res.vec().elems.push_back(var::num(v0[2].num()/v1[2].num())); - return res; -} - -var nas_vec3_neg(var* args, usize size, gc* ngc) { - if (args[0].type!=vm_vec) - return nil; - auto& v0=args[0].vec().elems; - if (v0.size()!=3) - return nil; - var res=ngc->alloc(vm_vec); - res.vec().elems.push_back(var::num(-v0[0].num())); - res.vec().elems.push_back(var::num(-v0[1].num())); - res.vec().elems.push_back(var::num(-v0[2].num())); - return res; -} - -var nas_vec3_norm(var* args, usize size, gc* ngc) { - if (args[0].type!=vm_vec) - return nil; - auto& v0=args[0].vec().elems; - if (v0.size()!=3) - return nil; - auto x=v0[0].num(); - auto y=v0[1].num(); - auto z=v0[2].num(); - auto t=std::sqrt(x*x+y*y+z*z); - var res=ngc->alloc(vm_vec); - res.vec().elems.push_back(var::num(x/t)); - res.vec().elems.push_back(var::num(y/t)); - res.vec().elems.push_back(var::num(z/t)); - return res; -} - -var nas_vec3_len(var* args, usize size, gc* ngc) { - if (args[0].type!=vm_vec) - return nil; - auto& v0=args[0].vec().elems; - if (v0.size()!=3) - return nil; - auto x=v0[0].num(); - auto y=v0[1].num(); - auto z=v0[2].num(); - return var::num(std::sqrt(x*x+y*y+z*z)); -} - -var nas_rotate_x(var* args, usize size, gc* ngc) { - if (args[0].type!=vm_vec) - return nil; - auto& v0=args[0].vec().elems; - if (v0.size()!=3) - return nil; - auto angle=args[1].num(); - var res=ngc->alloc(vm_vec); - res.vec().elems.push_back(var::num(v0[0].num())); - res.vec().elems.push_back(var::num(v0[2].num()*std::sin(angle)+v0[1].num()*std::cos(angle))); - res.vec().elems.push_back(var::num(v0[2].num()*std::cos(angle)-v0[1].num()*std::sin(angle))); - return res; -} - -var nas_rotate_y(var* args, usize size, gc* ngc) { - if (args[0].type!=vm_vec) - return nil; - auto& v0=args[0].vec().elems; - if (v0.size()!=3) - return nil; - auto angle=args[1].num(); - var res=ngc->alloc(vm_vec); - res.vec().elems.push_back(var::num(v0[0].num()*std::cos(angle)-v0[2].num()*std::sin(angle))); - res.vec().elems.push_back(var::num(v0[1].num())); - res.vec().elems.push_back(var::num(v0[0].num()*std::sin(angle)+v0[2].num()*std::cos(angle))); - return res; -} - -var nas_rotate_z(var* args, usize size, gc* ngc) { - if (args[0].type!=vm_vec) - return nil; - auto& v0=args[0].vec().elems; - if (v0.size()!=3) - return nil; - auto angle=args[1].num(); - var res=ngc->alloc(vm_vec); - res.vec().elems.push_back(var::num(v0[0].num()*std::cos(angle)-v0[1].num()*std::sin(angle))); - res.vec().elems.push_back(var::num(v0[0].num()*std::sin(angle)+v0[1].num()*std::cos(angle))); - res.vec().elems.push_back(var::num(v0[2].num())); - return res; -} - -var nas_vec3_dot(var* args, usize size, gc* ngc) { - if (args[0].type!=vm_vec || args[1].type!=vm_vec) - return nil; - auto& v0=args[0].vec().elems; - auto& v1=args[1].vec().elems; - if (v0.size()!=3 || v1.size()!=3) - return nil; - return var::num(v0[0].num()*v1[0].num()+v0[1].num()*v1[1].num()+v0[2].num()*v1[2].num()); -} - -module_func_info func_tbl[]={ - {"nas_vec2",nas_vec2}, - {"nas_vec2_add",nas_vec2_add}, - {"nas_vec2_sub",nas_vec2_sub}, - {"nas_vec2_mult",nas_vec2_mult}, - {"nas_vec2_div",nas_vec2_div}, - {"nas_vec2_neg",nas_vec2_neg}, - {"nas_vec2_norm",nas_vec2_norm}, - {"nas_vec2_len",nas_vec2_len}, - {"nas_vec2_dot",nas_vec2_dot}, - {"nas_vec3",nas_vec3}, - {"nas_vec3_add",nas_vec3_add}, - {"nas_vec3_sub",nas_vec3_sub}, - {"nas_vec3_mult",nas_vec3_mult}, - {"nas_vec3_div",nas_vec3_div}, - {"nas_vec3_neg",nas_vec3_neg}, - {"nas_vec3_norm",nas_vec3_norm}, - {"nas_vec3_len",nas_vec3_len}, - {"nas_rotate_x",nas_rotate_x}, - {"nas_rotate_y",nas_rotate_y}, - {"nas_rotate_z",nas_rotate_z}, - {"nas_vec3_dot",nas_vec3_dot}, - {nullptr,nullptr} -}; - -extern "C" module_func_info* get(ghost_register_table* table) { - return func_tbl; +#include "../nasal.h" +#include + +var nas_vec2(var* args, usize size, gc* ngc) { + var res=ngc->alloc(vm_vec); + res.vec().elems.push_back(args[0]); + res.vec().elems.push_back(args[1]); + return res; +} + +var nas_vec3(var* args, usize size, gc* ngc) { + var res=ngc->alloc(vm_vec); + res.vec().elems.push_back(args[0]); + res.vec().elems.push_back(args[1]); + res.vec().elems.push_back(args[2]); + return res; +} + +var nas_vec2_add(var* args, usize size, gc* ngc) { + if (args[0].type!=vm_vec || args[1].type!=vm_vec) + return nil; + auto& v0=args[0].vec().elems; + auto& v1=args[1].vec().elems; + if (v0.size()!=2 || v1.size()!=2) + return nil; + var res=ngc->alloc(vm_vec); + res.vec().elems.push_back(var::num(v0[0].num()+v1[0].num())); + res.vec().elems.push_back(var::num(v0[1].num()+v1[1].num())); + return res; +} + +var nas_vec2_sub(var* args, usize size, gc* ngc) { + if (args[0].type!=vm_vec || args[1].type!=vm_vec) + return nil; + auto& v0=args[0].vec().elems; + auto& v1=args[1].vec().elems; + if (v0.size()!=2 || v1.size()!=2) + return nil; + var res=ngc->alloc(vm_vec); + res.vec().elems.push_back(var::num(v0[0].num()-v1[0].num())); + res.vec().elems.push_back(var::num(v0[1].num()-v1[1].num())); + return res; +} + +var nas_vec2_mult(var* args, usize size, gc* ngc) { + if (args[0].type!=vm_vec || args[1].type!=vm_vec) + return nil; + auto& v0=args[0].vec().elems; + auto& v1=args[1].vec().elems; + if (v0.size()!=2 || v1.size()!=2) + return nil; + var res=ngc->alloc(vm_vec); + res.vec().elems.push_back(var::num(v0[0].num()*v1[0].num())); + res.vec().elems.push_back(var::num(v0[1].num()*v1[1].num())); + return res; +} + +var nas_vec2_div(var* args, usize size, gc* ngc) { + if (args[0].type!=vm_vec || args[1].type!=vm_vec) + return nil; + auto& v0=args[0].vec().elems; + auto& v1=args[1].vec().elems; + if (v0.size()!=2 || v1.size()!=2) + return nil; + var res=ngc->alloc(vm_vec); + res.vec().elems.push_back(var::num(v0[0].num()/v1[0].num())); + res.vec().elems.push_back(var::num(v0[1].num()/v1[1].num())); + return res; +} + +var nas_vec2_neg(var* args, usize size, gc* ngc) { + if (args[0].type!=vm_vec) + return nil; + auto& v0=args[0].vec().elems; + if (v0.size()!=2) + return nil; + var res=ngc->alloc(vm_vec); + res.vec().elems.push_back(var::num(-v0[0].num())); + res.vec().elems.push_back(var::num(-v0[1].num())); + return res; +} + +var nas_vec2_norm(var* args, usize size, gc* ngc) { + if (args[0].type!=vm_vec) + return nil; + auto& v0=args[0].vec().elems; + if (v0.size()!=2) + return nil; + auto x=v0[0].num(); + auto y=v0[1].num(); + auto t=std::sqrt(x*x+y*y); + var res=ngc->alloc(vm_vec); + res.vec().elems.push_back(var::num(x/t)); + res.vec().elems.push_back(var::num(y/t)); + return res; +} + +var nas_vec2_len(var* args, usize size, gc* ngc) { + if (args[0].type!=vm_vec) + return nil; + auto& v0=args[0].vec().elems; + if (v0.size()!=2) + return nil; + auto x=v0[0].num(); + auto y=v0[1].num(); + return var::num(std::sqrt(x*x+y*y)); +} + +var nas_vec2_dot(var* args, usize size, gc* ngc) { + if (args[0].type!=vm_vec || args[1].type!=vm_vec) + return nil; + auto& v0=args[0].vec().elems; + auto& v1=args[1].vec().elems; + if (v0.size()!=2 || v1.size()!=2) + return nil; + return var::num(v0[0].num()*v1[0].num()+v0[1].num()*v1[1].num()); +} + +var nas_vec3_add(var* args, usize size, gc* ngc) { + if (args[0].type!=vm_vec || args[1].type!=vm_vec) + return nil; + auto& v0=args[0].vec().elems; + auto& v1=args[1].vec().elems; + if (v0.size()!=3 || v1.size()!=3) + return nil; + var res=ngc->alloc(vm_vec); + res.vec().elems.push_back(var::num(v0[0].num()+v1[0].num())); + res.vec().elems.push_back(var::num(v0[1].num()+v1[1].num())); + res.vec().elems.push_back(var::num(v0[2].num()+v1[2].num())); + return res; +} + +var nas_vec3_sub(var* args, usize size, gc* ngc) { + if (args[0].type!=vm_vec || args[1].type!=vm_vec) + return nil; + auto& v0=args[0].vec().elems; + auto& v1=args[1].vec().elems; + if (v0.size()!=3 || v1.size()!=3) + return nil; + var res=ngc->alloc(vm_vec); + res.vec().elems.push_back(var::num(v0[0].num()-v1[0].num())); + res.vec().elems.push_back(var::num(v0[1].num()-v1[1].num())); + res.vec().elems.push_back(var::num(v0[2].num()-v1[2].num())); + return res; +} + +var nas_vec3_mult(var* args, usize size, gc* ngc) { + if (args[0].type!=vm_vec || args[1].type!=vm_vec) + return nil; + auto& v0=args[0].vec().elems; + auto& v1=args[1].vec().elems; + if (v0.size()!=3 || v1.size()!=3) + return nil; + var res=ngc->alloc(vm_vec); + res.vec().elems.push_back(var::num(v0[0].num()*v1[0].num())); + res.vec().elems.push_back(var::num(v0[1].num()*v1[1].num())); + res.vec().elems.push_back(var::num(v0[2].num()*v1[2].num())); + return res; +} + +var nas_vec3_div(var* args, usize size, gc* ngc) { + if (args[0].type!=vm_vec || args[1].type!=vm_vec) + return nil; + auto& v0=args[0].vec().elems; + auto& v1=args[1].vec().elems; + if (v0.size()!=3 || v1.size()!=3) + return nil; + var res=ngc->alloc(vm_vec); + res.vec().elems.push_back(var::num(v0[0].num()/v1[0].num())); + res.vec().elems.push_back(var::num(v0[1].num()/v1[1].num())); + res.vec().elems.push_back(var::num(v0[2].num()/v1[2].num())); + return res; +} + +var nas_vec3_neg(var* args, usize size, gc* ngc) { + if (args[0].type!=vm_vec) + return nil; + auto& v0=args[0].vec().elems; + if (v0.size()!=3) + return nil; + var res=ngc->alloc(vm_vec); + res.vec().elems.push_back(var::num(-v0[0].num())); + res.vec().elems.push_back(var::num(-v0[1].num())); + res.vec().elems.push_back(var::num(-v0[2].num())); + return res; +} + +var nas_vec3_norm(var* args, usize size, gc* ngc) { + if (args[0].type!=vm_vec) + return nil; + auto& v0=args[0].vec().elems; + if (v0.size()!=3) + return nil; + auto x=v0[0].num(); + auto y=v0[1].num(); + auto z=v0[2].num(); + auto t=std::sqrt(x*x+y*y+z*z); + var res=ngc->alloc(vm_vec); + res.vec().elems.push_back(var::num(x/t)); + res.vec().elems.push_back(var::num(y/t)); + res.vec().elems.push_back(var::num(z/t)); + return res; +} + +var nas_vec3_len(var* args, usize size, gc* ngc) { + if (args[0].type!=vm_vec) + return nil; + auto& v0=args[0].vec().elems; + if (v0.size()!=3) + return nil; + auto x=v0[0].num(); + auto y=v0[1].num(); + auto z=v0[2].num(); + return var::num(std::sqrt(x*x+y*y+z*z)); +} + +var nas_rotate_x(var* args, usize size, gc* ngc) { + if (args[0].type!=vm_vec) + return nil; + auto& v0=args[0].vec().elems; + if (v0.size()!=3) + return nil; + auto angle=args[1].num(); + var res=ngc->alloc(vm_vec); + res.vec().elems.push_back(var::num(v0[0].num())); + res.vec().elems.push_back(var::num(v0[2].num()*std::sin(angle)+v0[1].num()*std::cos(angle))); + res.vec().elems.push_back(var::num(v0[2].num()*std::cos(angle)-v0[1].num()*std::sin(angle))); + return res; +} + +var nas_rotate_y(var* args, usize size, gc* ngc) { + if (args[0].type!=vm_vec) + return nil; + auto& v0=args[0].vec().elems; + if (v0.size()!=3) + return nil; + auto angle=args[1].num(); + var res=ngc->alloc(vm_vec); + res.vec().elems.push_back(var::num(v0[0].num()*std::cos(angle)-v0[2].num()*std::sin(angle))); + res.vec().elems.push_back(var::num(v0[1].num())); + res.vec().elems.push_back(var::num(v0[0].num()*std::sin(angle)+v0[2].num()*std::cos(angle))); + return res; +} + +var nas_rotate_z(var* args, usize size, gc* ngc) { + if (args[0].type!=vm_vec) + return nil; + auto& v0=args[0].vec().elems; + if (v0.size()!=3) + return nil; + auto angle=args[1].num(); + var res=ngc->alloc(vm_vec); + res.vec().elems.push_back(var::num(v0[0].num()*std::cos(angle)-v0[1].num()*std::sin(angle))); + res.vec().elems.push_back(var::num(v0[0].num()*std::sin(angle)+v0[1].num()*std::cos(angle))); + res.vec().elems.push_back(var::num(v0[2].num())); + return res; +} + +var nas_vec3_dot(var* args, usize size, gc* ngc) { + if (args[0].type!=vm_vec || args[1].type!=vm_vec) + return nil; + auto& v0=args[0].vec().elems; + auto& v1=args[1].vec().elems; + if (v0.size()!=3 || v1.size()!=3) + return nil; + return var::num(v0[0].num()*v1[0].num()+v0[1].num()*v1[1].num()+v0[2].num()*v1[2].num()); +} + +module_func_info func_tbl[]={ + {"nas_vec2",nas_vec2}, + {"nas_vec2_add",nas_vec2_add}, + {"nas_vec2_sub",nas_vec2_sub}, + {"nas_vec2_mult",nas_vec2_mult}, + {"nas_vec2_div",nas_vec2_div}, + {"nas_vec2_neg",nas_vec2_neg}, + {"nas_vec2_norm",nas_vec2_norm}, + {"nas_vec2_len",nas_vec2_len}, + {"nas_vec2_dot",nas_vec2_dot}, + {"nas_vec3",nas_vec3}, + {"nas_vec3_add",nas_vec3_add}, + {"nas_vec3_sub",nas_vec3_sub}, + {"nas_vec3_mult",nas_vec3_mult}, + {"nas_vec3_div",nas_vec3_div}, + {"nas_vec3_neg",nas_vec3_neg}, + {"nas_vec3_norm",nas_vec3_norm}, + {"nas_vec3_len",nas_vec3_len}, + {"nas_rotate_x",nas_rotate_x}, + {"nas_rotate_y",nas_rotate_y}, + {"nas_rotate_z",nas_rotate_z}, + {"nas_vec3_dot",nas_vec3_dot}, + {nullptr,nullptr} +}; + +extern "C" module_func_info* get(ghost_register_table* table) { + return func_tbl; } \ No newline at end of file diff --git a/module/nasocket.cpp b/module/nasocket.cpp index 4234b11..5320244 100644 --- a/module/nasocket.cpp +++ b/module/nasocket.cpp @@ -1,211 +1,214 @@ -#include "../nasal.h" -#include - -#ifdef _WIN32 -#include -#pragma comment(lib,"ws2_32") - -class WSAmanager{ -private: - WSAData data; -public: - WSAmanager() { - WSAStartup(0x1010, &data); - } - ~WSAmanager() { - WSACleanup(); - } -}; - -static WSAmanager win; -#else -#include -#include -#include -#include -#endif - -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) - return nas_err("socket","\"af\", \"type\", \"protocol\" should be number"); - int sd=socket(args[0].num(),args[1].num(),args[2].num()); - return var::num((double)sd); -} - -var nas_closesocket(var* args, usize size, gc* ngc) { - if (args[0].type!=vm_num) - return nas_err("closesocket","\"sd\" should be number"); -#ifdef _WIN32 - return var::num((double)closesocket(args[0].num())); -#else - return var::num((double)close(args[0].num())); -#endif -} - -var nas_shutdown(var* args, usize size, gc* ngc) { - if (args[0].type!=vm_num) - return nas_err("shutdown","\"sd\" must be a number"); - if (args[1].type!=vm_num) - return nas_err("shutdown","\"how\" must be a number"); - return var::num((double)shutdown(args[0].num(),args[1].num())); -} - -var nas_bind(var* args, usize size, gc* ngc) { - if (args[0].type!=vm_num) - return nas_err("bind","\"sd\" muse be a number"); - if (args[1].type!=vm_str) - return nas_err("bind","\"ip\" should be a string including an ip with correct format"); - if (args[2].type!=vm_num) - return nas_err("bind","\"port\" must be a number"); - sockaddr_in server; - memset(&server,0,sizeof(sockaddr_in)); - server.sin_family=AF_INET; - server.sin_addr.s_addr=inet_addr(args[1].str().c_str()); - server.sin_port=htons(args[2].num()); - return var::num((double)bind(args[0].num(),(sockaddr*)&server,sizeof(server))); -} - -var nas_listen(var* args, usize size, gc* ngc) { - if (args[0].type!=vm_num) - return nas_err("listen","\"sd\" must be a number"); - if (args[1].type!=vm_num) - return nas_err("listen","\"backlog\" must be a number"); - return var::num((double)listen(args[0].num(),args[1].num())); -} - -var nas_connect(var* args, usize size, gc* ngc) { - if (args[0].type!=vm_num) - return nas_err("connect","\"sd\" must be a number"); - if (args[1].type!=vm_str) - return nas_err("connect","\"hostname\" must be a string"); - if (args[2].type!=vm_num) - return nas_err("connect","\"port\" must be a number"); - sockaddr_in addr; - memset(&addr,0,sizeof(sockaddr_in)); - addr.sin_family=AF_INET; - addr.sin_port=htons(args[2].num()); - hostent* entry=gethostbyname(args[1].str().c_str()); - memcpy(&addr.sin_addr,entry->h_addr,entry->h_length); - return var::num((double)connect(args[0].num(),(sockaddr*)&addr,sizeof(sockaddr_in))); -} - -var nas_accept(var* args, usize size, gc* ngc) { - if (args[0].type!=vm_num) - return nas_err("accept","\"sd\" must be a number"); - sockaddr_in client; - int socklen=sizeof(sockaddr_in); -#ifdef _WIN32 - int client_sd=accept(args[0].num(),(sockaddr*)&client,&socklen); -#else - int client_sd=accept(args[0].num(),(sockaddr*)&client,(socklen_t*)&socklen); -#endif - var res=ngc->temp=ngc->alloc(vm_hash); - auto& hash=res.hash().elems; - hash["sd"]=var::num((double)client_sd); - hash["ip"]=ngc->newstr(inet_ntoa(client.sin_addr)); - ngc->temp=nil; - return res; -} - -var nas_send(var* args, usize size, gc* ngc) { - if (args[0].type!=vm_num) - return nas_err("send","\"sd\" must be a number"); - if (args[1].type!=vm_str) - return nas_err("send","\"buff\" must be a string"); - if (args[2].type!=vm_num) - return nas_err("send","\"flags\" muse be a number"); - return var::num((double)send(args[0].num(),args[1].str().c_str(),args[1].str().length(),args[2].num())); -} - -var nas_sendto(var* args, usize size, gc* ngc) { - if (args[0].type!=vm_num) - return nas_err("sendto","\"sd\" must be a number"); - if (args[1].type!=vm_str) - return nas_err("sendto","\"hostname\" must be a string"); - if (args[2].type!=vm_num) - return nas_err("sendto","\"port\" must be a number"); - if (args[3].type!=vm_str) - return nas_err("sendto","\"buff\" must be a string"); - if (args[4].type!=vm_num) - return nas_err("sendto","\"flags\" must be a number"); - sockaddr_in addr; - memset(&addr,0,sizeof(sockaddr_in)); - addr.sin_family=AF_INET; - addr.sin_port=htons(args[2].num()); - hostent* entry=gethostbyname(args[1].str().c_str()); - memcpy(&addr.sin_addr,entry->h_addr,entry->h_length); - return var::num((double)sendto(args[0].num(),args[3].str().c_str(),args[3].str().length(),args[4].num(),(sockaddr*)&addr,sizeof(sockaddr_in))); -} - -var nas_recv(var* args, usize size, gc* ngc) { - if (args[0].type!=vm_num) - return nas_err("recv","\"sd\" must be a number"); - if (args[1].type!=vm_num) - return nas_err("recv","\"len\" must be a number"); - if (args[1].num()<=0 || args[1].num()>16*1024*1024) - return nas_err("recv","\"len\" out of range"); - if (args[2].type!=vm_num) - return nas_err("recv","\"flags\" muse be a number"); - var res=ngc->temp=ngc->alloc(vm_hash); - auto& hash=res.hash().elems; - char* buf=new char[(int)args[1].num()]; - auto recvsize=recv(args[0].num(),buf,args[1].num(),args[2].num()); - hash["size"]=var::num((double)recvsize); - buf[recvsize>=0?recvsize:0]=0; - hash["str"]=ngc->newstr(buf); - delete[] buf; - ngc->temp=nil; - return res; -} - -var nas_recvfrom(var* args, usize size, gc* ngc) { - if (args[0].type!=vm_num) - return nas_err("recvfrom","\"sd\" must be a number"); - if (args[1].type!=vm_num) - return nas_err("recvfrom","\"len\" must be a number"); - if (args[1].num()<=0 || args[1].num()>16*1024*1024) - return nas_err("recvfrom","\"len\" out of range"); - if (args[2].type!=vm_num) - return nas_err("recvfrom","\"flags\" muse be a number"); - sockaddr_in addr; - int socklen=sizeof(sockaddr_in); - var res=ngc->temp=ngc->alloc(vm_hash); - auto& hash=res.hash().elems; - char* buf=new char[(int)args[1].num()+1]; -#ifdef _WIN32 - auto recvsize=recvfrom(args[0].num(),buf,args[1].num(),args[2].num(),(sockaddr*)&addr,&socklen); -#else - auto recvsize=recvfrom(args[0].num(),buf,args[1].num(),args[2].num(),(sockaddr*)&addr,(socklen_t*)&socklen); -#endif - hash["size"]=var::num((double)recvsize); - buf[recvsize>=0?recvsize:0]=0; - hash["str"]=ngc->newstr(buf); - delete[] buf; - hash["fromip"]=ngc->newstr(inet_ntoa(addr.sin_addr)); - ngc->temp=nil; - return res; -} - -var nas_errno(var* args, usize size, gc* ngc) { - return ngc->newstr(strerror(errno)); -} - -module_func_info func_tbl[]={ - {"nas_socket",nas_socket}, - {"nas_closesocket",nas_closesocket}, - {"nas_shutdown",nas_shutdown}, - {"nas_bind",nas_bind}, - {"nas_listen",nas_listen}, - {"nas_connect",nas_connect}, - {"nas_accept",nas_accept}, - {"nas_send",nas_send}, - {"nas_sendto",nas_sendto}, - {"nas_recv",nas_recv}, - {"nas_recvfrom",nas_recvfrom}, - {"nas_errno",nas_errno}, - {nullptr,nullptr} -}; - -extern "C" module_func_info* get(ghost_register_table* table) { - return func_tbl; +#include "../nasal.h" + +#ifndef _MSC_VER +#include +#endif + +#ifdef _WIN32 +#include +#pragma comment(lib,"ws2_32") + +class WSAmanager{ +private: + WSAData data; +public: + WSAmanager() { + WSAStartup(0x1010, &data); + } + ~WSAmanager() { + WSACleanup(); + } +}; + +static WSAmanager win; +#else +#include +#include +#include +#include +#endif + +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) + return nas_err("socket","\"af\", \"type\", \"protocol\" should be number"); + int sd=socket(args[0].num(),args[1].num(),args[2].num()); + return var::num((double)sd); +} + +var nas_closesocket(var* args, usize size, gc* ngc) { + if (args[0].type!=vm_num) + return nas_err("closesocket","\"sd\" should be number"); +#ifdef _WIN32 + return var::num((double)closesocket(args[0].num())); +#else + return var::num((double)close(args[0].num())); +#endif +} + +var nas_shutdown(var* args, usize size, gc* ngc) { + if (args[0].type!=vm_num) + return nas_err("shutdown","\"sd\" must be a number"); + if (args[1].type!=vm_num) + return nas_err("shutdown","\"how\" must be a number"); + return var::num((double)shutdown(args[0].num(),args[1].num())); +} + +var nas_bind(var* args, usize size, gc* ngc) { + if (args[0].type!=vm_num) + return nas_err("bind","\"sd\" muse be a number"); + if (args[1].type!=vm_str) + return nas_err("bind","\"ip\" should be a string including an ip with correct format"); + if (args[2].type!=vm_num) + return nas_err("bind","\"port\" must be a number"); + sockaddr_in server; + memset(&server,0,sizeof(sockaddr_in)); + server.sin_family=AF_INET; + server.sin_addr.s_addr=inet_addr(args[1].str().c_str()); + server.sin_port=htons(args[2].num()); + return var::num((double)bind(args[0].num(),(sockaddr*)&server,sizeof(server))); +} + +var nas_listen(var* args, usize size, gc* ngc) { + if (args[0].type!=vm_num) + return nas_err("listen","\"sd\" must be a number"); + if (args[1].type!=vm_num) + return nas_err("listen","\"backlog\" must be a number"); + return var::num((double)listen(args[0].num(),args[1].num())); +} + +var nas_connect(var* args, usize size, gc* ngc) { + if (args[0].type!=vm_num) + return nas_err("connect","\"sd\" must be a number"); + if (args[1].type!=vm_str) + return nas_err("connect","\"hostname\" must be a string"); + if (args[2].type!=vm_num) + return nas_err("connect","\"port\" must be a number"); + sockaddr_in addr; + memset(&addr,0,sizeof(sockaddr_in)); + addr.sin_family=AF_INET; + addr.sin_port=htons(args[2].num()); + hostent* entry=gethostbyname(args[1].str().c_str()); + memcpy(&addr.sin_addr,entry->h_addr,entry->h_length); + return var::num((double)connect(args[0].num(),(sockaddr*)&addr,sizeof(sockaddr_in))); +} + +var nas_accept(var* args, usize size, gc* ngc) { + if (args[0].type!=vm_num) + return nas_err("accept","\"sd\" must be a number"); + sockaddr_in client; + int socklen=sizeof(sockaddr_in); +#ifdef _WIN32 + int client_sd=accept(args[0].num(),(sockaddr*)&client,&socklen); +#else + int client_sd=accept(args[0].num(),(sockaddr*)&client,(socklen_t*)&socklen); +#endif + var res=ngc->temp=ngc->alloc(vm_hash); + auto& hash=res.hash().elems; + hash["sd"]=var::num((double)client_sd); + hash["ip"]=ngc->newstr(inet_ntoa(client.sin_addr)); + ngc->temp=nil; + return res; +} + +var nas_send(var* args, usize size, gc* ngc) { + if (args[0].type!=vm_num) + return nas_err("send","\"sd\" must be a number"); + if (args[1].type!=vm_str) + return nas_err("send","\"buff\" must be a string"); + if (args[2].type!=vm_num) + return nas_err("send","\"flags\" muse be a number"); + return var::num((double)send(args[0].num(),args[1].str().c_str(),args[1].str().length(),args[2].num())); +} + +var nas_sendto(var* args, usize size, gc* ngc) { + if (args[0].type!=vm_num) + return nas_err("sendto","\"sd\" must be a number"); + if (args[1].type!=vm_str) + return nas_err("sendto","\"hostname\" must be a string"); + if (args[2].type!=vm_num) + return nas_err("sendto","\"port\" must be a number"); + if (args[3].type!=vm_str) + return nas_err("sendto","\"buff\" must be a string"); + if (args[4].type!=vm_num) + return nas_err("sendto","\"flags\" must be a number"); + sockaddr_in addr; + memset(&addr,0,sizeof(sockaddr_in)); + addr.sin_family=AF_INET; + addr.sin_port=htons(args[2].num()); + hostent* entry=gethostbyname(args[1].str().c_str()); + memcpy(&addr.sin_addr,entry->h_addr,entry->h_length); + return var::num((double)sendto(args[0].num(),args[3].str().c_str(),args[3].str().length(),args[4].num(),(sockaddr*)&addr,sizeof(sockaddr_in))); +} + +var nas_recv(var* args, usize size, gc* ngc) { + if (args[0].type!=vm_num) + return nas_err("recv","\"sd\" must be a number"); + if (args[1].type!=vm_num) + return nas_err("recv","\"len\" must be a number"); + if (args[1].num()<=0 || args[1].num()>16*1024*1024) + return nas_err("recv","\"len\" out of range"); + if (args[2].type!=vm_num) + return nas_err("recv","\"flags\" muse be a number"); + var res=ngc->temp=ngc->alloc(vm_hash); + auto& hash=res.hash().elems; + char* buf=new char[(int)args[1].num()]; + auto recvsize=recv(args[0].num(),buf,args[1].num(),args[2].num()); + hash["size"]=var::num((double)recvsize); + buf[recvsize>=0?recvsize:0]=0; + hash["str"]=ngc->newstr(buf); + delete[] buf; + ngc->temp=nil; + return res; +} + +var nas_recvfrom(var* args, usize size, gc* ngc) { + if (args[0].type!=vm_num) + return nas_err("recvfrom","\"sd\" must be a number"); + if (args[1].type!=vm_num) + return nas_err("recvfrom","\"len\" must be a number"); + if (args[1].num()<=0 || args[1].num()>16*1024*1024) + return nas_err("recvfrom","\"len\" out of range"); + if (args[2].type!=vm_num) + return nas_err("recvfrom","\"flags\" muse be a number"); + sockaddr_in addr; + int socklen=sizeof(sockaddr_in); + var res=ngc->temp=ngc->alloc(vm_hash); + auto& hash=res.hash().elems; + char* buf=new char[(int)args[1].num()+1]; +#ifdef _WIN32 + auto recvsize=recvfrom(args[0].num(),buf,args[1].num(),args[2].num(),(sockaddr*)&addr,&socklen); +#else + auto recvsize=recvfrom(args[0].num(),buf,args[1].num(),args[2].num(),(sockaddr*)&addr,(socklen_t*)&socklen); +#endif + hash["size"]=var::num((double)recvsize); + buf[recvsize>=0?recvsize:0]=0; + hash["str"]=ngc->newstr(buf); + delete[] buf; + hash["fromip"]=ngc->newstr(inet_ntoa(addr.sin_addr)); + ngc->temp=nil; + return res; +} + +var nas_errno(var* args, usize size, gc* ngc) { + return ngc->newstr(strerror(errno)); +} + +module_func_info func_tbl[]={ + {"nas_socket",nas_socket}, + {"nas_closesocket",nas_closesocket}, + {"nas_shutdown",nas_shutdown}, + {"nas_bind",nas_bind}, + {"nas_listen",nas_listen}, + {"nas_connect",nas_connect}, + {"nas_accept",nas_accept}, + {"nas_send",nas_send}, + {"nas_sendto",nas_sendto}, + {"nas_recv",nas_recv}, + {"nas_recvfrom",nas_recvfrom}, + {"nas_errno",nas_errno}, + {nullptr,nullptr} +}; + +extern "C" module_func_info* get(ghost_register_table* table) { + return func_tbl; } \ No newline at end of file From 7f258dd17e472d514b34ebef86603b931d8c5e6d Mon Sep 17 00:00:00 2001 From: ValKmjolnir Date: Thu, 11 May 2023 19:58:25 +0800 Subject: [PATCH 5/6] :sparkles: vs could build with cmakelists.txt --- CMakeLists.txt | 24 +++++++++++++++++------- nasal_builtin.h | 3 +++ nasal_codegen.h | 5 +++++ nasal_gc.h | 5 +++++ nasal_lexer.h | 5 +++++ nasal_vm.h | 6 ++++++ 6 files changed, 41 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 39e57cd..278dcd9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,6 +2,8 @@ cmake_minimum_required(VERSION 3.10) project(nasal VERSION 10.1) +message("CMAKE_HOST_SYSTEM_NAME: ${CMAKE_HOST_SYSTEM_NAME}") + # -std=c++14 -Wshadow -Wall set(CMAKE_CXX_STANDARD 14) set(CMAKE_CXX_STANDARD_REQUIRED True) @@ -24,12 +26,20 @@ add_library(nasock SHARED ${CMAKE_SOURCE_DIR}/module/nasocket.cpp) target_include_directories(nasock PRIVATE ${CMAKE_SOURCE_DIR}) add_executable(nasal main.cpp) -target_link_libraries(nasal dl) + +if(CMAKE_HOST_SYSTEM_NAME MATCHES "Windows") + message("Ignore linking dl lib") +else() + target_link_libraries(nasal dl) +endif() + target_include_directories(nasal PRIVATE ${CMAKE_SOURCE_DIR}) -add_custom_command( - TARGET nasal POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy - ${CMAKE_SOURCE_DIR}/build/nasal - ${CMAKE_SOURCE_DIR}/nasal -) \ No newline at end of file +if(NOT CMAKE_HOST_SYSTEM_NAME MATCHES "Windows") + add_custom_command( + TARGET nasal POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy + ${CMAKE_SOURCE_DIR}/build/nasal + ${CMAKE_SOURCE_DIR}/nasal + ) +endif() \ No newline at end of file diff --git a/nasal_builtin.h b/nasal_builtin.h index f8653da..cb492fd 100644 --- a/nasal_builtin.h +++ b/nasal_builtin.h @@ -8,6 +8,9 @@ #include #else #pragma warning (disable:4566) // i know i'm using utf-8, fuck you +#pragma warning (disable:4244) +#pragma warning (disable:4267) +#pragma warning (disable:4996) #define _CRT_SECURE_NO_DEPRECATE 1 #define _CRT_NONSTDC_NO_DEPRECATE 1 #include diff --git a/nasal_codegen.h b/nasal_codegen.h index f503b90..ddae5b5 100644 --- a/nasal_codegen.h +++ b/nasal_codegen.h @@ -9,6 +9,11 @@ #include #include +#ifdef _MSC_VER +#pragma warning (disable:4244) +#pragma warning (disable:4267) +#endif + class codegen { private: u16 fileindex; diff --git a/nasal_gc.h b/nasal_gc.h index fe51d8b..271405a 100644 --- a/nasal_gc.h +++ b/nasal_gc.h @@ -1,4 +1,9 @@ #pragma once +#ifdef _MSC_VER +#pragma warning (disable:4244) +#pragma warning (disable:4267) +#pragma warning (disable:4102) +#endif #ifndef _MSC_VER #include diff --git a/nasal_lexer.h b/nasal_lexer.h index 27813ed..b6cae34 100644 --- a/nasal_lexer.h +++ b/nasal_lexer.h @@ -1,4 +1,9 @@ #pragma once +#ifdef _MSC_VER +#pragma warning (disable:4244) +#pragma warning (disable:4267) +#pragma warning (disable:4102) +#endif #include #include diff --git a/nasal_vm.h b/nasal_vm.h index a90a862..04de83c 100644 --- a/nasal_vm.h +++ b/nasal_vm.h @@ -7,6 +7,12 @@ #include "nasal_gc.h" #include "nasal_codegen.h" +#ifdef _MSC_VER +#pragma warning (disable:4244) +#pragma warning (disable:4267) +#pragma warning (disable:4102) +#endif + class vm { protected: From 63ec070d15724b5543a64f44c7e0716fd77ace50 Mon Sep 17 00:00:00 2001 From: ValKmjolnir Date: Thu, 11 May 2023 20:12:59 +0800 Subject: [PATCH 6/6] :memo: update doc for vs build --- .gitignore | 2 ++ doc/vs.md | 22 +++++++++++++++++----- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index cd32b92..0cfb1fc 100644 --- a/.gitignore +++ b/.gitignore @@ -38,6 +38,7 @@ *.vcxproj.user .vs x64 +CMakePresents.json # nasal executable nasal @@ -49,6 +50,7 @@ dump # build dir build +out # macOS special cache directory .DS_Store diff --git a/doc/vs.md b/doc/vs.md index ead05fe..afcf8b3 100644 --- a/doc/vs.md +++ b/doc/vs.md @@ -2,12 +2,22 @@ ## First | 首先 -Make sure you are using VS 2022. +We give a __CMakeLists.txt__ for you to create new VS project from it. -确保你使用的是 VS 2022。 +我们为你提供了 __CMakeLists.txt__ 用于创建新的 VS 工程。 + +If you are using this way, you will __not need__ to continue reading. + +如果你使用的是这种方式,下面的内容你就 __不需要__ 再读了。 + +Creating VS project from a CMake file is the __simplest__ way. + +从 CMake 文件创建 VS 工程是 __最简单__ 的方式。 ## How to Create VS project +Make sure you are using VS 2022. You may not get the dynamic libraries by using this way to compile. + 1. Get code from this repo using `git`. 2. In Visual Studio, click `File`->`New`->`Project From Existing Code...`. @@ -20,12 +30,14 @@ Make sure you are using VS 2022. ## 如何创建VS工程 -1. 用`git`从这个仓库获取代码。 +确保你使用的是 VS 2022。这个方式可能无法生成一些动态库。 + +1. 用 `git` 从这个仓库获取代码。 2. 在VS的界面,点击文件(F)->新建(N)->从现有代码创建项目(E)。 -3. 选择创建`Visual C++`项目->下一步->项目文件位置选择你下载的代码存放的文件夹->填项目名称,随便写->完成。 +3. 选择创建 `Visual C++` 项目->下一步->项目文件位置选择你下载的代码存放的文件夹->填项目名称,随便写->完成。 4. 从项目中去掉 `module` 里的cpp文件,以防止编译错误。(那些本应该编译到动态库) -5. 点开左侧解决方案资源管理器中的`Source Files`,右键点击`main.cpp`,编译。 +5. 点开左侧解决方案资源管理器中的 `Source Files`,右键点击 `main.cpp`,编译。