From cdc8139e295a768ac581e0a7c784c1adfee0668b Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Tue, 24 Oct 2000 17:12:06 -0200 Subject: [PATCH] registry mechanism --- ldblib.c | 73 +++++++++++++++++++++++++++++--------------------------- lstate.c | 7 ++++-- lua.h | 8 ++++++- 3 files changed, 50 insertions(+), 38 deletions(-) diff --git a/ldblib.c b/ldblib.c index f016fcde..f3b732e9 100644 --- a/ldblib.c +++ b/ldblib.c @@ -1,5 +1,5 @@ /* -** $Id: ldblib.c,v 1.22 2000/10/02 20:10:55 roberto Exp roberto $ +** $Id: ldblib.c,v 1.23 2000/10/20 16:39:03 roberto Exp roberto $ ** Interface from Lua to its debug API ** See Copyright Notice in lua.h */ @@ -109,58 +109,61 @@ static int setlocal (lua_State *L) { } -/* -** because of these variables, this module is not reentrant, and should -** not be used in multiple states -*/ -static int linehook = LUA_NOREF; /* Lua reference to line hook function */ -static int callhook = LUA_NOREF; /* Lua reference to call hook function */ +#define KEY_CALLHOOK "dblib_callhook" +#define KEY_LINEHOOK "dblib_linehook" - -static void linef (lua_State *L, lua_Debug *ar) { - if (linehook != LUA_NOREF) { - lua_getref(L, linehook); - lua_pushnumber(L, ar->currentline); +static void hookf (lua_State *L, const char *key) { + lua_getregistry(L); + lua_pushstring(L, key); + lua_gettable(L, -2); + if (lua_isfunction(L, -1)) { + lua_pushvalue(L, 1); lua_call(L, 1, 0); } + else + lua_pop(L, 1); /* pop result from gettable */ + lua_pop(L, 1); /* pop table */ } static void callf (lua_State *L, lua_Debug *ar) { - if (callhook != LUA_NOREF) { - lua_getref(L, callhook); - lua_pushstring(L, ar->event); - lua_call(L, 1, 0); - } + lua_pushstring(L, ar->event); + hookf(L, KEY_CALLHOOK); +} + + +static void linef (lua_State *L, lua_Debug *ar) { + lua_pushnumber(L, ar->currentline); + hookf(L, KEY_LINEHOOK); +} + + +static void sethook (lua_State *L, const char *key, lua_Hook hook, + lua_Hook (*sethookf)(lua_State * L, lua_Hook h)) { + lua_settop(L, 1); + lua_getregistry(L); + lua_pushstring(L, key); + if (lua_isnil(L, 1)) + (*sethookf)(L, NULL); + else if (lua_isfunction(L, 1)) + (*sethookf)(L, hook); + else + luaL_argerror(L, 1, "function expected"); + lua_pushvalue(L, 1); + lua_settable(L, -3); } static int setcallhook (lua_State *L) { - lua_unref(L, callhook); - if (lua_isnull(L, 1)) { - callhook = LUA_NOREF; - lua_setcallhook(L, NULL); - } - else { - callhook = lua_ref(L, 1); - lua_setcallhook(L, callf); - } + sethook(L, KEY_CALLHOOK, callf, lua_setcallhook); return 0; } static int setlinehook (lua_State *L) { - lua_unref(L, linehook); - if (lua_isnull(L, 1)) { - linehook = LUA_NOREF; - lua_setlinehook(L, NULL); - } - else { - linehook = lua_ref(L, 1); - lua_setlinehook(L, linef); - } + sethook(L, KEY_LINEHOOK, linef, lua_setlinehook); return 0; } diff --git a/lstate.c b/lstate.c index bd07488a..ba7ed328 100644 --- a/lstate.c +++ b/lstate.c @@ -1,5 +1,5 @@ /* -** $Id: lstate.c,v 1.44 2000/10/06 19:28:47 roberto Exp roberto $ +** $Id: lstate.c,v 1.45 2000/10/20 16:39:03 roberto Exp roberto $ ** Global State ** See Copyright Notice in lua.h */ @@ -47,16 +47,19 @@ static void f_luaopen (lua_State *L, void *ud) { stacksize = DEFAULT_STACK_SIZE; else stacksize += LUA_MINSTACK; - L->gt = luaH_new(L, 10); + L->gt = luaH_new(L, 10); /* table of globals */ luaD_init(L, stacksize); luaS_init(L); luaX_init(L); luaT_init(L); + lua_newtable(L); + lua_ref(L, 1); /* create registry */ lua_register(L, LUA_ERRORMESSAGE, errormessage); #ifdef DEBUG luaB_opentests(L); if (lua_state == NULL) lua_state = L; /* keep first state to be opened */ #endif + LUA_ASSERT(lua_gettop(L) == 0, "wrong API stack"); } diff --git a/lua.h b/lua.h index f2cc880a..c2c77a80 100644 --- a/lua.h +++ b/lua.h @@ -1,5 +1,5 @@ /* -** $Id: lua.h,v 1.74 2000/10/09 15:46:43 roberto Exp roberto $ +** $Id: lua.h,v 1.75 2000/10/20 16:39:03 roberto Exp roberto $ ** Lua - An Extensible Extension Language ** TeCGraf: Grupo de Tecnologia em Computacao Grafica, PUC-Rio, Brazil ** e-mail: lua@tecgraf.puc-rio.br @@ -29,12 +29,16 @@ #define LUA_ERRORMESSAGE "_ERRORMESSAGE" +/* pre-defined references */ #define LUA_NOREF (-2) #define LUA_REFNIL (-1) +#define LUA_REFREGISTRY 0 +/* pre-defined tags */ #define LUA_ANYTAG (-1) #define LUA_NOTAG (-2) + #define LUA_MULTRET (-1) @@ -198,6 +202,8 @@ LUA_API void lua_concat (lua_State *L, int n); #define lua_isnil(L,n) (lua_type(L,n) == LUA_TNIL) #define lua_isnull(L,n) (lua_type(L,n) == LUA_TNONE) +#define lua_getregistry(L) lua_getref(L, LUA_REFREGISTRY) + #endif