Browse Source

lock mechanism seperseded by the REFERENCE mechanism.

Roberto Ierusalimschy 29 years ago
parent
commit
0ef5cf2289
9 changed files with 163 additions and 93 deletions
  1. 43 27
      fallback.c
  2. 5 3
      fallback.h
  3. 15 6
      lua.h
  4. 2 2
      luamem.h
  5. 46 29
      manual.tex
  6. 4 4
      mathlib.c
  7. 26 20
      opcode.c
  8. 20 1
      table.c
  9. 2 1
      table.h

+ 43 - 27
fallback.c

@@ -3,7 +3,7 @@
 ** TecCGraf - PUC-Rio
 ** TecCGraf - PUC-Rio
 */
 */
  
  
-char *rcs_fallback="$Id: fallback.c,v 1.22 1996/03/19 22:28:37 roberto Exp roberto $";
+char *rcs_fallback="$Id: fallback.c,v 1.23 1996/03/21 16:31:32 roberto Exp roberto $";
 
 
 #include <stdio.h>
 #include <stdio.h>
 #include <string.h>
 #include <string.h>
@@ -12,6 +12,7 @@ char *rcs_fallback="$Id: fallback.c,v 1.22 1996/03/19 22:28:37 roberto Exp rober
 #include "fallback.h"
 #include "fallback.h"
 #include "opcode.h"
 #include "opcode.h"
 #include "lua.h"
 #include "lua.h"
+#include "table.h"
 
 
 
 
 static void errorFB (void);
 static void errorFB (void);
@@ -112,59 +113,74 @@ static void funcFB (void)
 
 
 
 
 /*
 /*
-** Lock routines
+** Reference routines
 */
 */
 
 
-static Object *lockArray = NULL;
-static int lockSize = 0;
+static struct ref {
+  Object o;
+  enum {LOCK, HOLD, FREE, COLLECTED} status;
+} *refArray = NULL;
+static int refSize = 0;
 
 
-int luaI_lock (Object *object)
+lua_Reference luaI_ref (Object *object, int lock)
 {
 {
   int i;
   int i;
   int oldSize;
   int oldSize;
   if (tag(object) == LUA_T_NIL)
   if (tag(object) == LUA_T_NIL)
-    return -1;   /* special lock ref for nil */
-  for (i=0; i<lockSize; i++)
-    if (tag(&lockArray[i]) == LUA_T_NIL)
-    {
-      lockArray[i] = *object;
-      return i;
-    }
+    return -1;   /* special ref for nil */
+  for (i=0; i<refSize; i++)
+    if (refArray[i].status == FREE)
+      goto found;
   /* no more empty spaces */
   /* no more empty spaces */
-  oldSize = lockSize;
-  lockSize = growvector(&lockArray, lockSize, Object, lockEM, MAX_WORD);
-  for (i=oldSize; i<lockSize; i++)
-    tag(&lockArray[i]) = LUA_T_NIL;
-  lockArray[oldSize] = *object;
-  return oldSize;
+  oldSize = refSize;
+  refSize = growvector(&refArray, refSize, struct ref, refEM, MAX_WORD);
+  for (i=oldSize; i<refSize; i++)
+    refArray[i].status = FREE;
+  i = oldSize;
+ found:
+  refArray[i].o = *object;
+  refArray[i].status = lock ? LOCK : HOLD;
+  return i;
 }
 }
 
 
 
 
-void lua_unlock (int ref)
+void lua_unref (lua_Reference ref)
 {
 {
-  if (ref >= 0 && ref < lockSize)
-    tag(&lockArray[ref]) = LUA_T_NIL;
+  if (ref >= 0 && ref < refSize)
+    refArray[ref].status = FREE;
 }
 }
 
 
 
 
-Object *luaI_getlocked (int ref)
+Object *luaI_getref (lua_Reference ref)
 {
 {
   static Object nul = {LUA_T_NIL, {0}};
   static Object nul = {LUA_T_NIL, {0}};
-  if (ref >= 0 && ref < lockSize)
-    return &lockArray[ref];
-  else
+  if (ref == -1)
     return &nul;
     return &nul;
+  if (ref >= 0 && ref < refSize &&
+      (refArray[ref].status == LOCK || refArray[ref].status == HOLD))
+    return &refArray[ref].o;
+  else
+    return NULL;
 }
 }
 
 
 
 
 void luaI_travlock (int (*fn)(Object *))
 void luaI_travlock (int (*fn)(Object *))
 {
 {
   int i;
   int i;
-  for (i=0; i<lockSize; i++)
-    fn(&lockArray[i]);
+  for (i=0; i<refSize; i++)
+    if (refArray[i].status == LOCK)
+      fn(&refArray[i].o);
 }
 }
 
 
 
 
