mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-08-07 10:20:29 +00:00
Simplify handling of coroutine state
This commit is contained in:
parent
e5314dedde
commit
6bcef3028a
1 changed files with 18 additions and 36 deletions
|
@ -1057,21 +1057,22 @@ static nodiscard char *LuaFormatStack(lua_State *L) {
|
|||
}
|
||||
|
||||
// calling convention for lua stack of L is:
|
||||
// -3 is lua_newthread() called by caller
|
||||
// -2 is function
|
||||
// -1 is is argument (assuming nargs == 1)
|
||||
// L will have this after the call
|
||||
// -2 is lua_newthread() called by caller
|
||||
// -1 is result (assuming nres == 1)
|
||||
// -1 is error or result (assuming nres == 1)
|
||||
// @param L is main Lua interpreter
|
||||
// @param C should be the result of lua_newthread()
|
||||
// @note this needs to be reentrant
|
||||
static int LuaCallWithTrace(lua_State *L, lua_State *C, int nargs, int nres) {
|
||||
static int LuaCallWithTrace(lua_State *L, int nargs, int nres) {
|
||||
int nresults, status;
|
||||
lua_State *C = lua_newthread(L); // create a new coroutine
|
||||
lua_insert(L, 1); // move coroutine to the bottom of the stack
|
||||
|
||||
// move the function (and arguments) to the top of the coro stack
|
||||
lua_xmove(L, C, 1 + nargs);
|
||||
// resume the coroutine thus executing the function
|
||||
status = lua_resume(C, L, nargs, &nresults);
|
||||
lua_remove(L, 1); // remove coroutine (still) at the bottom
|
||||
if (status != LUA_OK && status != LUA_YIELD) {
|
||||
// move the error message
|
||||
lua_xmove(C, L, 1);
|
||||
|
@ -1079,10 +1080,7 @@ static int LuaCallWithTrace(lua_State *L, lua_State *C, int nargs, int nres) {
|
|||
luaL_traceback(L, C, lua_tostring(L, -1), 0);
|
||||
lua_remove(L, -2); // remove the error message
|
||||
} else {
|
||||
// move results to the main stack
|
||||
lua_xmove(C, L, nresults);
|
||||
// make sure the stack has enough space to grow
|
||||
luaL_checkstack(L, nres - nresults, NULL);
|
||||
lua_xmove(C, L, nresults); // move results to the main stack
|
||||
// grow the stack in case returned fewer results
|
||||
// than the caller expects, as lua_resume
|
||||
// doesn't adjust the stack for needed results
|
||||
|
@ -1098,14 +1096,12 @@ static void LogLuaError(char *hook, char *err) {
|
|||
|
||||
static bool LuaRunCode(const char *code) {
|
||||
lua_State *L = GL;
|
||||
lua_State *C = lua_newthread(L);
|
||||
int status = luaL_loadstring(L, code);
|
||||
if (status != LUA_OK || LuaCallWithTrace(L, C, 0, 0) != LUA_OK) {
|
||||
if (status != LUA_OK || LuaCallWithTrace(L, 0, 0) != LUA_OK) {
|
||||
LogLuaError("lua code", lua_tostring(L, -1));
|
||||
lua_pop(L, 2); // pop error and thread
|
||||
lua_pop(L, 1); // pop error
|
||||
return false;
|
||||
}
|
||||
lua_pop(L, 1); // pop thread
|
||||
AssertLuaStackIsEmpty(L);
|
||||
return true;
|
||||
}
|
||||
|
@ -1115,7 +1111,6 @@ static bool LuaOnClientConnection(void) {
|
|||
uint32_t ip, serverip;
|
||||
uint16_t port, serverport;
|
||||
lua_State *L = GL;
|
||||
lua_State *C = lua_newthread(L);
|
||||
lua_getglobal(L, "OnClientConnection");
|
||||
GetClientAddr(&ip, &port);
|
||||
GetServerAddr(&serverip, &serverport);
|
||||
|
@ -1123,14 +1118,13 @@ static bool LuaOnClientConnection(void) {
|
|||
lua_pushinteger(L, port);
|
||||
lua_pushinteger(L, serverip);
|
||||
lua_pushinteger(L, serverport);
|
||||
if (LuaCallWithTrace(L, C, 4, 1) == LUA_OK) {
|
||||
if (LuaCallWithTrace(L, 4, 1) == LUA_OK) {
|
||||
dropit = lua_toboolean(L, -1);
|
||||
} else {
|
||||
LogLuaError("OnClientConnection", lua_tostring(L, -1));
|
||||
lua_pop(L, 1); // pop error
|
||||
dropit = false;
|
||||
}
|
||||
lua_pop(L, 1); // pop thread
|
||||
AssertLuaStackIsEmpty(L);
|
||||
return dropit;
|
||||
}
|
||||
|
@ -1139,7 +1133,6 @@ static void LuaOnProcessCreate(int pid) {
|
|||
uint32_t ip, serverip;
|
||||
uint16_t port, serverport;
|
||||
lua_State *L = GL;
|
||||
lua_State *C = lua_newthread(L);
|
||||
lua_getglobal(L, "OnProcessCreate");
|
||||
GetClientAddr(&ip, &port);
|
||||
GetServerAddr(&serverip, &serverport);
|
||||
|
@ -1148,24 +1141,21 @@ static void LuaOnProcessCreate(int pid) {
|
|||
lua_pushinteger(L, port);
|
||||
lua_pushinteger(L, serverip);
|
||||
lua_pushinteger(L, serverport);
|
||||
if (LuaCallWithTrace(L, C, 5, 0) != LUA_OK) {
|
||||
if (LuaCallWithTrace(L, 5, 0) != LUA_OK) {
|
||||
LogLuaError("OnProcessCreate", lua_tostring(L, -1));
|
||||
lua_pop(L, 1); // pop error
|
||||
}
|
||||
lua_pop(L, 1); // pop thread
|
||||
AssertLuaStackIsEmpty(L);
|
||||
}
|
||||
|
||||
static void LuaOnProcessDestroy(int pid) {
|
||||
lua_State *L = GL;
|
||||
lua_State *C = lua_newthread(L);
|
||||
lua_getglobal(L, "OnProcessDestroy");
|
||||
lua_pushinteger(L, pid);
|
||||
if (LuaCallWithTrace(L, C, 1, 0) != LUA_OK) {
|
||||
if (LuaCallWithTrace(L, 1, 0) != LUA_OK) {
|
||||
LogLuaError("OnProcessDestroy", lua_tostring(L, -1));
|
||||
lua_pop(L, 1); // pop error
|
||||
}
|
||||
lua_pop(L, 1); // pop thread
|
||||
AssertLuaStackIsEmpty(L);
|
||||
}
|
||||
|
||||
|
@ -1182,13 +1172,11 @@ static inline bool IsHookDefined(const char *s) {
|
|||
|
||||
static void CallSimpleHook(const char *s) {
|
||||
lua_State *L = GL;
|
||||
lua_State *C = lua_newthread(L);
|
||||
lua_getglobal(L, s);
|
||||
if (LuaCallWithTrace(L, C, 0, 0) != LUA_OK) {
|
||||
if (LuaCallWithTrace(L, 0, 0) != LUA_OK) {
|
||||
LogLuaError(s, lua_tostring(L, -1));
|
||||
lua_pop(L, 1); // pop error
|
||||
}
|
||||
lua_pop(L, 1); // pop thread
|
||||
AssertLuaStackIsEmpty(L);
|
||||
}
|
||||
|
||||
|
@ -2987,12 +2975,10 @@ static bool IsLoopbackClient() {
|
|||
static char *LuaOnHttpRequest(void) {
|
||||
char *error;
|
||||
lua_State *L = GL;
|
||||
lua_State *C = lua_newthread(L);
|
||||
effectivepath.p = url.path.p;
|
||||
effectivepath.n = url.path.n;
|
||||
lua_getglobal(L, "OnHttpRequest");
|
||||
if (LuaCallWithTrace(L, C, 0, 0) == LUA_OK) {
|
||||
lua_pop(L, 1); // pop thread
|
||||
if (LuaCallWithTrace(L, 0, 0) == LUA_OK) {
|
||||
AssertLuaStackIsEmpty(L);
|
||||
return CommitOutput(GetLuaResponse());
|
||||
} else {
|
||||
|
@ -3000,7 +2986,7 @@ static char *LuaOnHttpRequest(void) {
|
|||
error =
|
||||
ServeErrorWithDetail(500, "Internal Server Error",
|
||||
IsLoopbackClient() ? lua_tostring(L, -1) : NULL);
|
||||
lua_pop(L, 2); // pop error and thread
|
||||
lua_pop(L, 1); // pop error
|
||||
AssertLuaStackIsEmpty(L);
|
||||
return error;
|
||||
}
|
||||
|
@ -3010,7 +2996,6 @@ static char *ServeLua(struct Asset *a, const char *s, size_t n) {
|
|||
char *code;
|
||||
size_t codelen;
|
||||
lua_State *L = GL;
|
||||
lua_State *C = lua_newthread(L);
|
||||
LockInc(&shared->c.dynamicrequests);
|
||||
effectivepath.p = s;
|
||||
effectivepath.n = n;
|
||||
|
@ -3018,8 +3003,7 @@ static char *ServeLua(struct Asset *a, const char *s, size_t n) {
|
|||
int status =
|
||||
luaL_loadbuffer(L, code, codelen,
|
||||
FreeLater(xasprintf("@%s", FreeLater(strndup(s, n)))));
|
||||
if (status == LUA_OK && LuaCallWithTrace(L, C, 0, 0) == LUA_OK) {
|
||||
lua_pop(L, 1); // pop thread
|
||||
if (status == LUA_OK && LuaCallWithTrace(L, 0, 0) == LUA_OK) {
|
||||
return CommitOutput(GetLuaResponse());
|
||||
} else {
|
||||
char *error;
|
||||
|
@ -3027,7 +3011,7 @@ static char *ServeLua(struct Asset *a, const char *s, size_t n) {
|
|||
error =
|
||||
ServeErrorWithDetail(500, "Internal Server Error",
|
||||
IsLoopbackClient() ? lua_tostring(L, -1) : NULL);
|
||||
lua_pop(L, 2); // pop error and thread
|
||||
lua_pop(L, 1); // pop error
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
@ -5695,18 +5679,16 @@ static bool LuaRunAsset(const char *path, bool mandatory) {
|
|||
if ((a = GetAsset(path, pathlen))) {
|
||||
if ((code = FreeLater(LoadAsset(a, &codelen)))) {
|
||||
lua_State *L = GL;
|
||||
lua_State *C = lua_newthread(L);
|
||||
effectivepath.p = path;
|
||||
effectivepath.n = pathlen;
|
||||
DEBUGF("(lua) LuaRunAsset(%`'s)", path);
|
||||
status =
|
||||
luaL_loadbuffer(L, code, codelen, FreeLater(xasprintf("@%s", path)));
|
||||
if (status != LUA_OK || LuaCallWithTrace(L, C, 0, 0) != LUA_OK) {
|
||||
if (status != LUA_OK || LuaCallWithTrace(L, 0, 0) != LUA_OK) {
|
||||
LogLuaError("lua code", lua_tostring(L, -1));
|
||||
lua_pop(L, 1); // pop error
|
||||
if (mandatory) exit(1);
|
||||
}
|
||||
lua_pop(L, 1); // pop thread
|
||||
}
|
||||
}
|
||||
return !!a;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue