From 7164e0322f2d6b9dfd9ef4a98714e1823677f6f8 Mon Sep 17 00:00:00 2001 From: Francois Perrad Date: Sat, 1 Apr 2017 14:57:40 +0200 Subject: [PATCH] extract lib_coro from lib_base --- src/Makefile | 2 +- src/Makefile.dep | 10 ++- src/lib_base.c | 124 +------------------------------------ src/lib_coro.c | 157 +++++++++++++++++++++++++++++++++++++++++++++++ src/lib_init.c | 1 + src/ljamalg.c | 1 + src/lualib.h | 1 + 7 files changed, 170 insertions(+), 126 deletions(-) create mode 100644 src/lib_coro.c diff --git a/src/Makefile b/src/Makefile index f56465d1..7dba87a3 100644 --- a/src/Makefile +++ b/src/Makefile @@ -475,7 +475,7 @@ LJVM_O= lj_vm.o LJVM_BOUT= $(LJVM_S) LJVM_MODE= elfasm -LJLIB_O= lib_base.o lib_math.o lib_bit.o lib_string.o lib_table.o \ +LJLIB_O= lib_base.o lib_coro.o lib_math.o lib_bit.o lib_string.o lib_table.o \ lib_io.o lib_os.o lib_package.o lib_debug.o lib_jit.o lib_ffi.o LJLIB_C= $(LJLIB_O:.o=.c) diff --git a/src/Makefile.dep b/src/Makefile.dep index 2b1cb5ef..22e2ebd0 100644 --- a/src/Makefile.dep +++ b/src/Makefile.dep @@ -10,6 +10,10 @@ lib_bit.o: lib_bit.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h lj_def.h \ lj_arch.h lj_err.h lj_errmsg.h lj_buf.h lj_gc.h lj_str.h lj_strscan.h \ lj_strfmt.h lj_ctype.h lj_cdata.h lj_cconv.h lj_carith.h lj_ff.h \ lj_ffdef.h lj_lib.h lj_libdef.h +lib_coro.o: lib_coro.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \ + lj_def.h lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_str.h \ + lj_tab.h lj_state.h lj_frame.h lj_bc.h lj_ff.h lj_ffdef.h lj_dispatch.h \ + lj_jit.h lj_ir.h lj_lib.h lj_libdef.h lib_debug.o: lib_debug.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \ lj_def.h lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_lib.h \ lj_libdef.h @@ -225,9 +229,9 @@ ljamalg.o: ljamalg.c lua.h luaconf.h lauxlib.h lj_gc.c lj_obj.h lj_def.h \ lj_opt_sink.c lj_mcode.c lj_snap.c lj_record.c lj_record.h lj_ffrecord.h \ lj_crecord.c lj_crecord.h lj_ffrecord.c lj_recdef.h lj_asm.c lj_asm.h \ lj_emit_*.h lj_asm_*.h lj_trace.c lj_gdbjit.h lj_gdbjit.c lj_alloc.c \ - lib_aux.c lib_base.c lj_libdef.h lib_math.c lib_string.c lib_table.c \ - lib_io.c lib_os.c lib_package.c lib_debug.c lib_bit.c lib_jit.c \ - lib_ffi.c lib_init.c + lib_aux.c lib_base.c lj_libdef.h lib_coro.c lib_math.c lib_string.c \ + lib_table.c lib_io.c lib_os.c lib_package.c lib_debug.c lib_bit.c \ + lib_jit.c lib_ffi.c lib_init.c luajit.o: luajit.c lua.h luaconf.h lauxlib.h lualib.h luajit.h lj_arch.h host/buildvm.o: host/buildvm.c host/buildvm.h lj_def.h lua.h luaconf.h \ lj_arch.h lj_obj.h lj_def.h lj_arch.h lj_gc.h lj_obj.h lj_bc.h lj_ir.h \ diff --git a/src/lib_base.c b/src/lib_base.c index 44014f9b..d4e34f3d 100644 --- a/src/lib_base.c +++ b/src/lib_base.c @@ -1,5 +1,5 @@ /* -** Base and coroutine library. +** Base library. ** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h ** ** Major portions taken verbatim or adapted from the Lua interpreter. @@ -524,125 +524,6 @@ LJLIB_SET(_VERSION) #include "lj_libdef.h" -/* -- Coroutine library --------------------------------------------------- */ - -#define LJLIB_MODULE_coroutine - -LJLIB_CF(coroutine_status) -{ - const char *s; - lua_State *co; - if (!(L->top > L->base && tvisthread(L->base))) - lj_err_arg(L, 1, LJ_ERR_NOCORO); - co = threadV(L->base); - if (co == L) s = "running"; - else if (co->status == LUA_YIELD) s = "suspended"; - else if (co->status != 0) s = "dead"; - else if (co->base > tvref(co->stack)+1+LJ_FR2) s = "normal"; - else if (co->top == co->base) s = "dead"; - else s = "suspended"; - lua_pushstring(L, s); - return 1; -} - -LJLIB_CF(coroutine_running) -{ -#if LJ_52 - int ismain = lua_pushthread(L); - setboolV(L->top++, ismain); - return 2; -#else - if (lua_pushthread(L)) - setnilV(L->top++); - return 1; -#endif -} - -LJLIB_CF(coroutine_isyieldable) -{ - setboolV(L->top++, cframe_canyield(L->cframe)); - return 1; -} - -LJLIB_CF(coroutine_create) -{ - lua_State *L1; - if (!(L->base < L->top && tvisfunc(L->base))) - lj_err_argt(L, 1, LUA_TFUNCTION); - L1 = lua_newthread(L); - setfuncV(L, L1->top++, funcV(L->base)); - return 1; -} - -LJLIB_ASM(coroutine_yield) -{ - lj_err_caller(L, LJ_ERR_CYIELD); - return FFH_UNREACHABLE; -} - -static int ffh_resume(lua_State *L, lua_State *co, int wrap) -{ - if (co->cframe != NULL || co->status > LUA_YIELD || - (co->status == 0 && co->top == co->base)) { - ErrMsg em = co->cframe ? LJ_ERR_CORUN : LJ_ERR_CODEAD; - if (wrap) lj_err_caller(L, em); - setboolV(L->base-1-LJ_FR2, 0); - setstrV(L, L->base-LJ_FR2, lj_err_str(L, em)); - return FFH_RES(2); - } - lj_state_growstack(co, (MSize)(L->top - L->base)); - return FFH_RETRY; -} - -LJLIB_ASM(coroutine_resume) -{ - if (!(L->top > L->base && tvisthread(L->base))) - lj_err_arg(L, 1, LJ_ERR_NOCORO); - return ffh_resume(L, threadV(L->base), 0); -} - -LJLIB_NOREG LJLIB_ASM(coroutine_wrap_aux) -{ - return ffh_resume(L, threadV(lj_lib_upvalue(L, 1)), 1); -} - -/* Inline declarations. */ -LJ_ASMF void lj_ff_coroutine_wrap_aux(void); -#if !(LJ_TARGET_MIPS && defined(ljamalg_c)) -LJ_FUNCA_NORET void LJ_FASTCALL lj_ffh_coroutine_wrap_err(lua_State *L, - lua_State *co); -#endif - -/* Error handler, called from assembler VM. */ -void LJ_FASTCALL lj_ffh_coroutine_wrap_err(lua_State *L, lua_State *co) -{ - co->top--; copyTV(L, L->top, co->top); L->top++; - if (tvisstr(L->top-1)) - lj_err_callermsg(L, strVdata(L->top-1)); - else - lj_err_run(L); -} - -/* Forward declaration. */ -static void setpc_wrap_aux(lua_State *L, GCfunc *fn); - -LJLIB_CF(coroutine_wrap) -{ - GCfunc *fn; - lj_cf_coroutine_create(L); - fn = lj_lib_pushcc(L, lj_ffh_coroutine_wrap_aux, FF_coroutine_wrap_aux, 1); - setpc_wrap_aux(L, fn); - return 1; -} - -#include "lj_libdef.h" - -/* Fix the PC of wrap_aux. Really ugly workaround. */ -static void setpc_wrap_aux(lua_State *L, GCfunc *fn) -{ - setmref(fn->c.pc, &L2GG(L)->bcff[lj_lib_init_coroutine[1]+2]); -} - /* ------------------------------------------------------------------------ */ static void newproxy_weaktable(lua_State *L) @@ -664,7 +545,6 @@ LUALIB_API int luaopen_base(lua_State *L) lua_pushliteral(L, LUA_VERSION); /* top-3. */ newproxy_weaktable(L); /* top-2. */ LJ_LIB_REG(L, "_G", base); - LJ_LIB_REG(L, LUA_COLIBNAME, coroutine); - return 2; + return 1; } diff --git a/src/lib_coro.c b/src/lib_coro.c new file mode 100644 index 00000000..246af61e --- /dev/null +++ b/src/lib_coro.c @@ -0,0 +1,157 @@ +/* +** Coroutine library. +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h +** +** Major portions taken verbatim or adapted from the Lua interpreter. +** Copyright (C) 1994-2011 Lua.org, PUC-Rio. See Copyright Notice in lua.h +*/ + +#include + +#define lib_coroutine_c +#define LUA_LIB + +#include "lua.h" +#include "lauxlib.h" +#include "lualib.h" + +#include "lj_obj.h" +#include "lj_gc.h" +#include "lj_err.h" +#include "lj_debug.h" +#include "lj_str.h" +#include "lj_tab.h" +#include "lj_state.h" +#include "lj_frame.h" +#include "lj_ff.h" +#include "lj_dispatch.h" +#include "lj_lib.h" + + +/* -- Coroutine library --------------------------------------------------- */ + +#define LJLIB_MODULE_coroutine + +LJLIB_CF(coroutine_status) +{ + const char *s; + lua_State *co; + if (!(L->top > L->base && tvisthread(L->base))) + lj_err_arg(L, 1, LJ_ERR_NOCORO); + co = threadV(L->base); + if (co == L) s = "running"; + else if (co->status == LUA_YIELD) s = "suspended"; + else if (co->status != 0) s = "dead"; + else if (co->base > tvref(co->stack)+1+LJ_FR2) s = "normal"; + else if (co->top == co->base) s = "dead"; + else s = "suspended"; + lua_pushstring(L, s); + return 1; +} + +LJLIB_CF(coroutine_running) +{ +#if LJ_52 + int ismain = lua_pushthread(L); + setboolV(L->top++, ismain); + return 2; +#else + if (lua_pushthread(L)) + setnilV(L->top++); + return 1; +#endif +} + +LJLIB_CF(coroutine_isyieldable) +{ + setboolV(L->top++, cframe_canyield(L->cframe)); + return 1; +} + +LJLIB_CF(coroutine_create) +{ + lua_State *L1; + if (!(L->base < L->top && tvisfunc(L->base))) + lj_err_argt(L, 1, LUA_TFUNCTION); + L1 = lua_newthread(L); + setfuncV(L, L1->top++, funcV(L->base)); + return 1; +} + +LJLIB_ASM(coroutine_yield) +{ + lj_err_caller(L, LJ_ERR_CYIELD); + return FFH_UNREACHABLE; +} + +static int ffh_resume(lua_State *L, lua_State *co, int wrap) +{ + if (co->cframe != NULL || co->status > LUA_YIELD || + (co->status == 0 && co->top == co->base)) { + ErrMsg em = co->cframe ? LJ_ERR_CORUN : LJ_ERR_CODEAD; + if (wrap) lj_err_caller(L, em); + setboolV(L->base-1-LJ_FR2, 0); + setstrV(L, L->base-LJ_FR2, lj_err_str(L, em)); + return FFH_RES(2); + } + lj_state_growstack(co, (MSize)(L->top - L->base)); + return FFH_RETRY; +} + +LJLIB_ASM(coroutine_resume) +{ + if (!(L->top > L->base && tvisthread(L->base))) + lj_err_arg(L, 1, LJ_ERR_NOCORO); + return ffh_resume(L, threadV(L->base), 0); +} + +LJLIB_NOREG LJLIB_ASM(coroutine_wrap_aux) +{ + return ffh_resume(L, threadV(lj_lib_upvalue(L, 1)), 1); +} + +/* Inline declarations. */ +LJ_ASMF void lj_ff_coroutine_wrap_aux(void); +#if !(LJ_TARGET_MIPS && defined(ljamalg_c)) +LJ_FUNCA_NORET void LJ_FASTCALL lj_ffh_coroutine_wrap_err(lua_State *L, + lua_State *co); +#endif + +/* Error handler, called from assembler VM. */ +void LJ_FASTCALL lj_ffh_coroutine_wrap_err(lua_State *L, lua_State *co) +{ + co->top--; copyTV(L, L->top, co->top); L->top++; + if (tvisstr(L->top-1)) + lj_err_callermsg(L, strVdata(L->top-1)); + else + lj_err_run(L); +} + +/* Forward declaration. */ +static void setpc_wrap_aux(lua_State *L, GCfunc *fn); + +LJLIB_CF(coroutine_wrap) +{ + GCfunc *fn; + lj_cf_coroutine_create(L); + fn = lj_lib_pushcc(L, lj_ffh_coroutine_wrap_aux, FF_coroutine_wrap_aux, 1); + setpc_wrap_aux(L, fn); + return 1; +} + +#include "lj_libdef.h" + +/* Fix the PC of wrap_aux. Really ugly workaround. */ +static void setpc_wrap_aux(lua_State *L, GCfunc *fn) +{ + setmref(fn->c.pc, &L2GG(L)->bcff[lj_lib_init_coroutine[1]+2]); +} + +/* ------------------------------------------------------------------------ */ + +LUALIB_API int luaopen_coroutine(lua_State *L) +{ + LJ_LIB_REG(L, LUA_COLIBNAME, coroutine); + return 1; +} + diff --git a/src/lib_init.c b/src/lib_init.c index 2ed370e9..6aea2e8c 100644 --- a/src/lib_init.c +++ b/src/lib_init.c @@ -17,6 +17,7 @@ static const luaL_Reg lj_lib_load[] = { { "", luaopen_base }, + { LUA_COLIBNAME, luaopen_coroutine }, { LUA_LOADLIBNAME, luaopen_package }, { LUA_TABLIBNAME, luaopen_table }, { LUA_IOLIBNAME, luaopen_io }, diff --git a/src/ljamalg.c b/src/ljamalg.c index f1f28623..ac57a71f 100644 --- a/src/ljamalg.c +++ b/src/ljamalg.c @@ -83,6 +83,7 @@ #include "lib_aux.c" #include "lib_base.c" +#include "lib_coro.c" #include "lib_math.c" #include "lib_string.c" #include "lib_table.c" diff --git a/src/lualib.h b/src/lualib.h index bfc130a1..10fbc9ec 100644 --- a/src/lualib.h +++ b/src/lualib.h @@ -23,6 +23,7 @@ #define LUA_FFILIBNAME "ffi" LUALIB_API int luaopen_base(lua_State *L); +LUALIB_API int luaopen_coroutine(lua_State *L); LUALIB_API int luaopen_math(lua_State *L); LUALIB_API int luaopen_string(lua_State *L); LUALIB_API int luaopen_table(lua_State *L);