From 52e6adfe28649734b8d3a7e15d532cac2005dea7 Mon Sep 17 00:00:00 2001 From: ValKmjolnir Date: Tue, 8 Aug 2023 20:50:47 +0800 Subject: [PATCH 1/4] :fire: delete ghost type table --- module/fib.cpp | 14 ++------ module/keyboard.cpp | 2 +- module/matrix.cpp | 2 +- module/nasocket.cpp | 2 +- src/nasal_builtin.cpp | 34 ++++++++++---------- src/nasal_dbg.h | 2 ++ src/nasal_gc.cpp | 18 +++++++---- src/nasal_gc.h | 74 ++++++------------------------------------- 8 files changed, 46 insertions(+), 102 deletions(-) diff --git a/module/fib.cpp b/module/fib.cpp index 41c1449..80b4220 100644 --- a/module/fib.cpp +++ b/module/fib.cpp @@ -37,7 +37,7 @@ var quick_fib(var* args, usize size, gc* ngc) { return var::num(res); } -u32 ghost_for_test; +const auto ghost_for_test = "ghost_for_test"; void ghost_for_test_destructor(void* ptr) { std::cout << "ghost_for_test::destructor (0x"; @@ -49,7 +49,7 @@ void ghost_for_test_destructor(void* ptr) { var create_new_ghost(var* args, usize size, gc* ngc) { var res = ngc->alloc(vm_obj); - res.obj().set(ghost_for_test, new u32, &ngc->global_ghost_type_table); + res.obj().set(ghost_for_test, ghost_for_test_destructor, new u32); return res; } @@ -87,14 +87,6 @@ module_func_info func_tbl[] = { } -extern "C" module_func_info* get(ghost_register_table* table) { - if (table->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 - ); +extern "C" module_func_info* get() { return nasal_fib_module::func_tbl; } \ No newline at end of file diff --git a/module/keyboard.cpp b/module/keyboard.cpp index 18f0368..04a830d 100644 --- a/module/keyboard.cpp +++ b/module/keyboard.cpp @@ -99,6 +99,6 @@ module_func_info func_tbl[]={ {nullptr,nullptr} }; -extern "C" module_func_info* get(ghost_register_table* table) { +extern "C" module_func_info* get() { return func_tbl; } \ No newline at end of file diff --git a/module/matrix.cpp b/module/matrix.cpp index 8d1f582..e293837 100644 --- a/module/matrix.cpp +++ b/module/matrix.cpp @@ -291,6 +291,6 @@ module_func_info func_tbl[]={ {nullptr,nullptr} }; -extern "C" module_func_info* get(ghost_register_table* table) { +extern "C" module_func_info* get() { return func_tbl; } \ No newline at end of file diff --git a/module/nasocket.cpp b/module/nasocket.cpp index 5fffe8b..71b95c8 100644 --- a/module/nasocket.cpp +++ b/module/nasocket.cpp @@ -209,6 +209,6 @@ module_func_info func_tbl[]={ {nullptr,nullptr} }; -extern "C" module_func_info* get(ghost_register_table* table) { +extern "C" module_func_info* get() { return func_tbl; } \ No newline at end of file diff --git a/src/nasal_builtin.cpp b/src/nasal_builtin.cpp index 60ec19e..1047b6a 100644 --- a/src/nasal_builtin.cpp +++ b/src/nasal_builtin.cpp @@ -444,13 +444,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(ngc.global_ghost_type_table.ghost_file, res, &ngc.global_ghost_type_table); + ret.obj().set("file", filehandle_destructor, res); return ret; } var builtin_close(var* local, gc& ngc) { var fd = local[1]; - if (!fd.objchk(ngc.global_ghost_type_table.ghost_file)) { + if (!fd.objchk("file")) { return nas_err("close", "not a valid filehandle"); } fd.obj().clear(); @@ -461,7 +461,7 @@ var builtin_read(var* local, gc& ngc) { var fd = local[1]; var buf = local[2]; var len = local[3]; - if (!fd.objchk(ngc.global_ghost_type_table.ghost_file)) { + if (!fd.objchk("file")) { return nas_err("read", "not a valid filehandle"); } if (buf.type!=vm_str || buf.val.gcobj->unmut) { @@ -487,7 +487,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(ngc.global_ghost_type_table.ghost_file)) { + if (!fd.objchk("file")) { return nas_err("write", "not a valid filehandle"); } if (str.type!=vm_str) { @@ -500,7 +500,7 @@ var builtin_seek(var* local, gc& ngc) { var fd = local[1]; var pos = local[2]; var whence = local[3]; - if (!fd.objchk(ngc.global_ghost_type_table.ghost_file)) { + if (!fd.objchk("file")) { return nas_err("seek", "not a valid filehandle"); } return var::num((f64)fseek((FILE*)fd.obj().ptr, pos.num(), whence.num())); @@ -508,7 +508,7 @@ var builtin_seek(var* local, gc& ngc) { var builtin_tell(var* local, gc& ngc) { var fd = local[1]; - if (!fd.objchk(ngc.global_ghost_type_table.ghost_file)) { + if (!fd.objchk("file")) { return nas_err("tell", "not a valid filehandle"); } return var::num((f64)ftell((FILE*)fd.obj().ptr)); @@ -516,7 +516,7 @@ var builtin_tell(var* local, gc& ngc) { var builtin_readln(var* local, gc& ngc) { var fd = local[1]; - if (!fd.objchk(ngc.global_ghost_type_table.ghost_file)) { + if (!fd.objchk("file")) { return nas_err("readln", "not a valid filehandle"); } var str = ngc.alloc(vm_str); @@ -564,7 +564,7 @@ var builtin_stat(var* local, gc& ngc) { var builtin_eof(var* local, gc& ngc) { var fd = local[1]; - if (!fd.objchk(ngc.global_ghost_type_table.ghost_file)) { + if (!fd.objchk("file")) { return nas_err("readln", "not a valid filehandle"); } return var::num((f64)feof((FILE*)fd.obj().ptr)); @@ -646,13 +646,13 @@ var builtin_opendir(var* local, gc& ngc) { } #endif var ret = ngc.alloc(vm_obj); - ret.obj().set(ngc.global_ghost_type_table.ghost_dir, p, &ngc.global_ghost_type_table); + ret.obj().set("dir", dir_entry_destructor, p); return ret; } var builtin_readdir(var* local, gc& ngc) { var handle = local[1]; - if (!handle.objchk(ngc.global_ghost_type_table.ghost_dir)) { + if (!handle.objchk("dir")) { return nas_err("readdir", "not a valid dir handle"); } #ifdef _MSC_VER @@ -669,7 +669,7 @@ var builtin_readdir(var* local, gc& ngc) { var builtin_closedir(var* local, gc& ngc) { var handle = local[1]; - if (!handle.objchk(ngc.global_ghost_type_table.ghost_dir)) { + if (!handle.objchk("dir")) { return nas_err("closedir", "not a valid dir handle"); } handle.obj().clear(); @@ -733,7 +733,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(ngc.global_ghost_type_table.ghost_dylib, ptr, &ngc.global_ghost_type_table); + lib.obj().set("dylib", dylib_destructor, ptr); ret.hash().elems["lib"] = lib; #ifdef _WIN32 @@ -745,14 +745,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)(&ngc.global_ghost_type_table); + module_func_info* tbl = ((get_func_ptr)func)(); 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(ngc.global_ghost_type_table.ghost_faddr, p, &ngc.global_ghost_type_table); + tmp.obj().set("faddr", func_addr_destructor, p); ret.hash().elems[tbl[i].name] = tmp; } @@ -762,7 +762,7 @@ var builtin_dlopen(var* local, gc& ngc) { var builtin_dlclose(var* local, gc& ngc) { var libptr = local[1]; - if (!libptr.objchk(ngc.global_ghost_type_table.ghost_dylib)) { + if (!libptr.objchk("dylib")) { return nas_err("dlclose", "\"lib\" is not a valid dynamic lib"); } libptr.obj().clear(); @@ -772,7 +772,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(ngc.global_ghost_type_table.ghost_faddr)) { + if (!fp.objchk("faddr")) { return nas_err("dlcall", "\"ptr\" is not a valid function pointer"); } auto& vec = args.vec().elems; @@ -781,7 +781,7 @@ var builtin_dlcallv(var* local, gc& ngc) { var builtin_dlcall(var* local, gc& ngc) { var fp = local[1]; - if (!fp.objchk(ngc.global_ghost_type_table.ghost_faddr)) { + if (!fp.objchk("faddr")) { return nas_err("dlcall", "\"ptr\" is not a valid function pointer"); } diff --git a/src/nasal_dbg.h b/src/nasal_dbg.h index 7f466e4..f4c645a 100644 --- a/src/nasal_dbg.h +++ b/src/nasal_dbg.h @@ -141,9 +141,11 @@ private: u32 bk_line; error src; +private: debug_prof_data data; bool do_profiling; +private: std::vector parse(const std::string&); u16 file_index(const std::string&) const; void err(); diff --git a/src/nasal_gc.cpp b/src/nasal_gc.cpp index b99fe96..b7b9882 100644 --- a/src/nasal_gc.cpp +++ b/src/nasal_gc.cpp @@ -123,18 +123,22 @@ void nas_func::clear() { } void nas_ghost::set( - usize ghost_type, void* ghost_pointer, ghost_register_table* table) { - type = ghost_type; + const std::string& ghost_type_name, + destructor destructor_pointer, + void* ghost_pointer) { + type_name = ghost_type_name; + dtor_ptr = destructor_pointer; ptr = ghost_pointer; - ghost_type_table = table; } void nas_ghost::clear() { - if (!ptr) { + if (!ptr || !dtor_ptr) { return; } - ghost_type_table->destructor(type)(ptr); + dtor_ptr(ptr); + type_name = ""; ptr = nullptr; + dtor_ptr = nullptr; } std::ostream& operator<<(std::ostream& out, const nas_ghost& ghost) { @@ -268,8 +272,8 @@ std::ostream& operator<<(std::ostream& out, var& ref) { return out; } -bool var::objchk(usize obj_type) { - return type==vm_obj && obj().type==obj_type && obj().ptr; +bool var::objchk(const std::string& name) { + return type==vm_obj && obj().type_name==name && obj().ptr; } var var::none() { diff --git a/src/nasal_gc.h b/src/nasal_gc.h index 539104c..08529e4 100644 --- a/src/nasal_gc.h +++ b/src/nasal_gc.h @@ -93,7 +93,7 @@ public: // number and string can be translated to each other f64 tonum(); std::string tostr(); - bool objchk(usize); + bool objchk(const std::string&); // create new var object static var none(); @@ -185,77 +185,24 @@ void dir_entry_destructor(void*); void dylib_destructor(void*); void func_addr_destructor(void*); -struct ghost_register_table { -private: - using dtor=void (*)(void*); - -private: - std::unordered_map mapper; - std::vector ghost_name; - 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", 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); - } - - bool exists(const std::string& name) const { - return mapper.count(name); - } - - usize get_ghost_type_index(const std::string& name) const { - return mapper.at(name); - } - - const std::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: "; - std::cerr << "ghost type \"" << name << "\" already exists.\n"; - std::exit(1); - } - auto res = destructors.size(); - mapper[name] = res; - ghost_name.push_back(name); - destructors.push_back(ptr); - return res; - } - - dtor destructor(usize index) { - return destructors.at(index); - } -}; - struct nas_ghost { +private: + using destructor=void (*)(void*); + public: - usize type; + std::string type_name; + destructor dtor_ptr; void* ptr; -private: - ghost_register_table* ghost_type_table; - public: - nas_ghost(): type(0), ptr(nullptr), ghost_type_table(nullptr) {} + nas_ghost(): type_name(""), dtor_ptr(nullptr), ptr(nullptr) {} ~nas_ghost() {clear();} - void set(usize, void*, ghost_register_table*); + void set(const std::string&, destructor, void*); void clear(); public: const std::string& get_ghost_name() const { - return ghost_type_table->get_ghost_name(type); + return type_name; } }; @@ -336,7 +283,6 @@ 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; @@ -433,4 +379,4 @@ struct module_func_info { }; // module function "get" type -typedef module_func_info* (*get_func_ptr)(ghost_register_table*); +typedef module_func_info* (*get_func_ptr)(); From d690c779b84b8f52251af02010a9d469af28851a Mon Sep 17 00:00:00 2001 From: ValKmjolnir Date: Wed, 9 Aug 2023 00:31:23 +0800 Subject: [PATCH 2/4] :sparkles: split io lib --- CMakeLists.txt | 1 + makefile | 8 ++ module/libfib.nas | 77 +++++++++++------ module/libmat.nas | 104 ++++++++++++----------- src/io_lib.cpp | 191 ++++++++++++++++++++++++++++++++++++++++++ src/io_lib.h | 26 ++++++ src/nasal_builtin.cpp | 186 ---------------------------------------- src/nasal_builtin.h | 13 --- src/nasal_codegen.cpp | 1 + src/nasal_codegen.h | 1 + std/bits.nas | 14 ++-- test/module_test.nas | 4 + 12 files changed, 345 insertions(+), 281 deletions(-) create mode 100644 src/io_lib.cpp create mode 100644 src/io_lib.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 8dbdfd5..7e40a9b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,6 +23,7 @@ set(NASAL_OBJECT_SOURCE_FILE ${CMAKE_SOURCE_DIR}/src/coroutine.cpp ${CMAKE_SOURCE_DIR}/src/fg_props.cpp ${CMAKE_SOURCE_DIR}/src/bits_lib.cpp + ${CMAKE_SOURCE_DIR}/src/io_lib.cpp ${CMAKE_SOURCE_DIR}/src/math_lib.cpp ${CMAKE_SOURCE_DIR}/src/nasal_codegen.cpp ${CMAKE_SOURCE_DIR}/src/nasal_dbg.cpp diff --git a/makefile b/makefile index 0276c49..ba1c8e5 100644 --- a/makefile +++ b/makefile @@ -19,6 +19,7 @@ NASAL_HEADER=\ src/symbol_finder.h\ src/fg_props.h\ src/bits_lib.h\ + src/io_lib.h\ src/math_lib.h\ src/coroutine.h @@ -39,6 +40,7 @@ NASAL_OBJECT=\ build/nasal_gc.o\ build/nasal_builtin.o\ build/fg_props.o\ + build/io_lib.o\ build/math_lib.o\ build/coroutine.o\ build/nasal_vm.o\ @@ -111,6 +113,12 @@ build/math_lib.o: \ src/math_lib.h src/math_lib.cpp | build $(CXX) -std=$(STD) -c -O3 src/math_lib.cpp -fno-exceptions -fPIC -o build/math_lib.o -I . +build/io_lib.o: \ + src/nasal.h\ + src/nasal_gc.h\ + src/io_lib.h src/io_lib.cpp | build + $(CXX) -std=$(STD) -c -O3 src/io_lib.cpp -fno-exceptions -fPIC -o build/io_lib.o -I . + build/fg_props.o: \ src/nasal.h\ src/nasal_gc.h\ diff --git a/module/libfib.nas b/module/libfib.nas index 5367585..355a357 100644 --- a/module/libfib.nas +++ b/module/libfib.nas @@ -1,31 +1,54 @@ import.std.dylib; -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); - 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)} - }; +var _dl = dylib.dlopen("libfib."~(os.platform()=="windows"?"dll":"so")); - 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 - } +var _fib = _dl.fib; - return res; -}(); \ No newline at end of file +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); + +var _test_call = dylib.limitcall(2); + + +var fib = func(x) { + return _call(_fib, x) +} + + +var qfib = func(x) { + return _call(_qfib, x) +} + + +var create_ghost = func() { + return _zero_call(_create_ghost) +} + + +var set_ghost = func(object, x) { + return _test_call(_set_ghost, object, x) +} + + +var print_ghost = func(object) { + return _call(_print_ghost, object) +} + + +var test_ghost=func() { + var ghost = create_ghost(); + print_ghost(nil); # err + print_ghost(ghost); # random + set_ghost(nil, 114); # err + set_ghost(ghost, 114); # success + print_ghost(ghost); # 114 +} diff --git a/module/libmat.nas b/module/libmat.nas index 0159fc8..cd06928 100644 --- a/module/libmat.nas +++ b/module/libmat.nas @@ -1,62 +1,66 @@ import.std.dylib; -var dl=dylib.dlopen("libmat."~(os.platform()=="windows"?"dll":"so")); -var vec2=dl.nas_vec2; -var vec3=dl.nas_vec3; -var (vec2add,vec2sub,vec2mul,vec2div,vec2neg,vec2norm,vec2len,vec2dot)=( - dl.nas_vec2_add, - dl.nas_vec2_sub, - dl.nas_vec2_mult, - dl.nas_vec2_div, - dl.nas_vec2_neg, - dl.nas_vec2_norm, - dl.nas_vec2_len, - dl.nas_vec2_dot +var _dl = dylib.dlopen("libmat."~(os.platform()=="windows"?"dll":"so")); + +var _vec2 = _dl.nas_vec2; + +var _vec3 = _dl.nas_vec3; + +var (_vec2add, _vec2sub, _vec2mul, _vec2div, _vec2neg, _vec2norm, _vec2len, _vec2dot)=( + _dl.nas_vec2_add, + _dl.nas_vec2_sub, + _dl.nas_vec2_mult, + _dl.nas_vec2_div, + _dl.nas_vec2_neg, + _dl.nas_vec2_norm, + _dl.nas_vec2_len, + _dl.nas_vec2_dot ); -var (vec3add,vec3sub,vec3mul,vec3div,vec3neg,vec3norm,vec3len,vec3dot)=( - dl.nas_vec3_add, - dl.nas_vec3_sub, - dl.nas_vec3_mult, - dl.nas_vec3_div, - dl.nas_vec3_neg, - dl.nas_vec3_norm, - dl.nas_vec3_len, - dl.nas_vec3_dot +var (_vec3add, _vec3sub, _vec3mul, _vec3div, _vec3neg, _vec3norm, _vec3len, _vec3dot)=( + _dl.nas_vec3_add, + _dl.nas_vec3_sub, + _dl.nas_vec3_mult, + _dl.nas_vec3_div, + _dl.nas_vec3_neg, + _dl.nas_vec3_norm, + _dl.nas_vec3_len, + _dl.nas_vec3_dot ); -var (rotate_x,rotate_y,rotate_z)=( - dl.nas_rotate_x, - dl.nas_rotate_y, - dl.nas_rotate_z +var (_rotate_x, _rotate_y, _rotate_z)=( + _dl.nas_rotate_x, + _dl.nas_rotate_y, + _dl.nas_rotate_z ); -var (invoke_i,invoke_ii,invoke_iii)=( +var (_invoke_i, _invoke_ii, _invoke_iii)=( dylib.limitcall(1), dylib.limitcall(2), dylib.limitcall(3) ); -var vec2={ - new: func(x,y){return invoke_ii(vec2,x,y);}, - add: func(v0,v1){return invoke_ii(vec2add,v0,v1);}, - sub: func(v0,v1){return invoke_ii(vec2sub,v0,v1);}, - mul: func(v0,v1){return invoke_ii(vec2mul,v0,v1);}, - div: func(v0,v1){return invoke_ii(vec2div,v0,v1);}, - neg: func(v0){return invoke_i(vec2neg,v0);}, - norm: func(v0){return invoke_i(vec2norm,v0);}, - len: func(v0){return invoke_i(vec2len,v0);}, - dot: func(v0,v1){return invoke_ii(vec2dot,v0,v1);} -}; -var vec3={ - new: func(x,y,z){return invoke_iii(vec3,x,y,z);}, - add: func(v0,v1){return invoke_ii(vec3add,v0,v1);}, - sub: func(v0,v1){return invoke_ii(vec3sub,v0,v1);}, - mul: func(v0,v1){return invoke_ii(vec3mul,v0,v1);}, - div: func(v0,v1){return invoke_ii(vec3div,v0,v1);}, - neg: func(v0){return invoke_i(vec3neg,v0);}, - norm: func(v0){return invoke_i(vec3norm,v0);}, - len: func(v0){return invoke_i(vec3len,v0);}, - rx: func(v0,angle){return invoke_ii(rotate_x,v0,angle);}, - ry: func(v0,angle){return invoke_ii(rotate_y,v0,angle);}, - rz: func(v0,angle){return invoke_ii(rotate_z,v0,angle);}, - dot: func(v0,v1){return invoke_ii(vec3dot,v0,v1);} +var vec2 = { + new: func(x, y) {return _invoke_ii(_vec2, x, y);}, + add: func(v0, v1) {return _invoke_ii(_vec2add, v0, v1);}, + sub: func(v0, v1) {return _invoke_ii(_vec2sub, v0, v1);}, + mul: func(v0, v1) {return _invoke_ii(_vec2mul, v0, v1);}, + div: func(v0, v1) {return _invoke_ii(_vec2div, v0, v1);}, + neg: func(v0) {return _invoke_i(_vec2neg, v0);}, + norm: func(v0) {return _invoke_i(_vec2norm, v0);}, + len: func(v0) {return _invoke_i(_vec2len, v0);}, + dot: func(v0, v1) {return _invoke_ii(_vec2dot, v0, v1);} +}; + +var vec3 = { + new: func(x, y, z) {return _invoke_iii(_vec3, x, y, z);}, + add: func(v0, v1) {return _invoke_ii(_vec3add, v0, v1);}, + sub: func(v0, v1) {return _invoke_ii(_vec3sub, v0, v1);}, + mul: func(v0, v1) {return _invoke_ii(_vec3mul, v0, v1);}, + div: func(v0, v1) {return _invoke_ii(_vec3div, v0, v1);}, + neg: func(v0) {return _invoke_i(_vec3neg, v0);}, + norm: func(v0) {return _invoke_i(_vec3norm, v0);}, + len: func(v0) {return _invoke_i(_vec3len, v0);}, + rx: func(v0, angle) {return _invoke_ii(_rotate_x, v0, angle);}, + ry: func(v0, angle) {return _invoke_ii(_rotate_y, v0, angle);}, + rz: func(v0, angle) {return _invoke_ii(_rotate_z, v0, angle);}, + dot: func(v0, v1) {return _invoke_ii(_vec3dot, v0, v1);} }; diff --git a/src/io_lib.cpp b/src/io_lib.cpp new file mode 100644 index 0000000..b7463a9 --- /dev/null +++ b/src/io_lib.cpp @@ -0,0 +1,191 @@ +#include "io_lib.h" + +var builtin_readfile(var* local, gc& ngc) { + var val = local[1]; + if (val.type!=vm_str) { + return nas_err("io::readfile", "\"filename\" must be string"); + } + std::ifstream in(val.str(), std::ios::binary); + std::stringstream rd; + if (!in.fail()) { + rd << in.rdbuf(); + } + return ngc.newstr(rd.str()); +} + +var builtin_fout(var* local, gc& ngc) { + var val = local[1]; + var str = local[2]; + if (val.type!=vm_str) { + return nas_err("io::fout", "\"filename\" must be string"); + } + std::ofstream out(val.str()); + if (out.fail()) { + return nas_err("io::fout", "cannot open <"+val.str()+">"); + } + out << str; + return nil; +} + +var builtin_exists(var* local, gc& ngc) { + if (local[1].type!=vm_str) { + return zero; + } + return access(local[1].str().c_str(), F_OK)!=-1?one:zero; +} + +var builtin_open(var* local, gc& ngc) { + var name = local[1]; + var mode = local[2]; + if (name.type!=vm_str) { + return nas_err("open", "\"filename\" must be string"); + } + if (mode.type!=vm_str) { + return nas_err("open", "\"mode\" must be string"); + } + FILE* res = fopen(name.str().c_str(), mode.str().c_str()); + if (!res) { + return nas_err("open", "failed to open file <"+name.str()+">"); + } + var ret = ngc.alloc(vm_obj); + ret.obj().set("file", filehandle_destructor, res); + return ret; +} + +var builtin_close(var* local, gc& ngc) { + var fd = local[1]; + if (!fd.objchk("file")) { + return nas_err("close", "not a valid filehandle"); + } + fd.obj().clear(); + return nil; +} + +var builtin_read(var* local, gc& ngc) { + var fd = local[1]; + var buf = local[2]; + var len = local[3]; + if (!fd.objchk("file")) { + return nas_err("read", "not a valid filehandle"); + } + if (buf.type!=vm_str || buf.val.gcobj->unmut) { + return nas_err("read", "\"buf\" must be mutable string"); + } + if (len.type!=vm_num) { + return nas_err("read", "\"len\" must be number"); + } + if (len.num()<=0 || len.num()>=(1<<30)) { + return nas_err("read", "\"len\" less than 1 or too large"); + } + char* buff = new char[(usize)len.num()+1]; + if (!buff) { + return nas_err("read", "malloc failed"); + } + f64 res = fread(buff,1,len.num(), (FILE*)fd.obj().ptr); + buf.str() = buff; + buf.val.gcobj->unmut = true; + delete []buff; + return var::num(res); +} + +var builtin_write(var* local, gc& ngc) { + var fd = local[1]; + var str = local[2]; + if (!fd.objchk("file")) { + return nas_err("write", "not a valid filehandle"); + } + if (str.type!=vm_str) { + return nas_err("write", "\"str\" must be string"); + } + return var::num((f64)fwrite(str.str().c_str(), 1, str.str().length(), (FILE*)fd.obj().ptr)); +} + +var builtin_seek(var* local, gc& ngc) { + var fd = local[1]; + var pos = local[2]; + var whence = local[3]; + if (!fd.objchk("file")) { + return nas_err("seek", "not a valid filehandle"); + } + return var::num((f64)fseek((FILE*)fd.obj().ptr, pos.num(), whence.num())); +} + +var builtin_tell(var* local, gc& ngc) { + var fd = local[1]; + if (!fd.objchk("file")) { + return nas_err("tell", "not a valid filehandle"); + } + return var::num((f64)ftell((FILE*)fd.obj().ptr)); +} + +var builtin_readln(var* local, gc& ngc) { + var fd = local[1]; + if (!fd.objchk("file")) { + return nas_err("readln", "not a valid filehandle"); + } + var str = ngc.alloc(vm_str); + char c; + while((c = fgetc((FILE*)fd.obj().ptr))!=EOF) { + if (c=='\r') { + continue; + } + if (c=='\n') { + return str; + } + str.str() += c; + } + if (str.str().length()) { + return str; + } + return nil; +} + +var builtin_stat(var* local, gc& ngc) { + var name = local[1]; + if (name.type!=vm_str) { + return nas_err("stat", "\"filename\" must be string"); + } + struct stat buf; + if (stat(name.str().c_str(),&buf)<0) { + return nas_err("stat", "failed to open file <"+name.str()+">"); + } + var ret = ngc.alloc(vm_vec); + ret.vec().elems = { + var::num((f64)buf.st_dev), + var::num((f64)buf.st_ino), + var::num((f64)buf.st_mode), + var::num((f64)buf.st_nlink), + var::num((f64)buf.st_uid), + var::num((f64)buf.st_gid), + var::num((f64)buf.st_rdev), + var::num((f64)buf.st_size), + var::num((f64)buf.st_atime), + var::num((f64)buf.st_mtime), + var::num((f64)buf.st_ctime) + }; + return ret; +} + +var builtin_eof(var* local, gc& ngc) { + var fd = local[1]; + if (!fd.objchk("file")) { + return nas_err("readln", "not a valid filehandle"); + } + return var::num((f64)feof((FILE*)fd.obj().ptr)); +} + +nasal_builtin_table io_lib_native[] = { + {"__readfile", builtin_readfile}, + {"__fout", builtin_fout}, + {"__exists", builtin_exists}, + {"__open", builtin_open}, + {"__close", builtin_close}, + {"__read", builtin_read}, + {"__write", builtin_write}, + {"__seek", builtin_seek}, + {"__tell", builtin_tell}, + {"__readln", builtin_readln}, + {"__stat", builtin_stat}, + {"__eof", builtin_eof}, + {nullptr, nullptr} +}; \ No newline at end of file diff --git a/src/io_lib.h b/src/io_lib.h new file mode 100644 index 0000000..980dea8 --- /dev/null +++ b/src/io_lib.h @@ -0,0 +1,26 @@ +#pragma once + +#include "nasal.h" +#include "nasal_gc.h" +#include "nasal_builtin.h" + +#include + +#ifdef _MSC_VER +#define F_OK 0 // fuck msc +#endif + +var builtin_readfile(var*, gc&); +var builtin_fout(var*, gc&); +var builtin_exists(var*, gc&); +var builtin_open(var*, gc&); +var builtin_close(var*, gc&); +var builtin_read(var*, gc&); +var builtin_write(var*, gc&); +var builtin_seek(var*, gc&); +var builtin_tell(var*, gc&); +var builtin_readln(var*, gc&); +var builtin_stat(var*, gc&); +var builtin_eof(var*, gc&); + +extern nasal_builtin_table io_lib_native[]; \ No newline at end of file diff --git a/src/nasal_builtin.cpp b/src/nasal_builtin.cpp index 1047b6a..6a3c87c 100644 --- a/src/nasal_builtin.cpp +++ b/src/nasal_builtin.cpp @@ -72,33 +72,6 @@ var builtin_input(var* local, gc& ngc) { return ret; } -var builtin_readfile(var* local, gc& ngc) { - var val = local[1]; - if (val.type!=vm_str) { - return nas_err("io::readfile", "\"filename\" must be string"); - } - std::ifstream in(val.str(), std::ios::binary); - std::stringstream rd; - if (!in.fail()) { - rd << in.rdbuf(); - } - return ngc.newstr(rd.str()); -} - -var builtin_fout(var* local, gc& ngc) { - var val = local[1]; - var str = local[2]; - if (val.type!=vm_str) { - return nas_err("io::fout", "\"filename\" must be string"); - } - std::ofstream out(val.str()); - if (out.fail()) { - return nas_err("io::fout", "cannot open <"+val.str()+">"); - } - out << str; - return nil; -} - var builtin_split(var* local, gc& ngc) { var delimeter = local[1]; var str = local[2]; @@ -423,153 +396,6 @@ var builtin_values(var* local, gc& ngc) { return vec; } -var builtin_exists(var* local, gc& ngc) { - if (local[1].type!=vm_str) { - return zero; - } - return access(local[1].str().c_str(), F_OK)!=-1?one:zero; -} - -var builtin_open(var* local, gc& ngc) { - var name = local[1]; - var mode = local[2]; - if (name.type!=vm_str) { - return nas_err("open", "\"filename\" must be string"); - } - if (mode.type!=vm_str) { - return nas_err("open", "\"mode\" must be string"); - } - FILE* res = fopen(name.str().c_str(), mode.str().c_str()); - if (!res) { - return nas_err("open", "failed to open file <"+name.str()+">"); - } - var ret = ngc.alloc(vm_obj); - ret.obj().set("file", filehandle_destructor, res); - return ret; -} - -var builtin_close(var* local, gc& ngc) { - var fd = local[1]; - if (!fd.objchk("file")) { - return nas_err("close", "not a valid filehandle"); - } - fd.obj().clear(); - return nil; -} - -var builtin_read(var* local, gc& ngc) { - var fd = local[1]; - var buf = local[2]; - var len = local[3]; - if (!fd.objchk("file")) { - return nas_err("read", "not a valid filehandle"); - } - if (buf.type!=vm_str || buf.val.gcobj->unmut) { - return nas_err("read", "\"buf\" must be mutable string"); - } - if (len.type!=vm_num) { - return nas_err("read", "\"len\" must be number"); - } - if (len.num()<=0 || len.num()>=(1<<30)) { - return nas_err("read", "\"len\" less than 1 or too large"); - } - char* buff = new char[(usize)len.num()+1]; - if (!buff) { - return nas_err("read", "malloc failed"); - } - f64 res = fread(buff,1,len.num(), (FILE*)fd.obj().ptr); - buf.str() = buff; - buf.val.gcobj->unmut = true; - delete []buff; - return var::num(res); -} - -var builtin_write(var* local, gc& ngc) { - var fd = local[1]; - var str = local[2]; - if (!fd.objchk("file")) { - return nas_err("write", "not a valid filehandle"); - } - if (str.type!=vm_str) { - return nas_err("write", "\"str\" must be string"); - } - return var::num((f64)fwrite(str.str().c_str(), 1, str.str().length(), (FILE*)fd.obj().ptr)); -} - -var builtin_seek(var* local, gc& ngc) { - var fd = local[1]; - var pos = local[2]; - var whence = local[3]; - if (!fd.objchk("file")) { - return nas_err("seek", "not a valid filehandle"); - } - return var::num((f64)fseek((FILE*)fd.obj().ptr, pos.num(), whence.num())); -} - -var builtin_tell(var* local, gc& ngc) { - var fd = local[1]; - if (!fd.objchk("file")) { - return nas_err("tell", "not a valid filehandle"); - } - return var::num((f64)ftell((FILE*)fd.obj().ptr)); -} - -var builtin_readln(var* local, gc& ngc) { - var fd = local[1]; - if (!fd.objchk("file")) { - return nas_err("readln", "not a valid filehandle"); - } - var str = ngc.alloc(vm_str); - char c; - while((c = fgetc((FILE*)fd.obj().ptr))!=EOF) { - if (c=='\r') { - continue; - } - if (c=='\n') { - return str; - } - str.str() += c; - } - if (str.str().length()) { - return str; - } - return nil; -} - -var builtin_stat(var* local, gc& ngc) { - var name = local[1]; - if (name.type!=vm_str) { - return nas_err("stat", "\"filename\" must be string"); - } - struct stat buf; - if (stat(name.str().c_str(),&buf)<0) { - return nas_err("stat", "failed to open file <"+name.str()+">"); - } - var ret = ngc.alloc(vm_vec); - ret.vec().elems = { - var::num((f64)buf.st_dev), - var::num((f64)buf.st_ino), - var::num((f64)buf.st_mode), - var::num((f64)buf.st_nlink), - var::num((f64)buf.st_uid), - var::num((f64)buf.st_gid), - var::num((f64)buf.st_rdev), - var::num((f64)buf.st_size), - var::num((f64)buf.st_atime), - var::num((f64)buf.st_mtime), - var::num((f64)buf.st_ctime) - }; - return ret; -} - -var builtin_eof(var* local, gc& ngc) { - var fd = local[1]; - if (!fd.objchk("file")) { - return nas_err("readln", "not a valid filehandle"); - } - return var::num((f64)feof((FILE*)fd.obj().ptr)); -} - var builtin_sleep(var* local, gc& ngc) { var val = local[1]; if (val.type!=vm_num) { @@ -1003,8 +829,6 @@ nasal_builtin_table builtin[] = { {"__setsize", builtin_setsize}, {"__system", builtin_system}, {"__input", builtin_input}, - {"__readfile", builtin_readfile}, - {"__fout", builtin_fout}, {"__split", builtin_split}, {"__rand", builtin_rand}, {"__id", builtin_id}, @@ -1029,16 +853,6 @@ nasal_builtin_table builtin[] = { {"__chr", builtin_chr}, {"__char", builtin_char}, {"__values", builtin_values}, - {"__exists", builtin_exists}, - {"__open", builtin_open}, - {"__close", builtin_close}, - {"__read", builtin_read}, - {"__write", builtin_write}, - {"__seek", builtin_seek}, - {"__tell", builtin_tell}, - {"__readln", builtin_readln}, - {"__stat", builtin_stat}, - {"__eof", builtin_eof}, {"__sleep", builtin_sleep}, {"__pipe", builtin_pipe}, {"__fork", builtin_fork}, diff --git a/src/nasal_builtin.h b/src/nasal_builtin.h index f4a4e3d..c6c5a7a 100644 --- a/src/nasal_builtin.h +++ b/src/nasal_builtin.h @@ -21,7 +21,6 @@ #include #include #include -#include #ifdef _WIN32 #include @@ -43,8 +42,6 @@ var builtin_append(var*, gc&); var builtin_setsize(var*, gc&); var builtin_system(var*, gc&); var builtin_input(var*, gc&); -var builtin_readfile(var*, gc&); -var builtin_fout(var*, gc&); var builtin_split(var*, gc&); var builtin_rand(var*, gc&); var builtin_id(var*, gc&); @@ -69,16 +66,6 @@ var builtin_cmp(var*, gc&); var builtin_chr(var*, gc&); var builtin_char(var*, gc&); var builtin_values(var*, gc&); -var builtin_exists(var*, gc&); -var builtin_open(var*, gc&); -var builtin_close(var*, gc&); -var builtin_read(var*, gc&); -var builtin_write(var*, gc&); -var builtin_seek(var*, gc&); -var builtin_tell(var*, gc&); -var builtin_readln(var*, gc&); -var builtin_stat(var*, gc&); -var builtin_eof(var*, gc&); var builtin_sleep(var*, gc&); var builtin_pipe(var*, gc&); var builtin_fork(var*, gc&); diff --git a/src/nasal_codegen.cpp b/src/nasal_codegen.cpp index e55086e..7373a26 100644 --- a/src/nasal_codegen.cpp +++ b/src/nasal_codegen.cpp @@ -21,6 +21,7 @@ void codegen::load_native_function_table(nasal_builtin_table* table) { void codegen::init_native_function() { load_native_function_table(builtin); + load_native_function_table(io_lib_native); load_native_function_table(math_lib_native); load_native_function_table(bits_native); load_native_function_table(coroutine_native); diff --git a/src/nasal_codegen.h b/src/nasal_codegen.h index fdf10bc..53b84a7 100644 --- a/src/nasal_codegen.h +++ b/src/nasal_codegen.h @@ -13,6 +13,7 @@ #include "bits_lib.h" #include "math_lib.h" #include "fg_props.h" +#include "io_lib.h" #include #include diff --git a/std/bits.nas b/std/bits.nas index 597fdc8..177abf7 100644 --- a/std/bits.nas +++ b/std/bits.nas @@ -59,12 +59,16 @@ var buf = func(len) { return __buf; } -var bit = [var __ = 1]; -for(var i = 1; i<32; i += 1) { - func(vec, arg...){ +var bit = func() { + var res = [var __ = 1]; + var append = func(vec, arg...) { return __append; - }(bit, __ += __); -} + } + for(var i = 1; i<32; i += 1) { + append(res, __ += __); + } + return res; +}(); var test = func(n, b) { n /= bit[b]; diff --git a/test/module_test.nas b/test/module_test.nas index bc8f595..da9678c 100644 --- a/test/module_test.nas +++ b/test/module_test.nas @@ -1,4 +1,8 @@ import.std.dylib; +import.module.libfib; + +println(keys(libfib)); +libfib.test_ghost(); var libfib=func(){ var (dd,fib,qfib)=(nil,nil,nil); From 527cb5277bc96daea9aa314f07d800ededbd4e6b Mon Sep 17 00:00:00 2001 From: ValKmjolnir Date: Thu, 10 Aug 2023 00:40:00 +0800 Subject: [PATCH 3/4] :zap: optimize vm --- CMakeLists.txt | 2 ++ makefile | 16 ++++++++++++++++ src/dylib_lib.cpp | 5 +++++ src/dylib_lib.h | 7 +++++++ src/io_lib.cpp | 25 +++++++++++++++++-------- src/io_lib.h | 2 ++ src/nasal_codegen.cpp | 2 ++ src/nasal_codegen.h | 2 ++ src/nasal_gc.cpp | 7 ------- src/nasal_gc.h | 1 - src/nasal_vm.h | 2 +- src/unix_lib.cpp | 5 +++++ src/unix_lib.h | 7 +++++++ 13 files changed, 66 insertions(+), 17 deletions(-) create mode 100644 src/dylib_lib.cpp create mode 100644 src/dylib_lib.h create mode 100644 src/unix_lib.cpp create mode 100644 src/unix_lib.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 7e40a9b..a2a6f13 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,6 +25,8 @@ set(NASAL_OBJECT_SOURCE_FILE ${CMAKE_SOURCE_DIR}/src/bits_lib.cpp ${CMAKE_SOURCE_DIR}/src/io_lib.cpp ${CMAKE_SOURCE_DIR}/src/math_lib.cpp + ${CMAKE_SOURCE_DIR}/src/dylib_lib.cpp + ${CMAKE_SOURCE_DIR}/src/unix_lib.cpp ${CMAKE_SOURCE_DIR}/src/nasal_codegen.cpp ${CMAKE_SOURCE_DIR}/src/nasal_dbg.cpp ${CMAKE_SOURCE_DIR}/src/nasal_err.cpp diff --git a/makefile b/makefile index ba1c8e5..456f98d 100644 --- a/makefile +++ b/makefile @@ -21,6 +21,8 @@ NASAL_HEADER=\ src/bits_lib.h\ src/io_lib.h\ src/math_lib.h\ + src/dylib_lib.h\ + src/unix_lib.h\ src/coroutine.h NASAL_OBJECT=\ @@ -42,6 +44,8 @@ NASAL_OBJECT=\ build/fg_props.o\ build/io_lib.o\ build/math_lib.o\ + build/unix_lib.o\ + build/dylib_lib.o\ build/coroutine.o\ build/nasal_vm.o\ build/nasal_dbg.o\ @@ -119,6 +123,18 @@ build/io_lib.o: \ src/io_lib.h src/io_lib.cpp | build $(CXX) -std=$(STD) -c -O3 src/io_lib.cpp -fno-exceptions -fPIC -o build/io_lib.o -I . +build/dylib_lib.o: \ + src/nasal.h\ + src/nasal_gc.h\ + src/dylib_lib.h src/dylib_lib.cpp | build + $(CXX) -std=$(STD) -c -O3 src/dylib_lib.cpp -fno-exceptions -fPIC -o build/dylib_lib.o -I . + +build/unix_lib.o: \ + src/nasal.h\ + src/nasal_gc.h\ + src/unix_lib.h src/unix_lib.cpp | build + $(CXX) -std=$(STD) -c -O3 src/unix_lib.cpp -fno-exceptions -fPIC -o build/unix_lib.o -I . + build/fg_props.o: \ src/nasal.h\ src/nasal_gc.h\ diff --git a/src/dylib_lib.cpp b/src/dylib_lib.cpp new file mode 100644 index 0000000..467a18f --- /dev/null +++ b/src/dylib_lib.cpp @@ -0,0 +1,5 @@ +#include "dylib_lib.h" + +nasal_builtin_table dylib_lib_native[] = { + {nullptr, nullptr} +}; \ No newline at end of file diff --git a/src/dylib_lib.h b/src/dylib_lib.h new file mode 100644 index 0000000..3d8566b --- /dev/null +++ b/src/dylib_lib.h @@ -0,0 +1,7 @@ +#pragma once + +#include "nasal.h" +#include "nasal_gc.h" +#include "nasal_builtin.h" + +extern nasal_builtin_table dylib_lib_native[]; \ No newline at end of file diff --git a/src/io_lib.cpp b/src/io_lib.cpp index b7463a9..e59066c 100644 --- a/src/io_lib.cpp +++ b/src/io_lib.cpp @@ -1,5 +1,14 @@ #include "io_lib.h" +const auto file_type_name = "file"; + +void filehandle_destructor(void* ptr) { + if ((FILE*)ptr==stdin) { + return; + } + fclose((FILE*)ptr); +} + var builtin_readfile(var* local, gc& ngc) { var val = local[1]; if (val.type!=vm_str) { @@ -48,13 +57,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("file", filehandle_destructor, res); + ret.obj().set(file_type_name, filehandle_destructor, res); return ret; } var builtin_close(var* local, gc& ngc) { var fd = local[1]; - if (!fd.objchk("file")) { + if (!fd.objchk(file_type_name)) { return nas_err("close", "not a valid filehandle"); } fd.obj().clear(); @@ -65,7 +74,7 @@ var builtin_read(var* local, gc& ngc) { var fd = local[1]; var buf = local[2]; var len = local[3]; - if (!fd.objchk("file")) { + if (!fd.objchk(file_type_name)) { return nas_err("read", "not a valid filehandle"); } if (buf.type!=vm_str || buf.val.gcobj->unmut) { @@ -91,7 +100,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("file")) { + if (!fd.objchk(file_type_name)) { return nas_err("write", "not a valid filehandle"); } if (str.type!=vm_str) { @@ -104,7 +113,7 @@ var builtin_seek(var* local, gc& ngc) { var fd = local[1]; var pos = local[2]; var whence = local[3]; - if (!fd.objchk("file")) { + if (!fd.objchk(file_type_name)) { return nas_err("seek", "not a valid filehandle"); } return var::num((f64)fseek((FILE*)fd.obj().ptr, pos.num(), whence.num())); @@ -112,7 +121,7 @@ var builtin_seek(var* local, gc& ngc) { var builtin_tell(var* local, gc& ngc) { var fd = local[1]; - if (!fd.objchk("file")) { + if (!fd.objchk(file_type_name)) { return nas_err("tell", "not a valid filehandle"); } return var::num((f64)ftell((FILE*)fd.obj().ptr)); @@ -120,7 +129,7 @@ var builtin_tell(var* local, gc& ngc) { var builtin_readln(var* local, gc& ngc) { var fd = local[1]; - if (!fd.objchk("file")) { + if (!fd.objchk(file_type_name)) { return nas_err("readln", "not a valid filehandle"); } var str = ngc.alloc(vm_str); @@ -168,7 +177,7 @@ var builtin_stat(var* local, gc& ngc) { var builtin_eof(var* local, gc& ngc) { var fd = local[1]; - if (!fd.objchk("file")) { + if (!fd.objchk(file_type_name)) { return nas_err("readln", "not a valid filehandle"); } return var::num((f64)feof((FILE*)fd.obj().ptr)); diff --git a/src/io_lib.h b/src/io_lib.h index 980dea8..9d5016d 100644 --- a/src/io_lib.h +++ b/src/io_lib.h @@ -10,6 +10,8 @@ #define F_OK 0 // fuck msc #endif +void filehandle_destructor(void*); + var builtin_readfile(var*, gc&); var builtin_fout(var*, gc&); var builtin_exists(var*, gc&); diff --git a/src/nasal_codegen.cpp b/src/nasal_codegen.cpp index 7373a26..8e41af7 100644 --- a/src/nasal_codegen.cpp +++ b/src/nasal_codegen.cpp @@ -26,6 +26,8 @@ void codegen::init_native_function() { load_native_function_table(bits_native); load_native_function_table(coroutine_native); load_native_function_table(flight_gear_native); + load_native_function_table(dylib_lib_native); + load_native_function_table(unix_lib_native); } void codegen::check_id_exist(identifier* node) { diff --git a/src/nasal_codegen.h b/src/nasal_codegen.h index 53b84a7..141f75b 100644 --- a/src/nasal_codegen.h +++ b/src/nasal_codegen.h @@ -14,6 +14,8 @@ #include "math_lib.h" #include "fg_props.h" #include "io_lib.h" +#include "dylib_lib.h" +#include "unix_lib.h" #include #include diff --git a/src/nasal_gc.cpp b/src/nasal_gc.cpp index b7b9882..5557078 100644 --- a/src/nasal_gc.cpp +++ b/src/nasal_gc.cpp @@ -1,12 +1,5 @@ #include "nasal_gc.h" -void filehandle_destructor(void* ptr) { - if ((FILE*)ptr==stdin) { - return; - } - fclose((FILE*)ptr); -} - void dir_entry_destructor(void* ptr) { #ifndef _MSC_VER closedir((DIR*)ptr); diff --git a/src/nasal_gc.h b/src/nasal_gc.h index 08529e4..b83bca8 100644 --- a/src/nasal_gc.h +++ b/src/nasal_gc.h @@ -180,7 +180,6 @@ public: } }; -void filehandle_destructor(void*); void dir_entry_destructor(void*); void dylib_destructor(void*); void func_addr_destructor(void*); diff --git a/src/nasal_vm.h b/src/nasal_vm.h index 92a7a64..3b54cf7 100644 --- a/src/nasal_vm.h +++ b/src/nasal_vm.h @@ -23,6 +23,7 @@ protected: const f64* cnum = nullptr; // constant numbers const std::string* cstr = nullptr; // constant symbols and strings std::vector imm; // immediate number table + std::vector native; /* garbage collector */ gc ngc; @@ -33,7 +34,6 @@ protected: /* values used for debugger */ const std::string* files = nullptr; // file name list const opcode* bytecode = nullptr; // bytecode buffer address - std::vector native; /* vm initializing function */ void init( diff --git a/src/unix_lib.cpp b/src/unix_lib.cpp new file mode 100644 index 0000000..6795bab --- /dev/null +++ b/src/unix_lib.cpp @@ -0,0 +1,5 @@ +#include "unix_lib.h" + +nasal_builtin_table unix_lib_native[] = { + {nullptr, nullptr} +}; \ No newline at end of file diff --git a/src/unix_lib.h b/src/unix_lib.h new file mode 100644 index 0000000..48fd3fd --- /dev/null +++ b/src/unix_lib.h @@ -0,0 +1,7 @@ +#pragma once + +#include "nasal.h" +#include "nasal_gc.h" +#include "nasal_builtin.h" + +extern nasal_builtin_table unix_lib_native[]; \ No newline at end of file From e131c8da4bb275c868671c87738a1f5a3e4220bb Mon Sep 17 00:00:00 2001 From: ValKmjolnir Date: Fri, 11 Aug 2023 00:48:57 +0800 Subject: [PATCH 4/4] :sparkles: split dylib and unix lib --- src/dylib_lib.cpp | 100 +++++++++++++++++++ src/dylib_lib.h | 15 +++ src/nasal_builtin.cpp | 223 ------------------------------------------ src/nasal_builtin.h | 30 +----- src/nasal_gc.cpp | 18 ---- src/nasal_gc.h | 4 - src/unix_lib.cpp | 146 +++++++++++++++++++++++++++ src/unix_lib.h | 29 ++++++ std/unix.nas | 9 +- 9 files changed, 297 insertions(+), 277 deletions(-) diff --git a/src/dylib_lib.cpp b/src/dylib_lib.cpp index 467a18f..d2352b3 100644 --- a/src/dylib_lib.cpp +++ b/src/dylib_lib.cpp @@ -1,5 +1,105 @@ #include "dylib_lib.h" +const auto dylib_type_name = "dylib"; +const auto func_addr_type_name = "faddr"; + +void dylib_destructor(void* ptr) { +#ifdef _WIN32 + FreeLibrary((HMODULE)ptr); +#else + dlclose(ptr); +#endif +} + +void func_addr_destructor(void* ptr) {} + +var builtin_dlopen(var* local, gc& ngc) { + var dlname = local[1]; + if (dlname.type!=vm_str) { + return nas_err("dlopen", "\"libname\" must be string"); + } +#ifdef _WIN32 + wchar_t* str = new wchar_t[dlname.str().size()+1]; + if (!str) { + return nas_err("dlopen", "malloc failed"); + } + memset(str, 0, sizeof(wchar_t)*dlname.str().size()+1); + mbstowcs(str, dlname.str().c_str(),dlname.str().size()+1); + void* ptr = LoadLibraryA(dlname.str().c_str()); + delete []str; +#else + void* ptr = dlopen(dlname.str().c_str(), RTLD_LOCAL|RTLD_LAZY); +#endif + if (!ptr) { + return nas_err("dlopen", "cannot open dynamic lib <"+dlname.str()+">"); + } + var ret = ngc.temp = ngc.alloc(vm_hash); + var lib = ngc.alloc(vm_obj); + lib.obj().set(dylib_type_name, dylib_destructor, ptr); + ret.hash().elems["lib"] = lib; + +#ifdef _WIN32 + void* func = (void*)GetProcAddress((HMODULE)lib.obj().ptr, "get"); +#else + void* func = dlsym(lib.obj().ptr, "get"); +#endif + if (!func) { + return nas_err("dlopen", "cannot find function"); + } + // get function pointer by name + module_func_info* tbl = ((get_func_ptr)func)(); + 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(func_addr_type_name, func_addr_destructor, p); + ret.hash().elems[tbl[i].name] = tmp; + } + + ngc.temp = nil; + return ret; +} + +var builtin_dlclose(var* local, gc& ngc) { + var libptr = local[1]; + if (!libptr.objchk(dylib_type_name)) { + return nas_err("dlclose", "\"lib\" is not a valid dynamic lib"); + } + libptr.obj().clear(); + return nil; +} + +var builtin_dlcallv(var* local, gc& ngc) { + var fp = local[1]; + var args = local[2]; + if (!fp.objchk(func_addr_type_name)) { + return nas_err("dlcall", "\"ptr\" is not a valid function pointer"); + } + auto& vec = args.vec().elems; + 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(func_addr_type_name)) { + 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 ((module_func)fp.obj().ptr)( + local_frame_start, + local_frame_size, + &ngc); +} + nasal_builtin_table dylib_lib_native[] = { + {"__dlopen", builtin_dlopen}, + {"__dlclose", builtin_dlclose}, + {"__dlcallv", builtin_dlcallv}, + {"__dlcall", builtin_dlcall}, {nullptr, nullptr} }; \ No newline at end of file diff --git a/src/dylib_lib.h b/src/dylib_lib.h index 3d8566b..1abe4a8 100644 --- a/src/dylib_lib.h +++ b/src/dylib_lib.h @@ -4,4 +4,19 @@ #include "nasal_gc.h" #include "nasal_builtin.h" +#ifdef _WIN32 +#include +#else +#include +#include +#endif + +void dylib_destructor(void*); +void func_addr_destructor(void*); + +var builtin_dlopen(var*, gc&); +var builtin_dlclose(var*, gc&); +var builtin_dlcallv(var*, gc&); +var builtin_dlcall(var*, gc&); + extern nasal_builtin_table dylib_lib_native[]; \ No newline at end of file diff --git a/src/nasal_builtin.cpp b/src/nasal_builtin.cpp index 6a3c87c..17866ad 100644 --- a/src/nasal_builtin.cpp +++ b/src/nasal_builtin.cpp @@ -411,215 +411,6 @@ var builtin_sleep(var* local, gc& ngc) { return nil; } -var builtin_pipe(var* local, gc& ngc) { -#ifndef _WIN32 - i32 fd[2]; - var res = ngc.alloc(vm_vec); - if (pipe(fd)==-1) { - return nas_err("pipe", "failed to create pipe"); - } - res.vec().elems.push_back(var::num((f64)fd[0])); - res.vec().elems.push_back(var::num((f64)fd[1])); - return res; -#endif - return nas_err("pipe", "not supported"); -} - -var builtin_fork(var* local, gc& ngc) { -#ifndef _WIN32 - f64 res=fork(); - if (res<0) { - return nas_err("fork", "failed to fork a process"); - } - return var::num((f64)res); -#endif - return nas_err("fork", "not supported"); -} - -var builtin_waitpid(var* local, gc& ngc) { - var pid = local[1]; - var nohang = local[2]; - if (pid.type!=vm_num || nohang.type!=vm_num) { - return nas_err("waitpid", "pid and nohang must be number"); - } -#ifndef _WIN32 - i32 ret_pid,status; - ret_pid = waitpid(pid.num(),&status,nohang.num()==0? 0:WNOHANG); - var vec = ngc.alloc(vm_vec); - vec.vec().elems.push_back(var::num((f64)ret_pid)); - vec.vec().elems.push_back(var::num((f64)status)); - return vec; -#endif - return nas_err("waitpid", "not supported"); -} - -var builtin_opendir(var* local, gc& ngc) { - var path = local[1]; - if (path.type!=vm_str) { - return nas_err("opendir", "\"path\" must be string"); - } -#ifdef _MSC_VER - WIN32_FIND_DATAA data; - HANDLE p; - p = FindFirstFileA((path.str()+"\\*.*").c_str(),&data); - if (p==INVALID_HANDLE_VALUE) { - return nas_err("opendir", "cannot open dir <"+path.str()+">"); - } -#else - DIR* p = opendir(path.str().c_str()); - if (!p) { - return nas_err("opendir", "cannot open dir <"+path.str()+">"); - } -#endif - var ret = ngc.alloc(vm_obj); - ret.obj().set("dir", dir_entry_destructor, p); - return ret; -} - -var builtin_readdir(var* local, gc& ngc) { - var handle = local[1]; - if (!handle.objchk("dir")) { - return nas_err("readdir", "not a valid dir handle"); - } -#ifdef _MSC_VER - WIN32_FIND_DATAA data; - if (!FindNextFileA(handle.obj().ptr,&data)) { - return nil; - } - return ngc.newstr(data.cFileName); -#else - dirent* p = readdir((DIR*)handle.obj().ptr); - return p? ngc.newstr(p->d_name):nil; -#endif -} - -var builtin_closedir(var* local, gc& ngc) { - var handle = local[1]; - if (!handle.objchk("dir")) { - return nas_err("closedir", "not a valid dir handle"); - } - handle.obj().clear(); - return nil; -} - -var builtin_chdir(var* local, gc& ngc) { - var path = local[1]; - if (path.type!=vm_str) { - return var::num((f64)-1); - } - return var::num((f64)chdir(path.str().c_str())); -} - -var builtin_environ(var* local, gc& ngc) { - var res = ngc.temp = ngc.alloc(vm_vec); - auto& vec = res.vec().elems; - for(char** env = environ; *env; ++env) { - vec.push_back(ngc.newstr(*env)); - } - ngc.temp = nil; - return res; -} - -var builtin_getcwd(var* local, gc& ngc) { - char buf[1024]; - if (!getcwd(buf, sizeof(buf))) { - return nil; - } - return ngc.newstr(buf); -} - -var builtin_getenv(var* local, gc& ngc) { - var envvar = local[1]; - if (envvar.type!=vm_str) { - return nas_err("getenv", "\"envvar\" must be string"); - } - char* res = getenv(envvar.str().c_str()); - return res? ngc.newstr(res):nil; -} - -var builtin_dlopen(var* local, gc& ngc) { - var dlname = local[1]; - if (dlname.type!=vm_str) { - return nas_err("dlopen", "\"libname\" must be string"); - } -#ifdef _WIN32 - wchar_t* str = new wchar_t[dlname.str().size()+1]; - if (!str) { - return nas_err("dlopen", "malloc failed"); - } - memset(str, 0, sizeof(wchar_t)*dlname.str().size()+1); - mbstowcs(str, dlname.str().c_str(),dlname.str().size()+1); - void* ptr = LoadLibraryA(dlname.str().c_str()); - delete []str; -#else - void* ptr = dlopen(dlname.str().c_str(), RTLD_LOCAL|RTLD_LAZY); -#endif - if (!ptr) { - return nas_err("dlopen", "cannot open dynamic lib <"+dlname.str()+">"); - } - var ret = ngc.temp = ngc.alloc(vm_hash); - var lib = ngc.alloc(vm_obj); - lib.obj().set("dylib", dylib_destructor, ptr); - ret.hash().elems["lib"] = lib; - -#ifdef _WIN32 - void* func = (void*)GetProcAddress((HMODULE)lib.obj().ptr, "get"); -#else - void* func = dlsym(lib.obj().ptr, "get"); -#endif - if (!func) { - return nas_err("dlopen", "cannot find function"); - } - // get function pointer by name - module_func_info* tbl = ((get_func_ptr)func)(); - 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("faddr", func_addr_destructor, p); - ret.hash().elems[tbl[i].name] = tmp; - } - - ngc.temp = nil; - return ret; -} - -var builtin_dlclose(var* local, gc& ngc) { - var libptr = local[1]; - if (!libptr.objchk("dylib")) { - return nas_err("dlclose", "\"lib\" is not a valid dynamic lib"); - } - libptr.obj().clear(); - return nil; -} - -var builtin_dlcallv(var* local, gc& ngc) { - var fp = local[1]; - var args = local[2]; - if (!fp.objchk("faddr")) { - return nas_err("dlcall", "\"ptr\" is not a valid function pointer"); - } - auto& vec = args.vec().elems; - 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("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 ((module_func)fp.obj().ptr)( - local_frame_start, - local_frame_size, - &ngc); -} - var builtin_platform(var* local, gc& ngc) { if (is_windows()) { return ngc.newstr("windows"); @@ -854,20 +645,6 @@ nasal_builtin_table builtin[] = { {"__char", builtin_char}, {"__values", builtin_values}, {"__sleep", builtin_sleep}, - {"__pipe", builtin_pipe}, - {"__fork", builtin_fork}, - {"__waitpid", builtin_waitpid}, - {"__opendir", builtin_opendir}, - {"__readdir", builtin_readdir}, - {"__closedir", builtin_closedir}, - {"__chdir", builtin_chdir}, - {"__environ", builtin_environ}, - {"__getcwd", builtin_getcwd}, - {"__getenv", builtin_getenv}, - {"__dlopen", builtin_dlopen}, - {"__dlclose", builtin_dlclose}, - {"__dlcallv", builtin_dlcallv}, - {"__dlcall", builtin_dlcall}, {"__platform", builtin_platform}, {"__arch", builtin_arch}, {"__md5", builtin_md5}, diff --git a/src/nasal_builtin.h b/src/nasal_builtin.h index c6c5a7a..1948997 100644 --- a/src/nasal_builtin.h +++ b/src/nasal_builtin.h @@ -3,32 +3,20 @@ #include "nasal.h" #include "nasal_gc.h" -#ifndef _MSC_VER -#include -#include -#else -#define F_OK 0 // fuck msc +#ifdef _MSC_VER #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 -#include #endif #include #include #include -#ifdef _WIN32 -#include -#else -#include -#include -#endif - +// for environ #if defined __APPLE__ #include #define environ (*_NSGetEnviron()) @@ -67,20 +55,6 @@ var builtin_chr(var*, gc&); var builtin_char(var*, gc&); var builtin_values(var*, gc&); var builtin_sleep(var*, gc&); -var builtin_pipe(var*, gc&); -var builtin_fork(var*, gc&); -var builtin_waitpid(var*, gc&); -var builtin_opendir(var*, gc&); -var builtin_readdir(var*, gc&); -var builtin_closedir(var*, gc&); -var builtin_chdir(var*, gc&); -var builtin_environ(var*, gc&); -var builtin_getcwd(var*, gc&); -var builtin_getenv(var*, gc&); -var builtin_dlopen(var*, gc&); -var builtin_dlclose(var*, gc&); -var builtin_dlcallv(var*, gc&); -var builtin_dlcall(var*, gc&); var builtin_platform(var*, gc&); var builtin_arch(var*, gc&); // md5 related functions diff --git a/src/nasal_gc.cpp b/src/nasal_gc.cpp index 5557078..4523adf 100644 --- a/src/nasal_gc.cpp +++ b/src/nasal_gc.cpp @@ -1,23 +1,5 @@ #include "nasal_gc.h" -void dir_entry_destructor(void* ptr) { -#ifndef _MSC_VER - closedir((DIR*)ptr); -#else - FindClose(ptr); -#endif -} - -void dylib_destructor(void* ptr) { -#ifdef _WIN32 - FreeLibrary((HMODULE)ptr); -#else - dlclose(ptr); -#endif -} - -void func_addr_destructor(void* ptr) {} - var nas_vec::get_val(const i32 n) { i32 size = elems.size(); if (n<-size || n>=size) { diff --git a/src/nasal_gc.h b/src/nasal_gc.h index b83bca8..901db8e 100644 --- a/src/nasal_gc.h +++ b/src/nasal_gc.h @@ -180,10 +180,6 @@ public: } }; -void dir_entry_destructor(void*); -void dylib_destructor(void*); -void func_addr_destructor(void*); - struct nas_ghost { private: using destructor=void (*)(void*); diff --git a/src/unix_lib.cpp b/src/unix_lib.cpp index 6795bab..17408e3 100644 --- a/src/unix_lib.cpp +++ b/src/unix_lib.cpp @@ -1,5 +1,151 @@ #include "unix_lib.h" +const auto dir_type_name = "dir"; + +void dir_entry_destructor(void* ptr) { +#ifndef _MSC_VER + closedir((DIR*)ptr); +#else + FindClose(ptr); +#endif +} + +var builtin_pipe(var* local, gc& ngc) { +#ifndef _WIN32 + i32 fd[2]; + var res = ngc.alloc(vm_vec); + if (pipe(fd)==-1) { + return nas_err("pipe", "failed to create pipe"); + } + res.vec().elems.push_back(var::num((f64)fd[0])); + res.vec().elems.push_back(var::num((f64)fd[1])); + return res; +#endif + return nas_err("pipe", "not supported"); +} + +var builtin_fork(var* local, gc& ngc) { +#ifndef _WIN32 + f64 res=fork(); + if (res<0) { + return nas_err("fork", "failed to fork a process"); + } + return var::num((f64)res); +#endif + return nas_err("fork", "not supported"); +} + +var builtin_waitpid(var* local, gc& ngc) { + var pid = local[1]; + var nohang = local[2]; + if (pid.type!=vm_num || nohang.type!=vm_num) { + return nas_err("waitpid", "pid and nohang must be number"); + } +#ifndef _WIN32 + i32 ret_pid,status; + ret_pid = waitpid(pid.num(),&status,nohang.num()==0? 0:WNOHANG); + var vec = ngc.alloc(vm_vec); + vec.vec().elems.push_back(var::num((f64)ret_pid)); + vec.vec().elems.push_back(var::num((f64)status)); + return vec; +#endif + return nas_err("waitpid", "not supported"); +} + +var builtin_opendir(var* local, gc& ngc) { + var path = local[1]; + if (path.type!=vm_str) { + return nas_err("opendir", "\"path\" must be string"); + } +#ifdef _MSC_VER + WIN32_FIND_DATAA data; + HANDLE p; + p = FindFirstFileA((path.str()+"\\*.*").c_str(),&data); + if (p==INVALID_HANDLE_VALUE) { + return nas_err("opendir", "cannot open dir <"+path.str()+">"); + } +#else + DIR* p = opendir(path.str().c_str()); + if (!p) { + return nas_err("opendir", "cannot open dir <"+path.str()+">"); + } +#endif + var ret = ngc.alloc(vm_obj); + ret.obj().set(dir_type_name, dir_entry_destructor, p); + return ret; +} + +var builtin_readdir(var* local, gc& ngc) { + var handle = local[1]; + if (!handle.objchk(dir_type_name)) { + return nas_err("readdir", "not a valid dir handle"); + } +#ifdef _MSC_VER + WIN32_FIND_DATAA data; + if (!FindNextFileA(handle.obj().ptr,&data)) { + return nil; + } + return ngc.newstr(data.cFileName); +#else + dirent* p = readdir((DIR*)handle.obj().ptr); + return p? ngc.newstr(p->d_name):nil; +#endif +} + +var builtin_closedir(var* local, gc& ngc) { + var handle = local[1]; + if (!handle.objchk(dir_type_name)) { + return nas_err("closedir", "not a valid dir handle"); + } + handle.obj().clear(); + return nil; +} + +var builtin_chdir(var* local, gc& ngc) { + var path = local[1]; + if (path.type!=vm_str) { + return var::num((f64)-1); + } + return var::num((f64)chdir(path.str().c_str())); +} + +var builtin_environ(var* local, gc& ngc) { + var res = ngc.temp = ngc.alloc(vm_vec); + auto& vec = res.vec().elems; + for(char** env = environ; *env; ++env) { + vec.push_back(ngc.newstr(*env)); + } + ngc.temp = nil; + return res; +} + +var builtin_getcwd(var* local, gc& ngc) { + char buf[1024]; + if (!getcwd(buf, sizeof(buf))) { + return nil; + } + return ngc.newstr(buf); +} + +var builtin_getenv(var* local, gc& ngc) { + var envvar = local[1]; + if (envvar.type!=vm_str) { + return nas_err("getenv", "\"envvar\" must be string"); + } + char* res = getenv(envvar.str().c_str()); + return res? ngc.newstr(res):nil; +} + nasal_builtin_table unix_lib_native[] = { + {"__pipe", builtin_pipe}, + {"__fork", builtin_fork}, + {"__waitpid", builtin_waitpid}, + {"__opendir", builtin_opendir}, + {"__readdir", builtin_readdir}, + {"__closedir", builtin_closedir}, + {"__chdir", builtin_chdir}, + {"__environ", builtin_environ}, + {"__getcwd", builtin_getcwd}, + {"__getenv", builtin_getenv}, {nullptr, nullptr} }; \ No newline at end of file diff --git a/src/unix_lib.h b/src/unix_lib.h index 48fd3fd..e69da51 100644 --- a/src/unix_lib.h +++ b/src/unix_lib.h @@ -4,4 +4,33 @@ #include "nasal_gc.h" #include "nasal_builtin.h" +#ifndef _MSC_VER +#include +#include +#else +#define _CRT_SECURE_NO_DEPRECATE 1 +#define _CRT_NONSTDC_NO_DEPRECATE 1 +#include +#include +#endif + +#ifdef _WIN32 +#include +#else +#include +#endif + +void dir_entry_destructor(void*); + +var builtin_pipe(var*, gc&); +var builtin_fork(var*, gc&); +var builtin_waitpid(var*, gc&); +var builtin_opendir(var*, gc&); +var builtin_readdir(var*, gc&); +var builtin_closedir(var*, gc&); +var builtin_chdir(var*, gc&); +var builtin_environ(var*, gc&); +var builtin_getcwd(var*, gc&); +var builtin_getenv(var*, gc&); + extern nasal_builtin_table unix_lib_native[]; \ No newline at end of file diff --git a/std/unix.nas b/std/unix.nas index b42914a..9639400 100644 --- a/std/unix.nas +++ b/std/unix.nas @@ -1,6 +1,9 @@ # unix.nas # 2023 by ValKmjolnir +var _S_IFDIR = 0x4000; +var _S_IFREG = 0x8000; + var pipe = func() { return __pipe; } @@ -22,13 +25,11 @@ var waitpid = func(pid, nohang = 0) { } var isdir = func(path) { - # S_IFDIR 0x4000 - return !!bits.u32_and(io.stat(path)[2],0x4000); + return !!bits.u32_and(io.stat(path)[2], _S_IFDIR); } var isfile = func(path) { - # S_IFREG 0x8000 - return !!bits.u32_and(io.stat(path)[2],0x8000); + return !!bits.u32_and(io.stat(path)[2], _S_IFREG); } var opendir = func(path) {