🔥 delete ghost type table

This commit is contained in:
ValKmjolnir 2023-08-08 20:50:47 +08:00
parent 044ccb4bc6
commit 52e6adfe28
8 changed files with 46 additions and 102 deletions

View File

@ -37,7 +37,7 @@ var quick_fib(var* args, usize size, gc* ngc) {
return var::num(res); return var::num(res);
} }
u32 ghost_for_test; const auto ghost_for_test = "ghost_for_test";
void ghost_for_test_destructor(void* ptr) { void ghost_for_test_destructor(void* ptr) {
std::cout << "ghost_for_test::destructor (0x"; 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 create_new_ghost(var* args, usize size, gc* ngc) {
var res = ngc->alloc(vm_obj); 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; return res;
} }
@ -87,14 +87,6 @@ module_func_info func_tbl[] = {
} }
extern "C" module_func_info* get(ghost_register_table* table) { extern "C" module_func_info* get() {
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
);
return nasal_fib_module::func_tbl; return nasal_fib_module::func_tbl;
} }

View File

@ -99,6 +99,6 @@ module_func_info func_tbl[]={
{nullptr,nullptr} {nullptr,nullptr}
}; };
extern "C" module_func_info* get(ghost_register_table* table) { extern "C" module_func_info* get() {
return func_tbl; return func_tbl;
} }

View File

@ -291,6 +291,6 @@ module_func_info func_tbl[]={
{nullptr,nullptr} {nullptr,nullptr}
}; };
extern "C" module_func_info* get(ghost_register_table* table) { extern "C" module_func_info* get() {
return func_tbl; return func_tbl;
} }

View File

@ -209,6 +209,6 @@ module_func_info func_tbl[]={
{nullptr,nullptr} {nullptr,nullptr}
}; };
extern "C" module_func_info* get(ghost_register_table* table) { extern "C" module_func_info* get() {
return func_tbl; return func_tbl;
} }

View File

@ -444,13 +444,13 @@ var builtin_open(var* local, gc& ngc) {
return nas_err("open", "failed to open file <"+name.str()+">"); return nas_err("open", "failed to open file <"+name.str()+">");
} }
var ret = ngc.alloc(vm_obj); 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; return ret;
} }
var builtin_close(var* local, gc& ngc) { var builtin_close(var* local, gc& ngc) {
var fd = local[1]; 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"); return nas_err("close", "not a valid filehandle");
} }
fd.obj().clear(); fd.obj().clear();
@ -461,7 +461,7 @@ var builtin_read(var* local, gc& ngc) {
var fd = local[1]; var fd = local[1];
var buf = local[2]; var buf = local[2];
var len = local[3]; 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"); return nas_err("read", "not a valid filehandle");
} }
if (buf.type!=vm_str || buf.val.gcobj->unmut) { 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 builtin_write(var* local, gc& ngc) {
var fd = local[1]; var fd = local[1];
var str = local[2]; 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"); return nas_err("write", "not a valid filehandle");
} }
if (str.type!=vm_str) { if (str.type!=vm_str) {
@ -500,7 +500,7 @@ var builtin_seek(var* local, gc& ngc) {
var fd = local[1]; var fd = local[1];
var pos = local[2]; var pos = local[2];
var whence = local[3]; 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 nas_err("seek", "not a valid filehandle");
} }
return var::num((f64)fseek((FILE*)fd.obj().ptr, pos.num(), whence.num())); 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 builtin_tell(var* local, gc& ngc) {
var fd = local[1]; 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 nas_err("tell", "not a valid filehandle");
} }
return var::num((f64)ftell((FILE*)fd.obj().ptr)); 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 builtin_readln(var* local, gc& ngc) {
var fd = local[1]; 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 nas_err("readln", "not a valid filehandle");
} }
var str = ngc.alloc(vm_str); 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 builtin_eof(var* local, gc& ngc) {
var fd = local[1]; 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 nas_err("readln", "not a valid filehandle");
} }
return var::num((f64)feof((FILE*)fd.obj().ptr)); return var::num((f64)feof((FILE*)fd.obj().ptr));
@ -646,13 +646,13 @@ var builtin_opendir(var* local, gc& ngc) {
} }
#endif #endif
var ret = ngc.alloc(vm_obj); 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; return ret;
} }
var builtin_readdir(var* local, gc& ngc) { var builtin_readdir(var* local, gc& ngc) {
var handle = local[1]; 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"); return nas_err("readdir", "not a valid dir handle");
} }
#ifdef _MSC_VER #ifdef _MSC_VER
@ -669,7 +669,7 @@ var builtin_readdir(var* local, gc& ngc) {
var builtin_closedir(var* local, gc& ngc) { var builtin_closedir(var* local, gc& ngc) {
var handle = local[1]; 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"); return nas_err("closedir", "not a valid dir handle");
} }
handle.obj().clear(); handle.obj().clear();
@ -733,7 +733,7 @@ var builtin_dlopen(var* local, gc& ngc) {
} }
var ret = ngc.temp = ngc.alloc(vm_hash); var ret = ngc.temp = ngc.alloc(vm_hash);
var lib = ngc.alloc(vm_obj); 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; ret.hash().elems["lib"] = lib;
#ifdef _WIN32 #ifdef _WIN32
@ -745,14 +745,14 @@ var builtin_dlopen(var* local, gc& ngc) {
return nas_err("dlopen", "cannot find <get> function"); return nas_err("dlopen", "cannot find <get> function");
} }
// get function pointer by name // 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) { if (!tbl) {
return nas_err("dlopen", "failed to get module functions"); return nas_err("dlopen", "failed to get module functions");
} }
for(u32 i = 0; tbl[i].name; ++i) { for(u32 i = 0; tbl[i].name; ++i) {
void* p = (void*)tbl[i].fd; void* p = (void*)tbl[i].fd;
var tmp = ngc.alloc(vm_obj); 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; 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 builtin_dlclose(var* local, gc& ngc) {
var libptr = local[1]; 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"); return nas_err("dlclose", "\"lib\" is not a valid dynamic lib");
} }
libptr.obj().clear(); libptr.obj().clear();
@ -772,7 +772,7 @@ var builtin_dlclose(var* local, gc& ngc) {
var builtin_dlcallv(var* local, gc& ngc) { var builtin_dlcallv(var* local, gc& ngc) {
var fp = local[1]; var fp = local[1];
var args = local[2]; 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"); return nas_err("dlcall", "\"ptr\" is not a valid function pointer");
} }
auto& vec = args.vec().elems; auto& vec = args.vec().elems;
@ -781,7 +781,7 @@ var builtin_dlcallv(var* local, gc& ngc) {
var builtin_dlcall(var* local, gc& ngc) { var builtin_dlcall(var* local, gc& ngc) {
var fp = local[1]; 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"); return nas_err("dlcall", "\"ptr\" is not a valid function pointer");
} }

