simplified version of `gc' tag method (only for userdata now).
This commit is contained in:
30
lapi.c
30
lapi.c
@@ -1,11 +1,10 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lapi.c,v 1.49 1999/09/20 14:57:29 roberto Exp roberto $
|
** $Id: lapi.c,v 1.50 1999/09/21 16:10:13 roberto Exp roberto $
|
||||||
** Lua API
|
** Lua API
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "lapi.h"
|
#include "lapi.h"
|
||||||
@@ -15,6 +14,7 @@
|
|||||||
#include "lgc.h"
|
#include "lgc.h"
|
||||||
#include "lmem.h"
|
#include "lmem.h"
|
||||||
#include "lobject.h"
|
#include "lobject.h"
|
||||||
|
#include "lref.h"
|
||||||
#include "lstate.h"
|
#include "lstate.h"
|
||||||
#include "lstring.h"
|
#include "lstring.h"
|
||||||
#include "ltable.h"
|
#include "ltable.h"
|
||||||
@@ -387,14 +387,14 @@ void lua_settag (int tag) {
|
|||||||
|
|
||||||
TaggedString *luaA_nextvar (TaggedString *g) {
|
TaggedString *luaA_nextvar (TaggedString *g) {
|
||||||
if (g == NULL)
|
if (g == NULL)
|
||||||
g = (TaggedString *)L->rootglobal.next; /* first variable */
|
g = L->rootglobal; /* first variable */
|
||||||
else {
|
else {
|
||||||
/* check whether name is in global var list */
|
/* check whether name is in global var list */
|
||||||
luaL_arg_check((GCnode *)g != g->head.next, 1, "variable name expected");
|
luaL_arg_check(g != g->next, 1, "variable name expected");
|
||||||
g = (TaggedString *)g->head.next; /* get next */
|
g = g->next; /* get next */
|
||||||
}
|
}
|
||||||
while (g && g->u.s.globalval.ttype == LUA_T_NIL) /* skip globals with nil */
|
while (g && g->u.s.globalval.ttype == LUA_T_NIL) /* skip globals with nil */
|
||||||
g = (TaggedString *)g->head.next;
|
g = g->next;
|
||||||
if (g) {
|
if (g) {
|
||||||
ttype(L->stack.top) = LUA_T_STRING; tsvalue(L->stack.top) = g;
|
ttype(L->stack.top) = LUA_T_STRING; tsvalue(L->stack.top) = g;
|
||||||
incr_top;
|
incr_top;
|
||||||
@@ -574,12 +574,18 @@ static int checkfunc (TObject *o) {
|
|||||||
|
|
||||||
const char *lua_getobjname (lua_Object o, const char **name) {
|
const char *lua_getobjname (lua_Object o, const char **name) {
|
||||||
/* try to find a name for given function */
|
/* try to find a name for given function */
|
||||||
|
TaggedString *g;
|
||||||
set_normalized(L->stack.top, Address(o)); /* to be accessed by "checkfunc" */
|
set_normalized(L->stack.top, Address(o)); /* to be accessed by "checkfunc" */
|
||||||
if ((*name = luaS_travsymbol(checkfunc)) != NULL)
|
for (g=L->rootglobal; g; g=g->next) {
|
||||||
return "global";
|
if (checkfunc(&g->u.s.globalval)) {
|
||||||
else if ((*name = luaT_travtagmethods(checkfunc)) != NULL)
|
*name = g->str;
|
||||||
|
return "global";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* not found: try tag methods */
|
||||||
|
if ((*name = luaT_travtagmethods(checkfunc)) != NULL)
|
||||||
return "tag-method";
|
return "tag-method";
|
||||||
else return "";
|
else return ""; /* not found at all */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* }====================================================== */
|
/* }====================================================== */
|
||||||
@@ -615,7 +621,7 @@ void lua_endblock (void) {
|
|||||||
int lua_ref (int lock) {
|
int lua_ref (int lock) {
|
||||||
int ref;
|
int ref;
|
||||||
checkCparams(1);
|
checkCparams(1);
|
||||||
ref = luaC_ref(L->stack.top-1, lock);
|
ref = luaR_ref(L->stack.top-1, lock);
|
||||||
L->stack.top--;
|
L->stack.top--;
|
||||||
return ref;
|
return ref;
|
||||||
}
|
}
|
||||||
@@ -623,7 +629,7 @@ int lua_ref (int lock) {
|
|||||||
|
|
||||||
|
|
||||||
lua_Object lua_getref (int ref) {
|
lua_Object lua_getref (int ref) {
|
||||||
const TObject *o = luaC_getref(ref);
|
const TObject *o = luaR_getref(ref);
|
||||||
return (o ? put_luaObject(o) : LUA_NOOBJECT);
|
return (o ? put_luaObject(o) : LUA_NOOBJECT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
63
lbuiltin.c
63
lbuiltin.c
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lbuiltin.c,v 1.62 1999/09/08 20:45:18 roberto Exp roberto $
|
** $Id: lbuiltin.c,v 1.63 1999/09/20 14:57:29 roberto Exp roberto $
|
||||||
** Built-in functions
|
** Built-in functions
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -222,9 +222,15 @@ static void luaB_rawsettable (void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void luaB_settagmethod (void) {
|
static void luaB_settagmethod (void) {
|
||||||
|
int tag = luaL_check_int(1);
|
||||||
|
const char *event = luaL_check_string(2);
|
||||||
lua_Object nf = luaL_nonnullarg(3);
|
lua_Object nf = luaL_nonnullarg(3);
|
||||||
|
#ifndef LUA_COMPAT_GC
|
||||||
|
if (strcmp(event, "gc") == 0 && tag != LUA_T_NIL)
|
||||||
|
lua_error("cannot set this tag method from Lua");
|
||||||
|
#endif
|
||||||
lua_pushobject(nf);
|
lua_pushobject(nf);
|
||||||
lua_pushobject(lua_settagmethod(luaL_check_int(1), luaL_check_string(2)));
|
lua_pushobject(lua_settagmethod(tag, event));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void luaB_gettagmethod (void) {
|
static void luaB_gettagmethod (void) {
|
||||||
@@ -437,12 +443,11 @@ static void luaB_foreach (void) {
|
|||||||
|
|
||||||
|
|
||||||
static void luaB_foreachvar (void) {
|
static void luaB_foreachvar (void) {
|
||||||
GCnode *g;
|
TaggedString *s;
|
||||||
TObject f; /* see comment in 'foreachi' */
|
TObject f; /* see comment in 'foreachi' */
|
||||||
f = *luaA_Address(luaL_functionarg(1));
|
f = *luaA_Address(luaL_functionarg(1));
|
||||||
luaD_checkstack(4); /* for extra var name, f, var name, and globalval */
|
luaD_checkstack(4); /* for extra var name, f, var name, and globalval */
|
||||||
for (g = L->rootglobal.next; g; g = g->next) {
|
for (s = L->rootglobal; s; s = s->next) {
|
||||||
TaggedString *s = (TaggedString *)g;
|
|
||||||
if (s->u.s.globalval.ttype != LUA_T_NIL) {
|
if (s->u.s.globalval.ttype != LUA_T_NIL) {
|
||||||
pushtagstring(s); /* keep (extra) s on stack to avoid GC */
|
pushtagstring(s); /* keep (extra) s on stack to avoid GC */
|
||||||
*(L->stack.top++) = f;
|
*(L->stack.top++) = f;
|
||||||
@@ -451,10 +456,10 @@ static void luaB_foreachvar (void) {
|
|||||||
luaD_calln(2, 1);
|
luaD_calln(2, 1);
|
||||||
if (ttype(L->stack.top-1) != LUA_T_NIL) {
|
if (ttype(L->stack.top-1) != LUA_T_NIL) {
|
||||||
L->stack.top--;
|
L->stack.top--;
|
||||||
*(L->stack.top-1) = *L->stack.top; /* remove extra s */
|
*(L->stack.top-1) = *L->stack.top; /* remove extra `s' */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
L->stack.top-=2; /* remove result and extra s */
|
L->stack.top-=2; /* remove result and extra `s' */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -602,20 +607,42 @@ static void mem_query (void) {
|
|||||||
|
|
||||||
|
|
||||||
static void query_strings (void) {
|
static void query_strings (void) {
|
||||||
lua_pushnumber(L->string_root[luaL_check_int(1)].nuse);
|
int h = luaL_check_int(1) - 1;
|
||||||
|
int s = luaL_opt_int(2, 0) - 1;
|
||||||
|
if (s==-1) {
|
||||||
|
if (h < NUM_HASHS) {
|
||||||
|
lua_pushnumber(L->string_root[h].nuse);
|
||||||
|
lua_pushnumber(L->string_root[h].size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
TaggedString *ts = L->string_root[h].hash[s];
|
||||||
|
if (ts == NULL) lua_pushstring("<NIL>");
|
||||||
|
else if (ts == &luaS_EMPTY) lua_pushstring("<EMPTY>");
|
||||||
|
else if (ts->constindex == -1) lua_pushstring("<USERDATA>");
|
||||||
|
else lua_pushstring(ts->str);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void countlist (void) {
|
static void extra_services (void) {
|
||||||
const char *s = luaL_check_string(1);
|
const char *service = luaL_check_string(1);
|
||||||
GCnode *l = (s[0]=='t') ? L->roottable.next : (s[0]=='c') ? L->rootcl.next :
|
switch (*service) {
|
||||||
(s[0]=='p') ? L->rootproto.next : L->rootglobal.next;
|
case 'U': /* create a userdata with a given value/tag */
|
||||||
int i=0;
|
lua_pushusertag((void *)luaL_check_int(2), luaL_check_int(3));
|
||||||
while (l) {
|
break;
|
||||||
i++;
|
|
||||||
l = l->next;
|
case 'u': /* return the value of a userdata */
|
||||||
|
lua_pushnumber((int)lua_getuserdata(lua_getparam(2)));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 't': /* set `gc' tag method */
|
||||||
|
lua_pushobject(lua_getparam(3));
|
||||||
|
lua_settagmethod(luaL_check_int(2), "gc");
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: luaL_arg_check(0, 1, "invalid service");
|
||||||
}
|
}
|
||||||
lua_pushnumber(i);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -679,9 +706,9 @@ static void testC (void) {
|
|||||||
|
|
||||||
static const struct luaL_reg builtin_funcs[] = {
|
static const struct luaL_reg builtin_funcs[] = {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
{"extra", extra_services},
|
||||||
{"testC", testC},
|
{"testC", testC},
|
||||||
{"totalmem", mem_query},
|
{"totalmem", mem_query},
|
||||||
{"count", countlist},
|
|
||||||
{"querystr", query_strings},
|
{"querystr", query_strings},
|
||||||
#endif
|
#endif
|
||||||
{"_ALERT", luaB_alert},
|
{"_ALERT", luaB_alert},
|
||||||
|
|||||||
15
ldo.c
15
ldo.c
@@ -1,18 +1,16 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: ldo.c,v 1.46 1999/08/16 20:52:00 roberto Exp roberto $
|
** $Id: ldo.c,v 1.47 1999/09/06 15:24:46 roberto Exp roberto $
|
||||||
** Stack and Call structure of Lua
|
** Stack and Call structure of Lua
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "lauxlib.h"
|
#include "lauxlib.h"
|
||||||
#include "ldo.h"
|
#include "ldo.h"
|
||||||
#include "lfunc.h"
|
|
||||||
#include "lgc.h"
|
#include "lgc.h"
|
||||||
#include "lmem.h"
|
#include "lmem.h"
|
||||||
#include "lobject.h"
|
#include "lobject.h"
|
||||||
@@ -219,17 +217,6 @@ void luaD_calln (int nArgs, int nResults) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Traverse all objects on L->stack.stack
|
|
||||||
*/
|
|
||||||
void luaD_travstack (int (*fn)(TObject *)) {
|
|
||||||
StkId i;
|
|
||||||
for (i = (L->stack.top-1)-L->stack.stack; i>=0; i--)
|
|
||||||
fn(L->stack.stack+i);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void message (const char *s) {
|
static void message (const char *s) {
|
||||||
const TObject *em = &(luaS_new("_ERRORMESSAGE")->u.s.globalval);
|
const TObject *em = &(luaS_new("_ERRORMESSAGE")->u.s.globalval);
|
||||||
if (ttype(em) == LUA_T_PROTO || ttype(em) == LUA_T_CPROTO ||
|
if (ttype(em) == LUA_T_PROTO || ttype(em) == LUA_T_CPROTO ||
|
||||||
|
|||||||
3
ldo.h
3
ldo.h
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: ldo.h,v 1.6 1999/06/22 20:37:23 roberto Exp roberto $
|
** $Id: ldo.h,v 1.7 1999/08/16 20:52:00 roberto Exp roberto $
|
||||||
** Stack and Call structure of Lua
|
** Stack and Call structure of Lua
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -39,7 +39,6 @@ void luaD_calln (int nArgs, int nResults);
|
|||||||
void luaD_callTM (const TObject *f, int nParams, int nResults);
|
void luaD_callTM (const TObject *f, int nParams, int nResults);
|
||||||
int luaD_protectedrun (void);
|
int luaD_protectedrun (void);
|
||||||
void luaD_gcIM (const TObject *o);
|
void luaD_gcIM (const TObject *o);
|
||||||
void luaD_travstack (int (*fn)(TObject *));
|
|
||||||
void luaD_checkstack (int n);
|
void luaD_checkstack (int n);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
34
lfunc.c
34
lfunc.c
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lfunc.c,v 1.10 1999/03/04 21:17:26 roberto Exp roberto $
|
** $Id: lfunc.c,v 1.11 1999/08/16 20:52:00 roberto Exp roberto $
|
||||||
** Auxiliary functions to manipulate prototypes and closures
|
** Auxiliary functions to manipulate prototypes and closures
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -18,7 +18,9 @@
|
|||||||
|
|
||||||
Closure *luaF_newclosure (int nelems) {
|
Closure *luaF_newclosure (int nelems) {
|
||||||
Closure *c = (Closure *)luaM_malloc(sizeof(Closure)+nelems*sizeof(TObject));
|
Closure *c = (Closure *)luaM_malloc(sizeof(Closure)+nelems*sizeof(TObject));
|
||||||
luaO_insertlist(&(L->rootcl), (GCnode *)c);
|
c->next = L->rootcl;
|
||||||
|
L->rootcl = c;
|
||||||
|
c->marked = 0;
|
||||||
L->nblocks += gcsizeclosure(c);
|
L->nblocks += gcsizeclosure(c);
|
||||||
c->nelems = nelems;
|
c->nelems = nelems;
|
||||||
return c;
|
return c;
|
||||||
@@ -33,14 +35,16 @@ TProtoFunc *luaF_newproto (void) {
|
|||||||
f->consts = NULL;
|
f->consts = NULL;
|
||||||
f->nconsts = 0;
|
f->nconsts = 0;
|
||||||
f->locvars = NULL;
|
f->locvars = NULL;
|
||||||
luaO_insertlist(&(L->rootproto), (GCnode *)f);
|
f->next = L->rootproto;
|
||||||
|
L->rootproto = f;
|
||||||
|
f->marked = 0;
|
||||||
L->nblocks += gcsizeproto(f);
|
L->nblocks += gcsizeproto(f);
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void luaF_freeproto (TProtoFunc *f) {
|
||||||
static void freefunc (TProtoFunc *f) {
|
L->nblocks -= gcsizeproto(f);
|
||||||
luaM_free(f->code);
|
luaM_free(f->code);
|
||||||
luaM_free(f->locvars);
|
luaM_free(f->locvars);
|
||||||
luaM_free(f->consts);
|
luaM_free(f->consts);
|
||||||
@@ -48,23 +52,9 @@ static void freefunc (TProtoFunc *f) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void luaF_freeproto (TProtoFunc *l) {
|
void luaF_freeclosure (Closure *c) {
|
||||||
while (l) {
|
L->nblocks -= gcsizeclosure(c);
|
||||||
TProtoFunc *next = (TProtoFunc *)l->head.next;
|
luaM_free(c);
|
||||||
L->nblocks -= gcsizeproto(l);
|
|
||||||
freefunc(l);
|
|
||||||
l = next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void luaF_freeclosure (Closure *l) {
|
|
||||||
while (l) {
|
|
||||||
Closure *next = (Closure *)l->head.next;
|
|
||||||
L->nblocks -= gcsizeclosure(l);
|
|
||||||
luaM_free(l);
|
|
||||||
l = next;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
6
lfunc.h
6
lfunc.h
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lfunc.h,v 1.5 1997/12/15 16:17:20 roberto Exp roberto $
|
** $Id: lfunc.h,v 1.6 1999/08/16 20:52:00 roberto Exp roberto $
|
||||||
** Lua Function structures
|
** Lua Function structures
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -14,8 +14,8 @@
|
|||||||
|
|
||||||
TProtoFunc *luaF_newproto (void);
|
TProtoFunc *luaF_newproto (void);
|
||||||
Closure *luaF_newclosure (int nelems);
|
Closure *luaF_newclosure (int nelems);
|
||||||
void luaF_freeproto (TProtoFunc *l);
|
void luaF_freeproto (TProtoFunc *f);
|
||||||
void luaF_freeclosure (Closure *l);
|
void luaF_freeclosure (Closure *c);
|
||||||
|
|
||||||
const char *luaF_getlocalname (TProtoFunc *func, int local_number, int line);
|
const char *luaF_getlocalname (TProtoFunc *func, int local_number, int line);
|
||||||
|
|
||||||
|
|||||||
302
lgc.c
302
lgc.c
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lgc.c,v 1.25 1999/08/16 20:52:00 roberto Exp roberto $
|
** $Id: lgc.c,v 1.26 1999/09/27 18:00:25 roberto Exp roberto $
|
||||||
** Garbage Collector
|
** Garbage Collector
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -8,8 +8,8 @@
|
|||||||
#include "ldo.h"
|
#include "ldo.h"
|
||||||
#include "lfunc.h"
|
#include "lfunc.h"
|
||||||
#include "lgc.h"
|
#include "lgc.h"
|
||||||
#include "lmem.h"
|
|
||||||
#include "lobject.h"
|
#include "lobject.h"
|
||||||
|
#include "lref.h"
|
||||||
#include "lstate.h"
|
#include "lstate.h"
|
||||||
#include "lstring.h"
|
#include "lstring.h"
|
||||||
#include "ltable.h"
|
#include "ltable.h"
|
||||||
@@ -21,138 +21,15 @@
|
|||||||
static int markobject (TObject *o);
|
static int markobject (TObject *o);
|
||||||
|
|
||||||
|
|
||||||
|
/* mark a string; marks bigger than 1 cannot be changed */
|
||||||
|
#define strmark(s) {if ((s)->marked == 0) (s)->marked = 1;}
|
||||||
|
|
||||||
/*
|
|
||||||
** =======================================================
|
|
||||||
** REF mechanism
|
|
||||||
** =======================================================
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
int luaC_ref (const TObject *o, int lock) {
|
|
||||||
int ref;
|
|
||||||
if (ttype(o) == LUA_T_NIL)
|
|
||||||
ref = LUA_REFNIL;
|
|
||||||
else {
|
|
||||||
for (ref=0; ref<L->refSize; ref++)
|
|
||||||
if (L->refArray[ref].status == FREE)
|
|
||||||
break;
|
|
||||||
if (ref == L->refSize) { /* no more empty spaces? */
|
|
||||||
luaM_growvector(L->refArray, L->refSize, 1, struct ref, refEM, MAX_INT);
|
|
||||||
L->refSize++;
|
|
||||||
}
|
|
||||||
L->refArray[ref].o = *o;
|
|
||||||
L->refArray[ref].status = lock ? LOCK : HOLD;
|
|
||||||
}
|
|
||||||
return ref;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void lua_unref (int ref) {
|
|
||||||
if (ref >= 0 && ref < L->refSize)
|
|
||||||
L->refArray[ref].status = FREE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const TObject *luaC_getref (int ref) {
|
|
||||||
if (ref == LUA_REFNIL)
|
|
||||||
return &luaO_nilobject;
|
|
||||||
if (ref >= 0 && ref < L->refSize &&
|
|
||||||
(L->refArray[ref].status == LOCK || L->refArray[ref].status == HOLD))
|
|
||||||
return &L->refArray[ref].o;
|
|
||||||
else
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void travlock (void) {
|
|
||||||
int i;
|
|
||||||
for (i=0; i<L->refSize; i++)
|
|
||||||
if (L->refArray[i].status == LOCK)
|
|
||||||
markobject(&L->refArray[i].o);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int ismarked (const TObject *o) {
|
|
||||||
/* valid only for locked objects */
|
|
||||||
switch (o->ttype) {
|
|
||||||
case LUA_T_STRING: case LUA_T_USERDATA:
|
|
||||||
return o->value.ts->head.marked;
|
|
||||||
case LUA_T_ARRAY:
|
|
||||||
return o->value.a->head.marked;
|
|
||||||
case LUA_T_CLOSURE:
|
|
||||||
return o->value.cl->head.marked;
|
|
||||||
case LUA_T_PROTO:
|
|
||||||
return o->value.tf->head.marked;
|
|
||||||
#ifdef DEBUG
|
|
||||||
case LUA_T_LINE: case LUA_T_CLMARK:
|
|
||||||
case LUA_T_CMARK: case LUA_T_PMARK:
|
|
||||||
LUA_INTERNALERROR("invalid type");
|
|
||||||
#endif
|
|
||||||
default: /* nil, number or cproto */
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void invalidaterefs (void) {
|
|
||||||
int i;
|
|
||||||
for (i=0; i<L->refSize; i++)
|
|
||||||
if (L->refArray[i].status == HOLD && !ismarked(&L->refArray[i].o))
|
|
||||||
L->refArray[i].status = COLLECTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void luaC_hashcallIM (Hash *l) {
|
|
||||||
TObject t;
|
|
||||||
ttype(&t) = LUA_T_ARRAY;
|
|
||||||
for (; l; l=(Hash *)l->head.next) {
|
|
||||||
avalue(&t) = l;
|
|
||||||
luaD_gcIM(&t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void luaC_strcallIM (TaggedString *l) {
|
|
||||||
TObject o;
|
|
||||||
ttype(&o) = LUA_T_USERDATA;
|
|
||||||
for (; l; l=(TaggedString *)l->head.next)
|
|
||||||
if (l->constindex == -1) { /* is userdata? */
|
|
||||||
tsvalue(&o) = l;
|
|
||||||
luaD_gcIM(&o);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static GCnode *listcollect (GCnode *l) {
|
|
||||||
GCnode *frees = NULL;
|
|
||||||
while (l) {
|
|
||||||
GCnode *next = l->next;
|
|
||||||
l->marked = 0;
|
|
||||||
while (next && !next->marked) {
|
|
||||||
l->next = next->next;
|
|
||||||
next->next = frees;
|
|
||||||
frees = next;
|
|
||||||
next = l->next;
|
|
||||||
}
|
|
||||||
l = next;
|
|
||||||
}
|
|
||||||
return frees;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** mark a string; marks bigger than 1 cannot be changed.
|
|
||||||
*/
|
|
||||||
#define strmark(s) {if ((s)->head.marked == 0) (s)->head.marked = 1;}
|
|
||||||
|
|
||||||
|
|
||||||
static void protomark (TProtoFunc *f) {
|
static void protomark (TProtoFunc *f) {
|
||||||
if (!f->head.marked) {
|
if (!f->marked) {
|
||||||
int i;
|
int i;
|
||||||
f->head.marked = 1;
|
f->marked = 1;
|
||||||
strmark(f->source);
|
strmark(f->source);
|
||||||
for (i=f->nconsts-1; i>=0; i--)
|
for (i=f->nconsts-1; i>=0; i--)
|
||||||
markobject(&f->consts[i]);
|
markobject(&f->consts[i]);
|
||||||
@@ -161,9 +38,9 @@ static void protomark (TProtoFunc *f) {
|
|||||||
|
|
||||||
|
|
||||||
static void closuremark (Closure *f) {
|
static void closuremark (Closure *f) {
|
||||||
if (!f->head.marked) {
|
if (!f->marked) {
|
||||||
int i;
|
int i;
|
||||||
f->head.marked = 1;
|
f->marked = 1;
|
||||||
for (i=f->nelems; i>=0; i--)
|
for (i=f->nelems; i>=0; i--)
|
||||||
markobject(&f->consts[i]);
|
markobject(&f->consts[i]);
|
||||||
}
|
}
|
||||||
@@ -171,9 +48,9 @@ static void closuremark (Closure *f) {
|
|||||||
|
|
||||||
|
|
||||||
static void hashmark (Hash *h) {
|
static void hashmark (Hash *h) {
|
||||||
if (!h->head.marked) {
|
if (!h->marked) {
|
||||||
int i;
|
int i;
|
||||||
h->head.marked = 1;
|
h->marked = 1;
|
||||||
for (i=nhash(h)-1; i>=0; i--) {
|
for (i=nhash(h)-1; i>=0; i--) {
|
||||||
Node *n = node(h,i);
|
Node *n = node(h,i);
|
||||||
if (ttype(ref(n)) != LUA_T_NIL) {
|
if (ttype(ref(n)) != LUA_T_NIL) {
|
||||||
@@ -187,7 +64,7 @@ static void hashmark (Hash *h) {
|
|||||||
|
|
||||||
static void globalmark (void) {
|
static void globalmark (void) {
|
||||||
TaggedString *g;
|
TaggedString *g;
|
||||||
for (g=(TaggedString *)L->rootglobal.next; g; g=(TaggedString *)g->head.next){
|
for (g=L->rootglobal; g; g=g->next) {
|
||||||
LUA_ASSERT(g->constindex >= 0, "userdata in global list");
|
LUA_ASSERT(g->constindex >= 0, "userdata in global list");
|
||||||
if (g->u.s.globalval.ttype != LUA_T_NIL) {
|
if (g->u.s.globalval.ttype != LUA_T_NIL) {
|
||||||
markobject(&g->u.s.globalval);
|
markobject(&g->u.s.globalval);
|
||||||
@@ -197,6 +74,21 @@ static void globalmark (void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void travstack (void) {
|
||||||
|
StkId i;
|
||||||
|
for (i = (L->stack.top-1)-L->stack.stack; i>=0; i--)
|
||||||
|
markobject(L->stack.stack+i);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void travlock (void) {
|
||||||
|
int i;
|
||||||
|
for (i=0; i<L->refSize; i++)
|
||||||
|
if (L->refArray[i].status == LOCK)
|
||||||
|
markobject(&L->refArray[i].o);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int markobject (TObject *o) {
|
static int markobject (TObject *o) {
|
||||||
switch (ttype(o)) {
|
switch (ttype(o)) {
|
||||||
case LUA_T_USERDATA: case LUA_T_STRING:
|
case LUA_T_USERDATA: case LUA_T_STRING:
|
||||||
@@ -217,36 +109,138 @@ static int markobject (TObject *o) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void collectproto (void) {
|
||||||
|
TProtoFunc **p = &L->rootproto;
|
||||||
|
TProtoFunc *next;
|
||||||
|
while ((next = *p) != NULL) {
|
||||||
|
if (next->marked) {
|
||||||
|
next->marked = 0;
|
||||||
|
p = &next->next;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*p = next->next;
|
||||||
|
luaF_freeproto(next);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void collectclosure (void) {
|
||||||
|
Closure **p = &L->rootcl;
|
||||||
|
Closure *next;
|
||||||
|
while ((next = *p) != NULL) {
|
||||||
|
if (next->marked) {
|
||||||
|
next->marked = 0;
|
||||||
|
p = &next->next;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*p = next->next;
|
||||||
|
luaF_freeclosure(next);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void collecttable (void) {
|
||||||
|
Hash **p = &L->roottable;
|
||||||
|
Hash *next;
|
||||||
|
while ((next = *p) != NULL) {
|
||||||
|
if (next->marked) {
|
||||||
|
next->marked = 0;
|
||||||
|
p = &next->next;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*p = next->next;
|
||||||
|
luaH_free(next);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void clear_global_list (void) {
|
||||||
|
TaggedString **p = &L->rootglobal;
|
||||||
|
TaggedString *next;
|
||||||
|
while ((next = *p) != NULL) {
|
||||||
|
if (next->marked) p = &next->next;
|
||||||
|
else *p = next->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** collect all elements with `marked' < `limit'.
|
||||||
|
** with limit=1, that means all unmarked elements;
|
||||||
|
** with limit=MAX_INT, that means all elements (but EMPTY).
|
||||||
|
*/
|
||||||
|
static void collectstring (int limit) {
|
||||||
|
TObject o; /* to call userdata 'gc' tag method */
|
||||||
|
int i;
|
||||||
|
ttype(&o) = LUA_T_USERDATA;
|
||||||
|
clear_global_list();
|
||||||
|
for (i=0; i<NUM_HASHS; i++) {
|
||||||
|
stringtable *tb = &L->string_root[i];
|
||||||
|
int j;
|
||||||
|
for (j=0; j<tb->size; j++) {
|
||||||
|
TaggedString *t = tb->hash[j];
|
||||||
|
if (t == NULL) continue;
|
||||||
|
if (t->marked < limit) {
|
||||||
|
if (t->constindex == -1) { /* is userdata? */
|
||||||
|
tsvalue(&o) = t;
|
||||||
|
luaD_gcIM(&o);
|
||||||
|
}
|
||||||
|
luaS_free(t);
|
||||||
|
tb->hash[j] = &luaS_EMPTY;
|
||||||
|
}
|
||||||
|
else if (t->marked == 1)
|
||||||
|
t->marked = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef LUA_COMPAT_GC
|
||||||
|
static void tableTM (void) {
|
||||||
|
Hash *p;
|
||||||
|
TObject o;
|
||||||
|
ttype(&o) = LUA_T_ARRAY;
|
||||||
|
for (p = L->roottable; p; p = p->next) {
|
||||||
|
if (!p->marked) {
|
||||||
|
avalue(&o) = p;
|
||||||
|
luaD_gcIM(&o);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#define tableTM() /* do nothing */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void markall (void) {
|
static void markall (void) {
|
||||||
luaD_travstack(markobject); /* mark stack objects */
|
travstack(); /* mark stack objects */
|
||||||
globalmark(); /* mark global variable values and names */
|
globalmark(); /* mark global variable values and names */
|
||||||
travlock(); /* mark locked objects */
|
travlock(); /* mark locked objects */
|
||||||
luaT_travtagmethods(markobject); /* mark fallbacks */
|
luaT_travtagmethods(markobject); /* mark tag methods */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void luaC_collect (int all) {
|
||||||
|
L->GCthreshold *= 4; /* to avoid GC during GC */
|
||||||
|
tableTM(); /* call TM for tables (if LUA_COMPAT_GC) */
|
||||||
|
collecttable();
|
||||||
|
collectstring(all?MAX_INT:1);
|
||||||
|
collectproto();
|
||||||
|
collectclosure();
|
||||||
|
luaD_gcIM(&luaO_nilobject); /* GC tag method for nil (signal end of GC) */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
long lua_collectgarbage (long limit) {
|
long lua_collectgarbage (long limit) {
|
||||||
unsigned long recovered = L->nblocks; /* to subtract nblocks after gc */
|
unsigned long recovered = L->nblocks; /* to subtract nblocks after gc */
|
||||||
Hash *freetable;
|
|
||||||
TaggedString *freestr;
|
|
||||||
TProtoFunc *freefunc;
|
|
||||||
Closure *freeclos;
|
|
||||||
markall();
|
markall();
|
||||||
invalidaterefs();
|
luaR_invalidaterefs();
|
||||||
freestr = luaS_collector();
|
luaC_collect(0);
|
||||||
freetable = (Hash *)listcollect(&(L->roottable));
|
recovered = recovered - L->nblocks;
|
||||||
freefunc = (TProtoFunc *)listcollect(&(L->rootproto));
|
|
||||||
freeclos = (Closure *)listcollect(&(L->rootcl));
|
|
||||||
L->GCthreshold *= 4; /* to avoid GC during GC */
|
|
||||||
luaC_hashcallIM(freetable); /* GC tag methods for tables */
|
|
||||||
luaC_strcallIM(freestr); /* GC tag methods for userdata */
|
|
||||||
luaD_gcIM(&luaO_nilobject); /* GC tag method for nil (signal end of GC) */
|
|
||||||
luaH_free(freetable);
|
|
||||||
luaS_free(freestr);
|
|
||||||
luaF_freeproto(freefunc);
|
|
||||||
luaF_freeclosure(freeclos);
|
|
||||||
recovered = recovered-L->nblocks;
|
|
||||||
L->GCthreshold = (limit == 0) ? 2*L->nblocks : L->nblocks+limit;
|
L->GCthreshold = (limit == 0) ? 2*L->nblocks : L->nblocks+limit;
|
||||||
return recovered;
|
return recovered;
|
||||||
}
|
}
|
||||||
|
|||||||
7
lgc.h
7
lgc.h
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lgc.h,v 1.4 1997/12/01 20:31:25 roberto Exp roberto $
|
** $Id: lgc.h,v 1.5 1999/08/16 20:52:00 roberto Exp roberto $
|
||||||
** Garbage Collector
|
** Garbage Collector
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -12,10 +12,7 @@
|
|||||||
|
|
||||||
|
|
||||||
void luaC_checkGC (void);
|
void luaC_checkGC (void);
|
||||||
const TObject *luaC_getref (int ref);
|
void luaC_collect (int all);
|
||||||
int luaC_ref (const TObject *o, int lock);
|
|
||||||
void luaC_hashcallIM (Hash *l);
|
|
||||||
void luaC_strcallIM (TaggedString *l);
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
8
llex.c
8
llex.c
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: llex.c,v 1.38 1999/08/16 20:52:00 roberto Exp roberto $
|
** $Id: llex.c,v 1.39 1999/09/06 13:55:09 roberto Exp roberto $
|
||||||
** Lexical Analyzer
|
** Lexical Analyzer
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -37,7 +37,7 @@ void luaX_init (void) {
|
|||||||
int i;
|
int i;
|
||||||
for (i=0; i<(sizeof(reserved)/sizeof(reserved[0])); i++) {
|
for (i=0; i<(sizeof(reserved)/sizeof(reserved[0])); i++) {
|
||||||
TaggedString *ts = luaS_new(reserved[i]);
|
TaggedString *ts = luaS_new(reserved[i]);
|
||||||
ts->head.marked = FIRST_RESERVED+i; /* reserved word (always > 255) */
|
ts->marked = FIRST_RESERVED+i; /* reserved word (always > 255) */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -426,8 +426,8 @@ int luaX_lex (LexState *LS) {
|
|||||||
} while (isalnum(LS->current) || LS->current == '_');
|
} while (isalnum(LS->current) || LS->current == '_');
|
||||||
save('\0');
|
save('\0');
|
||||||
ts = luaS_new(L->Mbuffer+L->Mbuffbase);
|
ts = luaS_new(L->Mbuffer+L->Mbuffbase);
|
||||||
if (ts->head.marked >= FIRST_RESERVED)
|
if (ts->marked >= FIRST_RESERVED)
|
||||||
return ts->head.marked; /* reserved word */
|
return ts->marked; /* reserved word */
|
||||||
LS->seminfo.ts = ts;
|
LS->seminfo.ts = ts;
|
||||||
return NAME;
|
return NAME;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lobject.c,v 1.22 1999/09/06 20:19:22 roberto Exp roberto $
|
** $Id: lobject.c,v 1.23 1999/09/08 20:45:18 roberto Exp roberto $
|
||||||
** Some generic functions over Lua objects
|
** Some generic functions over Lua objects
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -55,13 +55,6 @@ int luaO_equalval (const TObject *t1, const TObject *t2) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void luaO_insertlist (GCnode *root, GCnode *node) {
|
|
||||||
node->next = root->next;
|
|
||||||
root->next = node;
|
|
||||||
node->marked = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef OLD_ANSI
|
#ifdef OLD_ANSI
|
||||||
void luaO_memup (void *dest, void *src, int size) {
|
void luaO_memup (void *dest, void *src, int size) {
|
||||||
while (size--)
|
while (size--)
|
||||||
|
|||||||
24
lobject.h
24
lobject.h
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lobject.h,v 1.29 1999/08/16 20:52:00 roberto Exp roberto $
|
** $Id: lobject.h,v 1.30 1999/09/06 20:34:18 roberto Exp roberto $
|
||||||
** Type definitions for Lua objects
|
** Type definitions for Lua objects
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -85,21 +85,13 @@ typedef struct TObject {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** generic header for garbage collector lists
|
|
||||||
*/
|
|
||||||
typedef struct GCnode {
|
|
||||||
struct GCnode *next;
|
|
||||||
int marked;
|
|
||||||
} GCnode;
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** String headers for string table
|
** String headers for string table
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct TaggedString {
|
typedef struct TaggedString {
|
||||||
GCnode head;
|
struct TaggedString *next;
|
||||||
|
int marked;
|
||||||
unsigned long hash;
|
unsigned long hash;
|
||||||
int constindex; /* hint to reuse constants (= -1 if this is a userdata) */
|
int constindex; /* hint to reuse constants (= -1 if this is a userdata) */
|
||||||
union {
|
union {
|
||||||
@@ -122,7 +114,8 @@ typedef struct TaggedString {
|
|||||||
** Function Prototypes
|
** Function Prototypes
|
||||||
*/
|
*/
|
||||||
typedef struct TProtoFunc {
|
typedef struct TProtoFunc {
|
||||||
GCnode head;
|
struct TProtoFunc *next;
|
||||||
|
int marked;
|
||||||
struct TObject *consts;
|
struct TObject *consts;
|
||||||
int nconsts;
|
int nconsts;
|
||||||
Byte *code; /* ends with opcode ENDCODE */
|
Byte *code; /* ends with opcode ENDCODE */
|
||||||
@@ -157,7 +150,8 @@ typedef struct LocVar {
|
|||||||
** Closures
|
** Closures
|
||||||
*/
|
*/
|
||||||
typedef struct Closure {
|
typedef struct Closure {
|
||||||
GCnode head;
|
struct Closure *next;
|
||||||
|
int marked;
|
||||||
int nelems; /* not included the first one (always the prototype) */
|
int nelems; /* not included the first one (always the prototype) */
|
||||||
TObject consts[1]; /* at least one for prototype */
|
TObject consts[1]; /* at least one for prototype */
|
||||||
} Closure;
|
} Closure;
|
||||||
@@ -170,7 +164,8 @@ typedef struct node {
|
|||||||
} Node;
|
} Node;
|
||||||
|
|
||||||
typedef struct Hash {
|
typedef struct Hash {
|
||||||
GCnode head;
|
struct Hash *next;
|
||||||
|
int marked;
|
||||||
Node *node;
|
Node *node;
|
||||||
int nhash;
|
int nhash;
|
||||||
int nuse;
|
int nuse;
|
||||||
@@ -189,7 +184,6 @@ extern const TObject luaO_nilobject;
|
|||||||
: luaO_equalval(t1,t2))
|
: luaO_equalval(t1,t2))
|
||||||
int luaO_equalval (const TObject *t1, const TObject *t2);
|
int luaO_equalval (const TObject *t1, const TObject *t2);
|
||||||
int luaO_redimension (int oldsize);
|
int luaO_redimension (int oldsize);
|
||||||
void luaO_insertlist (GCnode *root, GCnode *node);
|
|
||||||
int luaO_str2d (const char *s, real *result);
|
int luaO_str2d (const char *s, real *result);
|
||||||
|
|
||||||
#ifdef OLD_ANSI
|
#ifdef OLD_ANSI
|
||||||
|
|||||||
27
lstate.c
27
lstate.c
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lstate.c,v 1.12 1999/05/11 20:08:20 roberto Exp roberto $
|
** $Id: lstate.c,v 1.13 1999/08/16 20:52:00 roberto Exp roberto $
|
||||||
** Global State
|
** Global State
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -7,13 +7,11 @@
|
|||||||
|
|
||||||
#include "lbuiltin.h"
|
#include "lbuiltin.h"
|
||||||
#include "ldo.h"
|
#include "ldo.h"
|
||||||
#include "lfunc.h"
|
|
||||||
#include "lgc.h"
|
#include "lgc.h"
|
||||||
#include "llex.h"
|
#include "llex.h"
|
||||||
#include "lmem.h"
|
#include "lmem.h"
|
||||||
#include "lstate.h"
|
#include "lstate.h"
|
||||||
#include "lstring.h"
|
#include "lstring.h"
|
||||||
#include "ltable.h"
|
|
||||||
#include "ltm.h"
|
#include "ltm.h"
|
||||||
|
|
||||||
|
|
||||||
@@ -36,14 +34,10 @@ void lua_open (void) {
|
|||||||
L->debug = 0;
|
L->debug = 0;
|
||||||
L->callhook = NULL;
|
L->callhook = NULL;
|
||||||
L->linehook = NULL;
|
L->linehook = NULL;
|
||||||
L->rootproto.next = NULL;
|
L->rootproto = NULL;
|
||||||
L->rootproto.marked = 0;
|
L->rootcl = NULL;
|
||||||
L->rootcl.next = NULL;
|
L->rootglobal = NULL;
|
||||||
L->rootcl.marked = 0;
|
L->roottable = NULL;
|
||||||
L->rootglobal.next = NULL;
|
|
||||||
L->rootglobal.marked = 0;
|
|
||||||
L->roottable.next = NULL;
|
|
||||||
L->roottable.marked = 0;
|
|
||||||
L->IMtable = NULL;
|
L->IMtable = NULL;
|
||||||
L->refArray = NULL;
|
L->refArray = NULL;
|
||||||
L->refSize = 0;
|
L->refSize = 0;
|
||||||
@@ -58,21 +52,14 @@ void lua_open (void) {
|
|||||||
|
|
||||||
|
|
||||||
void lua_close (void) {
|
void lua_close (void) {
|
||||||
TaggedString *alludata = luaS_collectudata();
|
luaC_collect(1); /* collect all elements */
|
||||||
L->GCthreshold = MAX_INT; /* to avoid GC during GC */
|
|
||||||
luaC_hashcallIM((Hash *)L->roottable.next); /* GC t.methods for tables */
|
|
||||||
luaC_strcallIM(alludata); /* GC tag methods for userdata */
|
|
||||||
luaD_gcIM(&luaO_nilobject); /* GC tag method for nil (signal end of GC) */
|
|
||||||
luaH_free((Hash *)L->roottable.next);
|
|
||||||
luaF_freeproto((TProtoFunc *)L->rootproto.next);
|
|
||||||
luaF_freeclosure((Closure *)L->rootcl.next);
|
|
||||||
luaS_free(alludata);
|
|
||||||
luaS_freeall();
|
luaS_freeall();
|
||||||
luaM_free(L->stack.stack);
|
luaM_free(L->stack.stack);
|
||||||
luaM_free(L->IMtable);
|
luaM_free(L->IMtable);
|
||||||
luaM_free(L->refArray);
|
luaM_free(L->refArray);
|
||||||
luaM_free(L->Mbuffer);
|
luaM_free(L->Mbuffer);
|
||||||
luaM_free(L->Cblocks);
|
luaM_free(L->Cblocks);
|
||||||
|
LUA_ASSERT(L->nblocks == 0, "wrong count for nblocks");
|
||||||
luaM_free(L);
|
luaM_free(L);
|
||||||
L = NULL;
|
L = NULL;
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
|||||||
10
lstate.h
10
lstate.h
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lstate.h,v 1.18 1999/05/11 14:19:32 roberto Exp roberto $
|
** $Id: lstate.h,v 1.19 1999/05/11 20:08:20 roberto Exp roberto $
|
||||||
** Global State
|
** Global State
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -73,10 +73,10 @@ struct lua_State {
|
|||||||
lua_CHFunction callhook;
|
lua_CHFunction callhook;
|
||||||
lua_LHFunction linehook;
|
lua_LHFunction linehook;
|
||||||
/* global state */
|
/* global state */
|
||||||
GCnode rootproto; /* list of all prototypes */
|
TProtoFunc *rootproto; /* list of all prototypes */
|
||||||
GCnode rootcl; /* list of all closures */
|
Closure *rootcl; /* list of all closures */
|
||||||
GCnode roottable; /* list of all tables */
|
Hash *roottable; /* list of all tables */
|
||||||
GCnode rootglobal; /* list of strings with global values */
|
TaggedString *rootglobal; /* list of strings with global values */
|
||||||
stringtable *string_root; /* array of hash tables for strings and udata */
|
stringtable *string_root; /* array of hash tables for strings and udata */
|
||||||
struct IM *IMtable; /* table for tag methods */
|
struct IM *IMtable; /* table for tag methods */
|
||||||
int last_tag; /* last used tag in IMtable */
|
int last_tag; /* last used tag in IMtable */
|
||||||
|
|||||||
142
lstring.c
142
lstring.c
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lstring.c,v 1.20 1999/08/16 20:52:00 roberto Exp roberto $
|
** $Id: lstring.c,v 1.21 1999/09/28 12:27:06 roberto Exp roberto $
|
||||||
** String table (keeps all strings handled by Lua)
|
** String table (keeps all strings handled by Lua)
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -14,17 +14,13 @@
|
|||||||
#include "lua.h"
|
#include "lua.h"
|
||||||
|
|
||||||
|
|
||||||
#define NUM_HASHSTR 31
|
|
||||||
#define NUM_HASHUDATA 31
|
|
||||||
#define NUM_HASHS (NUM_HASHSTR+NUM_HASHUDATA)
|
|
||||||
|
|
||||||
|
|
||||||
#define gcsizestring(l) (1+(l/64)) /* "weight" for a string with length 'l' */
|
#define gcsizestring(l) (1+(l/64)) /* "weight" for a string with length 'l' */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static TaggedString EMPTY = {{NULL, 2}, 0L, 0,
|
TaggedString luaS_EMPTY = {NULL, MAX_INT, 0L, 0,
|
||||||
{{{LUA_T_NIL, {NULL}}, 0L}}, {0}};
|
{{{LUA_T_NIL, {NULL}}, 0L}}, {0}};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -49,6 +45,16 @@ void luaS_init (void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void luaS_freeall (void) {
|
||||||
|
int i;
|
||||||
|
for (i=0; i<NUM_HASHS; i++) {
|
||||||
|
if (L->string_root[i].hash != init_hash)
|
||||||
|
luaM_free(L->string_root[i].hash);
|
||||||
|
}
|
||||||
|
luaM_free(L->string_root);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static unsigned long hash_s (const char *s, long l) {
|
static unsigned long hash_s (const char *s, long l) {
|
||||||
unsigned long h = 0; /* seed */
|
unsigned long h = 0; /* seed */
|
||||||
while (l--)
|
while (l--)
|
||||||
@@ -57,12 +63,12 @@ static unsigned long hash_s (const char *s, long l) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int newsize (stringtable *tb) {
|
static int newsize (const stringtable *tb) {
|
||||||
int realuse = 0;
|
int realuse = 0;
|
||||||
int i;
|
int i;
|
||||||
/* count how many entries are really in use */
|
/* count how many entries are really in use */
|
||||||
for (i=0; i<tb->size; i++) {
|
for (i=0; i<tb->size; i++) {
|
||||||
if (tb->hash[i] != NULL && tb->hash[i] != &EMPTY)
|
if (tb->hash[i] != NULL && tb->hash[i] != &luaS_EMPTY)
|
||||||
realuse++;
|
realuse++;
|
||||||
}
|
}
|
||||||
return luaO_redimension(realuse*2);
|
return luaO_redimension(realuse*2);
|
||||||
@@ -78,7 +84,7 @@ static void grow (stringtable *tb) {
|
|||||||
/* rehash */
|
/* rehash */
|
||||||
tb->nuse = 0;
|
tb->nuse = 0;
|
||||||
for (i=0; i<tb->size; i++) {
|
for (i=0; i<tb->size; i++) {
|
||||||
if (tb->hash[i] != NULL && tb->hash[i] != &EMPTY) {
|
if (tb->hash[i] != NULL && tb->hash[i] != &luaS_EMPTY) {
|
||||||
unsigned long h = tb->hash[i]->hash;
|
unsigned long h = tb->hash[i]->hash;
|
||||||
int h1 = h%ns;
|
int h1 = h%ns;
|
||||||
while (newhash[h1]) {
|
while (newhash[h1]) {
|
||||||
@@ -103,8 +109,8 @@ static TaggedString *newone_s (const char *str, long l, unsigned long h) {
|
|||||||
ts->u.s.len = l;
|
ts->u.s.len = l;
|
||||||
ts->constindex = 0;
|
ts->constindex = 0;
|
||||||
L->nblocks += gcsizestring(l);
|
L->nblocks += gcsizestring(l);
|
||||||
ts->head.marked = 0;
|
ts->marked = 0;
|
||||||
ts->head.next = (GCnode *)ts; /* signal it is in no list */
|
ts->next = ts; /* signal it is in no list */
|
||||||
ts->hash = h;
|
ts->hash = h;
|
||||||
return ts;
|
return ts;
|
||||||
}
|
}
|
||||||
@@ -115,8 +121,8 @@ static TaggedString *newone_u (void *buff, int tag, unsigned long h) {
|
|||||||
ts->u.d.tag = (tag == LUA_ANYTAG) ? 0 : tag;
|
ts->u.d.tag = (tag == LUA_ANYTAG) ? 0 : tag;
|
||||||
ts->constindex = -1; /* tag -> this is a userdata */
|
ts->constindex = -1; /* tag -> this is a userdata */
|
||||||
L->nblocks++;
|
L->nblocks++;
|
||||||
ts->head.marked = 0;
|
ts->marked = 0;
|
||||||
ts->head.next = (GCnode *)ts; /* signal it is in no list */
|
ts->next = ts; /* signal it is in no list */
|
||||||
ts->hash = h;
|
ts->hash = h;
|
||||||
return ts;
|
return ts;
|
||||||
}
|
}
|
||||||
@@ -144,7 +150,7 @@ static TaggedString *insert_s (const char *str, long l, stringtable *tb) {
|
|||||||
int j = -1; /* last empty place found (or -1) */
|
int j = -1; /* last empty place found (or -1) */
|
||||||
int h1 = h%size;
|
int h1 = h%size;
|
||||||
while ((ts = tb->hash[h1]) != NULL) {
|
while ((ts = tb->hash[h1]) != NULL) {
|
||||||
if (ts == &EMPTY)
|
if (ts == &luaS_EMPTY)
|
||||||
j = h1;
|
j = h1;
|
||||||
else if (ts->u.s.len == l && (memcmp(str, ts->str, l) == 0))
|
else if (ts->u.s.len == l && (memcmp(str, ts->str, l) == 0))
|
||||||
return ts;
|
return ts;
|
||||||
@@ -168,7 +174,7 @@ static TaggedString *insert_u (void *buff, int tag, stringtable *tb) {
|
|||||||
int j = -1;
|
int j = -1;
|
||||||
int h1 = h%size;
|
int h1 = h%size;
|
||||||
while ((ts = tb->hash[h1]) != NULL) {
|
while ((ts = tb->hash[h1]) != NULL) {
|
||||||
if (ts == &EMPTY)
|
if (ts == &luaS_EMPTY)
|
||||||
j = h1;
|
j = h1;
|
||||||
else if ((tag == ts->u.d.tag || tag == LUA_ANYTAG) && buff == ts->u.d.v)
|
else if ((tag == ts->u.d.tag || tag == LUA_ANYTAG) && buff == ts->u.d.v)
|
||||||
return ts;
|
return ts;
|
||||||
@@ -200,115 +206,29 @@ TaggedString *luaS_new (const char *str) {
|
|||||||
|
|
||||||
TaggedString *luaS_newfixedstring (const char *str) {
|
TaggedString *luaS_newfixedstring (const char *str) {
|
||||||
TaggedString *ts = luaS_new(str);
|
TaggedString *ts = luaS_new(str);
|
||||||
if (ts->head.marked == 0)
|
if (ts->marked == 0) ts->marked = 2; /* avoid GC */
|
||||||
ts->head.marked = 2; /* avoid GC */
|
|
||||||
return ts;
|
return ts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void luaS_free (TaggedString *l) {
|
void luaS_free (TaggedString *t) {
|
||||||
while (l) {
|
L->nblocks -= (t->constindex == -1) ? 1 : gcsizestring(t->u.s.len);
|
||||||
TaggedString *next = (TaggedString *)l->head.next;
|
luaM_free(t);
|
||||||
L->nblocks -= (l->constindex == -1) ? 1 : gcsizestring(l->u.s.len);
|
|
||||||
luaM_free(l);
|
|
||||||
l = next;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
void luaS_rawsetglobal (TaggedString *ts, const TObject *newval) {
|
||||||
** Garbage collection functions.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void remove_from_list (GCnode *l) {
|
|
||||||
while (l) {
|
|
||||||
GCnode *next = l->next;
|
|
||||||
while (next && !next->marked)
|
|
||||||
next = l->next = next->next;
|
|
||||||
l = next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
TaggedString *luaS_collector (void) {
|
|
||||||
TaggedString *frees = NULL;
|
|
||||||
int i;
|
|
||||||
remove_from_list(&(L->rootglobal));
|
|
||||||
for (i=0; i<NUM_HASHS; i++) {
|
|
||||||
stringtable *tb = &L->string_root[i];
|
|
||||||
int j;
|
|
||||||
for (j=0; j<tb->size; j++) {
|
|
||||||
TaggedString *t = tb->hash[j];
|
|
||||||
if (t == NULL) continue;
|
|
||||||
if (t->head.marked == 1)
|
|
||||||
t->head.marked = 0;
|
|
||||||
else if (!t->head.marked) {
|
|
||||||
t->head.next = (GCnode *)frees;
|
|
||||||
frees = t;
|
|
||||||
tb->hash[j] = &EMPTY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return frees;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
TaggedString *luaS_collectudata (void) {
|
|
||||||
TaggedString *frees = NULL;
|
|
||||||
int i;
|
|
||||||
L->rootglobal.next = NULL; /* empty list of globals */
|
|
||||||
for (i=NUM_HASHSTR; i<NUM_HASHS; i++) {
|
|
||||||
stringtable *tb = &L->string_root[i];
|
|
||||||
int j;
|
|
||||||
for (j=0; j<tb->size; j++) {
|
|
||||||
TaggedString *t = tb->hash[j];
|
|
||||||
if (t == NULL || t == &EMPTY)
|
|
||||||
continue;
|
|
||||||
LUA_ASSERT(t->constindex == -1, "must be userdata");
|
|
||||||
t->head.next = (GCnode *)frees;
|
|
||||||
frees = t;
|
|
||||||
tb->hash[j] = &EMPTY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return frees;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void luaS_freeall (void) {
|
|
||||||
int i;
|
|
||||||
for (i=0; i<NUM_HASHS; i++) {
|
|
||||||
stringtable *tb = &L->string_root[i];
|
|
||||||
int j;
|
|
||||||
for (j=0; j<tb->size; j++) {
|
|
||||||
TaggedString *t = tb->hash[j];
|
|
||||||
if (t != &EMPTY) luaM_free(t);
|
|
||||||
}
|
|
||||||
if (tb->hash != init_hash) luaM_free(tb->hash);
|
|
||||||
}
|
|
||||||
luaM_free(L->string_root);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void luaS_rawsetglobal (TaggedString *ts, TObject *newval) {
|
|
||||||
ts->u.s.globalval = *newval;
|
ts->u.s.globalval = *newval;
|
||||||
if (ts->head.next == (GCnode *)ts) { /* is not in list? */
|
if (ts->next == ts) { /* is not in list? */
|
||||||
ts->head.next = L->rootglobal.next;
|
ts->next = L->rootglobal;
|
||||||
L->rootglobal.next = (GCnode *)ts;
|
L->rootglobal = ts;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const char *luaS_travsymbol (int (*fn)(TObject *)) {
|
|
||||||
TaggedString *g;
|
|
||||||
for (g=(TaggedString *)L->rootglobal.next; g; g=(TaggedString *)g->head.next)
|
|
||||||
if (fn(&g->u.s.globalval))
|
|
||||||
return g->str;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int luaS_globaldefined (const char *name) {
|
int luaS_globaldefined (const char *name) {
|
||||||
TaggedString *ts = luaS_new(name);
|
TaggedString *ts = luaS_new(name);
|
||||||
return ts->u.s.globalval.ttype != LUA_T_NIL;
|
return ts->u.s.globalval.ttype != LUA_T_NIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
18
lstring.h
18
lstring.h
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lstring.h,v 1.7 1998/03/06 16:54:42 roberto Exp roberto $
|
** $Id: lstring.h,v 1.8 1999/08/16 20:52:00 roberto Exp roberto $
|
||||||
** String table (keep all strings handled by Lua)
|
** String table (keep all strings handled by Lua)
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -11,18 +11,22 @@
|
|||||||
#include "lobject.h"
|
#include "lobject.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define NUM_HASHSTR 31
|
||||||
|
#define NUM_HASHUDATA 31
|
||||||
|
#define NUM_HASHS (NUM_HASHSTR+NUM_HASHUDATA)
|
||||||
|
|
||||||
|
|
||||||
|
extern TaggedString luaS_EMPTY;
|
||||||
|
|
||||||
void luaS_init (void);
|
void luaS_init (void);
|
||||||
TaggedString *luaS_createudata (void *udata, int tag);
|
TaggedString *luaS_createudata (void *udata, int tag);
|
||||||
TaggedString *luaS_collector (void);
|
void luaS_freeall (void);
|
||||||
void luaS_free (TaggedString *l);
|
void luaS_free (TaggedString *ts);
|
||||||
TaggedString *luaS_newlstr (const char *str, long l);
|
TaggedString *luaS_newlstr (const char *str, long l);
|
||||||
TaggedString *luaS_new (const char *str);
|
TaggedString *luaS_new (const char *str);
|
||||||
TaggedString *luaS_newfixedstring (const char *str);
|
TaggedString *luaS_newfixedstring (const char *str);
|
||||||
void luaS_rawsetglobal (TaggedString *ts, TObject *newval);
|
void luaS_rawsetglobal (TaggedString *ts, const TObject *newval);
|
||||||
const char *luaS_travsymbol (int (*fn)(TObject *));
|
|
||||||
int luaS_globaldefined (const char *name);
|
int luaS_globaldefined (const char *name);
|
||||||
TaggedString *luaS_collectudata (void);
|
|
||||||
void luaS_freeall (void);
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
25
ltable.c
25
ltable.c
@@ -1,10 +1,9 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: ltable.c,v 1.23 1999/08/16 20:52:00 roberto Exp roberto $
|
** $Id: ltable.c,v 1.24 1999/09/22 14:38:45 roberto Exp roberto $
|
||||||
** Lua tables (hash)
|
** Lua tables (hash)
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#include "lauxlib.h"
|
#include "lauxlib.h"
|
||||||
#include "lmem.h"
|
#include "lmem.h"
|
||||||
@@ -69,17 +68,6 @@ Node *luaH_present (const Hash *t, const TObject *key) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void luaH_free (Hash *frees) {
|
|
||||||
while (frees) {
|
|
||||||
Hash *next = (Hash *)frees->head.next;
|
|
||||||
L->nblocks -= gcsize(frees->nhash);
|
|
||||||
luaM_free(nodevector(frees));
|
|
||||||
luaM_free(frees);
|
|
||||||
frees = next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static Node *hashnodecreate (int nhash) {
|
static Node *hashnodecreate (int nhash) {
|
||||||
Node *const v = luaM_newvector(nhash, Node);
|
Node *const v = luaM_newvector(nhash, Node);
|
||||||
int i;
|
int i;
|
||||||
@@ -96,12 +84,21 @@ Hash *luaH_new (int nhash) {
|
|||||||
nhash(t) = nhash;
|
nhash(t) = nhash;
|
||||||
nuse(t) = 0;
|
nuse(t) = 0;
|
||||||
t->htag = TagDefault;
|
t->htag = TagDefault;
|
||||||
luaO_insertlist(&(L->roottable), (GCnode *)t);
|
t->next = L->roottable;
|
||||||
|
L->roottable = t;
|
||||||
|
t->marked = 0;
|
||||||
L->nblocks += gcsize(nhash);
|
L->nblocks += gcsize(nhash);
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void luaH_free (Hash *t) {
|
||||||
|
L->nblocks -= gcsize(t->nhash);
|
||||||
|
luaM_free(nodevector(t));
|
||||||
|
luaM_free(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int newsize (Hash *t) {
|
static int newsize (Hash *t) {
|
||||||
Node *const v = t->node;
|
Node *const v = t->node;
|
||||||
const int size = nhash(t);
|
const int size = nhash(t);
|
||||||
|
|||||||
4
ltable.h
4
ltable.h
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: ltable.h,v 1.11 1999/02/23 14:57:28 roberto Exp roberto $
|
** $Id: ltable.h,v 1.12 1999/08/16 20:52:00 roberto Exp roberto $
|
||||||
** Lua tables (hash)
|
** Lua tables (hash)
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
#define luaH_move(t,from,to) (luaH_setint(t, to, luaH_getint(t, from)))
|
#define luaH_move(t,from,to) (luaH_setint(t, to, luaH_getint(t, from)))
|
||||||
|
|
||||||
Hash *luaH_new (int nhash);
|
Hash *luaH_new (int nhash);
|
||||||
void luaH_free (Hash *frees);
|
void luaH_free (Hash *t);
|
||||||
Node *luaH_present (const Hash *t, const TObject *key);
|
Node *luaH_present (const Hash *t, const TObject *key);
|
||||||
void luaH_set (Hash *t, const TObject *ref, const TObject *val);
|
void luaH_set (Hash *t, const TObject *ref, const TObject *val);
|
||||||
int luaH_pos (const Hash *t, const TObject *r);
|
int luaH_pos (const Hash *t, const TObject *r);
|
||||||
|
|||||||
8
ltm.c
8
ltm.c
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: ltm.c,v 1.26 1999/08/16 20:52:00 roberto Exp roberto $
|
** $Id: ltm.c,v 1.27 1999/09/20 14:57:29 roberto Exp roberto $
|
||||||
** Tag methods
|
** Tag methods
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -39,13 +39,17 @@ static const char luaT_validevents[NUM_TAGS][IM_N] = {
|
|||||||
{1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1}, /* LUA_T_USERDATA */
|
{1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1}, /* LUA_T_USERDATA */
|
||||||
{1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1}, /* LUA_T_NUMBER */
|
{1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1}, /* LUA_T_NUMBER */
|
||||||
{1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, /* LUA_T_STRING */
|
{1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, /* LUA_T_STRING */
|
||||||
{0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, /* LUA_T_ARRAY */
|
{0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1}, /* LUA_T_ARRAY */
|
||||||
{1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, /* LUA_T_PROTO */
|
{1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, /* LUA_T_PROTO */
|
||||||
{1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, /* LUA_T_CPROTO */
|
{1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, /* LUA_T_CPROTO */
|
||||||
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1} /* LUA_T_NIL */
|
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1} /* LUA_T_NIL */
|
||||||
};
|
};
|
||||||
|
|
||||||
int luaT_validevent (int t, int e) { /* ORDER LUA_T */
|
int luaT_validevent (int t, int e) { /* ORDER LUA_T */
|
||||||
|
#ifdef LUA_COMPAT_GC
|
||||||
|
if (t == LUA_T_ARRAY && e == IM_GC)
|
||||||
|
return 1; /* old versions allowed gc tag method for tables */
|
||||||
|
#endif
|
||||||
return (t < LUA_T_NIL) ? 1 : luaT_validevents[-t][e];
|
return (t < LUA_T_NIL) ? 1 : luaT_validevents[-t][e];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
31
makefile
31
makefile
@@ -1,5 +1,5 @@
|
|||||||
#
|
#
|
||||||
## $Id: makefile,v 1.19 1999/02/24 21:31:03 roberto Exp roberto $
|
## $Id: makefile,v 1.20 1999/08/17 20:21:52 roberto Exp roberto $
|
||||||
## Makefile
|
## Makefile
|
||||||
## See Copyright Notice in lua.h
|
## See Copyright Notice in lua.h
|
||||||
#
|
#
|
||||||
@@ -15,20 +15,19 @@
|
|||||||
# facilities (e.g. strerror, locale.h, memmove). SunOS does not comply;
|
# facilities (e.g. strerror, locale.h, memmove). SunOS does not comply;
|
||||||
# so, add "-DOLD_ANSI" on SunOS
|
# so, add "-DOLD_ANSI" on SunOS
|
||||||
#
|
#
|
||||||
# define LUA_COMPAT2_5 if yous system does need to be compatible with
|
|
||||||
# version 2.5 (or older)
|
|
||||||
#
|
|
||||||
# define LUA_NUM_TYPE if you need numbers to be different from double
|
# define LUA_NUM_TYPE if you need numbers to be different from double
|
||||||
# (for instance, -DLUA_NUM_TYPE=float)
|
# (for instance, -DLUA_NUM_TYPE=float)
|
||||||
#
|
#
|
||||||
|
# define LUA_COMPAT_GC if you need garbage-collect tag methods for tables
|
||||||
|
# (only for compatibility with previous versions)
|
||||||
|
|
||||||
CONFIG = -DPOPEN -D_POSIX_SOURCE
|
CONFIG = -DPOPEN -D_POSIX_SOURCE
|
||||||
#CONFIG = -DLUA_COMPAT2_5 -DOLD_ANSI -DDEBUG
|
#CONFIG = -DOLD_ANSI -DDEBUG -DLUA_COMPAT_GC
|
||||||
|
|
||||||
|
|
||||||
# Compilation parameters
|
# Compilation parameters
|
||||||
CC = gcc
|
CC = gcc
|
||||||
CWARNS = -Wall -Wmissing-prototypes -Wshadow -pedantic -Wpointer-arith -Wcast-align -Waggregate-return -Wwrite-strings -Wcast-qual -Wstrict-prototypes -Wmissing-declarations -Wnested-externs
|
CWARNS = -Wall -Wmissing-prototypes -Wshadow -pedantic -Wpointer-arith -Wcast-align -Waggregate-return -Wwrite-strings -Wcast-qual -Wstrict-prototypes -Wmissing-declarations -Wnested-externs -Werror
|
||||||
CFLAGS = $(CONFIG) $(CWARNS) -ansi -O2
|
CFLAGS = $(CONFIG) $(CWARNS) -ansi -O2
|
||||||
|
|
||||||
|
|
||||||
@@ -53,6 +52,7 @@ LUAOBJS = \
|
|||||||
lmem.o \
|
lmem.o \
|
||||||
lobject.o \
|
lobject.o \
|
||||||
lparser.o \
|
lparser.o \
|
||||||
|
lref.o \
|
||||||
lstate.o \
|
lstate.o \
|
||||||
lstring.o \
|
lstring.o \
|
||||||
ltable.o \
|
ltable.o \
|
||||||
@@ -99,7 +99,7 @@ clear :
|
|||||||
|
|
||||||
|
|
||||||
lapi.o: lapi.c lapi.h lua.h lobject.h lauxlib.h ldo.h lstate.h \
|
lapi.o: lapi.c lapi.h lua.h lobject.h lauxlib.h ldo.h lstate.h \
|
||||||
luadebug.h lfunc.h lgc.h lmem.h lstring.h ltable.h ltm.h lvm.h
|
luadebug.h lfunc.h lgc.h lmem.h lref.h lstring.h ltable.h ltm.h lvm.h
|
||||||
lauxlib.o: lauxlib.c lauxlib.h lua.h luadebug.h
|
lauxlib.o: lauxlib.c lauxlib.h lua.h luadebug.h
|
||||||
lbuffer.o: lbuffer.c lauxlib.h lua.h lmem.h lstate.h lobject.h \
|
lbuffer.o: lbuffer.c lauxlib.h lua.h lmem.h lstate.h lobject.h \
|
||||||
luadebug.h
|
luadebug.h
|
||||||
@@ -107,11 +107,11 @@ lbuiltin.o: lbuiltin.c lapi.h lua.h lobject.h lauxlib.h lbuiltin.h \
|
|||||||
ldo.h lstate.h luadebug.h lfunc.h lmem.h lstring.h ltable.h ltm.h \
|
ldo.h lstate.h luadebug.h lfunc.h lmem.h lstring.h ltable.h ltm.h \
|
||||||
lundump.h lzio.h lvm.h
|
lundump.h lzio.h lvm.h
|
||||||
ldblib.o: ldblib.c lauxlib.h lua.h luadebug.h lualib.h
|
ldblib.o: ldblib.c lauxlib.h lua.h luadebug.h lualib.h
|
||||||
ldo.o: ldo.c ldo.h lobject.h lua.h lstate.h luadebug.h lfunc.h lgc.h \
|
ldo.o: ldo.c lauxlib.h lua.h ldo.h lobject.h lstate.h luadebug.h lgc.h \
|
||||||
lmem.h lparser.h lzio.h lstring.h ltm.h lundump.h lvm.h
|
lmem.h lparser.h lzio.h lstring.h ltm.h lundump.h lvm.h
|
||||||
lfunc.o: lfunc.c lfunc.h lobject.h lua.h lmem.h lstate.h luadebug.h
|
lfunc.o: lfunc.c lfunc.h lobject.h lua.h lmem.h lstate.h luadebug.h
|
||||||
lgc.o: lgc.c ldo.h lobject.h lua.h lstate.h luadebug.h lfunc.h lgc.h \
|
lgc.o: lgc.c ldo.h lobject.h lua.h lstate.h luadebug.h lfunc.h lgc.h \
|
||||||
lmem.h lstring.h ltable.h ltm.h
|
lref.h lstring.h ltable.h ltm.h
|
||||||
linit.o: linit.c lua.h lualib.h
|
linit.o: linit.c lua.h lualib.h
|
||||||
liolib.o: liolib.c lauxlib.h lua.h luadebug.h lualib.h
|
liolib.o: liolib.c lauxlib.h lua.h luadebug.h lualib.h
|
||||||
llex.o: llex.c lauxlib.h lua.h llex.h lobject.h lzio.h lmem.h \
|
llex.o: llex.c lauxlib.h lua.h llex.h lobject.h lzio.h lmem.h \
|
||||||
@@ -119,12 +119,11 @@ llex.o: llex.c lauxlib.h lua.h llex.h lobject.h lzio.h lmem.h \
|
|||||||
lmathlib.o: lmathlib.c lauxlib.h lua.h lualib.h
|
lmathlib.o: lmathlib.c lauxlib.h lua.h lualib.h
|
||||||
lmem.o: lmem.c lmem.h lstate.h lobject.h lua.h luadebug.h
|
lmem.o: lmem.c lmem.h lstate.h lobject.h lua.h luadebug.h
|
||||||
lobject.o: lobject.c lobject.h lua.h
|
lobject.o: lobject.c lobject.h lua.h
|
||||||
lparser.o: lparser.c lauxlib.h lua.h ldo.h lobject.h lstate.h \
|
lparser.o: lparser.c ldo.h lobject.h lua.h lstate.h luadebug.h lfunc.h \
|
||||||
luadebug.h lfunc.h llex.h lzio.h lmem.h lopcodes.h lparser.h \
|
llex.h lzio.h lmem.h lopcodes.h lparser.h lstring.h
|
||||||
lstring.h
|
lref.o: lref.c lmem.h lref.h lobject.h lua.h lstate.h luadebug.h
|
||||||
lstate.o: lstate.c lbuiltin.h ldo.h lobject.h lua.h lstate.h \
|
lstate.o: lstate.c lbuiltin.h ldo.h lobject.h lua.h lstate.h \
|
||||||
luadebug.h lfunc.h lgc.h llex.h lzio.h lmem.h lstring.h ltable.h \
|
luadebug.h lgc.h llex.h lzio.h lmem.h lstring.h ltm.h
|
||||||
ltm.h
|
|
||||||
lstring.o: lstring.c lmem.h lobject.h lua.h lstate.h luadebug.h \
|
lstring.o: lstring.c lmem.h lobject.h lua.h lstate.h luadebug.h \
|
||||||
lstring.h
|
lstring.h
|
||||||
lstrlib.o: lstrlib.c lauxlib.h lua.h lualib.h
|
lstrlib.o: lstrlib.c lauxlib.h lua.h lualib.h
|
||||||
@@ -134,7 +133,7 @@ ltm.o: ltm.c lauxlib.h lua.h lmem.h lobject.h lstate.h luadebug.h \
|
|||||||
ltm.h
|
ltm.h
|
||||||
lua.o: lua.c lua.h luadebug.h lualib.h
|
lua.o: lua.c lua.h luadebug.h lualib.h
|
||||||
lundump.o: lundump.c lauxlib.h lua.h lfunc.h lobject.h lmem.h \
|
lundump.o: lundump.c lauxlib.h lua.h lfunc.h lobject.h lmem.h \
|
||||||
lstring.h lundump.h lzio.h
|
lopcodes.h lstring.h lundump.h lzio.h
|
||||||
lvm.o: lvm.c lauxlib.h lua.h ldo.h lobject.h lstate.h luadebug.h \
|
lvm.o: lvm.c lauxlib.h lua.h ldo.h lobject.h lstate.h luadebug.h \
|
||||||
lfunc.h lgc.h lmem.h lopcodes.h lstring.h ltable.h ltm.h lvm.h
|
lfunc.h lgc.h lopcodes.h lstring.h ltable.h ltm.h lvm.h
|
||||||
lzio.o: lzio.c lzio.h
|
lzio.o: lzio.c lzio.h
|
||||||
|
|||||||
61
manual.tex
61
manual.tex
@@ -1,4 +1,4 @@
|
|||||||
% $Id: manual.tex,v 1.32 1999/05/11 20:46:28 roberto Exp roberto $
|
% $Id: manual.tex,v 1.33 1999/05/27 20:21:03 roberto Exp roberto $
|
||||||
|
|
||||||
\documentclass[11pt]{article}
|
\documentclass[11pt]{article}
|
||||||
\usepackage{fullpage,bnf}
|
\usepackage{fullpage,bnf}
|
||||||
@@ -41,7 +41,7 @@ Waldemar Celes
|
|||||||
\tecgraf\ --- Computer Science Department --- PUC-Rio
|
\tecgraf\ --- Computer Science Department --- PUC-Rio
|
||||||
}
|
}
|
||||||
|
|
||||||
\date{{\small \tt\$Date: 1999/05/11 20:46:28 $ $}}
|
\date{{\small \tt\$Date: 1999/05/27 20:21:03 $ $}}
|
||||||
|
|
||||||
\maketitle
|
\maketitle
|
||||||
|
|
||||||
@@ -1273,7 +1273,8 @@ is terminated, returning an error condition.
|
|||||||
|
|
||||||
The only argument to \verb|_ERRORMESSAGE| is a string
|
The only argument to \verb|_ERRORMESSAGE| is a string
|
||||||
describing the error.
|
describing the error.
|
||||||
The default definition for this function calls \verb|_ALERT|,
|
The default definition for
|
||||||
|
this function calls \verb|_ALERT|, \Deffunc{_ALERT}
|
||||||
which prints the message to \verb|stderr| \see{alert}.
|
which prints the message to \verb|stderr| \see{alert}.
|
||||||
The standard I/O library redefines \verb|_ERRORMESSAGE|,
|
The standard I/O library redefines \verb|_ERRORMESSAGE|,
|
||||||
and uses the debug facilities \see{debugI}
|
and uses the debug facilities \see{debugI}
|
||||||
@@ -1835,6 +1836,8 @@ void lua_unref (int ref);
|
|||||||
The function \verb|lua_ref| creates a reference
|
The function \verb|lua_ref| creates a reference
|
||||||
to the object that is on the top of the stack,
|
to the object that is on the top of the stack,
|
||||||
and returns this reference.
|
and returns this reference.
|
||||||
|
For a \nil{} object, the reference is always -1;
|
||||||
|
otherwise, it is a non-negative integer.
|
||||||
If \verb|lock| is true, the object is \emph{locked}:
|
If \verb|lock| is true, the object is \emph{locked}:
|
||||||
this means the object will not be garbage collected.
|
this means the object will not be garbage collected.
|
||||||
Note that an unlocked reference may be garbage collected.
|
Note that an unlocked reference may be garbage collected.
|
||||||
@@ -2503,26 +2506,32 @@ The following combinations are allowed in describing a character class:
|
|||||||
\item[\T{\%s}] --- represents all space characters.
|
\item[\T{\%s}] --- represents all space characters.
|
||||||
\item[\T{\%u}] --- represents all upper case letters.
|
\item[\T{\%u}] --- represents all upper case letters.
|
||||||
\item[\T{\%w}] --- represents all alphanumeric characters.
|
\item[\T{\%w}] --- represents all alphanumeric characters.
|
||||||
\item[\T{\%x}] --- represents all hexa-decimal digits.
|
\item[\T{\%x}] --- represents all hexadecimal digits.
|
||||||
\item[\T{\%z}] --- represents the character with representation 0.
|
\item[\T{\%z}] --- represents the character with representation 0.
|
||||||
\item[\T{\%\M{x}}] (where \M{x} is any non alphanumeric character) ---
|
\item[\T{\%\M{x}}] (where \M{x} is any non alphanumeric character) ---
|
||||||
represents the character \M{x}.
|
represents the character \M{x}.
|
||||||
This is the standard way to escape the magic characters \verb|()%.[]*-?|.
|
This is the standard way to escape the magic characters \verb|()%.[]*-?|.
|
||||||
It is strongly recommended that any control character (even the non magic),
|
It is strongly recommended that any control character (even the non magic),
|
||||||
when used to represent itself in a pattern, should be preceded by a \verb|%|.
|
when used to represent itself in a pattern, should be preceded by a \verb|%|.
|
||||||
|
|
||||||
\item[\T{[char-set]}] ---
|
\item[\T{[char-set]}] ---
|
||||||
Represents the class which is the union of all
|
Represents the class which is the union of all
|
||||||
characters in char-set.
|
characters in char-set.
|
||||||
To include a \verb|]| in char-set, it must be the first character.
|
|
||||||
A range of characters may be specified by
|
A range of characters may be specified by
|
||||||
separating the end characters of the range with a \verb|-|.
|
separating the end characters of the range with a \verb|-|.
|
||||||
If \verb|-| appears as the first or last character of char-set,
|
|
||||||
then it represents itself.
|
|
||||||
All classes \verb|%|\emph{x} described above can also be used as
|
All classes \verb|%|\emph{x} described above can also be used as
|
||||||
components in a char-set.
|
components in a char-set.
|
||||||
All other characters in char-set represent themselves.
|
All other characters in char-set represent themselves.
|
||||||
E.g., assuming an \emph{ascii} character set,
|
E.g., \verb|[%w_]| (or \verb|[_%w]|)
|
||||||
\verb|[%dA-Fa-f]| specifies the hexa-decimal digits.
|
represents all alphanumeric characters plus the underscore,
|
||||||
|
\verb|[0-7]| represents the octal digits,
|
||||||
|
and \verb|[0-7%l%-]| represents the octal digits plus
|
||||||
|
the lower case letters plus the \verb|-| character.
|
||||||
|
|
||||||
|
The interaction between ranges and classes is not defined.
|
||||||
|
Therefore, patterns like \verb|[%a-z]| or \verb|[a-%%]|
|
||||||
|
have no meaning.
|
||||||
|
|
||||||
\item[\T{[\^{ }char-set]}] ---
|
\item[\T{[\^{ }char-set]}] ---
|
||||||
represents the complement of char-set,
|
represents the complement of char-set,
|
||||||
where char-set is interpreted as above.
|
where char-set is interpreted as above.
|
||||||
@@ -3187,6 +3196,8 @@ accepting commands from standard input until an \verb|EOF|.
|
|||||||
Each line entered is immediately executed.
|
Each line entered is immediately executed.
|
||||||
\item[\T{-q}] same as \T{-i}, but without a prompt (quiet mode).
|
\item[\T{-q}] same as \T{-i}, but without a prompt (quiet mode).
|
||||||
\item[\T{-}] executes \verb|stdin| as a file.
|
\item[\T{-}] executes \verb|stdin| as a file.
|
||||||
|
\item[\T{--}] stops the execution of arguments;
|
||||||
|
all arguments after it are simply passed to the Lua script.
|
||||||
\item[\T{var=value}] sets global \verb|var| with string \verb|"value"|.
|
\item[\T{var=value}] sets global \verb|var| with string \verb|"value"|.
|
||||||
\item[\T{filename}] executes file \verb|filename| as a Lua chunk.
|
\item[\T{filename}] executes file \verb|filename| as a Lua chunk.
|
||||||
\end{description}
|
\end{description}
|
||||||
@@ -3203,6 +3214,37 @@ will first interact with the user until an \verb|EOF|,
|
|||||||
then will set \verb|a| to \verb|"test"|,
|
then will set \verb|a| to \verb|"test"|,
|
||||||
and finally will run the file \verb|prog.lua|.
|
and finally will run the file \verb|prog.lua|.
|
||||||
|
|
||||||
|
All arguments from the command line are passed to the Lua program in
|
||||||
|
a table called \verb|arg|.
|
||||||
|
If the command line has the \verb|--| argument,
|
||||||
|
this argument is at index 0;
|
||||||
|
the arguments after it get indices 1, 2, \ldots;
|
||||||
|
and the arguments before it get negative indices.
|
||||||
|
The field \verb|n| gets the index of the last argument,
|
||||||
|
and the field \verb|nn| gets the index of the first argument
|
||||||
|
(always a negative number).
|
||||||
|
For instance:
|
||||||
|
\begin{verbatim}
|
||||||
|
$ lua -e "foreach(arg, print)" -- a b
|
||||||
|
-1 foreach(arg, print)
|
||||||
|
-2 -e
|
||||||
|
-3 lua
|
||||||
|
0 --
|
||||||
|
1 a
|
||||||
|
2 b
|
||||||
|
nn -3
|
||||||
|
n 2
|
||||||
|
\end{verbatim}
|
||||||
|
If the command line has no \verb|--| argument,
|
||||||
|
all arguments have negative indices, with the last one at position -1.
|
||||||
|
As a general rule, if you want to traverse all the
|
||||||
|
arguments after the \verb|--|, you loop from 1 to \verb|arg.n|
|
||||||
|
(you can use the \verb|foreachi| function, for instance).
|
||||||
|
If you want to traverse all arguments,
|
||||||
|
you loop from \verb|arg.nn| until \verb|arg.n|.
|
||||||
|
In any case, you may call \verb|exit| at the end of a script,
|
||||||
|
to stop Lua from running the other arguments.
|
||||||
|
|
||||||
When in interactive mode,
|
When in interactive mode,
|
||||||
a multi-line statement can be written finishing intermediate
|
a multi-line statement can be written finishing intermediate
|
||||||
lines with a backslash (\verb|\|).
|
lines with a backslash (\verb|\|).
|
||||||
@@ -3216,6 +3258,7 @@ In Unix systems, Lua scripts can be made into executable programs
|
|||||||
by using the \verb|#!| form,
|
by using the \verb|#!| form,
|
||||||
as in \verb|#!/usr/local/bin/lua|.
|
as in \verb|#!/usr/local/bin/lua|.
|
||||||
|
|
||||||
|
|
||||||
\section*{Acknowledgments}
|
\section*{Acknowledgments}
|
||||||
|
|
||||||
The authors would like to thank CENPES/PETROBRAS which,
|
The authors would like to thank CENPES/PETROBRAS which,
|
||||||
|
|||||||
Reference in New Issue
Block a user