diff options
| author | ruki <[email protected]> | 2020-08-04 23:05:31 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2020-08-04 23:05:31 +0800 |
| commit | 96b0eae26058482a83f5bbf57bab15a834339464 (patch) | |
| tree | 94e8b6e90649f8a4c89d8406bf7e5198daa7b361 /core/src | |
| parent | 60a176cb2ae804bea3dfd11dbf8ed2f218fcefdb (diff) | |
improve stdfile
Diffstat (limited to 'core/src')
| -rw-r--r-- | core/src/xmake/io/file_close.c | 14 | ||||
| -rw-r--r-- | core/src/xmake/io/stdfile.c | 64 | ||||
| -rw-r--r-- | core/src/xmake/prefix.h | 11 |
3 files changed, 29 insertions, 60 deletions
diff --git a/core/src/xmake/io/file_close.c b/core/src/xmake/io/file_close.c index 98b2f1506..e0deff67e 100644 --- a/core/src/xmake/io/file_close.c +++ b/core/src/xmake/io/file_close.c @@ -88,6 +88,18 @@ tb_int_t xm_io_file_close(lua_State* lua) lua_pushboolean(lua, tb_true); return 1; } - else xm_io_return_error(lua, "cannot close this file!"); + else // for stdfile (gc/close) + { + // exit the line cache buffer + tb_buffer_exit(&file->rcache); + tb_buffer_exit(&file->wcache); + + // gc will free it if no any refs for lua_newuserdata() + // ... + + // ok + lua_pushboolean(lua, tb_true); + return 1; + } } diff --git a/core/src/xmake/io/stdfile.c b/core/src/xmake/io/stdfile.c index 96d495a7c..6987d5ef5 100644 --- a/core/src/xmake/io/stdfile.c +++ b/core/src/xmake/io/stdfile.c @@ -75,15 +75,10 @@ static tb_size_t xm_io_stdfile_isatty(tb_size_t type) if (answer) type |= XM_IO_FILE_FLAG_TTY; return type; } -static tb_handle_t xm_io_stdfile_instance_init(tb_cpointer_t* ppriv) +static xm_io_file_t* xm_io_stdfile_new(lua_State* lua, tb_size_t type) { - // get stdfile type - tb_size_t* ptype = (tb_size_t*)ppriv; - tb_assert_and_check_return_val(ptype, tb_null); - // init stdfile tb_stdfile_ref_t fp = tb_null; - tb_size_t type = *ptype; switch (type) { case XM_IO_FILE_TYPE_STDIN: @@ -97,9 +92,9 @@ static tb_handle_t xm_io_stdfile_instance_init(tb_cpointer_t* ppriv) break; } - // make file - xm_io_file_t* file = tb_malloc0_type(xm_io_file_t); - tb_assert_and_check_return_val(file, 0); + // new file + xm_io_file_t* file = lua_newuserdata(lua, sizeof(xm_io_file_t)); + tb_assert_and_check_return_val(file, tb_null); // init file file->std_ref = fp; @@ -111,31 +106,7 @@ static tb_handle_t xm_io_stdfile_instance_init(tb_cpointer_t* ppriv) // init the read/write line cache buffer tb_buffer_init(&file->rcache); tb_buffer_init(&file->wcache); - - // ok - return (tb_handle_t)file; -} -static tb_void_t xm_io_stdfile_instance_exit(tb_handle_t stdfile, tb_cpointer_t priv) -{ - xm_io_file_t* file = (xm_io_file_t*)stdfile; - if (file) - { - tb_buffer_exit(&file->rcache); - tb_buffer_exit(&file->wcache); - tb_free(file); - } -} -static xm_io_file_t* xm_io_stdfile_input() -{ - return (xm_io_file_t*)tb_singleton_instance(XM_IO_STDFILE_STDIN, xm_io_stdfile_instance_init, xm_io_stdfile_instance_exit, tb_null, tb_u2p(XM_IO_FILE_TYPE_STDIN)); -} -static xm_io_file_t* xm_io_stdfile_output() -{ - return (xm_io_file_t*)tb_singleton_instance(XM_IO_STDFILE_STDOUT, xm_io_stdfile_instance_init, xm_io_stdfile_instance_exit, tb_null, tb_u2p(XM_IO_FILE_TYPE_STDOUT)); -} -static xm_io_file_t* xm_io_stdfile_error() -{ - return (xm_io_file_t*)tb_singleton_instance(XM_IO_STDFILE_STDERR, xm_io_stdfile_instance_init, xm_io_stdfile_instance_exit, tb_null, tb_u2p(XM_IO_FILE_TYPE_STDERR)); + return file; } /* ////////////////////////////////////////////////////////////////////////////////////// @@ -151,25 +122,12 @@ tb_int_t xm_io_stdfile(lua_State* lua) // get std type tb_long_t type = lua_tointeger(lua, 1); - // get stdfile - xm_io_file_t* file = tb_null; - switch (type) - { - case XM_IO_FILE_TYPE_STDIN: - file = xm_io_stdfile_input(); - break; - case XM_IO_FILE_TYPE_STDOUT: - file = xm_io_stdfile_output(); - break; - case XM_IO_FILE_TYPE_STDERR: - file = xm_io_stdfile_error(); - break; - } - if (file) - { - lua_pushlightuserdata(lua, (tb_pointer_t)file); - return 1; - } + /* push a new stdfile + * + * @note we need to ensure that it is a singleton in the external lua script, and will only be created once, e.g. io.stdin, io.stdout, io.stderr + */ + xm_io_file_t* file = xm_io_stdfile_new(lua, type); + if (file) return 1; else xm_io_return_error(lua, "invalid stdfile type!"); } diff --git a/core/src/xmake/prefix.h b/core/src/xmake/prefix.h index 1b3d519ea..658ed57ea 100644 --- a/core/src/xmake/prefix.h +++ b/core/src/xmake/prefix.h @@ -37,21 +37,21 @@ /* we use this interface instead of lua_pushlightuserdata() to fix bad light userdata pointer bug * * @see https://github.com/xmake-io/xmake/issues/914 + * https://github.com/LuaJIT/LuaJIT/pull/230 * - * @note we cannot lua_newuserdata() because we need pass this pointer to lua code in poller_wait()/event_callback, but lua_pushuserdata does not exists + * @note we cannot lua_newuserdata() because we need pass this pointer to the external lua code + * in poller_wait()/event_callback, but lua_pushuserdata does not exists */ static __tb_inline__ tb_void_t xm_lua_pushpointer(lua_State* lua, tb_pointer_t ptr) { tb_uint64_t ptrval = (tb_uint64_t)ptr; - tb_trace_i("ptr: %p %llx", ptrval >> 47); - if (0)//(ptrval >> 47) == 0) + if ((ptrval >> 47) == 0) lua_pushlightuserdata(lua, ptr); else { tb_char_t str[64]; tb_long_t len = tb_snprintf(str, sizeof(str), "%p", ptr); lua_pushlstring(lua, str, len); - tb_trace_i("push ptr: %p, str: %s", ptr, str); } } static __tb_inline__ tb_bool_t xm_lua_ispointer(lua_State* lua, tb_int_t idx) @@ -68,12 +68,11 @@ static __tb_inline__ tb_pointer_t xm_lua_topointer2(lua_State* lua, tb_int_t idx } else { - size_t len = 0; + size_t len = 0; tb_char_t const* str = luaL_checklstring(lua, idx, &len); if (str && len > 2 && str[0] == '0' && str[1] == 'x') ptr = (tb_pointer_t)tb_s16tou64(str); if (pstr) *pstr = str; - tb_trace_i("to ptr: %p, str: %s", ptr, str); } return ptr; } |