View File

@ -141,9 +141,11 @@ private:
u32 bk_line; u32 bk_line;
error src; error src;
private:
debug_prof_data data; debug_prof_data data;
bool do_profiling; bool do_profiling;
private:
std::vector<std::string> parse(const std::string&); std::vector<std::string> parse(const std::string&);
u16 file_index(const std::string&) const; u16 file_index(const std::string&) const;
void err(); void err();

View File

@ -123,18 +123,22 @@ void nas_func::clear() {
} }
void nas_ghost::set( void nas_ghost::set(
usize ghost_type, void* ghost_pointer, ghost_register_table* table) { const std::string& ghost_type_name,
type = ghost_type; destructor destructor_pointer,
void* ghost_pointer) {
type_name = ghost_type_name;
dtor_ptr = destructor_pointer;
ptr = ghost_pointer; ptr = ghost_pointer;
ghost_type_table = table;
} }
void nas_ghost::clear() { void nas_ghost::clear() {
if (!ptr) { if (!ptr || !dtor_ptr) {
return; return;
} }
ghost_type_table->destructor(type)(ptr); dtor_ptr(ptr);
type_name = "";
ptr = nullptr; ptr = nullptr;
dtor_ptr = nullptr;
} }
std::ostream& operator<<(std::ostream& out, const nas_ghost& ghost) { std::ostream& operator<<(std::ostream& out, const nas_ghost& ghost) {
@ -268,8 +272,8 @@ std::ostream& operator<<(std::ostream& out, var& ref) {
return out; return out;
} }
bool var::objchk(usize obj_type) { bool var::objchk(const std::string& name) {
return type==vm_obj && obj().type==obj_type && obj().ptr; return type==vm_obj && obj().type_name==name && obj().ptr;
} }
var var::none() { var var::none() {

View File

@ -93,7 +93,7 @@ public:
// number and string can be translated to each other // number and string can be translated to each other
f64 tonum(); f64 tonum();
std::string tostr(); std::string tostr();
bool objchk(usize); bool objchk(const std::string&);
// create new var object // create new var object
static var none(); static var none();
@ -185,77 +185,24 @@ void dir_entry_destructor(void*);
void dylib_destructor(void*); void dylib_destructor(void*);
void func_addr_destructor(void*); void func_addr_destructor(void*);
struct ghost_register_table {
private:
using dtor=void (*)(void*);
private:
std::unordered_map<std::string, usize> mapper;
std::vector<std::string> ghost_name;
std::vector<dtor> 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 { struct nas_ghost {
private:
using destructor=void (*)(void*);
public: public:
usize type; std::string type_name;
destructor dtor_ptr;
void* ptr; void* ptr;
private:
ghost_register_table* ghost_type_table;
public: public:
nas_ghost(): type(0), ptr(nullptr), ghost_type_table(nullptr) {} nas_ghost(): type_name(""), dtor_ptr(nullptr), ptr(nullptr) {}
~nas_ghost() {clear();} ~nas_ghost() {clear();}
void set(usize, void*, ghost_register_table*); void set(const std::string&, destructor, void*);
void clear(); void clear();
public: public:
const std::string& get_ghost_name() const { 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(); const var nil = var::nil();
struct gc { struct gc {
ghost_register_table global_ghost_type_table;
/* main context temporary storage */ /* main context temporary storage */
context mctx; context mctx;
@ -433,4 +379,4 @@ struct module_func_info {
}; };
// module function "get" type // module function "get" type
typedef module_func_info* (*get_func_ptr)(ghost_register_table*); typedef module_func_info* (*get_func_ptr)();