summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lapi.c78
-rw-r--r--lapi.h3
-rw-r--r--lbuiltin.c102
-rw-r--r--lbuiltin.h7
-rw-r--r--lcode.c10
-rw-r--r--ldebug.c11
-rw-r--r--ldo.c5
-rw-r--r--lgc.c31
-rw-r--r--llex.c11
-rw-r--r--lobject.h12
-rw-r--r--lstate.c6
-rw-r--r--lstate.h6
-rw-r--r--lstring.c65
-rw-r--r--lstring.h7
-rw-r--r--ltable.c22
-rw-r--r--ltable.h6
-rw-r--r--ltests.c7
-rw-r--r--lua.h13
-rw-r--r--lundump.c5
-rw-r--r--lvm.c40
-rw-r--r--lvm.h7
21 files changed, 180 insertions, 274 deletions
diff --git a/lapi.c b/lapi.c
index 6685abdc..60a9b45c 100644
--- a/lapi.c
+++ b/lapi.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lapi.c,v 1.77 2000/03/29 20:19:20 roberto Exp roberto $ 2** $Id: lapi.c,v 1.78 2000/04/17 19:23:12 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*/
@@ -65,6 +65,20 @@ lua_Object lua_pop (lua_State *L) {
65} 65}
66 66
67 67
68void lua_pushglobaltable (lua_State *L) {
69 avalue(L->top) = L->gt;
70 ttype(L->top) = TAG_TABLE;
71 incr_top;
72}
73
74
75void lua_setglobaltable (lua_State *L, lua_Object newtable) {
76 if (lua_type(L, newtable)[0] != 't') /* type == "table"? */
77 lua_error(L, "Lua API error - invalid value for global table");
78 L->gt = avalue(newtable);
79}
80
81
68/* 82/*
69** Get a parameter, returning the object handle or LUA_NOOBJECT on error. 83** Get a parameter, returning the object handle or LUA_NOOBJECT on error.
70** `number' must be 1 to get the first parameter. 84** `number' must be 1 to get the first parameter.
@@ -131,7 +145,10 @@ void lua_settable (lua_State *L) {
131 145
132void lua_rawsettable (lua_State *L) { 146void lua_rawsettable (lua_State *L) {
133 luaA_checkCargs(L, 3); 147 luaA_checkCargs(L, 3);
134 luaV_rawsettable(L, L->top-3); 148 if (ttype(L->top-3) != TAG_TABLE)
149 lua_error(L, "indexed expression not a table");
150 luaH_set(L, avalue(L->top-3), L->top-2, L->top-1);
151 L->top -= 3;
135} 152}
136 153
137 154
@@ -145,27 +162,32 @@ lua_Object lua_createtable (lua_State *L) {
145 162
146 163
147lua_Object lua_getglobal (lua_State *L, const char *name) { 164lua_Object lua_getglobal (lua_State *L, const char *name) {
148 luaV_getglobal(L, luaS_assertglobalbyname(L, name), L->top++); 165 luaV_getglobal(L, luaS_new(L, name), L->top++);
149 return luaA_putObjectOnTop(L); 166 return luaA_putObjectOnTop(L);
150} 167}
151 168
152 169
153lua_Object lua_rawgetglobal (lua_State *L, const char *name) { 170void lua_setglobal (lua_State *L, const char *name) {
154 GlobalVar *gv = luaS_assertglobalbyname(L, name); 171 luaA_checkCargs(L, 1);
155 return luaA_putluaObject(L, &gv->value); 172 luaV_setglobal(L, luaS_new(L, name), L->top--);
156} 173}
157 174
158 175
159void lua_setglobal (lua_State *L, const char *name) { 176/* deprecated */
160 luaA_checkCargs(L, 1); 177lua_Object lua_rawgetglobal (lua_State *L, const char *name) {
161 luaV_setglobal(L, luaS_assertglobalbyname(L, name), L->top--); 178 lua_pushglobaltable(L);
179 lua_pushstring(L, name);
180 return lua_rawgettable(L);
162} 181}
163 182
164 183
184/* deprecated */
165void lua_rawsetglobal (lua_State *L, const char *name) { 185void lua_rawsetglobal (lua_State *L, const char *name) {
166 GlobalVar *gv = luaS_assertglobalbyname(L, name); 186 TObject key;
167 luaA_checkCargs(L, 1); 187 luaA_checkCargs(L, 1);
168 gv->value = *(--L->top); 188 ttype(&key) = TAG_STRING;
189 tsvalue(&key) = luaS_new(L, name);
190 luaH_set(L, L->gt, &key, --L->top);
169} 191}
170 192
171 193
@@ -334,40 +356,6 @@ void lua_settag (lua_State *L, int tag) {
334} 356}
335 357
336 358
337GlobalVar *luaA_nextvar (lua_State *L, TString *ts) {
338 GlobalVar *gv;
339 if (ts == NULL)
340 gv = L->rootglobal; /* first variable */
341 else {
342 /* check whether name is in global var list */
343 luaL_arg_check(L, ts->u.s.gv, 1, "variable name expected");
344 gv = ts->u.s.gv->next; /* get next */
345 }
346 while (gv && gv->value.ttype == TAG_NIL) /* skip globals with nil */
347 gv = gv->next;
348 if (gv) {
349 ttype(L->top) = TAG_STRING; tsvalue(L->top) = gv->name;
350 incr_top;
351 luaA_pushobject(L, &gv->value);
352 }
353 return gv;
354}
355
356
357const char *lua_nextvar (lua_State *L, const char *varname) {
358 TString *ts = (varname == NULL) ? NULL : luaS_new(L, varname);
359 GlobalVar *gv = luaA_nextvar(L, ts);
360 if (gv) {
361 top2LC(L, 2);
362 return gv->name->str;
363 }
364 else {
365 top2LC(L, 0);
366 return NULL;
367 }
368}
369
370
371int luaA_next (lua_State *L, const Hash *t, int i) { 359int luaA_next (lua_State *L, const Hash *t, int i) {
372 int tsize = t->size; 360 int tsize = t->size;
373 for (; i<tsize; i++) { 361 for (; i<tsize; i++) {
diff --git a/lapi.h b/lapi.h
index 7f43c2a0..ec0fa707 100644
--- a/lapi.h
+++ b/lapi.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lapi.h,v 1.15 2000/03/10 18:37:44 roberto Exp roberto $ 2** $Id: lapi.h,v 1.16 2000/03/29 20:19:20 roberto Exp roberto $
3** Auxiliary functions from Lua API 3** Auxiliary functions from Lua API
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -13,7 +13,6 @@
13 13
14void luaA_checkCargs (lua_State *L, int nargs); 14void luaA_checkCargs (lua_State *L, int nargs);
15void luaA_pushobject (lua_State *L, const TObject *o); 15void luaA_pushobject (lua_State *L, const TObject *o);
16GlobalVar *luaA_nextvar (lua_State *L, TString *g);
17int luaA_next (lua_State *L, const Hash *t, int i); 16int luaA_next (lua_State *L, const Hash *t, int i);
18lua_Object luaA_putluaObject (lua_State *L, const TObject *o); 17lua_Object luaA_putluaObject (lua_State *L, const TObject *o);
19lua_Object luaA_putObjectOnTop (lua_State *L); 18lua_Object luaA_putObjectOnTop (lua_State *L);
diff --git a/lbuiltin.c b/lbuiltin.c
index d57f9fa2..060127f7 100644
--- a/lbuiltin.c
+++ b/lbuiltin.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lbuiltin.c,v 1.106 2000/04/17 19:23:12 roberto Exp roberto $ 2** $Id: lbuiltin.c,v 1.107 2000/04/25 16:55:09 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*/
@@ -52,13 +52,6 @@ void luaB_opentests (lua_State *L);
52*/ 52*/
53 53
54 54
55static void pushtagstring (lua_State *L, TString *s) {
56 ttype(L->top) = TAG_STRING;
57 tsvalue(L->top) = s;
58 incr_top;
59}
60
61
62static Number getsize (const Hash *h) { 55static Number getsize (const Hash *h) {
63 Number max = 0; 56 Number max = 0;
64 int i = h->size; 57 int i = h->size;
@@ -191,21 +184,10 @@ void luaB_setglobal (lua_State *L) {
191 lua_setglobal(L, name); 184 lua_setglobal(L, name);
192} 185}
193 186
194void luaB_rawsetglobal (lua_State *L) {
195 const char *name = luaL_check_string(L, 1);
196 lua_Object value = luaL_nonnullarg(L, 2);
197 lua_pushobject(L, value);
198 lua_rawsetglobal(L, name);
199}
200
201void luaB_getglobal (lua_State *L) { 187void luaB_getglobal (lua_State *L) {
202 lua_pushobject(L, lua_getglobal(L, luaL_check_string(L, 1))); 188 lua_pushobject(L, lua_getglobal(L, luaL_check_string(L, 1)));
203} 189}
204 190
205void luaB_rawgetglobal (lua_State *L) {
206 lua_pushobject(L, lua_rawgetglobal(L, luaL_check_string(L, 1)));
207}
208
209void luaB_tag (lua_State *L) { 191void luaB_tag (lua_State *L) {
210 lua_pushnumber(L, lua_tag(L, luaL_nonnullarg(L, 1))); 192 lua_pushnumber(L, lua_tag(L, luaL_nonnullarg(L, 1)));
211} 193}
@@ -226,6 +208,12 @@ void luaB_copytagmethods (lua_State *L) {
226 luaL_check_int(L, 2))); 208 luaL_check_int(L, 2)));
227} 209}
228 210
211void luaB_globals (lua_State *L) {
212 lua_pushglobaltable(L);
213 if (lua_getparam(L, 1) != LUA_NOOBJECT)
214 lua_setglobaltable(L, luaL_tablearg(L, 1));
215}
216
229void luaB_rawgettable (lua_State *L) { 217void luaB_rawgettable (lua_State *L) {
230 lua_pushobject(L, luaL_nonnullarg(L, 1)); 218 lua_pushobject(L, luaL_nonnullarg(L, 1));
231 lua_pushobject(L, luaL_nonnullarg(L, 2)); 219 lua_pushobject(L, luaL_nonnullarg(L, 2));
@@ -346,20 +334,6 @@ void luaB_call (lua_State *L) {
346} 334}
347 335
348 336
349void luaB_nextvar (lua_State *L) {
350 lua_Object o = lua_getparam(L, 1);
351 TString *name;
352 if (o == LUA_NOOBJECT || ttype(o) == TAG_NIL)
353 name = NULL;
354 else {
355 luaL_arg_check(L, ttype(o) == TAG_STRING, 1, "variable name expected");
356 name = tsvalue(o);
357 }
358 if (!luaA_nextvar(L, name))
359 lua_pushnil(L);
360}
361
362
363void luaB_next (lua_State *L) { 337void luaB_next (lua_State *L) {
364 const Hash *a = gettable(L, 1); 338 const Hash *a = gettable(L, 1);
365 lua_Object k = lua_getparam(L, 2); 339 lua_Object k = lua_getparam(L, 2);
@@ -463,28 +437,6 @@ void luaB_foreach (lua_State *L) {
463} 437}
464 438
465 439
466void luaB_foreachvar (lua_State *L) {
467 lua_Object f = luaL_functionarg(L, 1);
468 GlobalVar *gv;
469 luaD_checkstack(L, 4); /* for extra var name, f, var name, and globalval */
470 for (gv = L->rootglobal; gv; gv = gv->next) {
471 if (gv->value.ttype != TAG_NIL) {
472 pushtagstring(L, gv->name); /* keep (extra) name on stack to avoid GC */
473 *(L->top++) = *f;
474 pushtagstring(L, gv->name);
475 *(L->top++) = gv->value;
476 luaD_call(L, L->top-3, 1);
477 if (ttype(L->top-1) != TAG_NIL) {
478 *(L->top-2) = *(L->top-1); /* remove extra name */
479 L->top--;
480 return;
481 }
482 L->top-=2; /* remove result and extra name */
483 }
484 }
485}
486
487
488void luaB_getn (lua_State *L) { 440void luaB_getn (lua_State *L) {
489 lua_pushnumber(L, getnarg(L, gettable(L, 1))); 441 lua_pushnumber(L, getnarg(L, gettable(L, 1)));
490} 442}
@@ -610,6 +562,39 @@ void luaB_sort (lua_State *L) {
610/* }====================================================== */ 562/* }====================================================== */
611 563
612 564
565/*
566** {======================================================
567** Deprecated functions to manipulate global environment:
568** all of them can be simulated through table operations
569** over the global table.
570** =======================================================
571*/
572
573#define num_deprecated 4
574
575static const struct luaL_reg deprecated_global_funcs[num_deprecated] = {
576 {"foreachvar", luaB_foreach},
577 {"nextvar", luaB_next},
578 {"rawgetglobal", luaB_rawgettable},
579 {"rawsetglobal", luaB_rawsettable}
580};
581
582
583
584static void deprecated_funcs (lua_State *L) {
585 TObject gt;
586 int i;
587 ttype(&gt) = TAG_TABLE;
588 avalue(&gt) = L->gt;
589 for (i=0; i<num_deprecated; i++) {
590 lua_pushobject(L, &gt);
591 lua_pushcclosure(L, deprecated_global_funcs[i].func, 1);
592 lua_setglobal(L, deprecated_global_funcs[i].name);
593 }
594}
595
596/* }====================================================== */
597
613static const struct luaL_reg builtin_funcs[] = { 598static const struct luaL_reg builtin_funcs[] = {
614 {"_ALERT", luaB__ALERT}, 599 {"_ALERT", luaB__ALERT},
615 {"_ERRORMESSAGE", luaB__ERRORMESSAGE}, 600 {"_ERRORMESSAGE", luaB__ERRORMESSAGE},
@@ -621,13 +606,11 @@ static const struct luaL_reg builtin_funcs[] = {
621 {"error", luaB_error}, 606 {"error", luaB_error},
622 {"getglobal", luaB_getglobal}, 607 {"getglobal", luaB_getglobal},
623 {"gettagmethod", luaB_gettagmethod}, 608 {"gettagmethod", luaB_gettagmethod},
609 {"globals", luaB_globals},
624 {"newtag", luaB_newtag}, 610 {"newtag", luaB_newtag},
625 {"next", luaB_next}, 611 {"next", luaB_next},
626 {"nextvar", luaB_nextvar},
627 {"print", luaB_print}, 612 {"print", luaB_print},
628 {"rawgetglobal", luaB_rawgetglobal},
629 {"rawgettable", luaB_rawgettable}, 613 {"rawgettable", luaB_rawgettable},
630 {"rawsetglobal", luaB_rawsetglobal},
631 {"rawsettable", luaB_rawsettable}, 614 {"rawsettable", luaB_rawsettable},
632 {"setglobal", luaB_setglobal}, 615 {"setglobal", luaB_setglobal},
633 {"settag", luaB_settag}, 616 {"settag", luaB_settag},
@@ -640,7 +623,6 @@ static const struct luaL_reg builtin_funcs[] = {
640 {"assert", luaB_assert}, 623 {"assert", luaB_assert},
641 {"foreach", luaB_foreach}, 624 {"foreach", luaB_foreach},
642 {"foreachi", luaB_foreachi}, 625 {"foreachi", luaB_foreachi},
643 {"foreachvar", luaB_foreachvar},
644 {"getn", luaB_getn}, 626 {"getn", luaB_getn},
645 {"sort", luaB_sort}, 627 {"sort", luaB_sort},
646 {"tinsert", luaB_tinsert}, 628 {"tinsert", luaB_tinsert},
@@ -648,6 +630,7 @@ static const struct luaL_reg builtin_funcs[] = {
648}; 630};
649 631
650 632
633
651void luaB_predefine (lua_State *L) { 634void luaB_predefine (lua_State *L) {
652 /* pre-register mem error messages, to avoid loop when error arises */ 635 /* pre-register mem error messages, to avoid loop when error arises */
653 luaS_newfixed(L, tableEM); 636 luaS_newfixed(L, tableEM);
@@ -658,5 +641,6 @@ void luaB_predefine (lua_State *L) {
658#endif 641#endif
659 lua_pushstring(L, LUA_VERSION); 642 lua_pushstring(L, LUA_VERSION);
660 lua_setglobal(L, "_VERSION"); 643 lua_setglobal(L, "_VERSION");
644 deprecated_funcs(L);
661} 645}
662 646
diff --git a/lbuiltin.h b/lbuiltin.h
index bf2376d3..2bf34105 100644
--- a/lbuiltin.h
+++ b/lbuiltin.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lbuiltin.h,v 1.6 2000/03/03 14:58:26 roberto Exp roberto $ 2** $Id: lbuiltin.h,v 1.7 2000/04/17 19:23:12 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*/
@@ -20,17 +20,14 @@ void luaB_dostring (lua_State *L);
20void luaB_error (lua_State *L); 20void luaB_error (lua_State *L);
21void luaB_foreach (lua_State *L); 21void luaB_foreach (lua_State *L);
22void luaB_foreachi (lua_State *L); 22void luaB_foreachi (lua_State *L);
23void luaB_foreachvar (lua_State *L);
24void luaB_getglobal (lua_State *L); 23void luaB_getglobal (lua_State *L);
25void luaB_getn (lua_State *L); 24void luaB_getn (lua_State *L);
26void luaB_gettagmethod (lua_State *L); 25void luaB_gettagmethod (lua_State *L);
26void luaB_globals (lua_State *L);
27void luaB_newtag (lua_State *L); 27void luaB_newtag (lua_State *L);
28void luaB_next (lua_State *L); 28void luaB_next (lua_State *L);
29void luaB_nextvar (lua_State *L);
30void luaB_print (lua_State *L); 29void luaB_print (lua_State *L);
31void luaB_rawgetglobal (lua_State *L);
32void luaB_rawgettable (lua_State *L); 30void luaB_rawgettable (lua_State *L);
33void luaB_rawsetglobal (lua_State *L);
34void luaB_rawsettable (lua_State *L); 31void luaB_rawsettable (lua_State *L);
35void luaB_setglobal (lua_State *L); 32void luaB_setglobal (lua_State *L);
36void luaB_settag (lua_State *L); 33void luaB_settag (lua_State *L);
diff --git a/lcode.c b/lcode.c
index 296d5cf3..b5ef968e 100644
--- a/lcode.c
+++ b/lcode.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lcode.c,v 1.27 2000/04/17 14:05:34 roberto Exp roberto $ 2** $Id: lcode.c,v 1.28 2000/04/19 13:41:37 roberto Exp roberto $
3** Code generator for Lua 3** Code generator for Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -16,7 +16,6 @@
16#include "lobject.h" 16#include "lobject.h"
17#include "lopcodes.h" 17#include "lopcodes.h"
18#include "lparser.h" 18#include "lparser.h"
19#include "lstring.h"
20 19
21 20
22void luaK_error (LexState *ls, const char *msg) { 21void luaK_error (LexState *ls, const char *msg) {
@@ -148,11 +147,6 @@ void luaK_setcallreturns (FuncState *fs, int nresults) {
148} 147}
149 148
150 149
151static void assertglobal (FuncState *fs, int index) {
152 luaS_assertglobal(fs->L, fs->f->kstr[index]);
153}
154
155
156static int discharge (FuncState *fs, expdesc *var) { 150static int discharge (FuncState *fs, expdesc *var) {
157 switch (var->k) { 151 switch (var->k) {
158 case VLOCAL: 152 case VLOCAL:
@@ -160,7 +154,6 @@ static int discharge (FuncState *fs, expdesc *var) {
160 break; 154 break;
161 case VGLOBAL: 155 case VGLOBAL:
162 luaK_code1(fs, OP_GETGLOBAL, var->u.index); 156 luaK_code1(fs, OP_GETGLOBAL, var->u.index);
163 assertglobal(fs, var->u.index); /* make sure that there is a global */
164 break; 157 break;
165 case VINDEXED: 158 case VINDEXED:
166 luaK_code0(fs, OP_GETTABLE); 159 luaK_code0(fs, OP_GETTABLE);
@@ -190,7 +183,6 @@ void luaK_storevar (LexState *ls, const expdesc *var) {
190 break; 183 break;
191 case VGLOBAL: 184 case VGLOBAL:
192 luaK_code1(fs, OP_SETGLOBAL, var->u.index); 185 luaK_code1(fs, OP_SETGLOBAL, var->u.index);
193 assertglobal(fs, var->u.index); /* make sure that there is a global */
194 break; 186 break;
195 case VINDEXED: /* table is at top-3; pop 3 elements after operation */ 187 case VINDEXED: /* table is at top-3; pop 3 elements after operation */
196 luaK_code2(fs, OP_SETTABLE, 3, 3); 188 luaK_code2(fs, OP_SETTABLE, 3, 3);
diff --git a/ldebug.c b/ldebug.c
index ef934d86..3a381455 100644
--- a/ldebug.c
+++ b/ldebug.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldebug.c,v 1.15 2000/03/30 17:19:48 roberto Exp roberto $ 2** $Id: ldebug.c,v 1.16 2000/03/30 20:55:50 roberto Exp roberto $
3** Debug Interface 3** Debug Interface
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -159,12 +159,13 @@ static int checkfunc (lua_State *L, TObject *o) {
159 159
160 160
161static void lua_getobjname (lua_State *L, StkId f, lua_Debug *ar) { 161static void lua_getobjname (lua_State *L, StkId f, lua_Debug *ar) {
162 GlobalVar *g; 162 Hash *g = L->gt;
163 int i;
163 /* try to find a name for given function */ 164 /* try to find a name for given function */
164 setnormalized(L->top, f); /* to be used by `checkfunc' */ 165 setnormalized(L->top, f); /* to be used by `checkfunc' */
165 for (g=L->rootglobal; g; g=g->next) { 166 for (i=0; i<=g->size; i++) {
166 if (checkfunc(L, &g->value)) { 167 if (checkfunc(L, val(node(g,i))) && ttype(key(node(g,i))) == TAG_STRING) {
167 ar->name = g->name->str; 168 ar->name = tsvalue(key(node(g,i)))->str;
168 ar->namewhat = "global"; 169 ar->namewhat = "global";
169 return; 170 return;
170 } 171 }
diff --git a/ldo.c b/ldo.c
index 9791c7f5..edbaab85 100644
--- a/ldo.c
+++ b/ldo.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldo.c,v 1.72 2000/03/30 20:55:50 roberto Exp roberto $ 2** $Id: ldo.c,v 1.73 2000/04/14 18:12:35 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*/
@@ -21,6 +21,7 @@
21#include "lparser.h" 21#include "lparser.h"
22#include "lstate.h" 22#include "lstate.h"
23#include "lstring.h" 23#include "lstring.h"
24#include "ltable.h"
24#include "ltm.h" 25#include "ltm.h"
25#include "lua.h" 26#include "lua.h"
26#include "luadebug.h" 27#include "luadebug.h"
@@ -222,7 +223,7 @@ void luaD_call (lua_State *L, StkId func, int nResults) {
222 223
223 224
224static void message (lua_State *L, const char *s) { 225static void message (lua_State *L, const char *s) {
225 const TObject *em = &(luaS_assertglobalbyname(L, "_ERRORMESSAGE")->value); 226 const TObject *em = luaH_getglobal(L, "_ERRORMESSAGE");
226 if (*luaO_typename(em) == 'f') { 227 if (*luaO_typename(em) == 'f') {
227 *L->top = *em; 228 *L->top = *em;
228 incr_top; 229 incr_top;
diff --git a/lgc.c b/lgc.c
index ac213df2..32dd6471 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.c,v 1.46 2000/03/30 20:55:50 roberto Exp roberto $ 2** $Id: lgc.c,v 1.47 2000/04/14 18:12:35 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*/
@@ -77,18 +77,6 @@ static void hashmark (lua_State *L, Hash *h) {
77} 77}
78 78
79 79
80static void travglobal (lua_State *L) {
81 GlobalVar *gv;
82 for (gv=L->rootglobal; gv; gv=gv->next) {
83 LUA_ASSERT(L, gv->name->u.s.gv == gv, "inconsistent global name");
84 if (gv->value.ttype != TAG_NIL) {
85 strmark(L, gv->name); /* cannot collect non nil global variables */
86 markobject(L, &gv->value);
87 }
88 }
89}
90
91
92static void travstack (lua_State *L) { 80static void travstack (lua_State *L) {
93 int i; 81 int i;
94 for (i = (L->top-1)-L->stack; i>=0; i--) 82 for (i = (L->top-1)-L->stack; i>=0; i--)
@@ -174,20 +162,6 @@ static void collecttable (lua_State *L) {
174 162
175 163
176/* 164/*
177** remove from the global list globals whose names will be collected
178** (the global itself is freed when its name is freed)
179*/
180static void clear_global_list (lua_State *L, int limit) {
181 GlobalVar **p = &L->rootglobal;
182 GlobalVar *next;
183 while ((next = *p) != NULL) {
184 if (next->name->marked >= limit) p = &next->next;
185 else *p = next->next;
186 }
187}
188
189
190/*
191** collect all elements with `marked' < `limit'. 165** collect all elements with `marked' < `limit'.
192** with limit=1, that means all unmarked elements; 166** with limit=1, that means all unmarked elements;
193** with limit=MAX_INT, that means all elements. 167** with limit=MAX_INT, that means all elements.
@@ -196,7 +170,6 @@ static void collectstring (lua_State *L, int limit) {
196 TObject o; /* to call userdata `gc' tag method */ 170 TObject o; /* to call userdata `gc' tag method */
197 int i; 171 int i;
198 ttype(&o) = TAG_USERDATA; 172 ttype(&o) = TAG_USERDATA;
199 clear_global_list(L, limit);
200 for (i=0; i<NUM_HASHS; i++) { /* for each hash table */ 173 for (i=0; i<NUM_HASHS; i++) { /* for each hash table */
201 stringtable *tb = &L->string_root[i]; 174 stringtable *tb = &L->string_root[i];
202 int j; 175 int j;
@@ -228,7 +201,7 @@ static void collectstring (lua_State *L, int limit) {
228 201
229static void markall (lua_State *L) { 202static void markall (lua_State *L) {
230 travstack(L); /* mark stack objects */ 203 travstack(L); /* mark stack objects */
231 travglobal(L); /* mark global variable values and names */ 204 hashmark(L, L->gt); /* mark global variable values and names */
232 travlock(L); /* mark locked objects */ 205 travlock(L); /* mark locked objects */
233 luaT_travtagmethods(L, markobject); /* mark tag methods */ 206 luaT_travtagmethods(L, markobject); /* mark tag methods */
234} 207}
diff --git a/llex.c b/llex.c
index 4efcb873..ae498715 100644
--- a/llex.c
+++ b/llex.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: llex.c,v 1.56 2000/04/07 13:11:49 roberto Exp roberto $ 2** $Id: llex.c,v 1.57 2000/04/12 18:57:19 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*/
@@ -18,6 +18,7 @@
18#include "lparser.h" 18#include "lparser.h"
19#include "lstate.h" 19#include "lstate.h"
20#include "lstring.h" 20#include "lstring.h"
21#include "ltable.h"
21#include "luadebug.h" 22#include "luadebug.h"
22#include "lzio.h" 23#include "lzio.h"
23 24
@@ -121,12 +122,18 @@ static void skipspace (LexState *LS) {
121} 122}
122 123
123 124
125static int globaldefined (lua_State *L, const char *name) {
126 const TObject *value = luaH_getglobal(L, name);
127 return ttype(value) != TAG_NIL;
128}
129
130
124static int checkcond (lua_State *L, LexState *LS, const char *buff) { 131static int checkcond (lua_State *L, LexState *LS, const char *buff) {
125 static const char *const opts[] = {"nil", "1", NULL}; 132 static const char *const opts[] = {"nil", "1", NULL};
126 int i = luaL_findstring(buff, opts); 133 int i = luaL_findstring(buff, opts);
127 if (i >= 0) return i; 134 if (i >= 0) return i;
128 else if (isalpha((unsigned char)buff[0]) || buff[0] == '_') 135 else if (isalpha((unsigned char)buff[0]) || buff[0] == '_')
129 return luaS_globaldefined(L, buff); 136 return globaldefined(L, buff);
130 else { 137 else {
131 luaX_syntaxerror(LS, "invalid $if condition", buff); 138 luaX_syntaxerror(LS, "invalid $if condition", buff);
132 return 0; /* to avoid warnings */ 139 return 0; /* to avoid warnings */
diff --git a/lobject.h b/lobject.h
index 921a7a05..c4e605c6 100644
--- a/lobject.h
+++ b/lobject.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lobject.h,v 1.60 2000/04/10 19:20:24 roberto Exp roberto $ 2** $Id: lobject.h,v 1.61 2000/04/25 16:55:09 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*/
@@ -85,20 +85,13 @@ typedef struct TObject {
85} TObject; 85} TObject;
86 86
87 87
88typedef struct GlobalVar {
89 TObject value;
90 struct GlobalVar *next;
91 struct TString *name;
92} GlobalVar;
93
94
95/* 88/*
96** String headers for string table 89** String headers for string table
97*/ 90*/
98typedef struct TString { 91typedef struct TString {
99 union { 92 union {
100 struct { /* for strings */ 93 struct { /* for strings */
101 GlobalVar *gv; /* eventual global value with this name */ 94 unsigned long hash;
102 long len; 95 long len;
103 } s; 96 } s;
104 struct { /* for userdata */ 97 struct { /* for userdata */
@@ -107,7 +100,6 @@ typedef struct TString {
107 } d; 100 } d;
108 } u; 101 } u;
109 struct TString *nexthash; /* chain for hash table */ 102 struct TString *nexthash; /* chain for hash table */
110 unsigned long hash;
111 int constindex; /* hint to reuse constants (= -1 if this is a userdata) */ 103 int constindex; /* hint to reuse constants (= -1 if this is a userdata) */
112 unsigned char marked; 104 unsigned char marked;
113 char str[1]; /* variable length string!! must be the last field! */ 105 char str[1]; /* variable length string!! must be the last field! */
diff --git a/lstate.c b/lstate.c
index f1949df0..7ba9bcff 100644
--- a/lstate.c
+++ b/lstate.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstate.c,v 1.24 2000/01/13 16:30:47 roberto Exp roberto $ 2** $Id: lstate.c,v 1.25 2000/03/31 16:28:45 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*/
@@ -18,6 +18,7 @@
18#include "lref.h" 18#include "lref.h"
19#include "lstate.h" 19#include "lstate.h"
20#include "lstring.h" 20#include "lstring.h"
21#include "ltable.h"
21#include "ltm.h" 22#include "ltm.h"
22 23
23 24
@@ -35,7 +36,6 @@ static lua_State *newstate_aux (int stacksize, int put_builtin) {
35 L->numCblocks = 0; 36 L->numCblocks = 0;
36 L->rootproto = NULL; 37 L->rootproto = NULL;
37 L->rootcl = NULL; 38 L->rootcl = NULL;
38 L->rootglobal = NULL;
39 L->roottable = NULL; 39 L->roottable = NULL;
40 L->IMtable = NULL; 40 L->IMtable = NULL;
41 L->refArray = NULL; 41 L->refArray = NULL;
@@ -47,6 +47,7 @@ static lua_State *newstate_aux (int stacksize, int put_builtin) {
47 L->callhook = NULL; 47 L->callhook = NULL;
48 L->linehook = NULL; 48 L->linehook = NULL;
49 L->allowhooks = 1; 49 L->allowhooks = 1;
50 L->gt = luaH_new(L, 10);
50 luaD_init(L, stacksize); 51 luaD_init(L, stacksize);
51 luaS_init(L); 52 luaS_init(L);
52 luaX_init(L); 53 luaX_init(L);
@@ -87,7 +88,6 @@ void lua_close (lua_State *L) {
87 luaC_collect(L, 1); /* collect all elements */ 88 luaC_collect(L, 1); /* collect all elements */
88 LUA_ASSERT(L, L->rootproto == NULL, "list should be empty"); 89 LUA_ASSERT(L, L->rootproto == NULL, "list should be empty");
89 LUA_ASSERT(L, L->rootcl == NULL, "list should be empty"); 90 LUA_ASSERT(L, L->rootcl == NULL, "list should be empty");
90 LUA_ASSERT(L, L->rootglobal == NULL, "list should be empty");
91 LUA_ASSERT(L, L->roottable == NULL, "list should be empty"); 91 LUA_ASSERT(L, L->roottable == NULL, "list should be empty");
92 luaS_freeall(L); 92 luaS_freeall(L);
93 luaM_free(L, L->stack); 93 luaM_free(L, L->stack);
diff --git a/lstate.h b/lstate.h
index d099e6aa..6e943b30 100644
--- a/lstate.h
+++ b/lstate.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstate.h,v 1.30 2000/03/10 18:37:44 roberto Exp roberto $ 2** $Id: lstate.h,v 1.31 2000/03/30 17:19:48 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*/
@@ -42,7 +42,7 @@ struct C_Lua_Stack {
42 42
43typedef struct stringtable { 43typedef struct stringtable {
44 int size; 44 int size;
45 int nuse; /* number of elements (including EMPTYs) */ 45 int nuse; /* number of elements */
46 TString **hash; 46 TString **hash;
47} stringtable; 47} stringtable;
48 48
@@ -66,8 +66,8 @@ struct lua_State {
66 Proto *rootproto; /* list of all prototypes */ 66 Proto *rootproto; /* list of all prototypes */
67 Closure *rootcl; /* list of all closures */ 67 Closure *rootcl; /* list of all closures */
68 Hash *roottable; /* list of all tables */ 68 Hash *roottable; /* list of all tables */
69 GlobalVar *rootglobal; /* list of global variables */
70 stringtable *string_root; /* array of hash tables for strings and udata */ 69 stringtable *string_root; /* array of hash tables for strings and udata */
70 Hash *gt; /* table for globals */
71 struct IM *IMtable; /* table for tag methods */ 71 struct IM *IMtable; /* table for tag methods */
72 int last_tag; /* last used tag in IMtable */ 72 int last_tag; /* last used tag in IMtable */
73 struct Ref *refArray; /* locked objects */ 73 struct Ref *refArray; /* locked objects */
diff --git a/lstring.c b/lstring.c
index 1dd4c9b9..3c9d0d8f 100644
--- a/lstring.c
+++ b/lstring.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstring.c,v 1.33 2000/03/10 14:38:10 roberto Exp roberto $ 2** $Id: lstring.c,v 1.34 2000/03/10 18:37:44 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*/
@@ -62,11 +62,13 @@ void luaS_resize (lua_State *L, stringtable *tb, int newsize) {
62 TString *p = tb->hash[i]; 62 TString *p = tb->hash[i];
63 while (p) { /* for each node in the list */ 63 while (p) { /* for each node in the list */
64 TString *next = p->nexthash; /* save next */ 64 TString *next = p->nexthash; /* save next */
65 int h = p->hash&(newsize-1); /* new position */ 65 unsigned long h = (p->constindex == -1) ? IntPoint(p->u.d.value) :
66 LUA_ASSERT(L, p->hash%newsize == (p->hash&(newsize-1)), 66 p->u.s.hash;
67 int h1 = h&(newsize-1); /* new position */
68 LUA_ASSERT(L, h%newsize == (h&(newsize-1)),
67 "a&(x-1) == a%x, for x power of 2"); 69 "a&(x-1) == a%x, for x power of 2");
68 p->nexthash = newhash[h]; /* chain it in new position */ 70 p->nexthash = newhash[h1]; /* chain it in new position */
69 newhash[h] = p; 71 newhash[h1] = p;
70 p = next; 72 p = next;
71 } 73 }
72 } 74 }
@@ -76,32 +78,29 @@ void luaS_resize (lua_State *L, stringtable *tb, int newsize) {
76} 78}
77 79
78 80
79static TString *newone (lua_State *L, long l, unsigned long h) { 81static TString *newone (lua_State *L, long l) {
80 TString *ts = (TString *)luaM_malloc(L, 82 TString *ts = (TString *)luaM_malloc(L, sizeof(TString)+l*sizeof(char));
81 sizeof(TString)+l*sizeof(char));
82 ts->marked = 0; 83 ts->marked = 0;
83 ts->nexthash = NULL; 84 ts->nexthash = NULL;
84 ts->hash = h;
85 return ts; 85 return ts;
86} 86}
87 87
88 88
89static TString *newone_s (lua_State *L, const char *str, 89static TString *newone_s (lua_State *L, const char *str,
90 long l, unsigned long h) { 90 long l, unsigned long h) {
91 TString *ts = newone(L, l, h); 91 TString *ts = newone(L, l);
92 memcpy(ts->str, str, l); 92 memcpy(ts->str, str, l);
93 ts->str[l] = 0; /* ending 0 */ 93 ts->str[l] = 0; /* ending 0 */
94 ts->u.s.gv = NULL; /* no global value */
95 ts->u.s.len = l; 94 ts->u.s.len = l;
95 ts->u.s.hash = h;
96 ts->constindex = 0; 96 ts->constindex = 0;
97 L->nblocks += gcsizestring(L, l); 97 L->nblocks += gcsizestring(L, l);
98 return ts; 98 return ts;
99} 99}
100 100
101 101
102static TString *newone_u (lua_State *L, void *buff, 102static TString *newone_u (lua_State *L, void *buff, int tag) {
103 int tag, unsigned long h) { 103 TString *ts = newone(L, 0);
104 TString *ts = newone(L, 0, h);
105 ts->u.d.value = buff; 104 ts->u.d.value = buff;
106 ts->u.d.tag = (tag == LUA_ANYTAG) ? 0 : tag; 105 ts->u.d.tag = (tag == LUA_ANYTAG) ? 0 : tag;
107 ts->constindex = -1; /* tag -> this is a userdata */ 106 ts->constindex = -1; /* tag -> this is a userdata */
@@ -141,7 +140,7 @@ TString *luaS_newlstr (lua_State *L, const char *str, long l) {
141** so two '&' operations would be highly correlated 140** so two '&' operations would be highly correlated
142*/ 141*/
143TString *luaS_createudata (lua_State *L, void *udata, int tag) { 142TString *luaS_createudata (lua_State *L, void *udata, int tag) {
144 unsigned long h = IntPoint(L, udata); 143 unsigned long h = IntPoint(udata);
145 stringtable *tb = &L->string_root[(h%NUM_HASHUDATA)+NUM_HASHSTR]; 144 stringtable *tb = &L->string_root[(h%NUM_HASHUDATA)+NUM_HASHSTR];
146 int h1 = h&(tb->size-1); 145 int h1 = h&(tb->size-1);
147 TString *ts; 146 TString *ts;
@@ -150,7 +149,7 @@ TString *luaS_createudata (lua_State *L, void *udata, int tag) {
150 return ts; 149 return ts;
151 } 150 }
152 /* not found */ 151 /* not found */
153 ts = newone_u(L, udata, tag, h); 152 ts = newone_u(L, udata, tag);
154 newentry(L, tb, ts, h1); 153 newentry(L, tb, ts, h1);
155 return ts; 154 return ts;
156} 155}
@@ -168,38 +167,8 @@ TString *luaS_newfixed (lua_State *L, const char *str) {
168 167
169 168
170void luaS_free (lua_State *L, TString *t) { 169void luaS_free (lua_State *L, TString *t) {
171 if (t->constindex == -1) /* is userdata? */ 170 L->nblocks -= (t->constindex == -1) ? gcsizeudata :
172 L->nblocks -= gcsizeudata; 171 gcsizestring(L, t->u.s.len);
173 else { /* is string */
174 L->nblocks -= gcsizestring(L, t->u.s.len);
175 luaM_free(L, t->u.s.gv);
176 }
177 luaM_free(L, t); 172 luaM_free(L, t);
178} 173}
179 174
180
181GlobalVar *luaS_assertglobal (lua_State *L, TString *ts) {
182 GlobalVar *gv = ts->u.s.gv;
183 if (!gv) { /* no global value yet? */
184 gv = luaM_new(L, GlobalVar);
185 gv->value.ttype = TAG_NIL; /* initial value */
186 gv->name = ts;
187 gv->next = L->rootglobal; /* chain in global list */
188 L->rootglobal = gv;
189 ts->u.s.gv = gv;
190 }
191 return gv;
192}
193
194
195GlobalVar *luaS_assertglobalbyname (lua_State *L, const char *name) {
196 return luaS_assertglobal(L, luaS_new(L, name));
197}
198
199
200int luaS_globaldefined (lua_State *L, const char *name) {
201 TString *ts = luaS_new(L, name);
202 return ts->u.s.gv && ts->u.s.gv->value.ttype != TAG_NIL;
203}
204
205
diff --git a/lstring.h b/lstring.h
index 80aa0b8f..8e307292 100644
--- a/lstring.h
+++ b/lstring.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstring.h,v 1.17 2000/03/10 14:38:10 roberto Exp roberto $ 2** $Id: lstring.h,v 1.18 2000/03/10 18:37:44 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*/
@@ -18,7 +18,7 @@
18 18
19 19
20/* 20/*
21** any taggedstring with mark>=FIXMARK is never collected. 21** any TString with mark>=FIXMARK is never collected.
22** Marks>=RESERVEDMARK are used to identify reserved words. 22** Marks>=RESERVEDMARK are used to identify reserved words.
23*/ 23*/
24#define FIXMARK 2 24#define FIXMARK 2
@@ -33,9 +33,6 @@ void luaS_free (lua_State *L, TString *ts);
33TString *luaS_newlstr (lua_State *L, const char *str, long l); 33TString *luaS_newlstr (lua_State *L, const char *str, long l);
34TString *luaS_new (lua_State *L, const char *str); 34TString *luaS_new (lua_State *L, const char *str);
35TString *luaS_newfixed (lua_State *L, const char *str); 35TString *luaS_newfixed (lua_State *L, const char *str);
36GlobalVar *luaS_assertglobal (lua_State *L, TString *ts);
37GlobalVar *luaS_assertglobalbyname (lua_State *L, const char *name);
38int luaS_globaldefined (lua_State *L, const char *name);
39 36
40 37
41#endif 38#endif
diff --git a/ltable.c b/ltable.c
index cc3a64f1..fb8b3dfe 100644
--- a/ltable.c
+++ b/ltable.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltable.c,v 1.39 2000/03/31 16:28:45 roberto Exp roberto $ 2** $Id: ltable.c,v 1.40 2000/04/25 16:55:09 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*/
@@ -24,6 +24,7 @@
24#include "lmem.h" 24#include "lmem.h"
25#include "lobject.h" 25#include "lobject.h"
26#include "lstate.h" 26#include "lstate.h"
27#include "lstring.h"
27#include "ltable.h" 28#include "ltable.h"
28#include "lua.h" 29#include "lua.h"
29 30
@@ -46,14 +47,17 @@ Node *luaH_mainposition (const Hash *t, const TObject *key) {
46 case TAG_NUMBER: 47 case TAG_NUMBER:
47 h = (unsigned long)(long)nvalue(key); 48 h = (unsigned long)(long)nvalue(key);
48 break; 49 break;
49 case TAG_STRING: case TAG_USERDATA: 50 case TAG_STRING:
50 h = tsvalue(key)->hash; 51 h = tsvalue(key)->u.s.hash;
52 break;
53 case TAG_USERDATA:
54 h = IntPoint(tsvalue(key));
51 break; 55 break;
52 case TAG_TABLE: 56 case TAG_TABLE:
53 h = IntPoint(L, avalue(key)); 57 h = IntPoint(avalue(key));
54 break; 58 break;
55 case TAG_LCLOSURE: case TAG_CCLOSURE: 59 case TAG_LCLOSURE: case TAG_CCLOSURE:
56 h = IntPoint(L, clvalue(key)); 60 h = IntPoint(clvalue(key));
57 break; 61 break;
58 default: 62 default:
59 return NULL; /* invalid key */ 63 return NULL; /* invalid key */
@@ -91,8 +95,8 @@ const TObject *luaH_getnum (const Hash *t, Number key) {
91 95
92 96
93/* specialized version for strings */ 97/* specialized version for strings */
94static const TObject *luaH_getstr (const Hash *t, TString *key) { 98const TObject *luaH_getstr (const Hash *t, TString *key) {
95 Node *n = &t->node[key->hash&(t->size-1)]; 99 Node *n = &t->node[key->u.s.hash&(t->size-1)];
96 do { 100 do {
97 if (ttype(&n->key) == TAG_STRING && tsvalue(&n->key) == key) 101 if (ttype(&n->key) == TAG_STRING && tsvalue(&n->key) == key)
98 return &n->val; 102 return &n->val;
@@ -248,3 +252,7 @@ void luaH_setint (lua_State *L, Hash *t, int key, const TObject *val) {
248 luaH_set(L, t, &index, val); 252 luaH_set(L, t, &index, val);
249} 253}
250 254
255
256const TObject *luaH_getglobal (lua_State *L, const char *name) {
257 return luaH_getstr(L->gt, luaS_new(L, name));
258}
diff --git a/ltable.h b/ltable.h
index 9a5fe9a5..3d1f674a 100644
--- a/ltable.h
+++ b/ltable.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltable.h,v 1.18 1999/12/07 12:05:34 roberto Exp roberto $ 2** $Id: ltable.h,v 1.19 2000/04/25 16:55:09 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,11 +19,13 @@
19Hash *luaH_new (lua_State *L, int nhash); 19Hash *luaH_new (lua_State *L, int nhash);
20void luaH_free (lua_State *L, Hash *t); 20void luaH_free (lua_State *L, Hash *t);
21const TObject *luaH_get (lua_State *L, const Hash *t, const TObject *key); 21const TObject *luaH_get (lua_State *L, const Hash *t, const TObject *key);
22const TObject *luaH_getnum (const Hash *t, Number key);
23const TObject *luaH_getstr (const Hash *t, TString *key);
22void luaH_set (lua_State *L, Hash *t, const TObject *key, const TObject *val); 24void luaH_set (lua_State *L, Hash *t, const TObject *key, const TObject *val);
23int luaH_pos (lua_State *L, const Hash *t, const TObject *r); 25int luaH_pos (lua_State *L, const Hash *t, const TObject *r);
24void luaH_setint (lua_State *L, Hash *t, int key, const TObject *val); 26void luaH_setint (lua_State *L, Hash *t, int key, const TObject *val);
25const TObject *luaH_getnum (const Hash *t, Number key);
26unsigned long luaH_hash (lua_State *L, const TObject *key); 27unsigned long luaH_hash (lua_State *L, const TObject *key);
28const TObject *luaH_getglobal (lua_State *L, const char *name);
27 29
28/* exported only for debugging */ 30/* exported only for debugging */
29Node *luaH_mainposition (const Hash *t, const TObject *key); 31Node *luaH_mainposition (const Hash *t, const TObject *key);
diff --git a/ltests.c b/ltests.c
index 5ce089b9..03baa6e6 100644
--- a/ltests.c
+++ b/ltests.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltests.c,v 1.15 2000/04/13 16:51:01 roberto Exp roberto $ 2** $Id: ltests.c,v 1.16 2000/04/14 17:46:15 roberto Exp roberto $
3** Internal Module for Debugging of the Lua Implementation 3** Internal Module for Debugging of the Lua Implementation
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -167,7 +167,7 @@ static void hash_query (lua_State *L) {
167 lua_Object o = luaL_nonnullarg(L, 1); 167 lua_Object o = luaL_nonnullarg(L, 1);
168 if (lua_getparam(L, 2) == LUA_NOOBJECT) { 168 if (lua_getparam(L, 2) == LUA_NOOBJECT) {
169 luaL_arg_check(L, ttype(o) == TAG_STRING, 1, "string expected"); 169 luaL_arg_check(L, ttype(o) == TAG_STRING, 1, "string expected");
170 lua_pushnumber(L, tsvalue(o)->hash); 170 lua_pushnumber(L, tsvalue(o)->u.s.hash);
171 } 171 }
172 else { 172 else {
173 const Hash *t = avalue(luaL_tablearg(L, 2)); 173 const Hash *t = avalue(luaL_tablearg(L, 2));
@@ -334,9 +334,6 @@ static void testC (lua_State *L) {
334 else if EQ("type") { 334 else if EQ("type") {
335 lua_pushstring(L, lua_type(L, reg[getreg(L, &pc)])); 335 lua_pushstring(L, lua_type(L, reg[getreg(L, &pc)]));
336 } 336 }
337 else if EQ("nextvar") {
338 lua_pushstring(L, lua_nextvar(L, lua_getstring(L, reg[getreg(L, &pc)])));
339 }
340 else if EQ("next") { 337 else if EQ("next") {
341 int n = getreg(L, &pc); 338 int n = getreg(L, &pc);
342 n = lua_next(L, reg[n], (int)lua_getnumber(L, reg[getreg(L, &pc)])); 339 n = lua_next(L, reg[n], (int)lua_getnumber(L, reg[getreg(L, &pc)]));
diff --git a/lua.h b/lua.h
index 23f5e472..58d5b27d 100644
--- a/lua.h
+++ b/lua.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lua.h,v 1.47 2000/04/14 17:48:20 roberto Exp roberto $ 2** $Id: lua.h,v 1.48 2000/04/17 19:23:12 roberto Exp roberto $
3** Lua - An Extensible Extension Language 3** Lua - An Extensible Extension Language
4** TeCGraf: Grupo de Tecnologia em Computacao Grafica, PUC-Rio, Brazil 4** TeCGraf: Grupo de Tecnologia em Computacao Grafica, PUC-Rio, Brazil
5** e-mail: lua@tecgraf.puc-rio.br 5** e-mail: lua@tecgraf.puc-rio.br
@@ -54,6 +54,9 @@ int lua_callfunction (lua_State *L, lua_Object f);
54void lua_beginblock (lua_State *L); 54void lua_beginblock (lua_State *L);
55void lua_endblock (lua_State *L); 55void lua_endblock (lua_State *L);
56 56
57void lua_pushglobaltable (lua_State *L);
58void lua_setglobaltable (lua_State *L, lua_Object newtable);
59
57lua_Object lua_lua2C (lua_State *L, int number); 60lua_Object lua_lua2C (lua_State *L, int number);
58#define lua_getparam lua_lua2C 61#define lua_getparam lua_lua2C
59#define lua_getresult lua_lua2C 62#define lua_getresult lua_lua2C
@@ -88,8 +91,8 @@ void lua_pushobject (lua_State *L, lua_Object obj);
88lua_Object lua_pop (lua_State *L); 91lua_Object lua_pop (lua_State *L);
89 92
90lua_Object lua_getglobal (lua_State *L, const char *name); 93lua_Object lua_getglobal (lua_State *L, const char *name);
91lua_Object lua_rawgetglobal (lua_State *L, const char *name);
92void lua_setglobal (lua_State *L, const char *name); /* In: value */ 94void lua_setglobal (lua_State *L, const char *name); /* In: value */
95lua_Object lua_rawgetglobal (lua_State *L, const char *name);
93void lua_rawsetglobal (lua_State *L, const char *name);/* In: value */ 96void lua_rawsetglobal (lua_State *L, const char *name);/* In: value */
94 97
95void lua_settable (lua_State *L); /* In: table, index, value */ 98void lua_settable (lua_State *L); /* In: table, index, value */
@@ -99,7 +102,6 @@ lua_Object lua_rawgettable (lua_State *L); /* In: table, index */
99 102
100int lua_tag (lua_State *L, lua_Object obj); 103int lua_tag (lua_State *L, lua_Object obj);
101 104
102const char *lua_nextvar (lua_State *L, const char *varname); /* Out: value */
103int lua_next (lua_State *L, lua_Object o, int i); 105int lua_next (lua_State *L, lua_Object o, int i);
104 /* Out: ref, value */ 106 /* Out: ref, value */
105 107
@@ -167,6 +169,8 @@ extern lua_State *lua_state;
167#define lua_callfunction(f) (lua_callfunction)(lua_state, f) 169#define lua_callfunction(f) (lua_callfunction)(lua_state, f)
168#define lua_beginblock() (lua_beginblock)(lua_state) 170#define lua_beginblock() (lua_beginblock)(lua_state)
169#define lua_endblock() (lua_endblock)(lua_state) 171#define lua_endblock() (lua_endblock)(lua_state)
172#define lua_pushglobaltable() (lua_pushglobaltable)(lua_state)
173#define lua_setglobaltable(t) (lua_setglobaltable)(lua_state, t)
170#define lua_lua2C(number) (lua_lua2C)(lua_state, number) 174#define lua_lua2C(number) (lua_lua2C)(lua_state, number)
171#define lua_type(obj) (lua_type)(lua_state, obj) 175#define lua_type(obj) (lua_type)(lua_state, obj)
172#define lua_isnil(obj) (lua_isnil)(lua_state, obj) 176#define lua_isnil(obj) (lua_isnil)(lua_state, obj)
@@ -190,15 +194,14 @@ extern lua_State *lua_state;
190#define lua_pushobject(obj) (lua_pushobject)(lua_state, obj) 194#define lua_pushobject(obj) (lua_pushobject)(lua_state, obj)
191#define lua_pop() (lua_pop)(lua_state) 195#define lua_pop() (lua_pop)(lua_state)
192#define lua_getglobal(name) (lua_getglobal)(lua_state, name) 196#define lua_getglobal(name) (lua_getglobal)(lua_state, name)
193#define lua_rawgetglobal(name) (lua_rawgetglobal)(lua_state, name)
194#define lua_setglobal(name) (lua_setglobal)(lua_state, name) 197#define lua_setglobal(name) (lua_setglobal)(lua_state, name)
198#define lua_rawgetglobal(name) (lua_rawgetglobal)(lua_state, name)
195#define lua_rawsetglobal(name) (lua_rawsetglobal)(lua_state, name) 199#define lua_rawsetglobal(name) (lua_rawsetglobal)(lua_state, name)
196#define lua_settable() (lua_settable)(lua_state) 200#define lua_settable() (lua_settable)(lua_state)
197#define lua_rawsettable() (lua_rawsettable)(lua_state) 201#define lua_rawsettable() (lua_rawsettable)(lua_state)
198#define lua_gettable() (lua_gettable)(lua_state) 202#define lua_gettable() (lua_gettable)(lua_state)
199#define lua_rawgettable() (lua_rawgettable)(lua_state) 203#define lua_rawgettable() (lua_rawgettable)(lua_state)
200#define lua_tag(obj) (lua_tag)(lua_state, obj) 204#define lua_tag(obj) (lua_tag)(lua_state, obj)
201#define lua_nextvar(varname) (lua_nextvar)(lua_state, varname)
202#define lua_next(o,i) (lua_next)(lua_state, o,i) 205#define lua_next(o,i) (lua_next)(lua_state, o,i)
203#define lua_ref(lock) (lua_ref)(lua_state, lock) 206#define lua_ref(lock) (lua_ref)(lua_state, lock)
204#define lua_getref(ref) (lua_getref)(lua_state, ref) 207#define lua_getref(ref) (lua_getref)(lua_state, ref)
diff --git a/lundump.c b/lundump.c
index f9d90168..11ada16d 100644
--- a/lundump.c
+++ b/lundump.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lundump.c,v 1.28 2000/04/24 19:32:58 lhf Exp $ 2** $Id: lundump.c,v 1.20 2000/04/25 16:44:31 roberto Exp roberto $
3** load bytecodes from files 3** load bytecodes from files
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -155,8 +155,7 @@ static void LoadConstants (lua_State* L, Proto* tf, ZIO* Z, int native)
155 for (i=0; i<n; i++) 155 for (i=0; i<n; i++)
156 { 156 {
157 TString* s=LoadString(L,Z); 157 TString* s=LoadString(L,Z);
158 int isglobal=LoadByte(L,Z); 158 LoadByte(L,Z);
159 if (isglobal) luaS_assertglobal(L,s);
160 tf->kstr[i]=s; 159 tf->kstr[i]=s;
161 } 160 }
162 } 161 }
diff --git a/lvm.c b/lvm.c
index 23f59032..9b0ea0c8 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.c,v 1.103 2000/04/14 17:45:25 roberto Exp roberto $ 2** $Id: lvm.c,v 1.104 2000/04/19 13:36:25 roberto Exp roberto $
3** Lua virtual machine 3** Lua virtual machine
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -164,18 +164,8 @@ void luaV_settable (lua_State *L, StkId t, StkId top) {
164} 164}
165 165
166 166
167void luaV_rawsettable (lua_State *L, StkId t) { 167void luaV_getglobal (lua_State *L, TString *s, StkId top) {
168 if (ttype(t) != TAG_TABLE) 168 const TObject *value = luaH_getstr(L->gt, s);
169 lua_error(L, "indexed expression not a table");
170 else {
171 luaH_set(L, avalue(t), t+1, L->top-1);
172 L->top -= 3;
173 }
174}
175
176
177void luaV_getglobal (lua_State *L, GlobalVar *gv, StkId top) {
178 const TObject *value = &gv->value;
179 TObject *im = luaT_getimbyObj(L, value, IM_GETGLOBAL); 169 TObject *im = luaT_getimbyObj(L, value, IM_GETGLOBAL);
180 if (ttype(im) == TAG_NIL) /* is there a tag method? */ 170 if (ttype(im) == TAG_NIL) /* is there a tag method? */
181 *top = *value; /* default behavior */ 171 *top = *value; /* default behavior */
@@ -183,7 +173,7 @@ void luaV_getglobal (lua_State *L, GlobalVar *gv, StkId top) {
183 luaD_checkstack(L, 3); 173 luaD_checkstack(L, 3);
184 *top = *im; 174 *top = *im;
185 ttype(top+1) = TAG_STRING; 175 ttype(top+1) = TAG_STRING;
186 tsvalue(top+1) = gv->name; /* global name */ 176 tsvalue(top+1) = s; /* global name */
187 *(top+2) = *value; 177 *(top+2) = *value;
188 L->top = top+3; 178 L->top = top+3;
189 luaD_call(L, top, 1); 179 luaD_call(L, top, 1);
@@ -191,17 +181,25 @@ void luaV_getglobal (lua_State *L, GlobalVar *gv, StkId top) {
191} 181}
192 182
193 183
194void luaV_setglobal (lua_State *L, GlobalVar *gv, StkId top) { 184void luaV_setglobal (lua_State *L, TString *s, StkId top) {
195 const TObject *oldvalue = &gv->value; 185 const TObject *oldvalue = luaH_getstr(L->gt, s);
196 const TObject *im = luaT_getimbyObj(L, oldvalue, IM_SETGLOBAL); 186 const TObject *im = luaT_getimbyObj(L, oldvalue, IM_SETGLOBAL);
197 if (ttype(im) == TAG_NIL) /* is there a tag method? */ 187 if (ttype(im) == TAG_NIL) { /* is there a tag method? */
198 gv->value = *(top-1); 188 if (oldvalue != &luaO_nilobject)
189 *oldvalue = *(top-1);
190 else {
191 TObject key;
192 ttype(&key) = TAG_STRING;
193 tsvalue(&key) = s;
194 luaH_set(L, L->gt, &key, top-1);
195 }
196 }
199 else { 197 else {
200 luaD_checkstack(L, 3); 198 luaD_checkstack(L, 3);
201 *(top+2) = *(top-1); /* new value */ 199 *(top+2) = *(top-1); /* new value */
202 *(top+1) = *oldvalue; 200 *(top+1) = *oldvalue;
203 ttype(top) = TAG_STRING; 201 ttype(top) = TAG_STRING;
204 tsvalue(top) = gv->name; 202 tsvalue(top) = s;
205 *(top-1) = *im; 203 *(top-1) = *im;
206 L->top = top+3; 204 L->top = top+3;
207 luaD_call(L, top-1, 0); 205 luaD_call(L, top-1, 0);
@@ -415,7 +413,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
415 break; 413 break;
416 414
417 case OP_GETGLOBAL: 415 case OP_GETGLOBAL:
418 luaV_getglobal(L, kstr[GETARG_U(i)]->u.s.gv, top); 416 luaV_getglobal(L, kstr[GETARG_U(i)], top);
419 top++; 417 top++;
420 break; 418 break;
421 419
@@ -460,7 +458,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
460 break; 458 break;
461 459
462 case OP_SETGLOBAL: 460 case OP_SETGLOBAL:
463 luaV_setglobal(L, kstr[GETARG_U(i)]->u.s.gv, top); 461 luaV_setglobal(L, kstr[GETARG_U(i)], top);
464 top--; 462 top--;
465 break; 463 break;
466 464
diff --git a/lvm.h b/lvm.h
index c3b2b6cc..ae57346b 100644
--- a/lvm.h
+++ b/lvm.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.h,v 1.20 2000/03/29 20:19:20 roberto Exp roberto $ 2** $Id: lvm.h,v 1.21 2000/04/19 13:36:25 roberto Exp roberto $
3** Lua virtual machine 3** Lua virtual machine
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -23,9 +23,8 @@ int luaV_tostring (lua_State *L, TObject *obj);
23void luaV_setn (lua_State *L, Hash *t, int val); 23void luaV_setn (lua_State *L, Hash *t, int val);
24void luaV_gettable (lua_State *L, StkId top); 24void luaV_gettable (lua_State *L, StkId top);
25void luaV_settable (lua_State *L, StkId t, StkId top); 25void luaV_settable (lua_State *L, StkId t, StkId top);
26void luaV_rawsettable (lua_State *L, StkId t); 26void luaV_getglobal (lua_State *L, TString *s, StkId top);
27void luaV_getglobal (lua_State *L, GlobalVar *gv, StkId top); 27void luaV_setglobal (lua_State *L, TString *s, StkId top);
28void luaV_setglobal (lua_State *L, GlobalVar *gv, StkId top);
29StkId luaV_execute (lua_State *L, const Closure *cl, StkId base); 28StkId luaV_execute (lua_State *L, const Closure *cl, StkId base);
30void luaV_Cclosure (lua_State *L, lua_CFunction c, int nelems); 29void luaV_Cclosure (lua_State *L, lua_CFunction c, int nelems);
31void luaV_Lclosure (lua_State *L, Proto *l, int nelems); 30void luaV_Lclosure (lua_State *L, Proto *l, int nelems);