+void luaI_invalidaterefs (void)
+{
+  int i;
+  for (i=0; i<refSize; i++)
+    if (refArray[i].status == HOLD && !luaI_ismarked(&refArray[i].o))
+      refArray[i].status = COLLECTED;
+}
+
 char *luaI_travfallbacks (int (*fn)(Object *))
 char *luaI_travfallbacks (int (*fn)(Object *))
 {
 {
   int i;
   int i;

+ 5 - 3
fallback.h

@@ -1,10 +1,11 @@
 /*
 /*
-** $Id: fallback.h,v 1.10 1995/10/17 11:52:38 roberto Exp roberto $
+** $Id: fallback.h,v 1.11 1996/01/30 15:25:23 roberto Exp roberto $
 */
 */
  
  
 #ifndef fallback_h
 #ifndef fallback_h
 #define fallback_h
 #define fallback_h
 
 
+#include "lua.h"
 #include "opcode.h"
 #include "opcode.h"
 
 
 extern struct FB {
 extern struct FB {
@@ -26,9 +27,10 @@ extern struct FB {
 #define FB_GETGLOBAL 9
 #define FB_GETGLOBAL 9
 
 
 void luaI_setfallback (void);
 void luaI_setfallback (void);
-int luaI_lock (Object *object);
-Object *luaI_getlocked (int ref);
+lua_Reference luaI_ref (Object *object, int lock);
+Object *luaI_getref (lua_Reference ref);
 void luaI_travlock (int (*fn)(Object *));
 void luaI_travlock (int (*fn)(Object *));
+void luaI_invalidaterefs (void);
 char *luaI_travfallbacks (int (*fn)(Object *));
 char *luaI_travfallbacks (int (*fn)(Object *));
 
 
 #endif
 #endif

+ 15 - 6
lua.h

@@ -2,7 +2,7 @@
 ** LUA - Linguagem para Usuarios de Aplicacao
 ** LUA - Linguagem para Usuarios de Aplicacao
 ** Grupo de Tecnologia em Computacao Grafica
 ** Grupo de Tecnologia em Computacao Grafica
 ** TeCGraf - PUC-Rio
 ** TeCGraf - PUC-Rio
-** $Id: lua.h,v 3.24 1996/03/19 22:28:37 roberto Exp roberto $
+** $Id: lua.h,v 3.25 1996/03/21 21:30:29 roberto Exp roberto $
 */
 */
 
 
 
 
@@ -80,17 +80,20 @@ lua_Object     lua_getsubscript         (void);
 
 
 int            lua_type 		(lua_Object object);
 int            lua_type 		(lua_Object object);
 
 
-int	       lua_lock			(void);
-lua_Object     lua_getlocked		(int ref);
-void	       lua_pushlocked		(int ref);
-void	       lua_unlock		(int ref);
+
+typedef int lua_Reference;
+
+lua_Reference  lua_ref			(int lock);
+lua_Object     lua_getref		(lua_Reference ref);
+void	       lua_pushref		(lua_Reference ref);
+void	       lua_unref		(lua_Reference ref);
 
 
 lua_Object     lua_createtable		(void);
 lua_Object     lua_createtable		(void);
 
 
 
 
 /* some useful macros */
 /* some useful macros */
 
 
-#define lua_lockobject(o)  (lua_pushobject(o), lua_lock())
+#define lua_refobject(o,l)	(lua_pushobject(o), lua_ref(l))
 
 
 #define lua_register(n,f)	(lua_pushcfunction(f), lua_storeglobal(n))
 #define lua_register(n,f)	(lua_pushcfunction(f), lua_storeglobal(n))
 
 
@@ -99,6 +102,12 @@ lua_Object     lua_createtable		(void);
 
 
 /* for compatibility with old versions. Avoid using these macros */
 /* for compatibility with old versions. Avoid using these macros */
 
 
+#define lua_lockobject(o)  lua_refobject(o,1)
+#define	lua_lock() lua_ref(1)
+#define lua_getlocked lua_getref
+#define	lua_pushlocked lua_pushref
+#define	lua_unlock lua_unref
+
 #define lua_pushliteral(o)  lua_pushstring(o)
 #define lua_pushliteral(o)  lua_pushstring(o)
 
 
 #define lua_getindexed(o,n) (lua_pushobject(o), lua_pushnumber(n), lua_getsubscript())
 #define lua_getindexed(o,n) (lua_pushobject(o), lua_pushnumber(n), lua_getsubscript())

+ 2 - 2
luamem.h

@@ -1,7 +1,7 @@
 /*
 /*
 ** mem.c
 ** mem.c
 ** memory manager for lua
 ** memory manager for lua
-** $Id: mem.h,v 1.5 1996/03/21 16:31:32 roberto Exp roberto $
+** $Id: mem.h,v 1.6 1996/03/21 18:54:29 roberto Exp roberto $
 */
 */
  
  
 #ifndef mem_h
 #ifndef mem_h
@@ -18,7 +18,7 @@
 #define constantEM   "constant table overflow"
 #define constantEM   "constant table overflow"
 #define stackEM   "stack size overflow"
 #define stackEM   "stack size overflow"
 #define lexEM   "lex buffer overflow"
 #define lexEM   "lex buffer overflow"
-#define lockEM   "lock table overflow"
+#define refEM   "reference table overflow"
 #define tableEM  "table overflow"
 #define tableEM  "table overflow"
 #define memEM "not enough memory"
 #define memEM "not enough memory"
 
 

+ 46 - 29
manual.tex

@@ -1,4 +1,4 @@
-% $Id: manual.tex,v 1.14 1996/03/20 18:44:02 roberto Exp roberto $
+% $Id: manual.tex,v 1.15 1996/04/01 14:36:35 roberto Exp roberto $
 
 
 \documentstyle[fullpage,11pt,bnf]{article}
 \documentstyle[fullpage,11pt,bnf]{article}
 
 
@@ -34,7 +34,7 @@ Waldemar Celes Filho
 \tecgraf\ --- Departamento de Inform\'atica --- PUC-Rio
 \tecgraf\ --- Departamento de Inform\'atica --- PUC-Rio
 }
 }
 
 
-\date{\small \verb$Date: 1996/03/20 18:44:02 $}
+\date{\small \verb$Date: 1996/04/01 14:36:35 $}
 
 
 \maketitle
 \maketitle
 
 
@@ -739,7 +739,7 @@ The API functions can be classified in the following categories:
 \item manipulating (reading and writing) Lua objects;
 \item manipulating (reading and writing) Lua objects;
 \item calling Lua functions;
 \item calling Lua functions;
 \item C functions to be called by Lua;
 \item C functions to be called by Lua;
-\item locking Lua Objects.
+\item references to Lua Objects.
 \end{enumerate}
 \end{enumerate}
 All API functions are declared in the file \verb'lua.h'.
 All API functions are declared in the file \verb'lua.h'.
 
 
@@ -1069,30 +1069,39 @@ many results.
 Section~\ref{exCFunction} presents an example of a CFunction.
 Section~\ref{exCFunction} presents an example of a CFunction.
 
 
 
 
-\subsection{Locking Lua Objects}
+\subsection{References to Lua Objects}
 
 
 As already noted, \verb'lua_Object's are volatile.
 As already noted, \verb'lua_Object's are volatile.
 If the C code needs to keep a \verb'lua_Object'
 If the C code needs to keep a \verb'lua_Object'
 outside block boundaries,
 outside block boundaries,
-it has to {\em lock} the object.
-The routines to manipulate locking are the following:
-\Deffunc{lua_lock}\Deffunc{lua_getlocked}
-\Deffunc{lua_pushlocked}\Deffunc{lua_unlock}
-\begin{verbatim}
-int        lua_lock (void);
-lua_Object lua_getlocked  (int ref);
-void       lua_pushlocked (int ref);
-void       lua_unlock (int ref);
-\end{verbatim}
-The function \verb'lua_lock' locks the object
-which is on the top of the stack,
-and returns a reference to it.
-Whenever the locked object is needed,
-a call to \verb'lua_getlocked'
+it must create a \Def{reference} to the object.
+The routines to manipulate references are the following:
+\Deffunc{lua_ref}\Deffunc{lua_getref}
+\Deffunc{lua_pushref}\Deffunc{lua_unref}
+\begin{verbatim}
+typedef int lua_Reference;
+
+lua_Reference  lua_ref (int lock);
+lua_Object     lua_getref  (lua_Reference ref);
+void           lua_pushref (lua_Reference ref);
+void           lua_unref (lua_Reference ref);
+\end{verbatim}
+The function \verb'lua_ref' creates a reference
+to the object which is on the top of the stack,
+and returns this reference.
+If \verb'lock' is true, the object is {\em locked}:
+that means the object will not be garbage collected.
+Notice that an unlocked reference may be garbage collected.
+Whenever the referenced object is needed,
+a call to \verb'lua_getref'
 returns a handle to it,
 returns a handle to it,
-while \verb'lua_pushlocked' pushes the handle on the stack.
-When a locked object is no longer needed,
-it can be unlocked with a call to \verb'lua_unlock'.
+while \verb'lua_pushref' pushes the object on the stack.
+If the object has been collected,
+\verb'lua_getref' returns \verb'LUA_NOOBJECT',
+and \verb'lua_pushobject' issues an error.
+
+When a reference is no longer needed,
+it can be freed with a call to \verb'lua_unref'.
 
 
 
 
 
 
@@ -1839,12 +1848,14 @@ as illustrated in Figure~\ref{Cinher}.
 \begin{figure}
 \begin{figure}
 \Line
 \Line
 \begin{verbatim}
 \begin{verbatim}
-int lockedParentName;  /* stores the lock index for the string "parent" */
-int lockedOldIndex;    /* previous fallback function */
+#include "lua.h"
+
+lua_Reference lockedParentName;  /* lock index for the string "parent" */
+lua_Reference lockedOldIndex;    /* previous fallback function */
 
 
 void callOldFallback (lua_Object table, lua_Object index)
 void callOldFallback (lua_Object table, lua_Object index)
 {
 {
-  lua_Object oldIndex = lua_getlocked(lockedOldIndex);
+  lua_Object oldIndex = lua_getref(lockedOldIndex);
   lua_pushobject(table);
   lua_pushobject(table);
   lua_pushobject(index);
   lua_pushobject(index);
   lua_callfunction(oldIndex);
   lua_callfunction(oldIndex);
@@ -1861,7 +1872,7 @@ void Index (void)
     return;
     return;
   }
   }
   lua_pushobject(table);
   lua_pushobject(table);
-  lua_pushlocked(lockedParentName);
+  lua_pushref(lockedParentName);
   parent = lua_getsubscript();
   parent = lua_getsubscript();
   if (lua_istable(parent))
   if (lua_istable(parent))
   {
   {
@@ -1880,9 +1891,9 @@ void Index (void)
 This code must be registered with:
 This code must be registered with:
 \begin{verbatim}
 \begin{verbatim}
   lua_pushstring("parent");
   lua_pushstring("parent");
-  lockedParentName = lua_lock();
+  lockedParentName = lua_ref(1);
   lua_pushobject(lua_setfallback("index", Index));
   lua_pushobject(lua_setfallback("index", Index));
-  lockedOldIndex = lua_lock();
+  lockedOldIndex = lua_ref(1);
 \end{verbatim}
 \end{verbatim}
 Notice how the string \verb'"parent"' is kept
 Notice how the string \verb'"parent"' is kept
 locked in Lua for optimal performance.
 locked in Lua for optimal performance.
@@ -1892,6 +1903,9 @@ There are many different ways to do object-oriented programming in Lua.
 This section presents one possible way to
 This section presents one possible way to
 implement classes,
 implement classes,
 using the inheritance mechanism presented above.
 using the inheritance mechanism presented above.
+{\em Please notice: the following examples only work
+with the index fallback redefined according to
+Section~\ref{exfallback}}.
 
 
 As one could expect, a good way to represent a class is
 As one could expect, a good way to represent a class is
 as a table.
 as a table.
@@ -2079,9 +2093,12 @@ have been superseded by the new version of function \verb'date'.
 Function \verb'int2str' (from \verb'strlib') has been superseded by new
 Function \verb'int2str' (from \verb'strlib') has been superseded by new
 function \verb'format', with parameter \verb'"%c"'.
 function \verb'format', with parameter \verb'"%c"'.
 \item
 \item
+The lock mechanism has been superseded by the reference mechanism.
+However, \verb-lua.h- provides compatibility macros,
+so there is no need to change programs.
+\item
 API function \verb'lua_pushliteral' now is just a macro to
 API function \verb'lua_pushliteral' now is just a macro to
 \verb'lua_pushstring'.
 \verb'lua_pushstring'.
-Programmers are encouraged not to use this macro.
 \end{itemize}
 \end{itemize}
 
 
 \subsection*{Incompatibilities with \Index{version 2.1}}
 \subsection*{Incompatibilities with \Index{version 2.1}}

+ 4 - 4
mathlib.c

@@ -3,7 +3,7 @@
 ** Mathematics library to LUA
 ** Mathematics library to LUA
 */
 */
 
 
-char *rcs_mathlib="$Id: mathlib.c,v 1.13 1995/11/10 17:54:31 roberto Exp roberto $";
+char *rcs_mathlib="$Id: mathlib.c,v 1.14 1996/02/09 17:21:27 roberto Exp roberto $";
 
 
 #include <stdlib.h>
 #include <stdlib.h>
 #include <math.h>
 #include <math.h>
@@ -104,7 +104,7 @@ static void math_sqrt (void)
  lua_pushnumber (sqrt(d));
  lua_pushnumber (sqrt(d));
 }
 }
 
 
-static int old_pow;
+static lua_Reference old_pow;
 
 
 static void math_pow (void)
 static void math_pow (void)
 {
 {
@@ -113,7 +113,7 @@ static void math_pow (void)
  lua_Object op = lua_getparam(3);
  lua_Object op = lua_getparam(3);
  if (!lua_isnumber(o1) || !lua_isnumber(o2) || *(lua_getstring(op)) != 'p')
  if (!lua_isnumber(o1) || !lua_isnumber(o2) || *(lua_getstring(op)) != 'p')
  {
  {
-   lua_Object old = lua_getlocked(old_pow);
+   lua_Object old = lua_getref(old_pow);
    lua_pushobject(o1);
    lua_pushobject(o1);
    lua_pushobject(o2);
    lua_pushobject(o2);
    lua_pushobject(op);
    lua_pushobject(op);
@@ -223,5 +223,5 @@ void mathlib_open (void)
  lua_register ("random",     math_random);
  lua_register ("random",     math_random);
  lua_register ("randomseed", math_randomseed);
  lua_register ("randomseed", math_randomseed);
 
 
- old_pow = lua_lockobject(lua_setfallback("arith", math_pow));
+ old_pow = lua_refobject(lua_setfallback("arith", math_pow), 1);
 }
 }

+ 26 - 20
opcode.c

@@ -3,7 +3,7 @@
 ** TecCGraf - PUC-Rio
 ** TecCGraf - PUC-Rio
 */
 */
 
 
-char *rcs_opcode="$Id: opcode.c,v 3.65 1996/03/21 18:55:02 roberto Exp roberto $";
+char *rcs_opcode="$Id: opcode.c,v 3.66 1996/03/22 19:12:15 roberto Exp roberto $";
 
 
 #include <setjmp.h>
 #include <setjmp.h>
 #include <stdio.h>
 #include <stdio.h>
@@ -717,27 +717,31 @@ void *lua_getuserdata (lua_Object object)
 }
 }
 
 
 
 
-lua_Object lua_getlocked (int ref)
+lua_Object lua_getref (lua_Reference ref)
 {
 {
- adjustC(0);
- *top = *luaI_getlocked(ref);
- incr_top;
- CBase++;  /* incorporate object in the stack */
- return Ref(top-1);
+  Object *o = luaI_getref(ref);
+  if (o == NULL)
+    return LUA_NOOBJECT;
+  adjustC(0);
+  luaI_pushobject(o);
+  CBase++;  /* incorporate object in the stack */
+  return Ref(top-1);
 }
 }
 
 
 
 
-void lua_pushlocked (int ref)
+void lua_pushref (lua_Reference ref)
 {
 {
- *top = *luaI_getlocked(ref);
- incr_top;
+  Object *o = luaI_getref(ref);
+  if (o == NULL)
+    lua_error("access to invalid (possibly garbage collected) reference");
+  luaI_pushobject(o);
 }
 }
 
 
 
 
-int lua_lock (void)
+lua_Reference lua_ref (int lock)
 {
 {
   adjustC(1);
   adjustC(1);
-  return luaI_lock(--top);
+  return luaI_ref(--top, lock);
 }
 }
 
 
 
 
@@ -812,27 +816,29 @@ void lua_pushcfunction (lua_CFunction fn)
 */
 */
 void lua_pushusertag (void *u, int tag)
 void lua_pushusertag (void *u, int tag)
 {
 {
- if (tag < LUA_T_USERDATA) return;
+ if (tag < LUA_T_USERDATA) 
+   lua_error("invalid tag in `lua_pushusertag'");
  tag(top) = tag; uvalue(top) = u;
  tag(top) = tag; uvalue(top) = u;
  incr_top;
  incr_top;
 }
 }
 
 
 /*
 /*
-** Push a lua_Object to stack.
+** Push an object on the stack.
 */
 */
-void lua_pushobject (lua_Object o)
+void luaI_pushobject (Object *o)
 {
 {
- *top = *Address(o);
+ *top = *o;
  incr_top;
  incr_top;
 }
 }
 
 
 /*
 /*
-** Push an object on the stack.
+** Push a lua_Object on stack.
 */
 */
-void luaI_pushobject (Object *o)
+void lua_pushobject (lua_Object o)
 {
 {
- *top = *o;
- incr_top;
+  if (o == LUA_NOOBJECT)
+    lua_error("attempt to push a NOOBJECT");
+  luaI_pushobject(Address(o));
 }
 }
 
 
 int lua_type (lua_Object o)
 int lua_type (lua_Object o)

+ 20 - 1
table.c

@@ -3,7 +3,7 @@
 ** Module to control static tables
 ** Module to control static tables
 */
 */
 
 
-char *rcs_table="$Id: table.c,v 2.50 1996/03/21 16:31:32 roberto Exp roberto $";
+char *rcs_table="$Id: table.c,v 2.51 1996/03/21 18:54:29 roberto Exp roberto $";
 
 
 #include "mem.h"
 #include "mem.h"
 #include "opcode.h"
 #include "opcode.h"
@@ -170,6 +170,24 @@ int lua_markobject (Object *o)
  return 0;
  return 0;
 }
 }
 
 
+/*
+* returns 0 if the object is going to be (garbage) collected
+*/
+int luaI_ismarked (Object *o)
+{
+  switch (o->tag)
+  {
+   case LUA_T_STRING:
+     return o->value.ts->marked;
+   case LUA_T_FUNCTION:
+    return o->value.tf->marked;
+   case LUA_T_ARRAY:
+    return o->value.a->mark;
+   default:  /* nil, number, cfunction, or user data */
+    return 1;
+  }
+}
+
 
 
 /*
 /*
 ** Garbage collection. 
 ** Garbage collection. 
@@ -182,6 +200,7 @@ Long luaI_collectgarbage (void)
   lua_travsymbol(lua_markobject); /* mark symbol table objects */
   lua_travsymbol(lua_markobject); /* mark symbol table objects */
   luaI_travlock(lua_markobject); /* mark locked objects */
   luaI_travlock(lua_markobject); /* mark locked objects */
   luaI_travfallbacks(lua_markobject);  /* mark fallbacks */
   luaI_travfallbacks(lua_markobject);  /* mark fallbacks */
+  luaI_invalidaterefs();
   recovered += lua_strcollector();
   recovered += lua_strcollector();
   recovered += lua_hashcollector();
   recovered += lua_hashcollector();
   recovered += luaI_funccollector();
   recovered += luaI_funccollector();

+ 2 - 1
table.h

@@ -1,7 +1,7 @@
 /*
 /*
 ** Module to control static tables
 ** Module to control static tables
 ** TeCGraf - PUC-Rio
 ** TeCGraf - PUC-Rio
-** $Id: table.h,v 2.19 1996/02/26 21:00:27 roberto Exp roberto $
+** $Id: table.h,v 2.20 1996/03/14 15:57:19 roberto Exp roberto $
 */
 */
 
 
 #ifndef table_h
 #ifndef table_h
@@ -30,6 +30,7 @@ Word  luaI_findconstant    (TaggedString *t);
 Word  luaI_findconstantbyname (char *name);
 Word  luaI_findconstantbyname (char *name);
 TaggedString *luaI_createfixedstring  (char *str);
 TaggedString *luaI_createfixedstring  (char *str);
 int   lua_markobject      (Object *o);
 int   lua_markobject      (Object *o);
+int luaI_ismarked (Object *o);
 Long luaI_collectgarbage (void);
 Long luaI_collectgarbage (void);
 void  lua_pack            (void);
 void  lua_pack            (void);