From 820c05c9867e8fb305c2ce1e13f1f52012f14577 Mon Sep 17 00:00:00 2001 From: ValKmjolnir Date: Sat, 21 Oct 2023 00:31:39 +0800 Subject: [PATCH] :sparkles: change way of calling native functions --- src/bits_lib.cpp | 53 +++++---- src/bits_lib.h | 18 +-- src/coroutine.cpp | 105 ++++++++-------- src/coroutine.h | 10 +- src/dylib_lib.cpp | 34 +++--- src/dylib_lib.h | 8 +- src/fg_props.cpp | 7 +- src/fg_props.h | 2 +- src/io_lib.cpp | 76 ++++++------ src/io_lib.h | 24 ++-- src/math_lib.cpp | 44 +++---- src/math_lib.h | 20 ++-- src/nasal_builtin.cpp | 270 ++++++++++++++++++++++-------------------- src/nasal_builtin.h | 84 ++++++------- src/nasal_vm.h | 5 +- src/unix_lib.cpp | 78 ++++++------ src/unix_lib.h | 20 ++-- 17 files changed, 448 insertions(+), 410 deletions(-) diff --git a/src/bits_lib.cpp b/src/bits_lib.cpp index f33c79b..95639b9 100644 --- a/src/bits_lib.cpp +++ b/src/bits_lib.cpp @@ -2,45 +2,52 @@ namespace nasal { -var builtin_u32xor(var* local, gc& ngc) { +var builtin_u32xor(context* ctx, gc* ngc) { + auto local = ctx->localr; return var::num(static_cast( static_cast(local[1].num()) ^ static_cast(local[2].num()) )); } -var builtin_u32and(var* local, gc& ngc) { +var builtin_u32and(context* ctx, gc* ngc) { + auto local = ctx->localr; return var::num(static_cast( static_cast(local[1].num()) & static_cast(local[2].num()) )); } -var builtin_u32or(var* local, gc& ngc) { +var builtin_u32or(context* ctx, gc* ngc) { + auto local = ctx->localr; return var::num(static_cast( static_cast(local[1].num()) | static_cast(local[2].num()) )); } -var builtin_u32nand(var* local, gc& ngc) { +var builtin_u32nand(context* ctx, gc* ngc) { + auto local = ctx->localr; return var::num(static_cast(~( static_cast(local[1].num()) & static_cast(local[2].num()) ))); } -var builtin_u32not(var* local, gc& ngc) { - return var::num(static_cast(~static_cast(local[1].num()))); +var builtin_u32not(context* ctx, gc* ngc) { + return var::num(static_cast( + ~static_cast(ctx->localr[1].num()) + )); } -var builtin_fld(var* local, gc& ngc) { +var builtin_fld(context* ctx, gc* ngc) { // bits.fld(s,0,3); // if s stores 10100010(162) // will get 101(5) - var str = local[1]; - var startbit = local[2]; - var length = local[3]; + auto local = ctx->localr; + auto str = local[1]; + auto startbit = local[2]; + auto length = local[3]; if (str.type!=vm_str || str.val.gcobj->unmutable) { return nas_err("fld", "\"str\" must be mutable string"); } @@ -62,14 +69,15 @@ var builtin_fld(var* local, gc& ngc) { return var::num(static_cast(res)); } -var builtin_sfld(var* local, gc& ngc) { +var builtin_sfld(context* ctx, gc* ngc) { // bits.sfld(s,0,3); // if s stores 10100010(162) // will get 101(5) then this will be signed extended to // 11111101(-3) - var str = local[1]; - var startbit = local[2]; - var length = local[3]; + auto local = ctx->localr; + auto str = local[1]; + auto startbit = local[2]; + auto length = local[3]; if (str.type!=vm_str || str.val.gcobj->unmutable) { return nas_err("sfld", "\"str\" must be mutable string"); } @@ -94,15 +102,16 @@ var builtin_sfld(var* local, gc& ngc) { return var::num(static_cast(static_cast(res))); } -var builtin_setfld(var* local, gc& ngc) { +var builtin_setfld(context* ctx, gc* ngc) { // bits.setfld(s,0,8,69); // set 01000101(69) to string will get this: // 10100010(162) // so s[0]=162 - var str = local[1]; - var startbit = local[2]; - var length = local[3]; - var value = local[4]; + auto local = ctx->localr; + auto str = local[1]; + auto startbit = local[2]; + auto length = local[3]; + auto value = local[4]; if (str.type!=vm_str || str.val.gcobj->unmutable) { return nas_err("setfld", "\"str\" must be mutable string"); } @@ -126,12 +135,12 @@ var builtin_setfld(var* local, gc& ngc) { return nil; } -var builtin_buf(var* local, gc& ngc) { - var length = local[1]; +var builtin_buf(context* ctx, gc* ngc) { + var length = ctx->localr[1]; if (length.type!=vm_num || length.num()<=0) { return nas_err("buf", "\"len\" must be number greater than 0"); } - var str = ngc.alloc(vm_str); + var str = ngc->alloc(vm_str); auto& s = str.str(); s.resize(length.num(), '\0'); return str; diff --git a/src/bits_lib.h b/src/bits_lib.h index f2a8a37..0864cec 100644 --- a/src/bits_lib.h +++ b/src/bits_lib.h @@ -6,15 +6,15 @@ namespace nasal { -var builtin_u32xor(var*, gc&); -var builtin_u32and(var*, gc&); -var builtin_u32or(var*, gc&); -var builtin_u32nand(var*, gc&); -var builtin_u32not(var*, gc&); -var builtin_fld(var*, gc&); -var builtin_sfld(var*, gc&); -var builtin_setfld(var*, gc&); -var builtin_buf(var*, gc&); +var builtin_u32xor(context*, gc*); +var builtin_u32and(context*, gc*); +var builtin_u32or(context*, gc*); +var builtin_u32nand(context*, gc*); +var builtin_u32not(context*, gc*); +var builtin_fld(context*, gc*); +var builtin_sfld(context*, gc*); +var builtin_setfld(context*, gc*); +var builtin_buf(context*, gc*); extern nasal_builtin_table bits_native[]; diff --git a/src/coroutine.cpp b/src/coroutine.cpp index 319698e..5603656 100644 --- a/src/coroutine.cpp +++ b/src/coroutine.cpp @@ -2,7 +2,8 @@ namespace nasal { -var builtin_cocreate(var* local, gc& ngc) { +var builtin_cocreate(context* ctx, gc* ngc) { + // ``` // +-------------+ // | old pc | <- top[0] // +-------------+ @@ -15,69 +16,73 @@ var builtin_cocreate(var* local, gc& ngc) { // +-------------+ <- local pointer stored in localr // | old funcr | <- old function stored in funcr // +-------------+ - var func = local[1]; - if (func.type!=vm_func) { + // ``` + auto coroutine_function = ctx->localr[1]; + if (coroutine_function.type!=vm_func) { return nas_err( "coroutine::create", "must use a function to create coroutine" ); } - if (ngc.cort) { + if (ngc->cort) { return nas_err( "coroutine::create", "cannot create another coroutine in a coroutine" ); } - var co = ngc.alloc(vm_co); - nas_co& cort = co.co(); - cort.ctx.pc = func.func().entry-1; + auto coroutine_object = ngc->alloc(vm_co); + auto& coroutine = coroutine_object.co(); + coroutine.ctx.pc = coroutine_function.func().entry-1; + + coroutine.ctx.top[0] = nil; + coroutine.ctx.localr = coroutine.ctx.top+1; + coroutine.ctx.top = coroutine.ctx.localr + + coroutine_function.func().local_size; + coroutine.ctx.localr[0] = coroutine_function.func().local[0]; - cort.ctx.top[0] = nil; - cort.ctx.localr = cort.ctx.top+1; - cort.ctx.top = cort.ctx.localr+func.func().local_size; - cort.ctx.localr[0] = func.func().local[0]; // store old upvalr on stack - cort.ctx.top[0] = nil; - cort.ctx.top++; + coroutine.ctx.top[0] = nil; + coroutine.ctx.top++; + // store old localr on stack - cort.ctx.top[0] = var::addr((var*)nullptr); - cort.ctx.top++; + coroutine.ctx.top[0] = var::addr((var*)nullptr); + coroutine.ctx.top++; + // store old pc on stack // set to zero to make op_ret recognizing this as coroutine function - cort.ctx.top[0] = var::ret(0); + coroutine.ctx.top[0] = var::ret(0); // make sure the coroutine function can use correct upvalues - cort.ctx.funcr = func; - cort.status = nas_co::status::suspended; - - return co; + coroutine.ctx.funcr = coroutine_function; + coroutine.status = nas_co::status::suspended; + + return coroutine_object; } -var builtin_coresume(var* local, gc& ngc) { - if (ngc.cort) { +var builtin_coresume(context* ctx, gc* ngc) { + if (ngc->cort) { return nas_err( "coroutine::resume", "cannot start another coroutine when one is running" ); } - var co = local[1]; - // return nil if is not a coroutine object - if (co.type!=vm_co) { - return nil; - } - // cannot resume a dead coroutine - if (co.co().status==nas_co::status::dead) { + auto main_local_frame = ctx->localr; + auto coroutine_object = main_local_frame[1]; + // return nil if is not a coroutine object or coroutine exited + if (coroutine_object.type!=vm_co || + coroutine_object.co().status==nas_co::status::dead) { return nil; } // change to coroutine context - ngc.ctxchg(co.co()); + ngc->ctxchg(coroutine_object.co()); // fetch coroutine's stack top and return + // then coroutine's stack top will catch this return value // so the coroutine's stack top in fact is not changed - if (ngc.running_context->top[0].type==vm_ret) { + if (ngc->running_context->top[0].type==vm_ret) { // when first calling this coroutine, the stack top must be vm_ret - return ngc.running_context->top[0]; + return ngc->running_context->top[0]; } // after first calling the coroutine, each time coroutine.yield triggered @@ -87,39 +92,41 @@ var builtin_coresume(var* local, gc& ngc) { // the coroutine seems like coroutine.yield returns the value // but in fact coroutine.yield stop the coroutine // until main context calls the coroutine.resume - return local[2]; + return main_local_frame[2]; } -var builtin_coyield(var* local, gc& ngc) { - if (!ngc.cort) { +var builtin_coyield(context* ctx, gc* ngc) { + if (!ngc->cort) { return nas_err("coroutine::yield", "no coroutine is running"); } + // get coroutine local frame + auto coroutine_local_frame = ctx->localr; + + // vm context will set to main context + ngc->ctxreserve(); - // this will set to main stack top - ngc.ctxreserve(); - // then this will return value to main's stack top[0] // the procedure seems like coroutine.resume returns the value // but in fact coroutine.resume stop the main context // until coroutine calls the coroutine.yield - return local[1]; + return coroutine_local_frame[1]; } -var builtin_costatus(var* local, gc& ngc) { - var co = local[1]; - if (co.type!=vm_co) { - return ngc.newstr("error"); +var builtin_costatus(context* ctx, gc* ngc) { + auto coroutine_object = ctx->localr[1]; + if (coroutine_object.type!=vm_co) { + return ngc->newstr("error"); } - switch(co.co().status) { - case nas_co::status::suspended: return ngc.newstr("suspended"); - case nas_co::status::running: return ngc.newstr("running"); - case nas_co::status::dead: return ngc.newstr("dead"); + switch(coroutine_object.co().status) { + case nas_co::status::suspended: return ngc->newstr("suspended"); + case nas_co::status::running: return ngc->newstr("running"); + case nas_co::status::dead: return ngc->newstr("dead"); } return nil; } -var builtin_corun(var* local, gc& ngc) { - return ngc.cort? one:zero; +var builtin_corun(context* ctx, gc* ngc) { + return ngc->cort? one:zero; } nasal_builtin_table coroutine_native[] = { diff --git a/src/coroutine.h b/src/coroutine.h index e0fe1d3..44c0275 100644 --- a/src/coroutine.h +++ b/src/coroutine.h @@ -6,11 +6,11 @@ namespace nasal { -var builtin_cocreate(var*, gc&); -var builtin_coresume(var*, gc&); -var builtin_coyield(var*, gc&); -var builtin_costatus(var*, gc&); -var builtin_corun(var*, gc&); +var builtin_cocreate(context*, gc*); +var builtin_coresume(context*, gc*); +var builtin_coyield(context*, gc*); +var builtin_costatus(context*, gc*); +var builtin_corun(context*, gc*); extern nasal_builtin_table coroutine_native[]; diff --git a/src/dylib_lib.cpp b/src/dylib_lib.cpp index 0c424df..6d26152 100644 --- a/src/dylib_lib.cpp +++ b/src/dylib_lib.cpp @@ -15,8 +15,8 @@ void dylib_destructor(void* ptr) { void func_addr_destructor(void* ptr) {} -var builtin_dlopen(var* local, gc& ngc) { - var dlname = local[1]; +var builtin_dlopen(context* ctx, gc* ngc) { + auto dlname = ctx->localr[1]; if (dlname.type!=vm_str) { return nas_err("dlopen", "\"libname\" must be string"); } @@ -35,8 +35,8 @@ var builtin_dlopen(var* local, gc& ngc) { 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); + auto ret = ngc->temp = ngc->alloc(vm_hash); + auto lib = ngc->alloc(vm_obj); lib.obj().set(dylib_type_name, dylib_destructor, ptr); ret.hash().elems["lib"] = lib; @@ -52,23 +52,23 @@ var builtin_dlopen(var* local, gc& ngc) { return nas_err("dlopen", "cannot find function"); } // get function pointer by name - module_func_info* tbl = reinterpret_cast(func)(); + auto tbl = reinterpret_cast(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); + 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; + ngc->temp = nil; return ret; } -var builtin_dlclose(var* local, gc& ngc) { - var libptr = local[1]; +var builtin_dlclose(context* ctx, gc* ngc) { + auto libptr = ctx->localr[1]; if (!libptr.object_check(dylib_type_name)) { return nas_err("dlclose", "\"lib\" is not a valid dynamic lib"); } @@ -76,9 +76,10 @@ var builtin_dlclose(var* local, gc& ngc) { return nil; } -var builtin_dlcallv(var* local, gc& ngc) { - var fp = local[1]; - var args = local[2]; +var builtin_dlcallv(context* ctx, gc* ngc) { + auto local = ctx->localr; + auto fp = local[1]; + auto args = local[2]; if (!fp.object_check(func_addr_type_name)) { return nas_err("dlcall", "\"ptr\" is not a valid function pointer"); } @@ -86,23 +87,24 @@ var builtin_dlcallv(var* local, gc& ngc) { return reinterpret_cast(fp.obj().pointer)( vec.data(), vec.size(), - &ngc + ngc ); } -var builtin_dlcall(var* local, gc& ngc) { +var builtin_dlcall(context* ctx, gc* ngc) { + auto local = ctx->localr; var fp = local[1]; if (!fp.object_check(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.running_context->top-local_frame_start; + usize local_frame_size = ngc->running_context->top-local_frame_start; // arguments' stored place begins at local +2 return reinterpret_cast(fp.obj().pointer)( local_frame_start, local_frame_size, - &ngc + ngc ); } diff --git a/src/dylib_lib.h b/src/dylib_lib.h index 039f2b4..7eed093 100644 --- a/src/dylib_lib.h +++ b/src/dylib_lib.h @@ -16,10 +16,10 @@ namespace nasal { 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&); +var builtin_dlopen(context*, gc*); +var builtin_dlclose(context*, gc*); +var builtin_dlcallv(context*, gc*); +var builtin_dlcall(context*, gc*); extern nasal_builtin_table dylib_lib_native[]; diff --git a/src/fg_props.cpp b/src/fg_props.cpp index fd958f7..25ddf7e 100644 --- a/src/fg_props.cpp +++ b/src/fg_props.cpp @@ -4,9 +4,10 @@ namespace nasal { -var builtin_logprint(var* local, gc& ngc) { - var level = local[1]; - var elems = local[2]; +var builtin_logprint(context* ctx, gc* ngc) { + auto local = ctx->localr; + auto level = local[1]; + auto elems = local[2]; if (elems.type!=vm_vec) { return nas_err("logprint", "received argument is not vector."); } diff --git a/src/fg_props.h b/src/fg_props.h index 82a3f89..a76dcce 100644 --- a/src/fg_props.h +++ b/src/fg_props.h @@ -15,7 +15,7 @@ namespace nasal { #define SG_DEV_ALERT 8 #define SG_MANDATORY_INFO 9 -var builtin_logprint(var*, gc&); +var builtin_logprint(context*, gc*); extern nasal_builtin_table flight_gear_native[]; diff --git a/src/io_lib.cpp b/src/io_lib.cpp index 089647c..9fdd19a 100644 --- a/src/io_lib.cpp +++ b/src/io_lib.cpp @@ -11,8 +11,8 @@ void filehandle_destructor(void* ptr) { fclose(static_cast(ptr)); } -var builtin_readfile(var* local, gc& ngc) { - var val = local[1]; +var builtin_readfile(context* ctx, gc* ngc) { + auto val = ctx->localr[1]; if (val.type!=vm_str) { return nas_err("io::readfile", "\"filename\" must be string"); } @@ -21,12 +21,13 @@ var builtin_readfile(var* local, gc& ngc) { if (!in.fail()) { rd << in.rdbuf(); } - return ngc.newstr(rd.str()); + return ngc->newstr(rd.str()); } -var builtin_fout(var* local, gc& ngc) { - var val = local[1]; - var str = local[2]; +var builtin_fout(context* ctx, gc* ngc) { + auto local = ctx->localr; + auto val = local[1]; + auto str = local[2]; if (val.type!=vm_str) { return nas_err("io::fout", "\"filename\" must be string"); } @@ -38,16 +39,18 @@ var builtin_fout(var* local, gc& ngc) { return nil; } -var builtin_exists(var* local, gc& ngc) { +var builtin_exists(context* ctx, gc* ngc) { + auto local = ctx->localr; 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]; +var builtin_open(context* ctx, gc* ngc) { + auto local = ctx->localr; + auto name = local[1]; + auto mode = local[2]; if (name.type!=vm_str) { return nas_err("open", "\"filename\" must be string"); } @@ -58,13 +61,13 @@ var builtin_open(var* local, gc& ngc) { if (!res) { 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(file_type_name, filehandle_destructor, res); return ret; } -var builtin_close(var* local, gc& ngc) { - var fd = local[1]; +var builtin_close(context* ctx, gc* ngc) { + var fd = ctx->localr[1]; if (!fd.object_check(file_type_name)) { return nas_err("close", "not a valid filehandle"); } @@ -72,10 +75,11 @@ var builtin_close(var* local, gc& ngc) { return nil; } -var builtin_read(var* local, gc& ngc) { - var fd = local[1]; - var buf = local[2]; - var len = local[3]; +var builtin_read(context* ctx, gc* ngc) { + auto local = ctx->localr; + auto fd = local[1]; + auto buf = local[2]; + auto len = local[3]; if (!fd.object_check(file_type_name)) { return nas_err("read", "not a valid filehandle"); } @@ -99,9 +103,10 @@ var builtin_read(var* local, gc& ngc) { return var::num(res); } -var builtin_write(var* local, gc& ngc) { - var fd = local[1]; - var str = local[2]; +var builtin_write(context* ctx, gc* ngc) { + auto local = ctx->localr; + auto fd = local[1]; + auto str = local[2]; if (!fd.object_check(file_type_name)) { return nas_err("write", "not a valid filehandle"); } @@ -116,10 +121,11 @@ var builtin_write(var* local, gc& ngc) { ))); } -var builtin_seek(var* local, gc& ngc) { - var fd = local[1]; - var pos = local[2]; - var whence = local[3]; +var builtin_seek(context* ctx, gc* ngc) { + auto local = ctx->localr; + auto fd = local[1]; + auto pos = local[2]; + auto whence = local[3]; if (!fd.object_check(file_type_name)) { return nas_err("seek", "not a valid filehandle"); } @@ -130,8 +136,8 @@ var builtin_seek(var* local, gc& ngc) { ))); } -var builtin_tell(var* local, gc& ngc) { - var fd = local[1]; +var builtin_tell(context* ctx, gc* ngc) { + auto fd = ctx->localr[1]; if (!fd.object_check(file_type_name)) { return nas_err("tell", "not a valid filehandle"); } @@ -140,12 +146,12 @@ var builtin_tell(var* local, gc& ngc) { )); } -var builtin_readln(var* local, gc& ngc) { - var fd = local[1]; +var builtin_readln(context* ctx, gc* ngc) { + auto fd = ctx->localr[1]; if (!fd.object_check(file_type_name)) { return nas_err("readln", "not a valid filehandle"); } - var str = ngc.alloc(vm_str); + auto str = ngc->alloc(vm_str); char c; while((c = fgetc(static_cast(fd.obj().pointer)))!=EOF) { if (c=='\r') { @@ -162,16 +168,16 @@ var builtin_readln(var* local, gc& ngc) { return nil; } -var builtin_stat(var* local, gc& ngc) { - var name = local[1]; +var builtin_stat(context* ctx, gc* ngc) { + auto name = ctx->localr[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) { + if (stat(name.str().c_str(), &buf)<0) { return nas_err("stat", "failed to open file <"+name.str()+">"); } - var ret = ngc.alloc(vm_vec); + auto ret = ngc->alloc(vm_vec); ret.vec().elems = { var::num(static_cast(buf.st_dev)), var::num(static_cast(buf.st_ino)), @@ -188,8 +194,8 @@ var builtin_stat(var* local, gc& ngc) { return ret; } -var builtin_eof(var* local, gc& ngc) { - var fd = local[1]; +var builtin_eof(context* ctx, gc* ngc) { + auto fd = ctx->localr[1]; if (!fd.object_check(file_type_name)) { return nas_err("readln", "not a valid filehandle"); } diff --git a/src/io_lib.h b/src/io_lib.h index 3ea800d..a4dc136 100644 --- a/src/io_lib.h +++ b/src/io_lib.h @@ -20,18 +20,18 @@ namespace nasal { void filehandle_destructor(void*); -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&); +var builtin_readfile(context*, gc*); +var builtin_fout(context*, gc*); +var builtin_exists(context*, gc*); +var builtin_open(context*, gc*); +var builtin_close(context*, gc*); +var builtin_read(context*, gc*); +var builtin_write(context*, gc*); +var builtin_seek(context*, gc*); +var builtin_tell(context*, gc*); +var builtin_readln(context*, gc*); +var builtin_stat(context*, gc*); +var builtin_eof(context*, gc*); extern nasal_builtin_table io_lib_native[]; diff --git a/src/math_lib.cpp b/src/math_lib.cpp index e751636..750648a 100644 --- a/src/math_lib.cpp +++ b/src/math_lib.cpp @@ -2,61 +2,61 @@ namespace nasal { -var builtin_pow(var* local, gc& ngc) { - var x = local[1]; - var y = local[2]; +var builtin_pow(context* ctx, gc* ngc) { + auto x = ctx->localr[1]; + auto y = ctx->localr[2]; if (x.type!=vm_num || y.type!=vm_num) { return var::num(std::nan("")); } return var::num(std::pow(x.num(), y.num())); } -var builtin_sin(var* local, gc& ngc) { - var val = local[1]; +var builtin_sin(context* ctx, gc* ngc) { + auto val = ctx->localr[1]; return var::num(val.type==vm_num? sin(val.num()):std::nan("")); } -var builtin_cos(var* local, gc& ngc) { - var val = local[1]; +var builtin_cos(context* ctx, gc* ngc) { + auto val = ctx->localr[1]; return var::num(val.type==vm_num? cos(val.num()):std::nan("")); } -var builtin_tan(var* local, gc& ngc) { - var val = local[1]; +var builtin_tan(context* ctx, gc* ngc) { + auto val = ctx->localr[1]; return var::num(val.type==vm_num? tan(val.num()):std::nan("")); } -var builtin_exp(var* local, gc& ngc) { - var val = local[1]; +var builtin_exp(context* ctx, gc* ngc) { + auto val = ctx->localr[1]; return var::num(val.type==vm_num? exp(val.num()):std::nan("")); } -var builtin_lg(var* local, gc& ngc) { - var val = local[1]; +var builtin_lg(context* ctx, gc* ngc) { + auto val = ctx->localr[1]; return var::num(val.type==vm_num? log(val.num())/log(10.0):std::nan("")); } -var builtin_ln(var* local, gc& ngc) { - var val = local[1]; +var builtin_ln(context* ctx, gc* ngc) { + auto val = ctx->localr[1]; return var::num(val.type==vm_num? log(val.num()):std::nan("")); } -var builtin_sqrt(var* local, gc& ngc) { - var val = local[1]; +var builtin_sqrt(context* ctx, gc* ngc) { + auto val = ctx->localr[1]; return var::num(val.type==vm_num? sqrt(val.num()):std::nan("")); } -var builtin_atan2(var* local, gc& ngc) { - var x = local[1]; - var y = local[2]; +var builtin_atan2(context* ctx, gc* ngc) { + auto x = ctx->localr[1]; + auto y = ctx->localr[2]; if (x.type!=vm_num || y.type!=vm_num) { return var::num(std::nan("")); } return var::num(atan2(y.num(), x.num())); } -var builtin_isnan(var* local, gc& ngc) { - var x = local[1]; +var builtin_isnan(context* ctx, gc* ngc) { + auto x = ctx->localr[1]; return (x.type==vm_num && std::isnan(x.num()))? one:zero; } diff --git a/src/math_lib.h b/src/math_lib.h index a0c3550..e8a72b7 100644 --- a/src/math_lib.h +++ b/src/math_lib.h @@ -6,16 +6,16 @@ namespace nasal { -var builtin_pow(var*, gc&); -var builtin_sin(var*, gc&); -var builtin_cos(var*, gc&); -var builtin_tan(var*, gc&); -var builtin_exp(var*, gc&); -var builtin_lg(var*, gc&); -var builtin_ln(var*, gc&); -var builtin_sqrt(var*, gc&); -var builtin_atan2(var*, gc&); -var builtin_isnan(var*, gc&); +var builtin_pow(context*, gc*); +var builtin_sin(context*, gc*); +var builtin_cos(context*, gc*); +var builtin_tan(context*, gc*); +var builtin_exp(context*, gc*); +var builtin_lg(context*, gc*); +var builtin_ln(context*, gc*); +var builtin_sqrt(context*, gc*); +var builtin_atan2(context*, gc*); +var builtin_isnan(context*, gc*); extern nasal_builtin_table math_lib_native[]; diff --git a/src/nasal_builtin.cpp b/src/nasal_builtin.cpp index 8d21a02..499e92c 100644 --- a/src/nasal_builtin.cpp +++ b/src/nasal_builtin.cpp @@ -3,33 +3,34 @@ namespace nasal { -var builtin_print(var* local, gc& ngc) { - for(auto& i : local[1].vec().elems) { +var builtin_print(context* ctx, gc* ngc) { + for(auto& i : ctx->localr[1].vec().elems) { std::cout << i; } std::cout << std::flush; return nil; } -var builtin_println(var* local, gc& ngc) { - for(auto& i : local[1].vec().elems) { +var builtin_println(context* ctx, gc* ngc) { + for(auto& i : ctx->localr[1].vec().elems) { std::cout << i; } std::cout << std::endl; return nil; } -var builtin_exit(var* local, gc& ngc) { - std::exit(local[1].num()); +var builtin_exit(context* ctx, gc* ngc) { + std::exit(ctx->localr[1].num()); return nil; } -var builtin_abort(var* local, gc& ngc) { +var builtin_abort(context* ctx, gc* ngc) { std::abort(); return nil; } -var builtin_append(var* local, gc& ngc) { +var builtin_append(context* ctx, gc* ngc) { + auto local = ctx->localr; var vec = local[1]; var elem = local[2]; if (vec.type!=vm_vec) { @@ -42,7 +43,8 @@ var builtin_append(var* local, gc& ngc) { return nil; } -var builtin_setsize(var* local, gc& ngc) { +var builtin_setsize(context* ctx, gc* ngc) { + auto local = ctx->localr; var vec = local[1]; var size = local[2]; if (vec.type!=vm_vec) { @@ -55,17 +57,18 @@ var builtin_setsize(var* local, gc& ngc) { return nil; } -var builtin_system(var* local, gc& ngc) { - var str = local[1]; +var builtin_system(context* ctx, gc* ngc) { + auto str = ctx->localr[1]; if (str.type!=vm_str) { return var::num(-1); } return var::num(static_cast(system(str.str().c_str()))); } -var builtin_input(var* local, gc& ngc) { +var builtin_input(context* ctx, gc* ngc) { + auto local = ctx->localr; var end = local[1]; - var ret = ngc.alloc(vm_str); + var ret = ngc->alloc(vm_str); if (end.type!=vm_str || end.str().length()>1 || !end.str().length()) { std::cin >> ret.str(); } else { @@ -74,7 +77,8 @@ var builtin_input(var* local, gc& ngc) { return ret; } -var builtin_split(var* local, gc& ngc) { +var builtin_split(context* ctx, gc* ngc) { + auto local = ctx->localr; var delimeter = local[1]; var str = local[2]; if (delimeter.type!=vm_str) { @@ -87,34 +91,34 @@ var builtin_split(var* local, gc& ngc) { const auto& s = str.str(); // avoid being sweeped - var res = ngc.temp = ngc.alloc(vm_vec); + auto res = ngc->temp = ngc->alloc(vm_vec); auto& vec = res.vec().elems; if (!deli.length()) { for(auto i : s) { - vec.push_back(ngc.newstr(i)); + vec.push_back(ngc->newstr(i)); } - ngc.temp = nil; + ngc->temp = nil; return res; } usize last = 0; usize pos = s.find(deli, 0); while(pos!=std::string::npos) { if (pos>last) { - vec.push_back(ngc.newstr(s.substr(last, pos-last))); + vec.push_back(ngc->newstr(s.substr(last, pos-last))); } last = pos+deli.length(); pos = s.find(deli, last); } if (last!=s.length()) { - vec.push_back(ngc.newstr(s.substr(last))); + vec.push_back(ngc->newstr(s.substr(last))); } - ngc.temp = nil; + ngc->temp = nil; return res; } -var builtin_rand(var* local, gc& ngc) { - var val = local[1]; +var builtin_rand(context* ctx, gc* ngc) { + auto val = ctx->localr[1]; if (val.type!=vm_num && val.type!=vm_nil) { return nas_err("rand", "\"seed\" must be nil or number"); } @@ -129,65 +133,65 @@ var builtin_rand(var* local, gc& ngc) { return var::num(num); } -var builtin_id(var* local, gc& ngc) { - var val = local[1]; +var builtin_id(context* ctx, gc* ngc) { + auto val = ctx->localr[1]; std::stringstream ss; ss << "0"; if (val.type>vm_num) { ss << "x" << std::hex; ss << reinterpret_cast(val.val.gcobj) << std::dec; } - return ngc.newstr(ss.str()); + return ngc->newstr(ss.str()); } -var builtin_int(var* local, gc& ngc) { - var val = local[1]; +var builtin_int(context* ctx, gc* ngc) { + auto val = ctx->localr[1]; if (val.type!=vm_num && val.type!=vm_str) { return nil; } return var::num(static_cast(static_cast(val.to_num()))); } -var builtin_floor(var* local, gc& ngc) { - var val = local[1]; - return var::num(std::floor(val.num())); +var builtin_floor(context* ctx, gc* ngc) { + auto value = ctx->localr[1]; + return var::num(std::floor(value.num())); } -var builtin_num(var* local, gc& ngc) { - var val = local[1]; +var builtin_num(context* ctx, gc* ngc) { + auto val = ctx->localr[1]; if (val.type==vm_num) { return val; } if (val.type!=vm_str) { return nil; } - f64 res = val.to_num(); + auto res = val.to_num(); if (std::isnan(res)) { return nil; } return var::num(res); } -var builtin_pop(var* local, gc& ngc) { - var val = local[1]; +var builtin_pop(context* ctx, gc* ngc) { + auto val = ctx->localr[1]; if (val.type!=vm_vec) { return nas_err("pop", "\"vec\" must be vector"); } auto& vec = val.vec().elems; if (vec.size()) { - var tmp = vec.back(); + auto tmp = vec.back(); vec.pop_back(); return tmp; } return nil; } -var builtin_str(var* local, gc& ngc) { - return ngc.newstr(local[1].to_str()); +var builtin_str(context* ctx, gc* ngc) { + return ngc->newstr(ctx->localr[1].to_str()); } -var builtin_size(var* local, gc& ngc) { - var val = local[1]; +var builtin_size(context* ctx, gc* ngc) { + auto val = ctx->localr[1]; f64 num = 0; switch(val.type) { case vm_num: num = val.num(); break; @@ -199,16 +203,17 @@ var builtin_size(var* local, gc& ngc) { return var::num(num); } -var builtin_time(var* local, gc& ngc) { - var val = local[1]; +var builtin_time(context* ctx, gc* ngc) { + auto val = ctx->localr[1]; if (val.type!=vm_num) { return nas_err("time", "\"begin\" must be number"); } - time_t begin = (time_t)val.num(); + auto begin = static_cast(val.num()); return var::num(static_cast(time(&begin))); } -var builtin_contains(var* local, gc& ngc) { +var builtin_contains(context* ctx, gc* ngc) { + auto local = ctx->localr; var hash = local[1]; var key = local[2]; if (hash.type!=vm_hash || key.type!=vm_str) { @@ -217,7 +222,8 @@ var builtin_contains(var* local, gc& ngc) { return hash.hash().elems.count(key.str())? one:zero; } -var builtin_delete(var* local, gc& ngc) { +var builtin_delete(context* ctx, gc* ngc) { + auto local = ctx->localr; var hash = local[1]; var key = local[2]; if (hash.type!=vm_hash) { @@ -232,32 +238,33 @@ var builtin_delete(var* local, gc& ngc) { return nil; } -var builtin_keys(var* local, gc& ngc) { - var hash = local[1]; +var builtin_keys(context* ctx, gc* ngc) { + auto hash = ctx->localr[1]; if (hash.type!=vm_hash && hash.type!=vm_map) { return nas_err("keys", "\"hash\" must be hash"); } // avoid being sweeped - var res = ngc.temp = ngc.alloc(vm_vec); + auto res = ngc->temp = ngc->alloc(vm_vec); auto& vec = res.vec().elems; if (hash.type==vm_hash) { for(const auto& iter : hash.hash().elems) { - vec.push_back(ngc.newstr(iter.first)); + vec.push_back(ngc->newstr(iter.first)); } } else { for(const auto& iter : hash.map().mapper) { - vec.push_back(ngc.newstr(iter.first)); + vec.push_back(ngc->newstr(iter.first)); } } - ngc.temp=nil; + ngc->temp=nil; return res; } -var builtin_die(var* local, gc& ngc) { - return nas_err("error", local[1].to_str()); +var builtin_die(context* ctx, gc* ngc) { + return nas_err("error", ctx->localr[1].to_str()); } -var builtin_find(var* local, gc& ngc) { +var builtin_find(context* ctx, gc* ngc) { + auto local = ctx->localr; var needle = local[1]; var haystack = local[2]; usize pos = haystack.to_str().find(needle.to_str()); @@ -267,23 +274,24 @@ var builtin_find(var* local, gc& ngc) { return var::num(static_cast(pos)); } -var builtin_type(var* local, gc& ngc) { - switch(local[1].type) { - case vm_none: return ngc.newstr("undefined"); - case vm_nil: return ngc.newstr("nil"); - case vm_num: return ngc.newstr("num"); - case vm_str: return ngc.newstr("str"); - case vm_vec: return ngc.newstr("vec"); - case vm_hash: return ngc.newstr("hash"); - case vm_func: return ngc.newstr("func"); - case vm_obj: return ngc.newstr("obj"); - case vm_co: return ngc.newstr("coroutine"); - case vm_map: return ngc.newstr("namespace"); +var builtin_type(context* ctx, gc* ngc) { + switch(ctx->localr[1].type) { + case vm_none: return ngc->newstr("undefined"); + case vm_nil: return ngc->newstr("nil"); + case vm_num: return ngc->newstr("num"); + case vm_str: return ngc->newstr("str"); + case vm_vec: return ngc->newstr("vec"); + case vm_hash: return ngc->newstr("hash"); + case vm_func: return ngc->newstr("func"); + case vm_obj: return ngc->newstr("obj"); + case vm_co: return ngc->newstr("coroutine"); + case vm_map: return ngc->newstr("namespace"); } return nil; } -var builtin_substr(var* local, gc& ngc) { +var builtin_substr(context* ctx, gc* ngc) { + auto local = ctx->localr; var str = local[1]; var beg = local[2]; var len = local[3]; @@ -301,10 +309,11 @@ var builtin_substr(var* local, gc& ngc) { if (begin>=str.str().length()) { return nas_err("susbtr", "begin index out of range: "+std::to_string(begin)); } - return ngc.newstr(str.str().substr(begin,length)); + return ngc->newstr(str.str().substr(begin,length)); } -var builtin_streq(var* local, gc& ngc) { +var builtin_streq(context* ctx, gc* ngc) { + auto local = ctx->localr; var a = local[1]; var b = local[2]; return var::num(static_cast( @@ -312,7 +321,8 @@ var builtin_streq(var* local, gc& ngc) { )); } -var builtin_left(var* local, gc& ngc) { +var builtin_left(context* ctx, gc* ngc) { + auto local = ctx->localr; var str = local[1]; var len = local[2]; if (str.type!=vm_str) { @@ -322,12 +332,13 @@ var builtin_left(var* local, gc& ngc) { return nas_err("left", "\"length\" must be number"); } if (len.num()<0) { - return ngc.newstr(""); + return ngc->newstr(""); } - return ngc.newstr(str.str().substr(0, len.num())); + return ngc->newstr(str.str().substr(0, len.num())); } -var builtin_right(var* local, gc& ngc) { +var builtin_right(context* ctx, gc* ngc) { + auto local = ctx->localr; var str = local[1]; var len = local[2]; if (str.type!=vm_str) { @@ -344,10 +355,11 @@ var builtin_right(var* local, gc& ngc) { if (length<0) { length = 0; } - return ngc.newstr(str.str().substr(srclen-length, srclen)); + return ngc->newstr(str.str().substr(srclen-length, srclen)); } -var builtin_cmp(var* local, gc& ngc) { +var builtin_cmp(context* ctx, gc* ngc) { + auto local = ctx->localr; var a = local[1]; var b = local[2]; if (a.type!=vm_str || b.type!=vm_str) { @@ -359,7 +371,7 @@ var builtin_cmp(var* local, gc& ngc) { ))); } -var builtin_chr(var* local, gc& ngc) { +var builtin_chr(context* ctx, gc* ngc) { const char* extend[] = { "€"," ","‚","ƒ","„","…","†","‡", "ˆ","‰","Š","‹","Œ"," ","Ž"," ", @@ -378,25 +390,25 @@ var builtin_chr(var* local, gc& ngc) { "ð","ñ","ò","ó","ô","õ","ö","÷", "ø","ù","ú","û","ü","ý","þ","ÿ" }; - i32 num = local[1].num(); + auto num = static_cast(ctx->localr[1].num()); if (0<=num && num<128) { - return ngc.newstr((char)num); + return ngc->newstr((char)num); } else if (128<=num && num<256) { - return ngc.newstr(extend[num-128]); + return ngc->newstr(extend[num-128]); } - return ngc.newstr(" "); + return ngc->newstr(" "); } -var builtin_char(var* local, gc& ngc) { - return ngc.newstr((unsigned char)local[1].num()); +var builtin_char(context* ctx, gc* ngc) { + return ngc->newstr(static_cast(ctx->localr[1].num())); } -var builtin_values(var* local, gc& ngc) { - var hash = local[1]; +var builtin_values(context* ctx, gc* ngc) { + auto hash = ctx->localr[1]; if (hash.type!=vm_hash) { return nas_err("values", "\"hash\" must be hash"); } - var vec = ngc.alloc(vm_vec); + var vec = ngc->alloc(vm_vec); auto& v = vec.vec().elems; for(auto& i : hash.hash().elems) { v.push_back(i.second); @@ -404,8 +416,8 @@ var builtin_values(var* local, gc& ngc) { return vec; } -var builtin_sleep(var* local, gc& ngc) { - var val = local[1]; +var builtin_sleep(context* ctx, gc* ngc) { + auto val = ctx->localr[1]; if (val.type!=vm_num) { return nil; } @@ -421,36 +433,36 @@ var builtin_sleep(var* local, gc& ngc) { return nil; } -var builtin_platform(var* local, gc& ngc) { +var builtin_platform(context* ctx, gc* ngc) { if (is_windows()) { - return ngc.newstr("windows"); + return ngc->newstr("windows"); } else if (is_linux()) { - return ngc.newstr("linux"); + return ngc->newstr("linux"); } else if (is_macos()) { - return ngc.newstr("macOS"); + return ngc->newstr("macOS"); } - return ngc.newstr("unknown"); + return ngc->newstr("unknown"); } -var builtin_arch(var* local, gc& ngc) { +var builtin_arch(context* ctx, gc* ngc) { if (is_x86()) { - return ngc.newstr("x86"); + return ngc->newstr("x86"); } else if (is_x86_64()) { - return ngc.newstr("x86-64"); + return ngc->newstr("x86-64"); } else if (is_amd64()) { - return ngc.newstr("amd64"); + return ngc->newstr("amd64"); } else if (is_arm()) { - return ngc.newstr("arm"); + return ngc->newstr("arm"); } else if (is_aarch64()) { - return ngc.newstr("aarch64"); + return ngc->newstr("aarch64"); } else if (is_ia64()) { - return ngc.newstr("ia64"); + return ngc->newstr("ia64"); } else if (is_powerpc()) { - return ngc.newstr("powerpc"); + return ngc->newstr("powerpc"); } else if (is_superh()) { - return ngc.newstr("superh"); + return ngc->newstr("superh"); } - return ngc.newstr("unknown"); + return ngc->newstr("unknown"); } // md5 related functions @@ -536,64 +548,64 @@ std::string md5(const std::string& src) { return tohex(atmp)+tohex(btmp)+tohex(ctmp)+tohex(dtmp); } -var builtin_md5(var* local, gc& ngc) { - var str = local[1]; +var builtin_md5(context* ctx, gc* ngc) { + auto str = ctx->localr[1]; if (str.type!=vm_str) { return nas_err("md5", "\"str\" must be string"); } - return ngc.newstr(md5(str.str())); + return ngc->newstr(md5(str.str())); } -var builtin_millisec(var* local, gc& ngc) { +var builtin_millisec(context* ctx, gc* ngc) { f64 res = std::chrono::duration_cast (std::chrono::high_resolution_clock::now().time_since_epoch()) .count(); return var::num(res); } -var builtin_gcextend(var* local, gc& ngc) { - var type = local[1]; +var builtin_gcextend(context* ctx, gc* ngc) { + auto type = ctx->localr[1]; if (type.type!=vm_str) { return nil; } - auto& s = type.str(); + const auto& s = type.str(); if (s=="str") { - ngc.extend(vm_str); + ngc->extend(vm_str); } else if (s=="vec") { - ngc.extend(vm_vec); + ngc->extend(vm_vec); } else if (s=="hash") { - ngc.extend(vm_hash); + ngc->extend(vm_hash); } else if (s=="func") { - ngc.extend(vm_func); + ngc->extend(vm_func); } else if (s=="upval") { - ngc.extend(vm_upval); + ngc->extend(vm_upval); } else if (s=="obj") { - ngc.extend(vm_obj); + ngc->extend(vm_obj); } else if (s=="co") { - ngc.extend(vm_co); + ngc->extend(vm_co); } return nil; } -var builtin_gcinfo(var* local, gc& ngc) { +var builtin_gcinfo(context* ctx, gc* ngc) { auto den = std::chrono::high_resolution_clock::duration::period::den; - var res = ngc.alloc(vm_hash); + var res = ngc->alloc(vm_hash); double total = 0; for(u32 i = 0; igcnt[i]; } // using ms auto& map = res.hash().elems; - map["total"] = var::num(ngc.worktime*1.0/den*1000); - map["average"] = var::num(ngc.worktime*1.0/den*1000/total); - map["max_gc"] = var::num(ngc.max_time*1.0/den*1000); - map["max_mark"] = var::num(ngc.max_mark_time*1.0/den*1000); - map["max_sweep"] = var::num(ngc.max_sweep_time*1.0/den*1000); + map["total"] = var::num(ngc->worktime*1.0/den*1000); + map["average"] = var::num(ngc->worktime*1.0/den*1000/total); + map["max_gc"] = var::num(ngc->max_time*1.0/den*1000); + map["max_mark"] = var::num(ngc->max_mark_time*1.0/den*1000); + map["max_sweep"] = var::num(ngc->max_sweep_time*1.0/den*1000); return res; } -var builtin_logtime(var* local, gc& ngc) { +var builtin_logtime(context* ctx, gc* ngc) { time_t t = time(nullptr); tm* tm_t = localtime(&t); char s[64]; @@ -606,11 +618,11 @@ var builtin_logtime(var* local, gc& ngc) { tm_t->tm_min, tm_t->tm_sec ); - return ngc.newstr(s); + return ngc->newstr(s); } -var builtin_ghosttype(var* local, gc& ngc) { - var arg = local[1]; +var builtin_ghosttype(context* ctx, gc* ngc) { + auto arg = ctx->localr[1]; if (arg.type!=vm_obj) { return nas_err("ghosttype", "this is not a ghost object."); } @@ -618,7 +630,7 @@ var builtin_ghosttype(var* local, gc& ngc) { if (!name.length()) { return var::num(reinterpret_cast(arg.obj().pointer)); } - return ngc.newstr(name); + return ngc->newstr(name); } nasal_builtin_table builtin[] = { diff --git a/src/nasal_builtin.h b/src/nasal_builtin.h index cf7d6ea..00f0878 100644 --- a/src/nasal_builtin.h +++ b/src/nasal_builtin.h @@ -29,56 +29,56 @@ namespace nasal { -var builtin_print(var*, gc&); -var builtin_println(var*, gc&); -var builtin_exit(var*, gc&); -var builtin_abort(var*, gc&); -var builtin_append(var*, gc&); -var builtin_setsize(var*, gc&); -var builtin_system(var*, gc&); -var builtin_input(var*, gc&); -var builtin_split(var*, gc&); -var builtin_rand(var*, gc&); -var builtin_id(var*, gc&); -var builtin_int(var*, gc&); -var builtin_floor(var*, gc&); -var builtin_num(var*, gc&); -var builtin_pop(var*, gc&); -var builtin_str(var*, gc&); -var builtin_size(var*, gc&); -var builtin_time(var*, gc&); -var builtin_contains(var*, gc&); -var builtin_delete(var*, gc&); -var builtin_keys(var*, gc&); -var builtin_die(var*, gc&); -var builtin_find(var*, gc&); -var builtin_type(var*, gc&); -var builtin_substr(var*, gc&); -var builtin_streq(var*, gc&); -var builtin_left(var*, gc&); -var builtin_right(var*, gc&); -var builtin_cmp(var*, gc&); -var builtin_chr(var*, gc&); -var builtin_char(var*, gc&); -var builtin_values(var*, gc&); -var builtin_sleep(var*, gc&); -var builtin_platform(var*, gc&); -var builtin_arch(var*, gc&); +var builtin_print(context*, gc*); +var builtin_println(context*, gc*); +var builtin_exit(context*, gc*); +var builtin_abort(context*, gc*); +var builtin_append(context*, gc*); +var builtin_setsize(context*, gc*); +var builtin_system(context*, gc*); +var builtin_input(context*, gc*); +var builtin_split(context*, gc*); +var builtin_rand(context*, gc*); +var builtin_id(context*, gc*); +var builtin_int(context*, gc*); +var builtin_floor(context*, gc*); +var builtin_num(context*, gc*); +var builtin_pop(context*, gc*); +var builtin_str(context*, gc*); +var builtin_size(context*, gc*); +var builtin_time(context*, gc*); +var builtin_contains(context*, gc*); +var builtin_delete(context*, gc*); +var builtin_keys(context*, gc*); +var builtin_die(context*, gc*); +var builtin_find(context*, gc*); +var builtin_type(context*, gc*); +var builtin_substr(context*, gc*); +var builtin_streq(context*, gc*); +var builtin_left(context*, gc*); +var builtin_right(context*, gc*); +var builtin_cmp(context*, gc*); +var builtin_chr(context*, gc*); +var builtin_char(context*, gc*); +var builtin_values(context*, gc*); +var builtin_sleep(context*, gc*); +var builtin_platform(context*, gc*); +var builtin_arch(context*, gc*); // md5 related functions std::string tohex(u32); std::string md5(const std::string&); -var builtin_md5(var*, gc&); -var builtin_millisec(var*, gc&); -var builtin_gcextend(var*, gc&); -var builtin_gcinfo(var*, gc&); -var builtin_logtime(var*, gc&); -var builtin_ghosttype(var*, gc&); +var builtin_md5(context*, gc*); +var builtin_millisec(context*, gc*); +var builtin_gcextend(context*, gc*); +var builtin_gcinfo(context*, gc*); +var builtin_logtime(context*, gc*); +var builtin_ghosttype(context*, gc*); // register builtin function's name and it's address here in this table below // this table must end with {nullptr,nullptr} struct nasal_builtin_table { const char* name; - var (*func)(var*, gc&); + var (*func)(context*, gc*); }; extern nasal_builtin_table builtin[]; diff --git a/src/nasal_vm.h b/src/nasal_vm.h index cb8f985..481627c 100644 --- a/src/nasal_vm.h +++ b/src/nasal_vm.h @@ -821,11 +821,12 @@ inline void vm::o_callb() { // if running a native function about coroutine // (top) will be set to another context.top, instead of main_context.top - var tmp = (*native_function[imm[ctx.pc]].func)(ctx.localr, ngc); + auto function_pointer = native_function[imm[ctx.pc]].func; + var result = (*function_pointer)(&ctx, &ngc); // so we use tmp variable to store this return value // and set it to top[0] later - ctx.top[0] = tmp; + ctx.top[0] = result; // if get none, this means errors occurred when calling this native function if (ctx.top[0].type==vm_none) { diff --git a/src/unix_lib.cpp b/src/unix_lib.cpp index dbd64d9..32e5f5f 100644 --- a/src/unix_lib.cpp +++ b/src/unix_lib.cpp @@ -12,130 +12,130 @@ void dir_entry_destructor(void* ptr) { #endif } -var builtin_pipe(var* local, gc& ngc) { +var builtin_pipe(context* ctx, gc* ngc) { #ifndef _WIN32 i32 fd[2]; - var res = ngc.alloc(vm_vec); + var res = ngc->alloc(vm_vec); if (pipe(fd)==-1) { - return nas_err("pipe", "failed to create pipe"); + return nas_err("unix::pipe", "failed to create pipe"); } res.vec().elems.push_back(var::num(static_cast(fd[0]))); res.vec().elems.push_back(var::num(static_cast(fd[1]))); return res; #endif - return nas_err("pipe", "not supported on windows"); + return nas_err("unix::pipe", "not supported on windows"); } -var builtin_fork(var* local, gc& ngc) { +var builtin_fork(context* ctx, gc* ngc) { #ifndef _WIN32 f64 res=fork(); if (res<0) { - return nas_err("fork", "failed to fork a process"); + return nas_err("unix::fork", "failed to fork a process"); } return var::num(static_cast(res)); #endif - return nas_err("fork", "not supported on windows"); + return nas_err("unix::fork", "not supported on windows"); } -var builtin_waitpid(var* local, gc& ngc) { - var pid = local[1]; - var nohang = local[2]; +var builtin_waitpid(context* ctx, gc* ngc) { + auto pid = ctx->localr[1]; + auto nohang = ctx->localr[2]; if (pid.type!=vm_num || nohang.type!=vm_num) { - return nas_err("waitpid", "pid and nohang must be number"); + return nas_err("unix::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); + var vec = ngc->alloc(vm_vec); vec.vec().elems.push_back(var::num(static_cast(ret_pid))); vec.vec().elems.push_back(var::num(static_cast(status))); return vec; #endif - return nas_err("waitpid", "not supported on windows"); + return nas_err("unix::waitpid", "not supported on windows"); } -var builtin_opendir(var* local, gc& ngc) { - var path = local[1]; +var builtin_opendir(context* ctx, gc* ngc) { + auto path = ctx->localr[1]; if (path.type!=vm_str) { - return nas_err("opendir", "\"path\" must be string"); + return nas_err("unix::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()+">"); + return nas_err("unix::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()+">"); + return nas_err("unix::opendir", "cannot open dir <"+path.str()+">"); } #endif - var ret = ngc.alloc(vm_obj); + 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]; +var builtin_readdir(context* ctx, gc* ngc) { + auto handle = ctx->localr[1]; if (!handle.object_check(dir_type_name)) { - return nas_err("readdir", "not a valid dir handle"); + return nas_err("unix::readdir", "not a valid dir handle"); } #ifdef _MSC_VER WIN32_FIND_DATAA data; if (!FindNextFileA(handle.obj().pointer, &data)) { return nil; } - return ngc.newstr(data.cFileName); + return ngc->newstr(data.cFileName); #else dirent* p = readdir(static_cast(handle.obj().pointer)); - return p? ngc.newstr(p->d_name):nil; + return p? ngc->newstr(p->d_name):nil; #endif } -var builtin_closedir(var* local, gc& ngc) { - var handle = local[1]; +var builtin_closedir(context* ctx, gc* ngc) { + auto handle = ctx->localr[1]; if (!handle.object_check(dir_type_name)) { - return nas_err("closedir", "not a valid dir handle"); + return nas_err("unix::closedir", "not a valid dir handle"); } handle.obj().clear(); return nil; } -var builtin_chdir(var* local, gc& ngc) { - var path = local[1]; +var builtin_chdir(context* ctx, gc* ngc) { + auto path = ctx->localr[1]; if (path.type!=vm_str) { return var::num(-1.0); } return var::num(static_cast(chdir(path.str().c_str()))); } -var builtin_environ(var* local, gc& ngc) { - var res = ngc.temp = ngc.alloc(vm_vec); +var builtin_environ(context* ctx, 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)); + vec.push_back(ngc->newstr(*env)); } - ngc.temp = nil; + ngc->temp = nil; return res; } -var builtin_getcwd(var* local, gc& ngc) { +var builtin_getcwd(context* ctx, gc* ngc) { char buf[1024]; if (!getcwd(buf, sizeof(buf))) { return nil; } - return ngc.newstr(buf); + return ngc->newstr(buf); } -var builtin_getenv(var* local, gc& ngc) { - var envvar = local[1]; +var builtin_getenv(context* ctx, gc* ngc) { + auto envvar = ctx->localr[1]; if (envvar.type!=vm_str) { - return nas_err("getenv", "\"envvar\" must be string"); + return nas_err("unix::getenv", "\"envvar\" must be string"); } char* res = getenv(envvar.str().c_str()); - return res? ngc.newstr(res):nil; + return res? ngc->newstr(res):nil; } nasal_builtin_table unix_lib_native[] = { diff --git a/src/unix_lib.h b/src/unix_lib.h index 06205f6..bc9f5cc 100644 --- a/src/unix_lib.h +++ b/src/unix_lib.h @@ -24,16 +24,16 @@ namespace nasal { 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&); +var builtin_pipe(context*, gc*); +var builtin_fork(context*, gc*); +var builtin_waitpid(context*, gc*); +var builtin_opendir(context*, gc*); +var builtin_readdir(context*, gc*); +var builtin_closedir(context*, gc*); +var builtin_chdir(context*, gc*); +var builtin_environ(context*, gc*); +var builtin_getcwd(context*, gc*); +var builtin_getenv(context*, gc*); extern nasal_builtin_table unix_lib_native[];