🔥 delete ghost type table
This commit is contained in:
parent
044ccb4bc6
commit
52e6adfe28
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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 <get> 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");
|
||||
}
|
||||
|
||||
|
|
|
@ -141,9 +141,11 @@ private:
|
|||
u32 bk_line;
|
||||
error src;
|
||||
|
||||
private:
|
||||
debug_prof_data data;
|
||||
bool do_profiling;
|
||||
|
||||
private:
|
||||
std::vector<std::string> parse(const std::string&);
|
||||
u16 file_index(const std::string&) const;
|
||||
void err();
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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<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 {
|
||||
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)();
|
||||
|
|
Loading…
Reference in New Issue