add template get/convert for ghost

This commit is contained in:
ValKmjolnir 2024-06-13 23:47:58 +08:00
parent 9752b8823e
commit ce204352c6
13 changed files with 76 additions and 38 deletions

View File

@ -330,6 +330,7 @@ test:nasal
@ ./nasal -t -d test/quick_sort.nas
@ ./nasal -t -d test/regex_test.nas
@ ./nasal -e test/scalar.nas hello world
@ ./nasal test/subprocess_test.nas
@ ./nasal -e test/trait.nas
@ ./nasal -t -d test/turingmachine.nas
@ ./nasal -d test/wavecollapse.nas

View File

@ -91,10 +91,10 @@ var set_new_ghost(var* args, usize size, gc* ngc) {
}
f64 num = args[1].num();
reinterpret_cast<ghost_obj*>(res.ghost().pointer)->number = static_cast<u32>(num);
res.ghost().get<ghost_obj>()->number = static_cast<u32>(num);
std::cout << "set_new_ghost: successfully set ghost.number = " << num << "\n";
reinterpret_cast<ghost_obj*>(res.ghost().pointer)->test_string = ngc->newstr("just for test");
res.ghost().get<ghost_obj>()->test_string = ngc->newstr("just for test");
std::cout << "set_new_ghost: successfully set ghost.test_string = just for test\n";
return nil;
}
@ -106,9 +106,9 @@ var print_new_ghost(var* args, usize size, gc* ngc) {
return nil;
}
std::cout << "print_new_ghost: " << res.ghost() << " number = "
<< reinterpret_cast<ghost_obj*>(res.ghost().pointer)->number
<< res.ghost().get<ghost_obj>()->number
<< " test_string = "
<< reinterpret_cast<ghost_obj*>(res.ghost().pointer)->test_string
<< res.ghost().get<ghost_obj>()->test_string
<< "\n";
return nil;
}

View File

@ -164,7 +164,7 @@ void nas_ghost::clear() {
std::ostream& operator<<(std::ostream& out, const nas_ghost& ghost) {
out << "<object " << ghost.get_ghost_name();
out << " at 0x" << std::hex;
out << reinterpret_cast<u64>(ghost.pointer) << std::dec << ">";
out << ghost.convert<u64>() << std::dec << ">";
return out;
}

View File

@ -213,6 +213,12 @@ public:
public:
const auto& get_ghost_name() const { return type_name; }
public:
template<typename T>
T* get() { return static_cast<T*>(pointer); }
template<typename T>
T convert() const { return reinterpret_cast<T>(pointer); }
};
struct context {

View File

@ -615,7 +615,7 @@ var builtin_time_stamp(context* ctx, gc* ngc) {
if (!object.object_check("nasal-time-stamp")) {
return nil;
}
auto stamp = static_cast<time_stamp*>(object.ghost().pointer);
auto stamp = object.ghost().get<time_stamp>();
stamp->make_stamp();
return nil;
}
@ -625,7 +625,7 @@ var builtin_elapsed_millisecond(context* ctx, gc* ngc) {
if (!object.object_check("nasal-time-stamp")) {
return var::num(-1);
}
auto stamp = static_cast<time_stamp*>(object.ghost().pointer);
auto stamp = object.ghost().get<time_stamp>();
return var::num(static_cast<f64>(stamp->elapsed_milliseconds()));
}
@ -634,7 +634,7 @@ var builtin_elapsed_microsecond(context* ctx, gc* ngc) {
if (!object.object_check("nasal-time-stamp")) {
return var::num(-1);
}
auto stamp = static_cast<time_stamp*>(object.ghost().pointer);
auto stamp = object.ghost().get<time_stamp>();
return var::num(static_cast<f64>(stamp->elapsed_microseconds()));
}
@ -717,7 +717,7 @@ var builtin_ghosttype(context* ctx, gc* ngc) {
if (!name.length()) {
std::stringstream ss;
ss << "0x" << std::hex;
ss << reinterpret_cast<u64>(arg.ghost().pointer) << std::dec;
ss << arg.ghost().convert<u64>() << std::dec;
return ngc->newstr(ss.str());
}
return ngc->newstr(name);

View File

@ -55,7 +55,7 @@ var builtin_dlopen(context* ctx, gc* ngc) {
// get "get" function, to get the register table
#ifdef _WIN32
void* register_table_get_function = reinterpret_cast<void*>(GetProcAddress(
static_cast<HMODULE>(library_object.ghost().pointer), "get"
library_object.ghost().convert<HMODULE>(), "get"
));
#else
void* register_table_get_function = dlsym(
@ -105,7 +105,7 @@ var builtin_dlcallv(context* ctx, gc* ngc) {
);
}
auto& vec = arguments.vec().elems;
return reinterpret_cast<module_func>(function_object.ghost().pointer)(
return function_object.ghost().convert<module_func>()(
vec.data(),
vec.size(),
ngc
@ -124,7 +124,7 @@ var builtin_dlcall(context* ctx, gc* ngc) {
// so arguments starts from ctx->localr[2]
var* local_frame_start = ctx->localr + 2;
usize local_frame_size = ngc->running_context->top - local_frame_start;
return reinterpret_cast<module_func>(function_object.ghost().pointer)(
return function_object.ghost().convert<module_func>()(
local_frame_start,
local_frame_size,
ngc

View File

@ -101,7 +101,7 @@ var builtin_read(context* ctx, gc* ngc) {
}
auto read_size = fread(
temp_buffer, 1, length.num(),
static_cast<FILE*>(file_descriptor.ghost().pointer)
file_descriptor.ghost().get<FILE>()
);
buffer.str() = temp_buffer;
buffer.val.gcobj->immutable = true;
@ -121,7 +121,7 @@ var builtin_write(context* ctx, gc* ngc) {
}
return var::num(static_cast<f64>(fwrite(
source.str().c_str(), 1, source.str().length(),
static_cast<FILE*>(file_descriptor.ghost().pointer)
file_descriptor.ghost().get<FILE>()
)));
}
@ -134,7 +134,7 @@ var builtin_seek(context* ctx, gc* ngc) {
return nas_err("io::seek", "not a valid filehandle");
}
return var::num(static_cast<f64>(fseek(
static_cast<FILE*>(file_descriptor.ghost().pointer),
file_descriptor.ghost().get<FILE>(),
position.num(),
whence.num()
)));
@ -146,7 +146,7 @@ var builtin_tell(context* ctx, gc* ngc) {
return nas_err("io::tell", "not a valid filehandle");
}
return var::num(static_cast<f64>(
ftell(static_cast<FILE*>(file_descriptor.ghost().pointer))
ftell(file_descriptor.ghost().get<FILE>())
));
}
@ -157,7 +157,7 @@ var builtin_readln(context* ctx, gc* ngc) {
}
auto result = ngc->alloc(vm_type::vm_str);
char c;
while((c = fgetc(static_cast<FILE*>(file_descriptor.ghost().pointer)))!=EOF) {
while((c = fgetc(file_descriptor.ghost().get<FILE>()))!=EOF) {
if (c=='\r') {
continue;
}
@ -204,7 +204,7 @@ var builtin_eof(context* ctx, gc* ngc) {
return nas_err("io::readln", "not a valid filehandle");
}
return var::num(static_cast<f64>(
feof(static_cast<FILE*>(file_descriptor.ghost().pointer))
feof(file_descriptor.ghost().get<FILE>())
));
}

View File

@ -369,7 +369,7 @@ var builtin_json_stringify(context* ctx, gc* ngc) {
if (!json_object.object_check("nasal::json")) {
return nas_err("json::stringify", "expect a json object.");
}
auto json_ptr = static_cast<json*>(json_object.ghost().pointer);
auto json_ptr = json_object.ghost().get<json>();
return ngc->newstr(json_ptr->stringify(object));
}
@ -382,7 +382,7 @@ var builtin_json_parse(context* ctx, gc* ngc) {
if (!input_string.is_str()) {
return nas_err("json::parse", "require string as the input.");
}
auto json_ptr = static_cast<json*>(json_object.ghost().pointer);
auto json_ptr = json_object.ghost().get<json>();
return json_ptr->parse(input_string.str(), ngc);
}
@ -391,7 +391,7 @@ var builtin_json_get_error(context* ctx, gc* ngc) {
if (!json_object.object_check("nasal::json")) {
return nas_err("json::get_error", "expect a json object.");
}
auto json_ptr = static_cast<json*>(json_object.ghost().pointer);
auto json_ptr = json_object.ghost().get<json>();
return ngc->newstr(json_ptr->get_error());
}

View File

@ -24,18 +24,16 @@
namespace nasal {
const auto subproc_desc_name = "subprocess_descriptor";
void subprocess_desc_dtor(void* ptr) {
#ifdef WIN32
auto pi = &static_cast<subprocess_descriptor*>(ptr)->pi;
auto pi = &static_cast<subprocess*>(ptr)->pi;
WaitForSingleObject(pi->hProcess, 0);
TerminateProcess(pi->hProcess, 0);
CloseHandle(pi->hProcess);
CloseHandle(pi->hThread);
#else
auto pid = static_cast<subprocess_descriptor*>(ptr)->pid;
auto pid = static_cast<subprocess*>(ptr)->pid;
int status;
pid_t result = waitpid(pid, &status, WNOHANG);
@ -50,26 +48,30 @@ void subprocess_desc_dtor(void* ptr) {
var builtin_subprocess_create(context* ctx, gc* ngc) {
auto cmd = ctx->localr[1];
if (!cmd.is_vec()) {
return nas_err("subprocess::create", "expect a string as the command");
return nas_err("subprocess::create",
"expect string vector as the command"
);
}
for(const auto& v : cmd.vec().elems) {
if (!v.is_str()) {
return nas_err("subprocess::create", "non-string arguments");
return nas_err("subprocess::create",
"non-string argument found"
);
}
}
auto obj = ngc->alloc(vm_type::vm_ghost);
obj.ghost().set(
subproc_desc_name,
subprocess::name(),
subprocess_desc_dtor,
nullptr,
new subprocess_descriptor
new subprocess
);
#ifdef WIN32
auto si = &static_cast<subprocess_descriptor*>(obj.ghost().pointer)->si;
auto pi = &static_cast<subprocess_descriptor*>(obj.ghost().pointer)->pi;
auto si = &obj.ghost().get<subprocess>()->si;
auto pi = &obj.ghost().get<subprocess>()->pi;
// init STARTUPINFO
ZeroMemory(si, sizeof(STARTUPINFOW));
@ -135,7 +137,7 @@ var builtin_subprocess_create(context* ctx, gc* ngc) {
}
// parent process
static_cast<subprocess_descriptor*>(obj.ghost().pointer)->pid = pid;
obj.ghost().get<subprocess>()->pid = pid;
for(usize i = 0; argv[i]; ++i) {
delete argv[i];
}
@ -148,14 +150,14 @@ var builtin_subprocess_create(context* ctx, gc* ngc) {
var builtin_subprocess_terminate(context* ctx, gc* ngc) {
auto obj = ctx->localr[1];
if (!obj.object_check(subproc_desc_name)) {
if (!obj.object_check(subprocess::name())) {
return nas_err("subprocess::terminate",
"need correct subprocess descriptor"
"need correct subprocess object"
);
}
#ifdef WIN32
auto pi = &static_cast<subprocess_descriptor*>(obj.ghost().pointer)->pi;
auto pi = &obj.ghost().get<subprocess>()->pi;
WaitForSingleObject(pi->hProcess, 0);
TerminateProcess(pi->hProcess, -1);
@ -166,7 +168,7 @@ var builtin_subprocess_terminate(context* ctx, gc* ngc) {
CloseHandle(pi->hProcess);
CloseHandle(pi->hThread);
#else
auto pid = static_cast<subprocess_descriptor*>(obj.ghost().pointer)->pid;
auto pid = obj.ghost().get<subprocess>()->pid;
int status;
pid_t result = waitpid(pid, &status, WNOHANG);

View File

@ -14,13 +14,18 @@
namespace nasal {
struct subprocess_descriptor {
struct subprocess {
#ifndef WIN32
pid_t pid;
#else
STARTUPINFOW si;
PROCESS_INFORMATION pi;
#endif
public:
static const char* name() {
return "nasal::subprocess";
}
};
void subprocess_desc_dtor(void*);

View File

@ -89,7 +89,7 @@ var builtin_readdir(context* ctx, gc* ngc) {
}
return ngc->newstr(data.cFileName);
#else
dirent* p = readdir(static_cast<DIR*>(handle.ghost().pointer));
dirent* p = readdir(handle.ghost().get<DIR>());
return p? ngc->newstr(p->d_name):nil;
#endif
}

View File

@ -0,0 +1,11 @@
use std.unix;
var count = 0;
while(1) {
unix.sleep(0.1);
count += 0.1;
println("process running time: ", count);
if (count > 2) {
die("test failed");
}
}

13
test/subprocess_test.nas Normal file
View File

@ -0,0 +1,13 @@
use std.subprocess;
use std.unix;
var process = subprocess.create([
"./nasal",
"test/for_subprocess_test/infinite_loop.nas"
]);
unix.sleep(1);
println("kill subprocess...");
var res = subprocess.terminate(process);
println("subprocess killed, code ", res);