commit 0ef5cf22891c9d34a88ccc5d89eb0ed82b004471
parent fed9408ab51a4be5ff84450ad47d1e0cdaed97bc
Author: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
Date: Mon, 22 Apr 1996 15:00:17 -0300
lock mechanism seperseded by the REFERENCE mechanism.
Diffstat:
M | fallback.c | | | 70 | +++++++++++++++++++++++++++++++++++++++++++--------------------------- |
M | fallback.h | | | 8 | +++++--- |
M | lua.h | | | 21 | +++++++++++++++------ |
M | luamem.h | | | 4 | ++-- |
M | manual.tex | | | 75 | ++++++++++++++++++++++++++++++++++++++++++++++----------------------------- |
M | mathlib.c | | | 8 | ++++---- |
M | opcode.c | | | 46 | ++++++++++++++++++++++++++-------------------- |
M | table.c | | | 21 | ++++++++++++++++++++- |
M | table.h | | | 3 | ++- |
9 files changed, 163 insertions(+), 93 deletions(-)
diff --git a/fallback.c b/fallback.c
@@ -3,7 +3,7 @@
** 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 <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 "opcode.h"
#include "lua.h"
+#include "table.h"
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 oldSize;
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 */
- 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}};
- if (ref >= 0 && ref < lockSize)
- return &lockArray[ref];
- else
+ if (ref == -1)
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 *))
{
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 *))
{
int i;
diff --git a/fallback.h b/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
#define fallback_h
+#include "lua.h"
#include "opcode.h"
extern struct FB {
@@ -26,9 +27,10 @@ extern struct FB {
#define FB_GETGLOBAL 9
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_invalidaterefs (void);
char *luaI_travfallbacks (int (*fn)(Object *));
#endif
diff --git a/lua.h b/lua.h
@@ -2,7 +2,7 @@
** LUA - Linguagem para Usuarios de Aplicacao
** Grupo de Tecnologia em Computacao Grafica
** 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_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);
/* 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))
@@ -99,6 +102,12 @@ lua_Object lua_createtable (void);
/* 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_getindexed(o,n) (lua_pushobject(o), lua_pushnumber(n), lua_getsubscript())
diff --git a/luamem.h b/luamem.h
@@ -1,7 +1,7 @@
/*
** mem.c
** 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
@@ -18,7 +18,7 @@
#define constantEM "constant table overflow"
#define stackEM "stack size overflow"
#define lexEM "lex buffer overflow"
-#define lockEM "lock table overflow"
+#define refEM "reference table overflow"
#define tableEM "table overflow"
#define memEM "not enough memory"
diff --git a/manual.tex b/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}
@@ -34,7 +34,7 @@ Waldemar Celes Filho
\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
@@ -739,7 +739,7 @@ The API functions can be classified in the following categories:
\item manipulating (reading and writing) Lua objects;
\item calling Lua functions;
\item C functions to be called by Lua;
-\item locking Lua Objects.
+\item references to Lua Objects.
\end{enumerate}
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.
-\subsection{Locking Lua Objects}
+\subsection{References to Lua Objects}
As already noted, \verb'lua_Object's are volatile.
If the C code needs to keep a \verb'lua_Object'
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,
-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}
\Line
\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)
{
- lua_Object oldIndex = lua_getlocked(lockedOldIndex);
+ lua_Object oldIndex = lua_getref(lockedOldIndex);
lua_pushobject(table);
lua_pushobject(index);
lua_callfunction(oldIndex);
@@ -1861,7 +1872,7 @@ void Index (void)
return;
}
lua_pushobject(table);
- lua_pushlocked(lockedParentName);
+ lua_pushref(lockedParentName);
parent = lua_getsubscript();
if (lua_istable(parent))
{
@@ -1880,9 +1891,9 @@ void Index (void)
This code must be registered with:
\begin{verbatim}
lua_pushstring("parent");
- lockedParentName = lua_lock();
+ lockedParentName = lua_ref(1);
lua_pushobject(lua_setfallback("index", Index));
- lockedOldIndex = lua_lock();
+ lockedOldIndex = lua_ref(1);
\end{verbatim}
Notice how the string \verb'"parent"' is kept
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
implement classes,
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 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'format', with parameter \verb'"%c"'.
\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
\verb'lua_pushstring'.
-Programmers are encouraged not to use this macro.
\end{itemize}
\subsection*{Incompatibilities with \Index{version 2.1}}
diff --git a/mathlib.c b/mathlib.c
@@ -3,7 +3,7 @@
** 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 <math.h>
@@ -104,7 +104,7 @@ static void math_sqrt (void)
lua_pushnumber (sqrt(d));
}
-static int old_pow;
+static lua_Reference old_pow;
static void math_pow (void)
{
@@ -113,7 +113,7 @@ static void math_pow (void)
lua_Object op = lua_getparam(3);
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(o2);
lua_pushobject(op);
@@ -223,5 +223,5 @@ void mathlib_open (void)
lua_register ("random", math_random);
lua_register ("randomseed", math_randomseed);
- old_pow = lua_lockobject(lua_setfallback("arith", math_pow));
+ old_pow = lua_refobject(lua_setfallback("arith", math_pow), 1);
}
diff --git a/opcode.c b/opcode.c
@@ -3,7 +3,7 @@
** 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 <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);
- 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)
{
- if (tag < LUA_T_USERDATA) return;
+ if (tag < LUA_T_USERDATA)
+ lua_error("invalid tag in `lua_pushusertag'");
tag(top) = tag; uvalue(top) = u;
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;
}
/*
-** 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)
diff --git a/table.c b/table.c
@@ -3,7 +3,7 @@
** 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 "opcode.h"
@@ -170,6 +170,24 @@ int lua_markobject (Object *o)
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.
@@ -182,6 +200,7 @@ Long luaI_collectgarbage (void)
lua_travsymbol(lua_markobject); /* mark symbol table objects */
luaI_travlock(lua_markobject); /* mark locked objects */
luaI_travfallbacks(lua_markobject); /* mark fallbacks */
+ luaI_invalidaterefs();
recovered += lua_strcollector();
recovered += lua_hashcollector();
recovered += luaI_funccollector();
diff --git a/table.h b/table.h
@@ -1,7 +1,7 @@
/*
** Module to control static tables
** 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
@@ -30,6 +30,7 @@ Word luaI_findconstant (TaggedString *t);
Word luaI_findconstantbyname (char *name);
TaggedString *luaI_createfixedstring (char *str);
int lua_markobject (Object *o);
+int luaI_ismarked (Object *o);
Long luaI_collectgarbage (void);
void lua_pack (void);