From 5d6d1271e6dbdfa5e23d019774150822a865d251 Mon Sep 17 00:00:00 2001 From: Rui Guo Date: Wed, 10 Jun 2009 20:22:11 +0800 Subject: [PATCH] Make the merged code work again. Also fixs a SEGV. 1. Properly push function according to the new lua_handler structure. 2. Never return without balancing the stack! --- src/lua.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 57 insertions(+), 12 deletions(-) diff --git a/src/lua.c b/src/lua.c index 5f607b6..ac4c59f 100644 --- a/src/lua.c +++ b/src/lua.c @@ -297,6 +297,7 @@ struct_register(lua_State *L, const char *name, const luaL_reg fn_methods[], con lua_pushcclosure(L, newindex_handler, 1); lua_rawset(L, metatable); /* metatable.__newindex = newindex_handler */ + /* FIXME: Why do we leave an element on the stack? */ lua_pop(L, 1); /* drop metatable */ return 1; /* return methods on the stack */ } @@ -658,7 +659,7 @@ static int screen_append_msg(lua_State *L) { const char *msg, *color; - int len; + unsigned int len; msg = luaL_checklstring(L, 1, &len); if (lua_isnil(L, 2)) color = NULL; @@ -737,7 +738,16 @@ int LuaInit(void) /* To store handler funcs */ luaL_getmetatable(L, "screen"); - lua_pushstring(L, "_handlers"); + /* two kinds of info in this table: + * _funckey[func]->key + * _funckey[key]->refcnt */ + lua_pushstring(L, "_funckey"); + lua_newtable(L); + lua_rawset(L, -3); + /* two kinds of info in this table: + * _keyfunc[key]->func + * _keyfunc[func]->name */ + lua_pushstring(L, "_keyfunc"); lua_newtable(L); lua_rawset(L, -3); lua_pop(L, 1); @@ -770,7 +780,10 @@ LuaCallProcess(const char *name, struct fn_def defs[]) lua_getfield(L, LUA_GLOBALSINDEX, name); if (lua_isnil(L, -1)) - return 0; + { + lua_pop(L,1); + return 0; + } for (argc = 0; defs[argc].push_fn; argc++) defs[argc].push_fn(L, defs[argc].value); if (lua_pcall(L, argc, 0, 0) == LUA_ERRRUN && lua_isstring(L, -1)) @@ -870,6 +883,7 @@ int LuaCall(char *func, char **argv) lua_getfield(L, LUA_GLOBALSINDEX, func); if (lua_isnil(L, -1)) { + lua_pop(L, 1); lua_pushstring(L, "Could not find the script function\n"); LuaShowErr(L); return 0; @@ -890,19 +904,37 @@ int LuaCall(char *func, char **argv) return 1; } +/* Push nil if failed */ +void +LuaPushHandler(lua_State *L, struct lua_handler * lh) +{ + if (lh->type == LUA_HANDLER_TYPE_N) + lua_getfield(L, LUA_GLOBALSINDEX, lh->u.name); + else + { + luaL_getmetatable(L, "screen"); + lua_pushstring(L, "_keyfunc"); + lua_rawget(L, -2); + lua_rawgeti(L, -1, lh->u.reference); + lua_replace(L, -3); + lua_pop(L, 1); + } +} + static int LuaDispatch(void *handler, const char *params, va_list va) { struct lua_handler *lh = handler; int argc, retvalue; - if (lh->type == LUA_HANDLER_TYPE_N) - lua_getfield(L, LUA_GLOBALSINDEX, lh->u.name); - else - lua_rawgeti(L, LUA_REGISTRYINDEX, lh->u.reference); + StackDump(L, "before dispatch"); + LuaPushHandler(L, lh); if (lua_isnil(L, -1)) - return 0; + { + lua_pop(L, 1); + return 0; + } argc = LuaPushParams(L, params, va); if (lua_pcall(L, argc, 1, 0) == LUA_ERRRUN && lua_isstring(L, -1)) @@ -944,14 +976,14 @@ LuaCheckHandler(lua_State *L, int idx, int reg) } else if (lua_isfunction(L, idx)) { - char buf[20]; int key, htable; if (idx < 0) idx = lua_gettop(L) + 1 - idx; luaL_getmetatable(L, "screen"); - lua_pushstring(L, "_handlers"); + lua_pushstring(L, "_funckey"); lua_rawget(L, -2); + /* FIXME: Do we need to balance the stack here? */ if (lua_isnil(L, -1)) luaL_error(L, "Fatal! Should not happen! Fail to get global handler table!"); /* Map func to unique key and do reference count */ @@ -961,13 +993,26 @@ LuaCheckHandler(lua_State *L, int idx, int reg) if (lua_isnil(L, -1)) { /* not found */ + int kf; if (!reg) - return NULL; + { + lua_pop(L, 3); + return NULL; + } + lua_pushstring(L, "_keyfunc"); + lua_rawget(L, -4); + kf = lua_gettop(L); + lua_pushinteger(L, 1); key = luaL_ref(L, htable); /*htable[key] = 1*/ lua_pushvalue(L, idx); lua_pushinteger(L, key); lua_settable(L, htable); /*htable[func]=key*/ + + lua_pushinteger(L, key); + lua_pushvalue(L, idx); + lua_settable(L, kf); + lua_remove(L, kf); } else { @@ -1101,7 +1146,7 @@ LuaUnRegEvent(lua_State *L) } else { - LuaFreeHandler(&l->handler); + LuaFreeHandler(((struct lua_handler **)&(l->handler))); unregister_listener(l); lua_pushboolean(L, 1); } -- 2.11.4.GIT