✨ add template get/convert for ghost
This commit is contained in:
parent
9752b8823e
commit
ce204352c6
1
makefile
1
makefile
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>())
|
||||
));
|
||||
}
|
||||
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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*);
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
}
|
|
@ -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);
|
Loading…
Reference in New Issue