diff options
-rw-r--r-- | lapi.c | 30 | ||||
-rw-r--r-- | lbuiltin.c | 63 | ||||
-rw-r--r-- | ldo.c | 15 | ||||
-rw-r--r-- | ldo.h | 3 | ||||
-rw-r--r-- | lfunc.c | 34 | ||||
-rw-r--r-- | lfunc.h | 6 | ||||
-rw-r--r-- | lgc.c | 302 | ||||
-rw-r--r-- | lgc.h | 7 | ||||
-rw-r--r-- | llex.c | 8 | ||||
-rw-r--r-- | lobject.c | 9 | ||||
-rw-r--r-- | lobject.h | 24 | ||||
-rw-r--r-- | lstate.c | 27 | ||||
-rw-r--r-- | lstate.h | 10 | ||||
-rw-r--r-- | lstring.c | 142 | ||||
-rw-r--r-- | lstring.h | 18 | ||||
-rw-r--r-- | ltable.c | 25 | ||||
-rw-r--r-- | ltable.h | 4 | ||||
-rw-r--r-- | ltm.c | 8 | ||||
-rw-r--r-- | makefile | 31 | ||||
-rw-r--r-- | manual.tex | 61 |
20 files changed, 384 insertions, 443 deletions
@@ -1,11 +1,10 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lapi.c,v 1.49 1999/09/20 14:57:29 roberto Exp roberto $ | 2 | ** $Id: lapi.c,v 1.50 1999/09/21 16:10:13 roberto Exp roberto $ |
3 | ** Lua API | 3 | ** Lua API |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
6 | 6 | ||
7 | 7 | ||
8 | #include <stdlib.h> | ||
9 | #include <string.h> | 8 | #include <string.h> |
10 | 9 | ||
11 | #include "lapi.h" | 10 | #include "lapi.h" |
@@ -15,6 +14,7 @@ | |||
15 | #include "lgc.h" | 14 | #include "lgc.h" |
16 | #include "lmem.h" | 15 | #include "lmem.h" |
17 | #include "lobject.h" | 16 | #include "lobject.h" |
17 | #include "lref.h" | ||
18 | #include "lstate.h" | 18 | #include "lstate.h" |
19 | #include "lstring.h" | 19 | #include "lstring.h" |
20 | #include "ltable.h" | 20 | #include "ltable.h" |
@@ -387,14 +387,14 @@ void lua_settag (int tag) { | |||
387 | 387 | ||
388 | TaggedString *luaA_nextvar (TaggedString *g) { | 388 | TaggedString *luaA_nextvar (TaggedString *g) { |
389 | if (g == NULL) | 389 | if (g == NULL) |
390 | g = (TaggedString *)L->rootglobal.next; /* first variable */ | 390 | g = L->rootglobal; /* first variable */ |
391 | else { | 391 | else { |
392 | /* check whether name is in global var list */ | 392 | /* check whether name is in global var list */ |
393 | luaL_arg_check((GCnode *)g != g->head.next, 1, "variable name expected"); | 393 | luaL_arg_check(g != g->next, 1, "variable name expected"); |
394 | g = (TaggedString *)g->head.next; /* get next */ | 394 | g = g->next; /* get next */ |
395 | } | 395 | } |
396 | while (g && g->u.s.globalval.ttype == LUA_T_NIL) /* skip globals with nil */ | 396 | while (g && g->u.s.globalval.ttype == LUA_T_NIL) /* skip globals with nil */ |
397 | g = (TaggedString *)g->head.next; | 397 | g = g->next; |
398 | if (g) { | 398 | if (g) { |
399 | ttype(L->stack.top) = LUA_T_STRING; tsvalue(L->stack.top) = g; | 399 | ttype(L->stack.top) = LUA_T_STRING; tsvalue(L->stack.top) = g; |
400 | incr_top; | 400 | incr_top; |
@@ -574,12 +574,18 @@ static int checkfunc (TObject *o) { | |||
574 | 574 | ||
575 | const char *lua_getobjname (lua_Object o, const char **name) { | 575 | const char *lua_getobjname (lua_Object o, const char **name) { |
576 | /* try to find a name for given function */ | 576 | /* try to find a name for given function */ |
577 | TaggedString *g; | ||
577 | set_normalized(L->stack.top, Address(o)); /* to be accessed by "checkfunc" */ | 578 | set_normalized(L->stack.top, Address(o)); /* to be accessed by "checkfunc" */ |
578 | if ((*name = luaS_travsymbol(checkfunc)) != NULL) | 579 | for (g=L->rootglobal; g; g=g->next) { |
579 | return "global"; | 580 | if (checkfunc(&g->u.s.globalval)) { |
580 | else if ((*name = luaT_travtagmethods(checkfunc)) != NULL) | 581 | *name = g->str; |
582 | return "global"; | ||
583 | } | ||
584 | } | ||
585 | /* not found: try tag methods */ | ||
586 | if ((*name = luaT_travtagmethods(checkfunc)) != NULL) | ||
581 | return "tag-method"; | 587 | return "tag-method"; |
582 | else return ""; | 588 | else return ""; /* not found at all */ |
583 | } | 589 | } |
584 | 590 | ||
585 | /* }====================================================== */ | 591 | /* }====================================================== */ |
@@ -615,7 +621,7 @@ void lua_endblock (void) { | |||
615 | int lua_ref (int lock) { | 621 | int lua_ref (int lock) { |
616 | int ref; | 622 | int ref; |
617 | checkCparams(1); | 623 | checkCparams(1); |
618 | ref = luaC_ref(L->stack.top-1, lock); | 624 | ref = luaR_ref(L->stack.top-1, lock); |
619 | L->stack.top--; | 625 | L->stack.top--; |
620 | return ref; | 626 | return ref; |
621 | } | 627 | } |
@@ -623,7 +629,7 @@ int lua_ref (int lock) { | |||
623 | 629 | ||
624 | 630 | ||
625 | lua_Object lua_getref (int ref) { | 631 | lua_Object lua_getref (int ref) { |
626 | const TObject *o = luaC_getref(ref); | 632 | const TObject *o = luaR_getref(ref); |
627 | return (o ? put_luaObject(o) : LUA_NOOBJECT); | 633 | return (o ? put_luaObject(o) : LUA_NOOBJECT); |
628 | } | 634 | } |
629 | 635 | ||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lbuiltin.c,v 1.62 1999/09/08 20:45:18 roberto Exp roberto $ | 2 | ** $Id: lbuiltin.c,v 1.63 1999/09/20 14:57:29 roberto Exp roberto $ |
3 | ** Built-in functions | 3 | ** Built-in functions |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -222,9 +222,15 @@ static void luaB_rawsettable (void) { | |||
222 | } | 222 | } |
223 | 223 | ||
224 | static void luaB_settagmethod (void) { | 224 | static void luaB_settagmethod (void) { |
225 | int tag = luaL_check_int(1); | ||
226 | const char *event = luaL_check_string(2); | ||
225 | lua_Object nf = luaL_nonnullarg(3); | 227 | lua_Object nf = luaL_nonnullarg(3); |
228 | #ifndef LUA_COMPAT_GC | ||
229 | if (strcmp(event, "gc") == 0 && tag != LUA_T_NIL) | ||
230 | lua_error("cannot set this tag method from Lua"); | ||
231 | #endif | ||
226 | lua_pushobject(nf); | 232 | lua_pushobject(nf); |
227 | lua_pushobject(lua_settagmethod(luaL_check_int(1), luaL_check_string(2))); | 233 | lua_pushobject(lua_settagmethod(tag, event)); |
228 | } | 234 | } |
229 | 235 | ||
230 | static void luaB_gettagmethod (void) { | 236 | static void luaB_gettagmethod (void) { |
@@ -437,12 +443,11 @@ static void luaB_foreach (void) { | |||
437 | 443 | ||
438 | 444 | ||
439 | static void luaB_foreachvar (void) { | 445 | static void luaB_foreachvar (void) { |
440 | GCnode *g; | 446 | TaggedString *s; |
441 | TObject f; /* see comment in 'foreachi' */ | 447 | TObject f; /* see comment in 'foreachi' */ |
442 | f = *luaA_Address(luaL_functionarg(1)); | 448 | f = *luaA_Address(luaL_functionarg(1)); |
443 | luaD_checkstack(4); /* for extra var name, f, var name, and globalval */ | 449 | luaD_checkstack(4); /* for extra var name, f, var name, and globalval */ |
444 | for (g = L->rootglobal.next; g; g = g->next) { | 450 | for (s = L->rootglobal; s; s = s->next) { |
445 | TaggedString *s = (TaggedString *)g; | ||
446 | if (s->u.s.globalval.ttype != LUA_T_NIL) { | 451 | if (s->u.s.globalval.ttype != LUA_T_NIL) { |
447 | pushtagstring(s); /* keep (extra) s on stack to avoid GC */ | 452 | pushtagstring(s); /* keep (extra) s on stack to avoid GC */ |
448 | *(L->stack.top++) = f; | 453 | *(L->stack.top++) = f; |
@@ -451,10 +456,10 @@ static void luaB_foreachvar (void) { | |||
451 | luaD_calln(2, 1); | 456 | luaD_calln(2, 1); |
452 | if (ttype(L->stack.top-1) != LUA_T_NIL) { | 457 | if (ttype(L->stack.top-1) != LUA_T_NIL) { |
453 | L->stack.top--; | 458 | L->stack.top--; |
454 | *(L->stack.top-1) = *L->stack.top; /* remove extra s */ | 459 | *(L->stack.top-1) = *L->stack.top; /* remove extra `s' */ |
455 | return; | 460 | return; |
456 | } | 461 | } |
457 | L->stack.top-=2; /* remove result and extra s */ | 462 | L->stack.top-=2; /* remove result and extra `s' */ |
458 | } | 463 | } |
459 | } | 464 | } |
460 | } | 465 | } |
@@ -602,20 +607,42 @@ static void mem_query (void) { | |||
602 | 607 | ||
603 | 608 | ||
604 | static void query_strings (void) { | 609 | static void query_strings (void) { |
605 | lua_pushnumber(L->string_root[luaL_check_int(1)].nuse); | 610 | int h = luaL_check_int(1) - 1; |
611 | int s = luaL_opt_int(2, 0) - 1; | ||
612 | if (s==-1) { | ||
613 | if (h < NUM_HASHS) { | ||
614 | lua_pushnumber(L->string_root[h].nuse); | ||
615 | lua_pushnumber(L->string_root[h].size); | ||
616 | } | ||
617 | } | ||
618 | else { | ||
619 | TaggedString *ts = L->string_root[h].hash[s]; | ||
620 | if (ts == NULL) lua_pushstring("<NIL>"); | ||
621 | else if (ts == &luaS_EMPTY) lua_pushstring("<EMPTY>"); | ||
622 | else if (ts->constindex == -1) lua_pushstring("<USERDATA>"); | ||
623 | else lua_pushstring(ts->str); | ||
624 | } | ||
606 | } | 625 | } |
607 | 626 | ||
608 | 627 | ||
609 | static void countlist (void) { | 628 | static void extra_services (void) { |
610 | const char *s = luaL_check_string(1); | 629 | const char *service = luaL_check_string(1); |
611 | GCnode *l = (s[0]=='t') ? L->roottable.next : (s[0]=='c') ? L->rootcl.next : | 630 | switch (*service) { |
612 | (s[0]=='p') ? L->rootproto.next : L->rootglobal.next; | 631 | case 'U': /* create a userdata with a given value/tag */ |
613 | int i=0; | 632 | lua_pushusertag((void *)luaL_check_int(2), luaL_check_int(3)); |
614 | while (l) { | 633 | break; |
615 | i++; | 634 | |
616 | l = l->next; | 635 | case 'u': /* return the value of a userdata */ |
636 | lua_pushnumber((int)lua_getuserdata(lua_getparam(2))); | ||
637 | break; | ||
638 | |||
639 | case 't': /* set `gc' tag method */ | ||
640 | lua_pushobject(lua_getparam(3)); | ||
641 | lua_settagmethod(luaL_check_int(2), "gc"); | ||
642 | break; | ||
643 | |||
644 | default: luaL_arg_check(0, 1, "invalid service"); | ||
617 | } | 645 | } |
618 | lua_pushnumber(i); | ||
619 | } | 646 | } |
620 | 647 | ||
621 | 648 | ||
@@ -679,9 +706,9 @@ static void testC (void) { | |||
679 | 706 | ||
680 | static const struct luaL_reg builtin_funcs[] = { | 707 | static const struct luaL_reg builtin_funcs[] = { |
681 | #ifdef DEBUG | 708 | #ifdef DEBUG |
709 | {"extra", extra_services}, | ||
682 | {"testC", testC}, | 710 | {"testC", testC}, |
683 | {"totalmem", mem_query}, | 711 | {"totalmem", mem_query}, |
684 | {"count", countlist}, | ||
685 | {"querystr", query_strings}, | 712 | {"querystr", query_strings}, |
686 | #endif | 713 | #endif |
687 | {"_ALERT", luaB_alert}, | 714 | {"_ALERT", luaB_alert}, |
@@ -1,18 +1,16 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ldo.c,v 1.46 1999/08/16 20:52:00 roberto Exp roberto $ | 2 | ** $Id: ldo.c,v 1.47 1999/09/06 15:24:46 roberto Exp roberto $ |
3 | ** Stack and Call structure of Lua | 3 | ** Stack and Call structure of Lua |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
6 | 6 | ||
7 | 7 | ||
8 | #include <setjmp.h> | 8 | #include <setjmp.h> |
9 | #include <stdio.h> | ||
10 | #include <stdlib.h> | 9 | #include <stdlib.h> |
11 | #include <string.h> | 10 | #include <string.h> |
12 | 11 | ||
13 | #include "lauxlib.h" | 12 | #include "lauxlib.h" |
14 | #include "ldo.h" | 13 | #include "ldo.h" |
15 | #include "lfunc.h" | ||
16 | #include "lgc.h" | 14 | #include "lgc.h" |
17 | #include "lmem.h" | 15 | #include "lmem.h" |
18 | #include "lobject.h" | 16 | #include "lobject.h" |
@@ -219,17 +217,6 @@ void luaD_calln (int nArgs, int nResults) { | |||
219 | } | 217 | } |
220 | 218 | ||
221 | 219 | ||
222 | /* | ||
223 | ** Traverse all objects on L->stack.stack | ||
224 | */ | ||
225 | void luaD_travstack (int (*fn)(TObject *)) { | ||
226 | StkId i; | ||
227 | for (i = (L->stack.top-1)-L->stack.stack; i>=0; i--) | ||
228 | fn(L->stack.stack+i); | ||
229 | } | ||
230 | |||
231 | |||
232 | |||
233 | static void message (const char *s) { | 220 | static void message (const char *s) { |
234 | const TObject *em = &(luaS_new("_ERRORMESSAGE")->u.s.globalval); | 221 | const TObject *em = &(luaS_new("_ERRORMESSAGE")->u.s.globalval); |
235 | if (ttype(em) == LUA_T_PROTO || ttype(em) == LUA_T_CPROTO || | 222 | if (ttype(em) == LUA_T_PROTO || ttype(em) == LUA_T_CPROTO || |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ldo.h,v 1.6 1999/06/22 20:37:23 roberto Exp roberto $ | 2 | ** $Id: ldo.h,v 1.7 1999/08/16 20:52:00 roberto Exp roberto $ |
3 | ** Stack and Call structure of Lua | 3 | ** Stack and Call structure of Lua |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -39,7 +39,6 @@ void luaD_calln (int nArgs, int nResults); | |||
39 | void luaD_callTM (const TObject *f, int nParams, int nResults); | 39 | void luaD_callTM (const TObject *f, int nParams, int nResults); |
40 | int luaD_protectedrun (void); | 40 | int luaD_protectedrun (void); |
41 | void luaD_gcIM (const TObject *o); | 41 | void luaD_gcIM (const TObject *o); |
42 | void luaD_travstack (int (*fn)(TObject *)); | ||
43 | void luaD_checkstack (int n); | 42 | void luaD_checkstack (int n); |
44 | 43 | ||
45 | 44 | ||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lfunc.c,v 1.10 1999/03/04 21:17:26 roberto Exp roberto $ | 2 | ** $Id: lfunc.c,v 1.11 1999/08/16 20:52:00 roberto Exp roberto $ |
3 | ** Auxiliary functions to manipulate prototypes and closures | 3 | ** Auxiliary functions to manipulate prototypes and closures |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -18,7 +18,9 @@ | |||
18 | 18 | ||
19 | Closure *luaF_newclosure (int nelems) { | 19 | Closure *luaF_newclosure (int nelems) { |
20 | Closure *c = (Closure *)luaM_malloc(sizeof(Closure)+nelems*sizeof(TObject)); | 20 | Closure *c = (Closure *)luaM_malloc(sizeof(Closure)+nelems*sizeof(TObject)); |
21 | luaO_insertlist(&(L->rootcl), (GCnode *)c); | 21 | c->next = L->rootcl; |
22 | L->rootcl = c; | ||
23 | c->marked = 0; | ||
22 | L->nblocks += gcsizeclosure(c); | 24 | L->nblocks += gcsizeclosure(c); |
23 | c->nelems = nelems; | 25 | c->nelems = nelems; |
24 | return c; | 26 | return c; |
@@ -33,14 +35,16 @@ TProtoFunc *luaF_newproto (void) { | |||
33 | f->consts = NULL; | 35 | f->consts = NULL; |
34 | f->nconsts = 0; | 36 | f->nconsts = 0; |
35 | f->locvars = NULL; | 37 | f->locvars = NULL; |
36 | luaO_insertlist(&(L->rootproto), (GCnode *)f); | 38 | f->next = L->rootproto; |
39 | L->rootproto = f; | ||
40 | f->marked = 0; | ||
37 | L->nblocks += gcsizeproto(f); | 41 | L->nblocks += gcsizeproto(f); |
38 | return f; | 42 | return f; |
39 | } | 43 | } |
40 | 44 | ||
41 | 45 | ||
42 | 46 | void luaF_freeproto (TProtoFunc *f) { | |
43 | static void freefunc (TProtoFunc *f) { | 47 | L->nblocks -= gcsizeproto(f); |
44 | luaM_free(f->code); | 48 | luaM_free(f->code); |
45 | luaM_free(f->locvars); | 49 | luaM_free(f->locvars); |
46 | luaM_free(f->consts); | 50 | luaM_free(f->consts); |
@@ -48,23 +52,9 @@ static void freefunc (TProtoFunc *f) { | |||
48 | } | 52 | } |
49 | 53 | ||
50 | 54 | ||
51 | void luaF_freeproto (TProtoFunc *l) { | 55 | void luaF_freeclosure (Closure *c) { |
52 | while (l) { | 56 | L->nblocks -= gcsizeclosure(c); |
53 | TProtoFunc *next = (TProtoFunc *)l->head.next; | 57 | luaM_free(c); |
54 | L->nblocks -= gcsizeproto(l); | ||
55 | freefunc(l); | ||
56 | l = next; | ||
57 | } | ||
58 | } | ||
59 | |||
60 | |||
61 | void luaF_freeclosure (Closure *l) { | ||
62 | while (l) { | ||
63 | Closure *next = (Closure *)l->head.next; | ||
64 | L->nblocks -= gcsizeclosure(l); | ||
65 | luaM_free(l); | ||
66 | l = next; | ||
67 | } | ||
68 | } | 58 | } |
69 | 59 | ||
70 | 60 | ||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lfunc.h,v 1.5 1997/12/15 16:17:20 roberto Exp roberto $ | 2 | ** $Id: lfunc.h,v 1.6 1999/08/16 20:52:00 roberto Exp roberto $ |
3 | ** Lua Function structures | 3 | ** Lua Function structures |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -14,8 +14,8 @@ | |||
14 | 14 | ||
15 | TProtoFunc *luaF_newproto (void); | 15 | TProtoFunc *luaF_newproto (void); |
16 | Closure *luaF_newclosure (int nelems); | 16 | Closure *luaF_newclosure (int nelems); |
17 | void luaF_freeproto (TProtoFunc *l); | 17 | void luaF_freeproto (TProtoFunc *f); |
18 | void luaF_freeclosure (Closure *l); | 18 | void luaF_freeclosure (Closure *c); |
19 | 19 | ||
20 | const char *luaF_getlocalname (TProtoFunc *func, int local_number, int line); | 20 | const char *luaF_getlocalname (TProtoFunc *func, int local_number, int line); |
21 | 21 | ||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lgc.c,v 1.25 1999/08/16 20:52:00 roberto Exp roberto $ | 2 | ** $Id: lgc.c,v 1.26 1999/09/27 18:00:25 roberto Exp roberto $ |
3 | ** Garbage Collector | 3 | ** Garbage Collector |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -8,8 +8,8 @@ | |||
8 | #include "ldo.h" | 8 | #include "ldo.h" |
9 | #include "lfunc.h" | 9 | #include "lfunc.h" |
10 | #include "lgc.h" | 10 | #include "lgc.h" |
11 | #include "lmem.h" | ||
12 | #include "lobject.h" | 11 | #include "lobject.h" |
12 | #include "lref.h" | ||
13 | #include "lstate.h" | 13 | #include "lstate.h" |
14 | #include "lstring.h" | 14 | #include "lstring.h" |
15 | #include "ltable.h" | 15 | #include "ltable.h" |
@@ -21,138 +21,15 @@ | |||
21 | static int markobject (TObject *o); | 21 | static int markobject (TObject *o); |
22 | 22 | ||
23 | 23 | ||
24 | 24 | /* mark a string; marks bigger than 1 cannot be changed */ | |
25 | /* | 25 | #define strmark(s) {if ((s)->marked == 0) (s)->marked = 1;} |
26 | ** ======================================================= | ||
27 | ** REF mechanism | ||
28 | ** ======================================================= | ||
29 | */ | ||
30 | |||
31 | |||
32 | int luaC_ref (const TObject *o, int lock) { | ||
33 | int ref; | ||
34 | if (ttype(o) == LUA_T_NIL) | ||
35 | ref = LUA_REFNIL; | ||
36 | else { | ||
37 | for (ref=0; ref<L->refSize; ref++) | ||
38 | if (L->refArray[ref].status == FREE) | ||
39 | break; | ||
40 | if (ref == L->refSize) { /* no more empty spaces? */ | ||
41 | luaM_growvector(L->refArray, L->refSize, 1, struct ref, refEM, MAX_INT); | ||
42 | L->refSize++; | ||
43 | } | ||
44 | L->refArray[ref].o = *o; | ||
45 | L->refArray[ref].status = lock ? LOCK : HOLD; | ||
46 | } | ||
47 | return ref; | ||
48 | } | ||
49 | |||
50 | |||
51 | void lua_unref (int ref) { | ||
52 | if (ref >= 0 && ref < L->refSize) | ||
53 | L->refArray[ref].status = FREE; | ||
54 | } | ||
55 | |||
56 | |||
57 | const TObject *luaC_getref (int ref) { | ||
58 | if (ref == LUA_REFNIL) | ||
59 | return &luaO_nilobject; | ||
60 | if (ref >= 0 && ref < L->refSize && | ||
61 | (L->refArray[ref].status == LOCK || L->refArray[ref].status == HOLD)) | ||
62 | return &L->refArray[ref].o; | ||
63 | else | ||
64 | return NULL; | ||
65 | } | ||
66 | |||
67 | |||
68 | static void travlock (void) { | ||
69 | int i; | ||
70 | for (i=0; i<L->refSize; i++) | ||
71 | if (L->refArray[i].status == LOCK) | ||
72 | markobject(&L->refArray[i].o); | ||
73 | } | ||
74 | |||
75 | |||
76 | static int ismarked (const TObject *o) { | ||
77 | /* valid only for locked objects */ | ||
78 | switch (o->ttype) { | ||
79 | case LUA_T_STRING: case LUA_T_USERDATA: | ||
80 | return o->value.ts->head.marked; | ||
81 | case LUA_T_ARRAY: | ||
82 | return o->value.a->head.marked; | ||
83 | case LUA_T_CLOSURE: | ||
84 | return o->value.cl->head.marked; | ||
85 | case LUA_T_PROTO: | ||
86 | return o->value.tf->head.marked; | ||
87 | #ifdef DEBUG | ||
88 | case LUA_T_LINE: case LUA_T_CLMARK: | ||
89 | case LUA_T_CMARK: case LUA_T_PMARK: | ||
90 | LUA_INTERNALERROR("invalid type"); | ||
91 | #endif | ||
92 | default: /* nil, number or cproto */ | ||
93 | return 1; | ||
94 | } | ||
95 | } | ||
96 | 26 | ||
97 | 27 | ||
98 | static void invalidaterefs (void) { | ||
99 | int i; | ||
100 | for (i=0; i<L->refSize; i++) | ||
101 | if (L->refArray[i].status == HOLD && !ismarked(&L->refArray[i].o)) | ||
102 | L->refArray[i].status = COLLECTED; | ||
103 | } | ||
104 | |||
105 | |||
106 | |||
107 | void luaC_hashcallIM (Hash *l) { | ||
108 | TObject t; | ||
109 | ttype(&t) = LUA_T_ARRAY; | ||
110 | for (; l; l=(Hash *)l->head.next) { | ||
111 | avalue(&t) = l; | ||
112 | luaD_gcIM(&t); | ||
113 | } | ||
114 | } | ||
115 | |||
116 | |||
117 | void luaC_strcallIM (TaggedString *l) { | ||
118 | TObject o; | ||
119 | ttype(&o) = LUA_T_USERDATA; | ||
120 | for (; l; l=(TaggedString *)l->head.next) | ||
121 | if (l->constindex == -1) { /* is userdata? */ | ||
122 | tsvalue(&o) = l; | ||
123 | luaD_gcIM(&o); | ||
124 | } | ||
125 | } | ||
126 | |||
127 | |||
128 | |||
129 | static GCnode *listcollect (GCnode *l) { | ||
130 | GCnode *frees = NULL; | ||
131 | while (l) { | ||
132 | GCnode *next = l->next; | ||
133 | l->marked = 0; | ||
134 | while (next && !next->marked) { | ||
135 | l->next = next->next; | ||
136 | next->next = frees; | ||
137 | frees = next; | ||
138 | next = l->next; | ||
139 | } | ||
140 | l = next; | ||
141 | } | ||
142 | return frees; | ||
143 | } | ||
144 | |||
145 | |||
146 | /* | ||
147 | ** mark a string; marks bigger than 1 cannot be changed. | ||
148 | */ | ||
149 | #define strmark(s) {if ((s)->head.marked == 0) (s)->head.marked = 1;} | ||
150 | |||
151 | 28 | ||
152 | static void protomark (TProtoFunc *f) { | 29 | static void protomark (TProtoFunc *f) { |
153 | if (!f->head.marked) { | 30 | if (!f->marked) { |
154 | int i; | 31 | int i; |
155 | f->head.marked = 1; | 32 | f->marked = 1; |
156 | strmark(f->source); | 33 | strmark(f->source); |
157 | for (i=f->nconsts-1; i>=0; i--) | 34 | for (i=f->nconsts-1; i>=0; i--) |
158 | markobject(&f->consts[i]); | 35 | markobject(&f->consts[i]); |
@@ -161,9 +38,9 @@ static void protomark (TProtoFunc *f) { | |||
161 | 38 | ||
162 | 39 | ||
163 | static void closuremark (Closure *f) { | 40 | static void closuremark (Closure *f) { |
164 | if (!f->head.marked) { | 41 | if (!f->marked) { |
165 | int i; | 42 | int i; |
166 | f->head.marked = 1; | 43 | f->marked = 1; |
167 | for (i=f->nelems; i>=0; i--) | 44 | for (i=f->nelems; i>=0; i--) |
168 | markobject(&f->consts[i]); | 45 | markobject(&f->consts[i]); |
169 | } | 46 | } |
@@ -171,9 +48,9 @@ static void closuremark (Closure *f) { | |||
171 | 48 | ||
172 | 49 | ||
173 | static void hashmark (Hash *h) { | 50 | static void hashmark (Hash *h) { |
174 | if (!h->head.marked) { | 51 | if (!h->marked) { |
175 | int i; | 52 | int i; |
176 | h->head.marked = 1; | 53 | h->marked = 1; |
177 | for (i=nhash(h)-1; i>=0; i--) { | 54 | for (i=nhash(h)-1; i>=0; i--) { |
178 | Node *n = node(h,i); | 55 | Node *n = node(h,i); |
179 | if (ttype(ref(n)) != LUA_T_NIL) { | 56 | if (ttype(ref(n)) != LUA_T_NIL) { |
@@ -187,7 +64,7 @@ static void hashmark (Hash *h) { | |||
187 | 64 | ||
188 | static void globalmark (void) { | 65 | static void globalmark (void) { |
189 | TaggedString *g; | 66 | TaggedString *g; |
190 | for (g=(TaggedString *)L->rootglobal.next; g; g=(TaggedString *)g->head.next){ | 67 | for (g=L->rootglobal; g; g=g->next) { |
191 | LUA_ASSERT(g->constindex >= 0, "userdata in global list"); | 68 | LUA_ASSERT(g->constindex >= 0, "userdata in global list"); |
192 | if (g->u.s.globalval.ttype != LUA_T_NIL) { | 69 | if (g->u.s.globalval.ttype != LUA_T_NIL) { |
193 | markobject(&g->u.s.globalval); | 70 | markobject(&g->u.s.globalval); |
@@ -197,6 +74,21 @@ static void globalmark (void) { | |||
197 | } | 74 | } |
198 | 75 | ||
199 | 76 | ||
77 | static void travstack (void) { | ||
78 | StkId i; | ||
79 | for (i = (L->stack.top-1)-L->stack.stack; i>=0; i--) | ||
80 | markobject(L->stack.stack+i); | ||
81 | } | ||
82 | |||
83 | |||
84 | static void travlock (void) { | ||
85 | int i; | ||
86 | for (i=0; i<L->refSize; i++) | ||
87 | if (L->refArray[i].status == LOCK) | ||
88 | markobject(&L->refArray[i].o); | ||
89 | } | ||
90 | |||
91 | |||
200 | static int markobject (TObject *o) { | 92 | static int markobject (TObject *o) { |
201 | switch (ttype(o)) { | 93 | switch (ttype(o)) { |
202 | case LUA_T_USERDATA: case LUA_T_STRING: | 94 | case LUA_T_USERDATA: case LUA_T_STRING: |
@@ -217,36 +109,138 @@ static int markobject (TObject *o) { | |||
217 | } | 109 | } |
218 | 110 | ||
219 | 111 | ||
112 | static void collectproto (void) { | ||
113 | TProtoFunc **p = &L->rootproto; | ||
114 | TProtoFunc *next; | ||
115 | while ((next = *p) != NULL) { | ||
116 | if (next->marked) { | ||
117 | next->marked = 0; | ||
118 | p = &next->next; | ||
119 | } | ||
120 | else { | ||
121 | *p = next->next; | ||
122 | luaF_freeproto(next); | ||
123 | } | ||
124 | } | ||
125 | } | ||
126 | |||
127 | |||
128 | static void collectclosure (void) { | ||
129 | Closure **p = &L->rootcl; | ||
130 | Closure *next; | ||
131 | while ((next = *p) != NULL) { | ||
132 | if (next->marked) { | ||
133 | next->marked = 0; | ||
134 | p = &next->next; | ||
135 | } | ||
136 | else { | ||
137 | *p = next->next; | ||
138 | luaF_freeclosure(next); | ||
139 | } | ||
140 | } | ||
141 | } | ||
142 | |||
143 | |||
144 | static void collecttable (void) { | ||
145 | Hash **p = &L->roottable; | ||
146 | Hash *next; | ||
147 | while ((next = *p) != NULL) { | ||
148 | if (next->marked) { | ||
149 | next->marked = 0; | ||
150 | p = &next->next; | ||
151 | } | ||
152 | else { | ||
153 | *p = next->next; | ||
154 | luaH_free(next); | ||
155 | } | ||
156 | } | ||
157 | } | ||
158 | |||
159 | |||
160 | static void clear_global_list (void) { | ||
161 | TaggedString **p = &L->rootglobal; | ||
162 | TaggedString *next; | ||
163 | while ((next = *p) != NULL) { | ||
164 | if (next->marked) p = &next->next; | ||
165 | else *p = next->next; | ||
166 | } | ||
167 | } | ||
168 | |||
169 | |||
170 | /* | ||
171 | ** collect all elements with `marked' < `limit'. | ||
172 | ** with limit=1, that means all unmarked elements; | ||
173 | ** with limit=MAX_INT, that means all elements (but EMPTY). | ||
174 | */ | ||
175 | static void collectstring (int limit) { | ||
176 | TObject o; /* to call userdata 'gc' tag method */ | ||
177 | int i; | ||
178 | ttype(&o) = LUA_T_USERDATA; | ||
179 | clear_global_list(); | ||
180 | for (i=0; i<NUM_HASHS; i++) { | ||
181 | stringtable *tb = &L->string_root[i]; | ||
182 | int j; | ||
183 | for (j=0; j<tb->size; j++) { | ||
184 | TaggedString *t = tb->hash[j]; | ||
185 | if (t == NULL) continue; | ||
186 | if (t->marked < limit) { | ||
187 | if (t->constindex == -1) { /* is userdata? */ | ||
188 | tsvalue(&o) = t; | ||
189 | luaD_gcIM(&o); | ||
190 | } | ||
191 | luaS_free(t); | ||
192 | tb->hash[j] = &luaS_EMPTY; | ||
193 | } | ||
194 | else if (t->marked == 1) | ||
195 | t->marked = 0; | ||
196 | } | ||
197 | } | ||
198 | } | ||
199 | |||
200 | |||
201 | #ifdef LUA_COMPAT_GC | ||
202 | static void tableTM (void) { | ||
203 | Hash *p; | ||
204 | TObject o; | ||
205 | ttype(&o) = LUA_T_ARRAY; | ||
206 | for (p = L->roottable; p; p = p->next) { | ||
207 | if (!p->marked) { | ||
208 | avalue(&o) = p; | ||
209 | luaD_gcIM(&o); | ||
210 | } | ||
211 | } | ||
212 | } | ||
213 | #else | ||
214 | #define tableTM() /* do nothing */ | ||
215 | #endif | ||
216 | |||
217 | |||
220 | 218 | ||
221 | static void markall (void) { | 219 | static void markall (void) { |
222 | luaD_travstack(markobject); /* mark stack objects */ | 220 | travstack(); /* mark stack objects */ |
223 | globalmark(); /* mark global variable values and names */ | 221 | globalmark(); /* mark global variable values and names */ |
224 | travlock(); /* mark locked objects */ | 222 | travlock(); /* mark locked objects */ |
225 | luaT_travtagmethods(markobject); /* mark fallbacks */ | 223 | luaT_travtagmethods(markobject); /* mark tag methods */ |
224 | } | ||
225 | |||
226 | |||
227 | void luaC_collect (int all) { | ||
228 | L->GCthreshold *= 4; /* to avoid GC during GC */ | ||
229 | tableTM(); /* call TM for tables (if LUA_COMPAT_GC) */ | ||
230 | collecttable(); | ||
231 | collectstring(all?MAX_INT:1); | ||
232 | collectproto(); | ||
233 | collectclosure(); | ||
234 | luaD_gcIM(&luaO_nilobject); /* GC tag method for nil (signal end of GC) */ | ||
226 | } | 235 | } |
227 | 236 | ||
228 | 237 | ||
229 | long lua_collectgarbage (long limit) { | 238 | long lua_collectgarbage (long limit) { |
230 | unsigned long recovered = L->nblocks; /* to subtract nblocks after gc */ | 239 | unsigned long recovered = L->nblocks; /* to subtract nblocks after gc */ |
231 | Hash *freetable; | ||
232 | TaggedString *freestr; | ||
233 | TProtoFunc *freefunc; | ||
234 | Closure *freeclos; | ||
235 | markall(); | 240 | markall(); |
236 | invalidaterefs(); | 241 | luaR_invalidaterefs(); |
237 | freestr = luaS_collector(); | 242 | luaC_collect(0); |
238 | freetable = (Hash *)listcollect(&(L->roottable)); | 243 | recovered = recovered - L->nblocks; |
239 | freefunc = (TProtoFunc *)listcollect(&(L->rootproto)); | ||
240 | freeclos = (Closure *)listcollect(&(L->rootcl)); | ||
241 | L->GCthreshold *= 4; /* to avoid GC during GC */ | ||
242 | luaC_hashcallIM(freetable); /* GC tag methods for tables */ | ||
243 | luaC_strcallIM(freestr); /* GC tag methods for userdata */ | ||
244 | luaD_gcIM(&luaO_nilobject); /* GC tag method for nil (signal end of GC) */ | ||
245 | luaH_free(freetable); | ||
246 | luaS_free(freestr); | ||
247 | luaF_freeproto(freefunc); | ||
248 | luaF_freeclosure(freeclos); | ||
249 | recovered = recovered-L->nblocks; | ||
250 | L->GCthreshold = (limit == 0) ? 2*L->nblocks : L->nblocks+limit; | 244 | L->GCthreshold = (limit == 0) ? 2*L->nblocks : L->nblocks+limit; |
251 | return recovered; | 245 | return recovered; |
252 | } | 246 | } |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lgc.h,v 1.4 1997/12/01 20:31:25 roberto Exp roberto $ | 2 | ** $Id: lgc.h,v 1.5 1999/08/16 20:52:00 roberto Exp roberto $ |
3 | ** Garbage Collector | 3 | ** Garbage Collector |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -12,10 +12,7 @@ | |||
12 | 12 | ||
13 | 13 | ||
14 | void luaC_checkGC (void); | 14 | void luaC_checkGC (void); |
15 | const TObject *luaC_getref (int ref); | 15 | void luaC_collect (int all); |
16 | int luaC_ref (const TObject *o, int lock); | ||
17 | void luaC_hashcallIM (Hash *l); | ||
18 | void luaC_strcallIM (TaggedString *l); | ||
19 | 16 | ||
20 | 17 | ||
21 | #endif | 18 | #endif |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: llex.c,v 1.38 1999/08/16 20:52:00 roberto Exp roberto $ | 2 | ** $Id: llex.c,v 1.39 1999/09/06 13:55:09 roberto Exp roberto $ |
3 | ** Lexical Analyzer | 3 | ** Lexical Analyzer |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -37,7 +37,7 @@ void luaX_init (void) { | |||
37 | int i; | 37 | int i; |
38 | for (i=0; i<(sizeof(reserved)/sizeof(reserved[0])); i++) { | 38 | for (i=0; i<(sizeof(reserved)/sizeof(reserved[0])); i++) { |
39 | TaggedString *ts = luaS_new(reserved[i]); | 39 | TaggedString *ts = luaS_new(reserved[i]); |
40 | ts->head.marked = FIRST_RESERVED+i; /* reserved word (always > 255) */ | 40 | ts->marked = FIRST_RESERVED+i; /* reserved word (always > 255) */ |
41 | } | 41 | } |
42 | } | 42 | } |
43 | 43 | ||
@@ -426,8 +426,8 @@ int luaX_lex (LexState *LS) { | |||
426 | } while (isalnum(LS->current) || LS->current == '_'); | 426 | } while (isalnum(LS->current) || LS->current == '_'); |
427 | save('\0'); | 427 | save('\0'); |
428 | ts = luaS_new(L->Mbuffer+L->Mbuffbase); | 428 | ts = luaS_new(L->Mbuffer+L->Mbuffbase); |
429 | if (ts->head.marked >= FIRST_RESERVED) | 429 | if (ts->marked >= FIRST_RESERVED) |
430 | return ts->head.marked; /* reserved word */ | 430 | return ts->marked; /* reserved word */ |
431 | LS->seminfo.ts = ts; | 431 | LS->seminfo.ts = ts; |
432 | return NAME; | 432 | return NAME; |
433 | } | 433 | } |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lobject.c,v 1.22 1999/09/06 20:19:22 roberto Exp roberto $ | 2 | ** $Id: lobject.c,v 1.23 1999/09/08 20:45:18 roberto Exp roberto $ |
3 | ** Some generic functions over Lua objects | 3 | ** Some generic functions over Lua objects |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -55,13 +55,6 @@ int luaO_equalval (const TObject *t1, const TObject *t2) { | |||
55 | } | 55 | } |
56 | 56 | ||
57 | 57 | ||
58 | void luaO_insertlist (GCnode *root, GCnode *node) { | ||
59 | node->next = root->next; | ||
60 | root->next = node; | ||
61 | node->marked = 0; | ||
62 | } | ||
63 | |||
64 | |||
65 | #ifdef OLD_ANSI | 58 | #ifdef OLD_ANSI |
66 | void luaO_memup (void *dest, void *src, int size) { | 59 | void luaO_memup (void *dest, void *src, int size) { |
67 | while (size--) | 60 | while (size--) |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lobject.h,v 1.29 1999/08/16 20:52:00 roberto Exp roberto $ | 2 | ** $Id: lobject.h,v 1.30 1999/09/06 20:34:18 roberto Exp roberto $ |
3 | ** Type definitions for Lua objects | 3 | ** Type definitions for Lua objects |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -86,20 +86,12 @@ typedef struct TObject { | |||
86 | 86 | ||
87 | 87 | ||
88 | /* | 88 | /* |
89 | ** generic header for garbage collector lists | ||
90 | */ | ||
91 | typedef struct GCnode { | ||
92 | struct GCnode *next; | ||
93 | int marked; | ||
94 | } GCnode; | ||
95 | |||
96 | |||
97 | /* | ||
98 | ** String headers for string table | 89 | ** String headers for string table |
99 | */ | 90 | */ |
100 | 91 | ||
101 | typedef struct TaggedString { | 92 | typedef struct TaggedString { |
102 | GCnode head; | 93 | struct TaggedString *next; |
94 | int marked; | ||
103 | unsigned long hash; | 95 | unsigned long hash; |
104 | int constindex; /* hint to reuse constants (= -1 if this is a userdata) */ | 96 | int constindex; /* hint to reuse constants (= -1 if this is a userdata) */ |
105 | union { | 97 | union { |
@@ -122,7 +114,8 @@ typedef struct TaggedString { | |||
122 | ** Function Prototypes | 114 | ** Function Prototypes |
123 | */ | 115 | */ |
124 | typedef struct TProtoFunc { | 116 | typedef struct TProtoFunc { |
125 | GCnode head; | 117 | struct TProtoFunc *next; |
118 | int marked; | ||
126 | struct TObject *consts; | 119 | struct TObject *consts; |
127 | int nconsts; | 120 | int nconsts; |
128 | Byte *code; /* ends with opcode ENDCODE */ | 121 | Byte *code; /* ends with opcode ENDCODE */ |
@@ -157,7 +150,8 @@ typedef struct LocVar { | |||
157 | ** Closures | 150 | ** Closures |
158 | */ | 151 | */ |
159 | typedef struct Closure { | 152 | typedef struct Closure { |
160 | GCnode head; | 153 | struct Closure *next; |
154 | int marked; | ||
161 | int nelems; /* not included the first one (always the prototype) */ | 155 | int nelems; /* not included the first one (always the prototype) */ |
162 | TObject consts[1]; /* at least one for prototype */ | 156 | TObject consts[1]; /* at least one for prototype */ |
163 | } Closure; | 157 | } Closure; |
@@ -170,7 +164,8 @@ typedef struct node { | |||
170 | } Node; | 164 | } Node; |
171 | 165 | ||
172 | typedef struct Hash { | 166 | typedef struct Hash { |
173 | GCnode head; | 167 | struct Hash *next; |
168 | int marked; | ||
174 | Node *node; | 169 | Node *node; |
175 | int nhash; | 170 | int nhash; |
176 | int nuse; | 171 | int nuse; |
@@ -189,7 +184,6 @@ extern const TObject luaO_nilobject; | |||
189 | : luaO_equalval(t1,t2)) | 184 | : luaO_equalval(t1,t2)) |
190 | int luaO_equalval (const TObject *t1, const TObject *t2); | 185 | int luaO_equalval (const TObject *t1, const TObject *t2); |
191 | int luaO_redimension (int oldsize); | 186 | int luaO_redimension (int oldsize); |
192 | void luaO_insertlist (GCnode *root, GCnode *node); | ||
193 | int luaO_str2d (const char *s, real *result); | 187 | int luaO_str2d (const char *s, real *result); |
194 | 188 | ||
195 | #ifdef OLD_ANSI | 189 | #ifdef OLD_ANSI |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lstate.c,v 1.12 1999/05/11 20:08:20 roberto Exp roberto $ | 2 | ** $Id: lstate.c,v 1.13 1999/08/16 20:52:00 roberto Exp roberto $ |
3 | ** Global State | 3 | ** Global State |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -7,13 +7,11 @@ | |||
7 | 7 | ||
8 | #include "lbuiltin.h" | 8 | #include "lbuiltin.h" |
9 | #include "ldo.h" | 9 | #include "ldo.h" |
10 | #include "lfunc.h" | ||
11 | #include "lgc.h" | 10 | #include "lgc.h" |
12 | #include "llex.h" | 11 | #include "llex.h" |
13 | #include "lmem.h" | 12 | #include "lmem.h" |
14 | #include "lstate.h" | 13 | #include "lstate.h" |
15 | #include "lstring.h" | 14 | #include "lstring.h" |
16 | #include "ltable.h" | ||
17 | #include "ltm.h" | 15 | #include "ltm.h" |
18 | 16 | ||
19 | 17 | ||
@@ -36,14 +34,10 @@ void lua_open (void) { | |||
36 | L->debug = 0; | 34 | L->debug = 0; |
37 | L->callhook = NULL; | 35 | L->callhook = NULL; |
38 | L->linehook = NULL; | 36 | L->linehook = NULL; |
39 | L->rootproto.next = NULL; | 37 | L->rootproto = NULL; |
40 | L->rootproto.marked = 0; | 38 | L->rootcl = NULL; |
41 | L->rootcl.next = NULL; | 39 | L->rootglobal = NULL; |
42 | L->rootcl.marked = 0; | 40 | L->roottable = NULL; |
43 | L->rootglobal.next = NULL; | ||
44 | L->rootglobal.marked = 0; | ||
45 | L->roottable.next = NULL; | ||
46 | L->roottable.marked = 0; | ||
47 | L->IMtable = NULL; | 41 | L->IMtable = NULL; |
48 | L->refArray = NULL; | 42 | L->refArray = NULL; |
49 | L->refSize = 0; | 43 | L->refSize = 0; |
@@ -58,21 +52,14 @@ void lua_open (void) { | |||
58 | 52 | ||
59 | 53 | ||
60 | void lua_close (void) { | 54 | void lua_close (void) { |
61 | TaggedString *alludata = luaS_collectudata(); | 55 | luaC_collect(1); /* collect all elements */ |
62 | L->GCthreshold = MAX_INT; /* to avoid GC during GC */ | ||
63 | luaC_hashcallIM((Hash *)L->roottable.next); /* GC t.methods for tables */ | ||
64 | luaC_strcallIM(alludata); /* GC tag methods for userdata */ | ||
65 | luaD_gcIM(&luaO_nilobject); /* GC tag method for nil (signal end of GC) */ | ||
66 | luaH_free((Hash *)L->roottable.next); | ||
67 | luaF_freeproto((TProtoFunc *)L->rootproto.next); | ||
68 | luaF_freeclosure((Closure *)L->rootcl.next); | ||
69 | luaS_free(alludata); | ||
70 | luaS_freeall(); | 56 | luaS_freeall(); |
71 | luaM_free(L->stack.stack); | 57 | luaM_free(L->stack.stack); |
72 | luaM_free(L->IMtable); | 58 | luaM_free(L->IMtable); |
73 | luaM_free(L->refArray); | 59 | luaM_free(L->refArray); |
74 | luaM_free(L->Mbuffer); | 60 | luaM_free(L->Mbuffer); |
75 | luaM_free(L->Cblocks); | 61 | luaM_free(L->Cblocks); |
62 | LUA_ASSERT(L->nblocks == 0, "wrong count for nblocks"); | ||
76 | luaM_free(L); | 63 | luaM_free(L); |
77 | L = NULL; | 64 | L = NULL; |
78 | #ifdef DEBUG | 65 | #ifdef DEBUG |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lstate.h,v 1.18 1999/05/11 14:19:32 roberto Exp roberto $ | 2 | ** $Id: lstate.h,v 1.19 1999/05/11 20:08:20 roberto Exp roberto $ |
3 | ** Global State | 3 | ** Global State |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -73,10 +73,10 @@ struct lua_State { | |||
73 | lua_CHFunction callhook; | 73 | lua_CHFunction callhook; |
74 | lua_LHFunction linehook; | 74 | lua_LHFunction linehook; |
75 | /* global state */ | 75 | /* global state */ |
76 | GCnode rootproto; /* list of all prototypes */ | 76 | TProtoFunc *rootproto; /* list of all prototypes */ |
77 | GCnode rootcl; /* list of all closures */ | 77 | Closure *rootcl; /* list of all closures */ |
78 | GCnode roottable; /* list of all tables */ | 78 | Hash *roottable; /* list of all tables */ |
79 | GCnode rootglobal; /* list of strings with global values */ | 79 | TaggedString *rootglobal; /* list of strings with global values */ |
80 | stringtable *string_root; /* array of hash tables for strings and udata */ | 80 | stringtable *string_root; /* array of hash tables for strings and udata */ |
81 | struct IM *IMtable; /* table for tag methods */ | 81 | struct IM *IMtable; /* table for tag methods */ |
82 | int last_tag; /* last used tag in IMtable */ | 82 | int last_tag; /* last used tag in IMtable */ |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lstring.c,v 1.20 1999/08/16 20:52:00 roberto Exp roberto $ | 2 | ** $Id: lstring.c,v 1.21 1999/09/28 12:27:06 roberto Exp roberto $ |
3 | ** String table (keeps all strings handled by Lua) | 3 | ** String table (keeps all strings handled by Lua) |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -14,17 +14,13 @@ | |||
14 | #include "lua.h" | 14 | #include "lua.h" |
15 | 15 | ||
16 | 16 | ||
17 | #define NUM_HASHSTR 31 | ||
18 | #define NUM_HASHUDATA 31 | ||
19 | #define NUM_HASHS (NUM_HASHSTR+NUM_HASHUDATA) | ||
20 | |||
21 | 17 | ||
22 | #define gcsizestring(l) (1+(l/64)) /* "weight" for a string with length 'l' */ | 18 | #define gcsizestring(l) (1+(l/64)) /* "weight" for a string with length 'l' */ |
23 | 19 | ||
24 | 20 | ||
25 | 21 | ||
26 | static TaggedString EMPTY = {{NULL, 2}, 0L, 0, | 22 | TaggedString luaS_EMPTY = {NULL, MAX_INT, 0L, 0, |
27 | {{{LUA_T_NIL, {NULL}}, 0L}}, {0}}; | 23 | {{{LUA_T_NIL, {NULL}}, 0L}}, {0}}; |
28 | 24 | ||
29 | 25 | ||
30 | 26 | ||
@@ -49,6 +45,16 @@ void luaS_init (void) { | |||
49 | } | 45 | } |
50 | 46 | ||
51 | 47 | ||
48 | void luaS_freeall (void) { | ||
49 | int i; | ||
50 | for (i=0; i<NUM_HASHS; i++) { | ||
51 | if (L->string_root[i].hash != init_hash) | ||
52 | luaM_free(L->string_root[i].hash); | ||
53 | } | ||
54 | luaM_free(L->string_root); | ||
55 | } | ||
56 | |||
57 | |||
52 | static unsigned long hash_s (const char *s, long l) { | 58 | static unsigned long hash_s (const char *s, long l) { |
53 | unsigned long h = 0; /* seed */ | 59 | unsigned long h = 0; /* seed */ |
54 | while (l--) | 60 | while (l--) |
@@ -57,12 +63,12 @@ static unsigned long hash_s (const char *s, long l) { | |||
57 | } | 63 | } |
58 | 64 | ||
59 | 65 | ||
60 | static int newsize (stringtable *tb) { | 66 | static int newsize (const stringtable *tb) { |
61 | int realuse = 0; | 67 | int realuse = 0; |
62 | int i; | 68 | int i; |
63 | /* count how many entries are really in use */ | 69 | /* count how many entries are really in use */ |
64 | for (i=0; i<tb->size; i++) { | 70 | for (i=0; i<tb->size; i++) { |
65 | if (tb->hash[i] != NULL && tb->hash[i] != &EMPTY) | 71 | if (tb->hash[i] != NULL && tb->hash[i] != &luaS_EMPTY) |
66 | realuse++; | 72 | realuse++; |
67 | } | 73 | } |
68 | return luaO_redimension(realuse*2); | 74 | return luaO_redimension(realuse*2); |
@@ -78,7 +84,7 @@ static void grow (stringtable *tb) { | |||
78 | /* rehash */ | 84 | /* rehash */ |
79 | tb->nuse = 0; | 85 | tb->nuse = 0; |
80 | for (i=0; i<tb->size; i++) { | 86 | for (i=0; i<tb->size; i++) { |
81 | if (tb->hash[i] != NULL && tb->hash[i] != &EMPTY) { | 87 | if (tb->hash[i] != NULL && tb->hash[i] != &luaS_EMPTY) { |
82 | unsigned long h = tb->hash[i]->hash; | 88 | unsigned long h = tb->hash[i]->hash; |
83 | int h1 = h%ns; | 89 | int h1 = h%ns; |
84 | while (newhash[h1]) { | 90 | while (newhash[h1]) { |
@@ -103,8 +109,8 @@ static TaggedString *newone_s (const char *str, long l, unsigned long h) { | |||
103 | ts->u.s.len = l; | 109 | ts->u.s.len = l; |
104 | ts->constindex = 0; | 110 | ts->constindex = 0; |
105 | L->nblocks += gcsizestring(l); | 111 | L->nblocks += gcsizestring(l); |
106 | ts->head.marked = 0; | 112 | ts->marked = 0; |
107 | ts->head.next = (GCnode *)ts; /* signal it is in no list */ | 113 | ts->next = ts; /* signal it is in no list */ |
108 | ts->hash = h; | 114 | ts->hash = h; |
109 | return ts; | 115 | return ts; |
110 | } | 116 | } |
@@ -115,8 +121,8 @@ static TaggedString *newone_u (void *buff, int tag, unsigned long h) { | |||
115 | ts->u.d.tag = (tag == LUA_ANYTAG) ? 0 : tag; | 121 | ts->u.d.tag = (tag == LUA_ANYTAG) ? 0 : tag; |
116 | ts->constindex = -1; /* tag -> this is a userdata */ | 122 | ts->constindex = -1; /* tag -> this is a userdata */ |
117 | L->nblocks++; | 123 | L->nblocks++; |
118 | ts->head.marked = 0; | 124 | ts->marked = 0; |
119 | ts->head.next = (GCnode *)ts; /* signal it is in no list */ | 125 | ts->next = ts; /* signal it is in no list */ |
120 | ts->hash = h; | 126 | ts->hash = h; |
121 | return ts; | 127 | return ts; |
122 | } | 128 | } |
@@ -144,7 +150,7 @@ static TaggedString *insert_s (const char *str, long l, stringtable *tb) { | |||
144 | int j = -1; /* last empty place found (or -1) */ | 150 | int j = -1; /* last empty place found (or -1) */ |
145 | int h1 = h%size; | 151 | int h1 = h%size; |
146 | while ((ts = tb->hash[h1]) != NULL) { | 152 | while ((ts = tb->hash[h1]) != NULL) { |
147 | if (ts == &EMPTY) | 153 | if (ts == &luaS_EMPTY) |
148 | j = h1; | 154 | j = h1; |
149 | else if (ts->u.s.len == l && (memcmp(str, ts->str, l) == 0)) | 155 | else if (ts->u.s.len == l && (memcmp(str, ts->str, l) == 0)) |
150 | return ts; | 156 | return ts; |
@@ -168,7 +174,7 @@ static TaggedString *insert_u (void *buff, int tag, stringtable *tb) { | |||
168 | int j = -1; | 174 | int j = -1; |
169 | int h1 = h%size; | 175 | int h1 = h%size; |
170 | while ((ts = tb->hash[h1]) != NULL) { | 176 | while ((ts = tb->hash[h1]) != NULL) { |
171 | if (ts == &EMPTY) | 177 | if (ts == &luaS_EMPTY) |
172 | j = h1; | 178 | j = h1; |
173 | else if ((tag == ts->u.d.tag || tag == LUA_ANYTAG) && buff == ts->u.d.v) | 179 | else if ((tag == ts->u.d.tag || tag == LUA_ANYTAG) && buff == ts->u.d.v) |
174 | return ts; | 180 | return ts; |
@@ -200,115 +206,29 @@ TaggedString *luaS_new (const char *str) { | |||
200 | 206 | ||
201 | TaggedString *luaS_newfixedstring (const char *str) { | 207 | TaggedString *luaS_newfixedstring (const char *str) { |
202 | TaggedString *ts = luaS_new(str); | 208 | TaggedString *ts = luaS_new(str); |
203 | if (ts->head.marked == 0) | 209 | if (ts->marked == 0) ts->marked = 2; /* avoid GC */ |
204 | ts->head.marked = 2; /* avoid GC */ | ||
205 | return ts; | 210 | return ts; |
206 | } | 211 | } |
207 | 212 | ||
208 | 213 | ||
209 | void luaS_free (TaggedString *l) { | 214 | void luaS_free (TaggedString *t) { |
210 | while (l) { | 215 | L->nblocks -= (t->constindex == -1) ? 1 : gcsizestring(t->u.s.len); |
211 | TaggedString *next = (TaggedString *)l->head.next; | 216 | luaM_free(t); |
212 | L->nblocks -= (l->constindex == -1) ? 1 : gcsizestring(l->u.s.len); | ||
213 | luaM_free(l); | ||
214 | l = next; | ||
215 | } | ||
216 | } | ||
217 | |||
218 | |||
219 | /* | ||
220 | ** Garbage collection functions. | ||
221 | */ | ||
222 | |||
223 | static void remove_from_list (GCnode *l) { | ||
224 | while (l) { | ||
225 | GCnode *next = l->next; | ||
226 | while (next && !next->marked) | ||
227 | next = l->next = next->next; | ||
228 | l = next; | ||
229 | } | ||
230 | } | ||
231 | |||
232 | |||
233 | TaggedString *luaS_collector (void) { | ||
234 | TaggedString *frees = NULL; | ||
235 | int i; | ||
236 | remove_from_list(&(L->rootglobal)); | ||
237 | for (i=0; i<NUM_HASHS; i++) { | ||
238 | stringtable *tb = &L->string_root[i]; | ||
239 | int j; | ||
240 | for (j=0; j<tb->size; j++) { | ||
241 | TaggedString *t = tb->hash[j]; | ||
242 | if (t == NULL) continue; | ||
243 | if (t->head.marked == 1) | ||
244 | t->head.marked = 0; | ||
245 | else if (!t->head.marked) { | ||
246 | t->head.next = (GCnode *)frees; | ||
247 | frees = t; | ||
248 | tb->hash[j] = &EMPTY; | ||
249 | } | ||
250 | } | ||
251 | } | ||
252 | return frees; | ||
253 | } | ||
254 | |||
255 | |||
256 | TaggedString *luaS_collectudata (void) { | ||
257 | TaggedString *frees = NULL; | ||
258 | int i; | ||
259 | L->rootglobal.next = NULL; /* empty list of globals */ | ||
260 | for (i=NUM_HASHSTR; i<NUM_HASHS; i++) { | ||
261 | stringtable *tb = &L->string_root[i]; | ||
262 | int j; | ||
263 | for (j=0; j<tb->size; j++) { | ||
264 | TaggedString *t = tb->hash[j]; | ||
265 | if (t == NULL || t == &EMPTY) | ||
266 | continue; | ||
267 | LUA_ASSERT(t->constindex == -1, "must be userdata"); | ||
268 | t->head.next = (GCnode *)frees; | ||
269 | frees = t; | ||
270 | tb->hash[j] = &EMPTY; | ||
271 | } | ||
272 | } | ||
273 | return frees; | ||
274 | } | ||
275 | |||
276 | |||
277 | void luaS_freeall (void) { | ||
278 | int i; | ||
279 | for (i=0; i<NUM_HASHS; i++) { | ||
280 | stringtable *tb = &L->string_root[i]; | ||
281 | int j; | ||
282 | for (j=0; j<tb->size; j++) { | ||
283 | TaggedString *t = tb->hash[j]; | ||
284 | if (t != &EMPTY) luaM_free(t); | ||
285 | } | ||
286 | if (tb->hash != init_hash) luaM_free(tb->hash); | ||
287 | } | ||
288 | luaM_free(L->string_root); | ||
289 | } | 217 | } |
290 | 218 | ||
291 | 219 | ||
292 | void luaS_rawsetglobal (TaggedString *ts, TObject *newval) { | 220 | void luaS_rawsetglobal (TaggedString *ts, const TObject *newval) { |
293 | ts->u.s.globalval = *newval; | 221 | ts->u.s.globalval = *newval; |
294 | if (ts->head.next == (GCnode *)ts) { /* is not in list? */ | 222 | if (ts->next == ts) { /* is not in list? */ |
295 | ts->head.next = L->rootglobal.next; | 223 | ts->next = L->rootglobal; |
296 | L->rootglobal.next = (GCnode *)ts; | 224 | L->rootglobal = ts; |
297 | } | 225 | } |
298 | } | 226 | } |
299 | 227 | ||
300 | 228 | ||
301 | const char *luaS_travsymbol (int (*fn)(TObject *)) { | ||
302 | TaggedString *g; | ||
303 | for (g=(TaggedString *)L->rootglobal.next; g; g=(TaggedString *)g->head.next) | ||
304 | if (fn(&g->u.s.globalval)) | ||
305 | return g->str; | ||
306 | return NULL; | ||
307 | } | ||
308 | |||
309 | |||
310 | int luaS_globaldefined (const char *name) { | 229 | int luaS_globaldefined (const char *name) { |
311 | TaggedString *ts = luaS_new(name); | 230 | TaggedString *ts = luaS_new(name); |
312 | return ts->u.s.globalval.ttype != LUA_T_NIL; | 231 | return ts->u.s.globalval.ttype != LUA_T_NIL; |
313 | } | 232 | } |
314 | 233 | ||
234 | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lstring.h,v 1.7 1998/03/06 16:54:42 roberto Exp roberto $ | 2 | ** $Id: lstring.h,v 1.8 1999/08/16 20:52:00 roberto Exp roberto $ |
3 | ** String table (keep all strings handled by Lua) | 3 | ** String table (keep all strings handled by Lua) |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -11,18 +11,22 @@ | |||
11 | #include "lobject.h" | 11 | #include "lobject.h" |
12 | 12 | ||
13 | 13 | ||
14 | #define NUM_HASHSTR 31 | ||
15 | #define NUM_HASHUDATA 31 | ||
16 | #define NUM_HASHS (NUM_HASHSTR+NUM_HASHUDATA) | ||
17 | |||
18 | |||
19 | extern TaggedString luaS_EMPTY; | ||
20 | |||
14 | void luaS_init (void); | 21 | void luaS_init (void); |
15 | TaggedString *luaS_createudata (void *udata, int tag); | 22 | TaggedString *luaS_createudata (void *udata, int tag); |
16 | TaggedString *luaS_collector (void); | 23 | void luaS_freeall (void); |
17 | void luaS_free (TaggedString *l); | 24 | void luaS_free (TaggedString *ts); |
18 | TaggedString *luaS_newlstr (const char *str, long l); | 25 | TaggedString *luaS_newlstr (const char *str, long l); |
19 | TaggedString *luaS_new (const char *str); | 26 | TaggedString *luaS_new (const char *str); |
20 | TaggedString *luaS_newfixedstring (const char *str); | 27 | TaggedString *luaS_newfixedstring (const char *str); |
21 | void luaS_rawsetglobal (TaggedString *ts, TObject *newval); | 28 | void luaS_rawsetglobal (TaggedString *ts, const TObject *newval); |
22 | const char *luaS_travsymbol (int (*fn)(TObject *)); | ||
23 | int luaS_globaldefined (const char *name); | 29 | int luaS_globaldefined (const char *name); |
24 | TaggedString *luaS_collectudata (void); | ||
25 | void luaS_freeall (void); | ||
26 | 30 | ||
27 | 31 | ||
28 | #endif | 32 | #endif |
@@ -1,10 +1,9 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ltable.c,v 1.23 1999/08/16 20:52:00 roberto Exp roberto $ | 2 | ** $Id: ltable.c,v 1.24 1999/09/22 14:38:45 roberto Exp roberto $ |
3 | ** Lua tables (hash) | 3 | ** Lua tables (hash) |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
6 | 6 | ||
7 | #include <stdlib.h> | ||
8 | 7 | ||
9 | #include "lauxlib.h" | 8 | #include "lauxlib.h" |
10 | #include "lmem.h" | 9 | #include "lmem.h" |
@@ -69,17 +68,6 @@ Node *luaH_present (const Hash *t, const TObject *key) { | |||
69 | } | 68 | } |
70 | 69 | ||
71 | 70 | ||
72 | void luaH_free (Hash *frees) { | ||
73 | while (frees) { | ||
74 | Hash *next = (Hash *)frees->head.next; | ||
75 | L->nblocks -= gcsize(frees->nhash); | ||
76 | luaM_free(nodevector(frees)); | ||
77 | luaM_free(frees); | ||
78 | frees = next; | ||
79 | } | ||
80 | } | ||
81 | |||
82 | |||
83 | static Node *hashnodecreate (int nhash) { | 71 | static Node *hashnodecreate (int nhash) { |
84 | Node *const v = luaM_newvector(nhash, Node); | 72 | Node *const v = luaM_newvector(nhash, Node); |
85 | int i; | 73 | int i; |
@@ -96,12 +84,21 @@ Hash *luaH_new (int nhash) { | |||
96 | nhash(t) = nhash; | 84 | nhash(t) = nhash; |
97 | nuse(t) = 0; | 85 | nuse(t) = 0; |
98 | t->htag = TagDefault; | 86 | t->htag = TagDefault; |
99 | luaO_insertlist(&(L->roottable), (GCnode *)t); | 87 | t->next = L->roottable; |
88 | L->roottable = t; | ||
89 | t->marked = 0; | ||
100 | L->nblocks += gcsize(nhash); | 90 | L->nblocks += gcsize(nhash); |
101 | return t; | 91 | return t; |
102 | } | 92 | } |
103 | 93 | ||
104 | 94 | ||
95 | void luaH_free (Hash *t) { | ||
96 | L->nblocks -= gcsize(t->nhash); | ||
97 | luaM_free(nodevector(t)); | ||
98 | luaM_free(t); | ||
99 | } | ||
100 | |||
101 | |||
105 | static int newsize (Hash *t) { | 102 | static int newsize (Hash *t) { |
106 | Node *const v = t->node; | 103 | Node *const v = t->node; |
107 | const int size = nhash(t); | 104 | const int size = nhash(t); |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ltable.h,v 1.11 1999/02/23 14:57:28 roberto Exp roberto $ | 2 | ** $Id: ltable.h,v 1.12 1999/08/16 20:52:00 roberto Exp roberto $ |
3 | ** Lua tables (hash) | 3 | ** Lua tables (hash) |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -19,7 +19,7 @@ | |||
19 | #define luaH_move(t,from,to) (luaH_setint(t, to, luaH_getint(t, from))) | 19 | #define luaH_move(t,from,to) (luaH_setint(t, to, luaH_getint(t, from))) |
20 | 20 | ||
21 | Hash *luaH_new (int nhash); | 21 | Hash *luaH_new (int nhash); |
22 | void luaH_free (Hash *frees); | 22 | void luaH_free (Hash *t); |
23 | Node *luaH_present (const Hash *t, const TObject *key); | 23 | Node *luaH_present (const Hash *t, const TObject *key); |
24 | void luaH_set (Hash *t, const TObject *ref, const TObject *val); | 24 | void luaH_set (Hash *t, const TObject *ref, const TObject *val); |
25 | int luaH_pos (const Hash *t, const TObject *r); | 25 | int luaH_pos (const Hash *t, const TObject *r); |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ltm.c,v 1.26 1999/08/16 20:52:00 roberto Exp roberto $ | 2 | ** $Id: ltm.c,v 1.27 1999/09/20 14:57:29 roberto Exp roberto $ |
3 | ** Tag methods | 3 | ** Tag methods |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -39,13 +39,17 @@ static const char luaT_validevents[NUM_TAGS][IM_N] = { | |||
39 | {1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1}, /* LUA_T_USERDATA */ | 39 | {1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1}, /* LUA_T_USERDATA */ |
40 | {1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1}, /* LUA_T_NUMBER */ | 40 | {1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1}, /* LUA_T_NUMBER */ |
41 | {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, /* LUA_T_STRING */ | 41 | {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, /* LUA_T_STRING */ |
42 | {0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, /* LUA_T_ARRAY */ | 42 | {0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1}, /* LUA_T_ARRAY */ |
43 | {1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, /* LUA_T_PROTO */ | 43 | {1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, /* LUA_T_PROTO */ |
44 | {1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, /* LUA_T_CPROTO */ | 44 | {1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, /* LUA_T_CPROTO */ |
45 | {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1} /* LUA_T_NIL */ | 45 | {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1} /* LUA_T_NIL */ |
46 | }; | 46 | }; |
47 | 47 | ||
48 | int luaT_validevent (int t, int e) { /* ORDER LUA_T */ | 48 | int luaT_validevent (int t, int e) { /* ORDER LUA_T */ |
49 | #ifdef LUA_COMPAT_GC | ||
50 | if (t == LUA_T_ARRAY && e == IM_GC) | ||
51 | return 1; /* old versions allowed gc tag method for tables */ | ||
52 | #endif | ||
49 | return (t < LUA_T_NIL) ? 1 : luaT_validevents[-t][e]; | 53 | return (t < LUA_T_NIL) ? 1 : luaT_validevents[-t][e]; |
50 | } | 54 | } |
51 | 55 | ||
@@ -1,5 +1,5 @@ | |||
1 | # | 1 | # |
2 | ## $Id: makefile,v 1.19 1999/02/24 21:31:03 roberto Exp roberto $ | 2 | ## $Id: makefile,v 1.20 1999/08/17 20:21:52 roberto Exp roberto $ |
3 | ## Makefile | 3 | ## Makefile |
4 | ## See Copyright Notice in lua.h | 4 | ## See Copyright Notice in lua.h |
5 | # | 5 | # |
@@ -15,20 +15,19 @@ | |||
15 | # facilities (e.g. strerror, locale.h, memmove). SunOS does not comply; | 15 | # facilities (e.g. strerror, locale.h, memmove). SunOS does not comply; |
16 | # so, add "-DOLD_ANSI" on SunOS | 16 | # so, add "-DOLD_ANSI" on SunOS |
17 | # | 17 | # |
18 | # define LUA_COMPAT2_5 if yous system does need to be compatible with | ||
19 | # version 2.5 (or older) | ||
20 | # | ||
21 | # define LUA_NUM_TYPE if you need numbers to be different from double | 18 | # define LUA_NUM_TYPE if you need numbers to be different from double |
22 | # (for instance, -DLUA_NUM_TYPE=float) | 19 | # (for instance, -DLUA_NUM_TYPE=float) |
23 | # | 20 | # |
21 | # define LUA_COMPAT_GC if you need garbage-collect tag methods for tables | ||
22 | # (only for compatibility with previous versions) | ||
24 | 23 | ||
25 | CONFIG = -DPOPEN -D_POSIX_SOURCE | 24 | CONFIG = -DPOPEN -D_POSIX_SOURCE |
26 | #CONFIG = -DLUA_COMPAT2_5 -DOLD_ANSI -DDEBUG | 25 | #CONFIG = -DOLD_ANSI -DDEBUG -DLUA_COMPAT_GC |
27 | 26 | ||
28 | 27 | ||
29 | # Compilation parameters | 28 | # Compilation parameters |
30 | CC = gcc | 29 | CC = gcc |
31 | CWARNS = -Wall -Wmissing-prototypes -Wshadow -pedantic -Wpointer-arith -Wcast-align -Waggregate-return -Wwrite-strings -Wcast-qual -Wstrict-prototypes -Wmissing-declarations -Wnested-externs | 30 | CWARNS = -Wall -Wmissing-prototypes -Wshadow -pedantic -Wpointer-arith -Wcast-align -Waggregate-return -Wwrite-strings -Wcast-qual -Wstrict-prototypes -Wmissing-declarations -Wnested-externs -Werror |
32 | CFLAGS = $(CONFIG) $(CWARNS) -ansi -O2 | 31 | CFLAGS = $(CONFIG) $(CWARNS) -ansi -O2 |
33 | 32 | ||
34 | 33 | ||
@@ -53,6 +52,7 @@ LUAOBJS = \ | |||
53 | lmem.o \ | 52 | lmem.o \ |
54 | lobject.o \ | 53 | lobject.o \ |
55 | lparser.o \ | 54 | lparser.o \ |
55 | lref.o \ | ||
56 | lstate.o \ | 56 | lstate.o \ |
57 | lstring.o \ | 57 | lstring.o \ |
58 | ltable.o \ | 58 | ltable.o \ |
@@ -99,7 +99,7 @@ clear : | |||
99 | 99 | ||
100 | 100 | ||
101 | lapi.o: lapi.c lapi.h lua.h lobject.h lauxlib.h ldo.h lstate.h \ | 101 | lapi.o: lapi.c lapi.h lua.h lobject.h lauxlib.h ldo.h lstate.h \ |
102 | luadebug.h lfunc.h lgc.h lmem.h lstring.h ltable.h ltm.h lvm.h | 102 | luadebug.h lfunc.h lgc.h lmem.h lref.h lstring.h ltable.h ltm.h lvm.h |
103 | lauxlib.o: lauxlib.c lauxlib.h lua.h luadebug.h | 103 | lauxlib.o: lauxlib.c lauxlib.h lua.h luadebug.h |
104 | lbuffer.o: lbuffer.c lauxlib.h lua.h lmem.h lstate.h lobject.h \ | 104 | lbuffer.o: lbuffer.c lauxlib.h lua.h lmem.h lstate.h lobject.h \ |
105 | luadebug.h | 105 | luadebug.h |
@@ -107,11 +107,11 @@ lbuiltin.o: lbuiltin.c lapi.h lua.h lobject.h lauxlib.h lbuiltin.h \ | |||
107 | ldo.h lstate.h luadebug.h lfunc.h lmem.h lstring.h ltable.h ltm.h \ | 107 | ldo.h lstate.h luadebug.h lfunc.h lmem.h lstring.h ltable.h ltm.h \ |
108 | lundump.h lzio.h lvm.h | 108 | lundump.h lzio.h lvm.h |
109 | ldblib.o: ldblib.c lauxlib.h lua.h luadebug.h lualib.h | 109 | ldblib.o: ldblib.c lauxlib.h lua.h luadebug.h lualib.h |
110 | ldo.o: ldo.c ldo.h lobject.h lua.h lstate.h luadebug.h lfunc.h lgc.h \ | 110 | ldo.o: ldo.c lauxlib.h lua.h ldo.h lobject.h lstate.h luadebug.h lgc.h \ |
111 | lmem.h lparser.h lzio.h lstring.h ltm.h lundump.h lvm.h | 111 | lmem.h lparser.h lzio.h lstring.h ltm.h lundump.h lvm.h |
112 | lfunc.o: lfunc.c lfunc.h lobject.h lua.h lmem.h lstate.h luadebug.h | 112 | lfunc.o: lfunc.c lfunc.h lobject.h lua.h lmem.h lstate.h luadebug.h |
113 | lgc.o: lgc.c ldo.h lobject.h lua.h lstate.h luadebug.h lfunc.h lgc.h \ | 113 | lgc.o: lgc.c ldo.h lobject.h lua.h lstate.h luadebug.h lfunc.h lgc.h \ |
114 | lmem.h lstring.h ltable.h ltm.h | 114 | lref.h lstring.h ltable.h ltm.h |
115 | linit.o: linit.c lua.h lualib.h | 115 | linit.o: linit.c lua.h lualib.h |
116 | liolib.o: liolib.c lauxlib.h lua.h luadebug.h lualib.h | 116 | liolib.o: liolib.c lauxlib.h lua.h luadebug.h lualib.h |
117 | llex.o: llex.c lauxlib.h lua.h llex.h lobject.h lzio.h lmem.h \ | 117 | 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 \ | |||
119 | lmathlib.o: lmathlib.c lauxlib.h lua.h lualib.h | 119 | lmathlib.o: lmathlib.c lauxlib.h lua.h lualib.h |
120 | lmem.o: lmem.c lmem.h lstate.h lobject.h lua.h luadebug.h | 120 | lmem.o: lmem.c lmem.h lstate.h lobject.h lua.h luadebug.h |
121 | lobject.o: lobject.c lobject.h lua.h | 121 | lobject.o: lobject.c lobject.h lua.h |
122 | lparser.o: lparser.c lauxlib.h lua.h ldo.h lobject.h lstate.h \ | 122 | lparser.o: lparser.c ldo.h lobject.h lua.h lstate.h luadebug.h lfunc.h \ |
123 | luadebug.h lfunc.h llex.h lzio.h lmem.h lopcodes.h lparser.h \ | 123 | llex.h lzio.h lmem.h lopcodes.h lparser.h lstring.h |
124 | lstring.h | 124 | lref.o: lref.c lmem.h lref.h lobject.h lua.h lstate.h luadebug.h |
125 | lstate.o: lstate.c lbuiltin.h ldo.h lobject.h lua.h lstate.h \ | 125 | lstate.o: lstate.c lbuiltin.h ldo.h lobject.h lua.h lstate.h \ |
126 | luadebug.h lfunc.h lgc.h llex.h lzio.h lmem.h lstring.h ltable.h \ | 126 | luadebug.h lgc.h llex.h lzio.h lmem.h lstring.h ltm.h |
127 | ltm.h | ||
128 | lstring.o: lstring.c lmem.h lobject.h lua.h lstate.h luadebug.h \ | 127 | lstring.o: lstring.c lmem.h lobject.h lua.h lstate.h luadebug.h \ |
129 | lstring.h | 128 | lstring.h |
130 | lstrlib.o: lstrlib.c lauxlib.h lua.h lualib.h | 129 | 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 \ | |||
134 | ltm.h | 133 | ltm.h |
135 | lua.o: lua.c lua.h luadebug.h lualib.h | 134 | lua.o: lua.c lua.h luadebug.h lualib.h |
136 | lundump.o: lundump.c lauxlib.h lua.h lfunc.h lobject.h lmem.h \ | 135 | lundump.o: lundump.c lauxlib.h lua.h lfunc.h lobject.h lmem.h \ |
137 | lstring.h lundump.h lzio.h | 136 | lopcodes.h lstring.h lundump.h lzio.h |
138 | lvm.o: lvm.c lauxlib.h lua.h ldo.h lobject.h lstate.h luadebug.h \ | 137 | lvm.o: lvm.c lauxlib.h lua.h ldo.h lobject.h lstate.h luadebug.h \ |
139 | lfunc.h lgc.h lmem.h lopcodes.h lstring.h ltable.h ltm.h lvm.h | 138 | lfunc.h lgc.h lopcodes.h lstring.h ltable.h ltm.h lvm.h |
140 | lzio.o: lzio.c lzio.h | 139 | lzio.o: lzio.c lzio.h |
@@ -1,4 +1,4 @@ | |||
1 | % $Id: manual.tex,v 1.32 1999/05/11 20:46:28 roberto Exp roberto $ | 1 | % $Id: manual.tex,v 1.33 1999/05/27 20:21:03 roberto Exp roberto $ |
2 | 2 | ||
3 | \documentclass[11pt]{article} | 3 | \documentclass[11pt]{article} |
4 | \usepackage{fullpage,bnf} | 4 | \usepackage{fullpage,bnf} |
@@ -41,7 +41,7 @@ Waldemar Celes | |||
41 | \tecgraf\ --- Computer Science Department --- PUC-Rio | 41 | \tecgraf\ --- Computer Science Department --- PUC-Rio |
42 | } | 42 | } |
43 | 43 | ||
44 | \date{{\small \tt\$Date: 1999/05/11 20:46:28 $ $}} | 44 | \date{{\small \tt\$Date: 1999/05/27 20:21:03 $ $}} |
45 | 45 | ||
46 | \maketitle | 46 | \maketitle |
47 | 47 | ||
@@ -1273,7 +1273,8 @@ is terminated, returning an error condition. | |||
1273 | 1273 | ||
1274 | The only argument to \verb|_ERRORMESSAGE| is a string | 1274 | The only argument to \verb|_ERRORMESSAGE| is a string |
1275 | describing the error. | 1275 | describing the error. |
1276 | The default definition for this function calls \verb|_ALERT|, | 1276 | The default definition for |
1277 | this function calls \verb|_ALERT|, \Deffunc{_ALERT} | ||
1277 | which prints the message to \verb|stderr| \see{alert}. | 1278 | which prints the message to \verb|stderr| \see{alert}. |
1278 | The standard I/O library redefines \verb|_ERRORMESSAGE|, | 1279 | The standard I/O library redefines \verb|_ERRORMESSAGE|, |
1279 | and uses the debug facilities \see{debugI} | 1280 | and uses the debug facilities \see{debugI} |
@@ -1835,6 +1836,8 @@ void lua_unref (int ref); | |||
1835 | The function \verb|lua_ref| creates a reference | 1836 | The function \verb|lua_ref| creates a reference |
1836 | to the object that is on the top of the stack, | 1837 | to the object that is on the top of the stack, |
1837 | and returns this reference. | 1838 | and returns this reference. |
1839 | For a \nil{} object, the reference is always -1; | ||
1840 | otherwise, it is a non-negative integer. | ||
1838 | If \verb|lock| is true, the object is \emph{locked}: | 1841 | If \verb|lock| is true, the object is \emph{locked}: |
1839 | this means the object will not be garbage collected. | 1842 | this means the object will not be garbage collected. |
1840 | Note that an unlocked reference may be garbage collected. | 1843 | Note that an unlocked reference may be garbage collected. |
@@ -2503,26 +2506,32 @@ The following combinations are allowed in describing a character class: | |||
2503 | \item[\T{\%s}] --- represents all space characters. | 2506 | \item[\T{\%s}] --- represents all space characters. |
2504 | \item[\T{\%u}] --- represents all upper case letters. | 2507 | \item[\T{\%u}] --- represents all upper case letters. |
2505 | \item[\T{\%w}] --- represents all alphanumeric characters. | 2508 | \item[\T{\%w}] --- represents all alphanumeric characters. |
2506 | \item[\T{\%x}] --- represents all hexa-decimal digits. | 2509 | \item[\T{\%x}] --- represents all hexadecimal digits. |
2507 | \item[\T{\%z}] --- represents the character with representation 0. | 2510 | \item[\T{\%z}] --- represents the character with representation 0. |
2508 | \item[\T{\%\M{x}}] (where \M{x} is any non alphanumeric character) --- | 2511 | \item[\T{\%\M{x}}] (where \M{x} is any non alphanumeric character) --- |
2509 | represents the character \M{x}. | 2512 | represents the character \M{x}. |
2510 | This is the standard way to escape the magic characters \verb|()%.[]*-?|. | 2513 | This is the standard way to escape the magic characters \verb|()%.[]*-?|. |
2511 | It is strongly recommended that any control character (even the non magic), | 2514 | It is strongly recommended that any control character (even the non magic), |
2512 | when used to represent itself in a pattern, should be preceded by a \verb|%|. | 2515 | when used to represent itself in a pattern, should be preceded by a \verb|%|. |
2516 | |||
2513 | \item[\T{[char-set]}] --- | 2517 | \item[\T{[char-set]}] --- |
2514 | Represents the class which is the union of all | 2518 | Represents the class which is the union of all |
2515 | characters in char-set. | 2519 | characters in char-set. |
2516 | To include a \verb|]| in char-set, it must be the first character. | ||
2517 | A range of characters may be specified by | 2520 | A range of characters may be specified by |
2518 | separating the end characters of the range with a \verb|-|. | 2521 | separating the end characters of the range with a \verb|-|. |
2519 | If \verb|-| appears as the first or last character of char-set, | ||
2520 | then it represents itself. | ||
2521 | All classes \verb|%|\emph{x} described above can also be used as | 2522 | All classes \verb|%|\emph{x} described above can also be used as |
2522 | components in a char-set. | 2523 | components in a char-set. |
2523 | All other characters in char-set represent themselves. | 2524 | All other characters in char-set represent themselves. |
2524 | E.g., assuming an \emph{ascii} character set, | 2525 | E.g., \verb|[%w_]| (or \verb|[_%w]|) |
2525 | \verb|[%dA-Fa-f]| specifies the hexa-decimal digits. | 2526 | represents all alphanumeric characters plus the underscore, |
2527 | \verb|[0-7]| represents the octal digits, | ||
2528 | and \verb|[0-7%l%-]| represents the octal digits plus | ||
2529 | the lower case letters plus the \verb|-| character. | ||
2530 | |||
2531 | The interaction between ranges and classes is not defined. | ||
2532 | Therefore, patterns like \verb|[%a-z]| or \verb|[a-%%]| | ||
2533 | have no meaning. | ||
2534 | |||
2526 | \item[\T{[\^{ }char-set]}] --- | 2535 | \item[\T{[\^{ }char-set]}] --- |
2527 | represents the complement of char-set, | 2536 | represents the complement of char-set, |
2528 | where char-set is interpreted as above. | 2537 | where char-set is interpreted as above. |
@@ -3187,6 +3196,8 @@ accepting commands from standard input until an \verb|EOF|. | |||
3187 | Each line entered is immediately executed. | 3196 | Each line entered is immediately executed. |
3188 | \item[\T{-q}] same as \T{-i}, but without a prompt (quiet mode). | 3197 | \item[\T{-q}] same as \T{-i}, but without a prompt (quiet mode). |
3189 | \item[\T{-}] executes \verb|stdin| as a file. | 3198 | \item[\T{-}] executes \verb|stdin| as a file. |
3199 | \item[\T{--}] stops the execution of arguments; | ||
3200 | all arguments after it are simply passed to the Lua script. | ||
3190 | \item[\T{var=value}] sets global \verb|var| with string \verb|"value"|. | 3201 | \item[\T{var=value}] sets global \verb|var| with string \verb|"value"|. |
3191 | \item[\T{filename}] executes file \verb|filename| as a Lua chunk. | 3202 | \item[\T{filename}] executes file \verb|filename| as a Lua chunk. |
3192 | \end{description} | 3203 | \end{description} |
@@ -3203,6 +3214,37 @@ will first interact with the user until an \verb|EOF|, | |||
3203 | then will set \verb|a| to \verb|"test"|, | 3214 | then will set \verb|a| to \verb|"test"|, |
3204 | and finally will run the file \verb|prog.lua|. | 3215 | and finally will run the file \verb|prog.lua|. |
3205 | 3216 | ||
3217 | All arguments from the command line are passed to the Lua program in | ||
3218 | a table called \verb|arg|. | ||
3219 | If the command line has the \verb|--| argument, | ||
3220 | this argument is at index 0; | ||
3221 | the arguments after it get indices 1, 2, \ldots; | ||
3222 | and the arguments before it get negative indices. | ||
3223 | The field \verb|n| gets the index of the last argument, | ||
3224 | and the field \verb|nn| gets the index of the first argument | ||
3225 | (always a negative number). | ||
3226 | For instance: | ||
3227 | \begin{verbatim} | ||
3228 | $ lua -e "foreach(arg, print)" -- a b | ||
3229 | -1 foreach(arg, print) | ||
3230 | -2 -e | ||
3231 | -3 lua | ||
3232 | 0 -- | ||
3233 | 1 a | ||
3234 | 2 b | ||
3235 | nn -3 | ||
3236 | n 2 | ||
3237 | \end{verbatim} | ||
3238 | If the command line has no \verb|--| argument, | ||
3239 | all arguments have negative indices, with the last one at position -1. | ||
3240 | As a general rule, if you want to traverse all the | ||
3241 | arguments after the \verb|--|, you loop from 1 to \verb|arg.n| | ||
3242 | (you can use the \verb|foreachi| function, for instance). | ||
3243 | If you want to traverse all arguments, | ||
3244 | you loop from \verb|arg.nn| until \verb|arg.n|. | ||
3245 | In any case, you may call \verb|exit| at the end of a script, | ||
3246 | to stop Lua from running the other arguments. | ||
3247 | |||
3206 | When in interactive mode, | 3248 | When in interactive mode, |
3207 | a multi-line statement can be written finishing intermediate | 3249 | a multi-line statement can be written finishing intermediate |
3208 | lines with a backslash (\verb|\|). | 3250 | lines with a backslash (\verb|\|). |
@@ -3216,6 +3258,7 @@ In Unix systems, Lua scripts can be made into executable programs | |||
3216 | by using the \verb|#!| form, | 3258 | by using the \verb|#!| form, |
3217 | as in \verb|#!/usr/local/bin/lua|. | 3259 | as in \verb|#!/usr/local/bin/lua|. |
3218 | 3260 | ||
3261 | |||
3219 | \section*{Acknowledgments} | 3262 | \section*{Acknowledgments} |
3220 | 3263 | ||
3221 | The authors would like to thank CENPES/PETROBRAS which, | 3264 | The authors would like to thank CENPES/PETROBRAS which, |