mirror of https://github.com/rusefi/lua.git
lock mechanism seperseded by the REFERENCE mechanism.
This commit is contained in:
parent
fed9408ab5
commit
0ef5cf2289
70
fallback.c
70
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;
|
||||
|
|
|
@ -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
|
||||
|
|
21
lua.h
21
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())
|
||||
|
|
4
luamem.h
4
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"
|
||||
|
||||
|
|
71
manual.tex
71
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}
|
||||
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}
|
||||
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);
|
||||
\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'
|
||||
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}}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
50
opcode.c
50
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,20 +816,12 @@ 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.
|
||||
*/
|
||||
void lua_pushobject (lua_Object o)
|
||||
{
|
||||
*top = *Address(o);
|
||||
incr_top;
|
||||
}
|
||||
|
||||
/*
|
||||
** Push an object on the stack.
|
||||
*/
|
||||
|
@ -835,6 +831,16 @@ void luaI_pushobject (Object *o)
|
|||
incr_top;
|
||||
}
|
||||
|
||||
/*
|
||||
** Push a lua_Object on stack.
|
||||
*/
|
||||
void lua_pushobject (lua_Object o)
|
||||
{
|
||||
if (o == LUA_NOOBJECT)
|
||||
lua_error("attempt to push a NOOBJECT");
|
||||
luaI_pushobject(Address(o));
|
||||
}
|
||||
|
||||
int lua_type (lua_Object o)
|
||||
{
|
||||
if (o == LUA_NOOBJECT)
|
||||
|
|
21
table.c
21
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();
|
||||
|
|
3
table.h
3
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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue