summaryrefslogtreecommitdiff
path: root/core/src
diff options
context:
space:
mode:
authorruki <[email protected]>2020-08-04 23:05:31 +0800
committerruki <[email protected]>2020-08-04 23:05:31 +0800
commit96b0eae26058482a83f5bbf57bab15a834339464 (patch)
tree94e8b6e90649f8a4c89d8406bf7e5198daa7b361 /core/src
parent60a176cb2ae804bea3dfd11dbf8ed2f218fcefdb (diff)
improve stdfile
Diffstat (limited to 'core/src')
-rw-r--r--core/src/xmake/io/file_close.c14
-rw-r--r--core/src/xmake/io/stdfile.c64
-rw-r--r--core/src/xmake/prefix.h11
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;
}