Explorar el Código

registry mechanism

Roberto Ierusalimschy hace 25 años
padre
commit
cdc8139e29
Se han modificado 3 ficheros con 50 adiciones y 38 borrados
  1. 38 35
      ldblib.c
  2. 5 2
      lstate.c
  3. 7 1
      lua.h

+ 38 - 35
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;
 }
 

+ 5 - 2
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");
 }
 
 

+ 7 - 1
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: [email protected]
@@ -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