aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2001-12-05 18:15:18 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2001-12-05 18:15:18 -0200
commit592a309177edc52847b1196969ad6d49ba21f4fb (patch)
tree06add977885c012ee22cc4f105785c435b6af353
parent413fc7334bf8ceaea71417d73edef15c99d3a793 (diff)
downloadlua-592a309177edc52847b1196969ad6d49ba21f4fb.tar.gz
lua-592a309177edc52847b1196969ad6d49ba21f4fb.tar.bz2
lua-592a309177edc52847b1196969ad6d49ba21f4fb.zip
tag system replaced by event tables
-rw-r--r--lapi.c150
-rw-r--r--lauxlib.c19
-rw-r--r--lauxlib.h6
-rw-r--r--lbaselib.c138
-rw-r--r--ldebug.c29
-rw-r--r--ldo.c21
-rw-r--r--lfunc.c4
-rw-r--r--lgc.c121
-rw-r--r--lgc.h4
-rw-r--r--liolib.c58
-rw-r--r--lmathlib.c5
-rw-r--r--lobject.h22
-rw-r--r--lstate.c21
-rw-r--r--lstate.h34
-rw-r--r--lstring.c8
-rw-r--r--lstrlib.c4
-rw-r--r--ltable.c19
-rw-r--r--ltable.h3
-rw-r--r--ltests.c61
-rw-r--r--ltm.c165
-rw-r--r--ltm.h49
-rw-r--r--lua.h36
-rw-r--r--lvm.c137
-rw-r--r--lvm.h4
24 files changed, 412 insertions, 706 deletions
diff --git a/lapi.c b/lapi.c
index 91cea50c..6e941752 100644
--- a/lapi.c
+++ b/lapi.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lapi.c,v 1.160 2001/11/16 16:29:51 roberto Exp $ 2** $Id: lapi.c,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $
3** Lua API 3** Lua API
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -45,8 +45,8 @@ static TObject *negindex (lua_State *L, int index) {
45 return L->top+index; 45 return L->top+index;
46 } 46 }
47 else switch (index) { /* pseudo-indices */ 47 else switch (index) { /* pseudo-indices */
48 case LUA_REGISTRYINDEX: return &G(L)->registry; 48 case LUA_REGISTRYINDEX: return registry(L);
49 case LUA_GLOBALSINDEX: return &L->gt; 49 case LUA_GLOBALSINDEX: return gt(L);
50 default: { 50 default: {
51 TObject *func = (L->ci->base - 1); 51 TObject *func = (L->ci->base - 1);
52 index = LUA_GLOBALSINDEX - index; 52 index = LUA_GLOBALSINDEX - index;
@@ -149,20 +149,15 @@ LUA_API void lua_pushvalue (lua_State *L, int index) {
149*/ 149*/
150 150
151 151
152LUA_API int lua_rawtag (lua_State *L, int index) { 152LUA_API int lua_type (lua_State *L, int index) {
153 StkId o = luaA_indexAcceptable(L, index); 153 StkId o = luaA_indexAcceptable(L, index);
154 return (o == NULL) ? LUA_TNONE : ttype(o); 154 return (o == NULL) ? LUA_TNONE : ttype(o);
155} 155}
156 156
157 157
158LUA_API const char *lua_type (lua_State *L, int index) { 158LUA_API const char *lua_typename (lua_State *L, int t) {
159 StkId o; 159 UNUSED(L);
160 const char *type; 160 return (t == LUA_TNONE) ? "no value" : luaT_typenames[t];
161 lua_lock(L);
162 o = luaA_indexAcceptable(L, index);
163 type = (o == NULL) ? "no value" : luaT_typename(G(L), o);
164 lua_unlock(L);
165 return type;
166} 161}
167 162
168 163
@@ -180,22 +175,11 @@ LUA_API int lua_isnumber (lua_State *L, int index) {
180 175
181 176
182LUA_API int lua_isstring (lua_State *L, int index) { 177LUA_API int lua_isstring (lua_State *L, int index) {
183 int t = lua_rawtag(L, index); 178 int t = lua_type(L, index);
184 return (t == LUA_TSTRING || t == LUA_TNUMBER); 179 return (t == LUA_TSTRING || t == LUA_TNUMBER);
185} 180}
186 181
187 182
188LUA_API int lua_tag (lua_State *L, int index) {
189 StkId o;
190 int i;
191 lua_lock(L); /* other thread could be changing the tag */
192 o = luaA_indexAcceptable(L, index);
193 i = (o == NULL) ? LUA_NOTAG : luaT_tag(o);
194 lua_unlock(L);
195 return i;
196}
197
198
199LUA_API int lua_equal (lua_State *L, int index1, int index2) { 183LUA_API int lua_equal (lua_State *L, int index1, int index2) {
200 StkId o1 = luaA_indexAcceptable(L, index1); 184 StkId o1 = luaA_indexAcceptable(L, index1);
201 StkId o2 = luaA_indexAcceptable(L, index2); 185 StkId o2 = luaA_indexAcceptable(L, index2);
@@ -346,8 +330,10 @@ LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
346 330
347 331
348LUA_API void lua_getglobal (lua_State *L, const char *name) { 332LUA_API void lua_getglobal (lua_State *L, const char *name) {
333 TObject o;
349 lua_lock(L); 334 lua_lock(L);
350 luaV_getglobal(L, luaS_new(L, name), L->top); 335 setsvalue(&o, luaS_new(L, name));
336 luaV_gettable(L, gt(L), &o, L->top);
351 api_incr_top(L); 337 api_incr_top(L);
352 lua_unlock(L); 338 lua_unlock(L);
353} 339}
@@ -391,6 +377,29 @@ LUA_API void lua_newtable (lua_State *L) {
391} 377}
392 378
393 379
380LUA_API void lua_geteventtable (lua_State *L, int objindex) {
381 StkId obj;
382 Table *et;
383 lua_lock(L);
384 obj = luaA_indexAcceptable(L, objindex);
385 switch (ttype(obj)) {
386 case LUA_TTABLE:
387 et = hvalue(obj)->eventtable;
388 break;
389 case LUA_TUSERDATA:
390 et = uvalue(obj)->uv.eventtable;
391 break;
392 default:
393 et = hvalue(defaultet(L));
394 }
395 if (et == hvalue(defaultet(L)))
396 setnilvalue(L->top);
397 else
398 sethvalue(L->top, et);
399 api_incr_top(L);
400 lua_unlock(L);
401}
402
394 403
395/* 404/*
396** set functions (stack -> Lua) 405** set functions (stack -> Lua)
@@ -398,9 +407,11 @@ LUA_API void lua_newtable (lua_State *L) {
398 407
399 408
400LUA_API void lua_setglobal (lua_State *L, const char *name) { 409LUA_API void lua_setglobal (lua_State *L, const char *name) {
410 TObject o;
401 lua_lock(L); 411 lua_lock(L);
402 api_checknelems(L, 1); 412 api_checknelems(L, 1);
403 luaV_setglobal(L, luaS_new(L, name), L->top - 1); 413 setsvalue(&o, luaS_new(L, name));
414 luaV_settable(L, gt(L), &o, L->top - 1);
404 L->top--; /* remove element from the top */ 415 L->top--; /* remove element from the top */
405 lua_unlock(L); 416 lua_unlock(L);
406} 417}
@@ -447,11 +458,32 @@ LUA_API void lua_setglobals (lua_State *L) {
447 api_checknelems(L, 1); 458 api_checknelems(L, 1);
448 newtable = --L->top; 459 newtable = --L->top;
449 api_check(L, ttype(newtable) == LUA_TTABLE); 460 api_check(L, ttype(newtable) == LUA_TTABLE);
450 setobj(&L->gt, newtable); 461 setobj(gt(L), newtable);
451 lua_unlock(L); 462 lua_unlock(L);
452} 463}
453 464
454 465
466LUA_API void lua_seteventtable (lua_State *L, int objindex) {
467 StkId obj, et;
468 lua_lock(L);
469 api_checknelems(L, 1);
470 obj = luaA_indexAcceptable(L, objindex);
471 et = --L->top;
472 api_check(L, ttype(et) == LUA_TTABLE);
473 switch (ttype(obj)) {
474 case LUA_TTABLE:
475 hvalue(obj)->eventtable = hvalue(et);
476 break;
477 case LUA_TUSERDATA:
478 uvalue(obj)->uv.eventtable = hvalue(et);
479 break;
480 default:
481 luaO_verror(L, "cannot change the event table of a %.20s",
482 luaT_typenames[ttype(obj)]);
483 }
484 lua_unlock(L);
485}
486
455 487
456/* 488/*
457** `do' functions (run Lua code) 489** `do' functions (run Lua code)
@@ -533,70 +565,6 @@ LUA_API void lua_setgcthreshold (lua_State *L, int newthreshold) {
533** miscellaneous functions 565** miscellaneous functions
534*/ 566*/
535 567
536LUA_API int lua_newtype (lua_State *L, const char *name, int basictype) {
537 int tag;
538 lua_lock(L);
539 if (basictype != LUA_TNONE &&
540 basictype != LUA_TTABLE &&
541 basictype != LUA_TUSERDATA)
542 luaO_verror(L, "invalid basic type (%d) for new type", basictype);
543 tag = luaT_newtag(L, name, basictype);
544 if (tag == LUA_TNONE)
545 luaO_verror(L, "type name '%.30s' already exists", name);
546 lua_unlock(L);
547 return tag;
548}
549
550
551LUA_API int lua_name2tag (lua_State *L, const char *name) {
552 int tag;
553 const TObject *v;
554 lua_lock(L);
555 v = luaH_getstr(G(L)->type2tag, luaS_new(L, name));
556 if (ttype(v) == LUA_TNIL)
557 tag = LUA_TNONE;
558 else {
559 lua_assert(ttype(v) == LUA_TNUMBER);
560 tag = cast(int, nvalue(v));
561 }
562 lua_unlock(L);
563 return tag;
564}
565
566
567LUA_API const char *lua_tag2name (lua_State *L, int tag) {
568 const char *s;
569 lua_lock(L);
570 s = (tag == LUA_TNONE) ? "no value" : typenamebytag(G(L), tag);
571 lua_unlock(L);
572 return s;
573}
574
575
576LUA_API void lua_settag (lua_State *L, int tag) {
577 int basictype;
578 lua_lock(L);
579 api_checknelems(L, 1);
580 if (tag < 0 || tag >= G(L)->ntag)
581 luaO_verror(L, "%d is not a valid tag", tag);
582 basictype = G(L)->TMtable[tag].basictype;
583 if (basictype != LUA_TNONE && basictype != ttype(L->top-1))
584 luaO_verror(L, "tag %d can only be used for type '%.20s'", tag,
585 typenamebytag(G(L), basictype));
586 switch (ttype(L->top-1)) {
587 case LUA_TTABLE:
588 hvalue(L->top-1)->htag = tag;
589 break;
590 case LUA_TUSERDATA:
591 uvalue(L->top-1)->uv.tag = tag;
592 break;
593 default:
594 luaO_verror(L, "cannot change the tag of a %.20s",
595 luaT_typename(G(L), L->top-1));
596 }
597 lua_unlock(L);
598}
599
600 568
601LUA_API void lua_error (lua_State *L, const char *s) { 569LUA_API void lua_error (lua_State *L, const char *s) {
602 lua_lock(L); 570 lua_lock(L);
diff --git a/lauxlib.c b/lauxlib.c
index 1189af50..849daa33 100644
--- a/lauxlib.c
+++ b/lauxlib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lauxlib.c,v 1.53 2001/10/31 19:40:14 roberto Exp $ 2** $Id: lauxlib.c,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $
3** Auxiliary functions for building Lua libraries 3** Auxiliary functions for building Lua libraries
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -43,7 +43,8 @@ LUALIB_API void luaL_argerror (lua_State *L, int narg, const char *extramsg) {
43 43
44LUALIB_API void luaL_typerror (lua_State *L, int narg, const char *tname) { 44LUALIB_API void luaL_typerror (lua_State *L, int narg, const char *tname) {
45 char buff[80]; 45 char buff[80];
46 sprintf(buff, "%.25s expected, got %.25s", tname, lua_type(L,narg)); 46 sprintf(buff, "%.25s expected, got %.25s", tname,
47 lua_typename(L, lua_type(L,narg)));
47 luaL_argerror(L, narg, buff); 48 luaL_argerror(L, narg, buff);
48} 49}
49 50
@@ -59,26 +60,18 @@ LUALIB_API void luaL_check_stack (lua_State *L, int space, const char *mes) {
59} 60}
60 61
61 62
62LUALIB_API void luaL_check_rawtype(lua_State *L, int narg, int t) { 63LUALIB_API void luaL_check_type(lua_State *L, int narg, int t) {
63 if (lua_rawtag(L, narg) != t) 64 if (lua_type(L, narg) != t)
64 tag_error(L, narg, t); 65 tag_error(L, narg, t);
65} 66}
66 67
67 68
68LUALIB_API void luaL_check_any (lua_State *L, int narg) { 69LUALIB_API void luaL_check_any (lua_State *L, int narg) {
69 if (lua_rawtag(L, narg) == LUA_TNONE) 70 if (lua_type(L, narg) == LUA_TNONE)
70 luaL_argerror(L, narg, "value expected"); 71 luaL_argerror(L, narg, "value expected");
71} 72}
72 73
73 74
74LUALIB_API void *luaL_check_userdata (lua_State *L, int narg,
75 const char *name) {
76 if (strcmp(lua_type(L, narg), name) != 0)
77 luaL_typerror(L, narg, name);
78 return lua_touserdata(L, narg);
79}
80
81
82LUALIB_API const char *luaL_check_lstr (lua_State *L, int narg, size_t *len) { 75LUALIB_API const char *luaL_check_lstr (lua_State *L, int narg, size_t *len) {
83 const char *s = lua_tostring(L, narg); 76 const char *s = lua_tostring(L, narg);
84 if (!s) tag_error(L, narg, LUA_TSTRING); 77 if (!s) tag_error(L, narg, LUA_TSTRING);
diff --git a/lauxlib.h b/lauxlib.h
index 43405bf2..fd9d1f53 100644
--- a/lauxlib.h
+++ b/lauxlib.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lauxlib.h,v 1.38 2001/10/31 19:40:14 roberto Exp $ 2** $Id: lauxlib.h,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $
3** Auxiliary functions for building Lua libraries 3** Auxiliary functions for building Lua libraries
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -38,10 +38,8 @@ LUALIB_API lua_Number luaL_check_number (lua_State *L, int numArg);
38LUALIB_API lua_Number luaL_opt_number (lua_State *L, int nArg, lua_Number def); 38LUALIB_API lua_Number luaL_opt_number (lua_State *L, int nArg, lua_Number def);
39 39
40LUALIB_API void luaL_check_stack (lua_State *L, int space, const char *msg); 40LUALIB_API void luaL_check_stack (lua_State *L, int space, const char *msg);
41LUALIB_API void luaL_check_rawtype (lua_State *L, int narg, int t); 41LUALIB_API void luaL_check_type (lua_State *L, int narg, int t);
42LUALIB_API void luaL_check_any (lua_State *L, int narg); 42LUALIB_API void luaL_check_any (lua_State *L, int narg);
43LUALIB_API void *luaL_check_userdata (lua_State *L, int narg,
44 const char *name);
45 43
46LUALIB_API void luaL_verror (lua_State *L, const char *fmt, ...); 44LUALIB_API void luaL_verror (lua_State *L, const char *fmt, ...);
47LUALIB_API int luaL_findstring (const char *name, 45LUALIB_API int luaL_findstring (const char *name,
diff --git a/lbaselib.c b/lbaselib.c
index 52343fe5..adb9af0c 100644
--- a/lbaselib.c
+++ b/lbaselib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lbaselib.c,v 1.45 2001/10/26 17:33:30 roberto Exp $ 2** $Id: lbaselib.c,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $
3** Basic library 3** Basic library
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -41,7 +41,7 @@ static int luaB__ALERT (lua_State *L) {
41** The library `liolib' redefines _ERRORMESSAGE for better error information. 41** The library `liolib' redefines _ERRORMESSAGE for better error information.
42*/ 42*/
43static int luaB__ERRORMESSAGE (lua_State *L) { 43static int luaB__ERRORMESSAGE (lua_State *L) {
44 luaL_check_rawtype(L, 1, LUA_TSTRING); 44 luaL_check_type(L, 1, LUA_TSTRING);
45 lua_getglobal(L, LUA_ALERT); 45 lua_getglobal(L, LUA_ALERT);
46 if (lua_isfunction(L, -1)) { /* avoid error loop if _ALERT is not defined */ 46 if (lua_isfunction(L, -1)) { /* avoid error loop if _ALERT is not defined */
47 lua_Debug ar; 47 lua_Debug ar;
@@ -136,41 +136,22 @@ static int luaB_getglobal (lua_State *L) {
136} 136}
137 137
138 138
139/* auxiliary function to get `tags' */ 139static int luaB_eventtable (lua_State *L) {
140static int gettag (lua_State *L, int narg) { 140 luaL_check_type(L, 1, LUA_TTABLE);
141 switch (lua_rawtag(L, narg)) { 141 if (lua_isnull(L, 2))
142 case LUA_TNUMBER: 142 lua_geteventtable(L, 1);
143 return (int)(lua_tonumber(L, narg)); 143 else {
144 case LUA_TSTRING: { 144 lua_settop(L, 2);
145 const char *name = lua_tostring(L, narg); 145 luaL_check_type(L, 2, LUA_TTABLE);
146 int tag = lua_name2tag(L, name); 146 lua_seteventtable(L, 1);
147 if (tag == LUA_TNONE)
148 luaL_verror(L, "'%.30s' is not a valid type name", name);
149 return tag;
150 }
151 default:
152 luaL_argerror(L, narg, "tag or type name expected");
153 return 0; /* to avoid warnings */
154 } 147 }
155}
156
157
158static int luaB_tag (lua_State *L) {
159 luaL_check_any(L, 1);
160 lua_pushnumber(L, lua_tag(L, 1));
161 return 1; 148 return 1;
162} 149}
163 150
164static int luaB_settype (lua_State *L) {
165 luaL_check_rawtype(L, 1, LUA_TTABLE);
166 lua_pushvalue(L, 1); /* push table */
167 lua_settag(L, gettag(L, 2));
168 return 1; /* return table */
169}
170 151
171static int luaB_weakmode (lua_State *L) { 152static int luaB_weakmode (lua_State *L) {
172 const char *mode = luaL_check_string(L, 2); 153 const char *mode = luaL_check_string(L, 2);
173 luaL_check_rawtype(L, 1, LUA_TTABLE); 154 luaL_check_type(L, 1, LUA_TTABLE);
174 if (*mode == '?') { 155 if (*mode == '?') {
175 char buff[3]; 156 char buff[3];
176 char *s = buff; 157 char *s = buff;
@@ -191,17 +172,11 @@ static int luaB_weakmode (lua_State *L) {
191 } 172 }
192} 173}
193 174
194static int luaB_newtype (lua_State *L) {
195 const char *name = luaL_opt_string(L, 1, NULL);
196 lua_pushnumber(L, lua_newtype(L, name, LUA_TTABLE));
197 return 1;
198}
199
200 175
201static int luaB_globals (lua_State *L) { 176static int luaB_globals (lua_State *L) {
202 lua_getglobals(L); /* value to be returned */ 177 lua_getglobals(L); /* value to be returned */
203 if (!lua_isnull(L, 1)) { 178 if (!lua_isnull(L, 1)) {
204 luaL_check_rawtype(L, 1, LUA_TTABLE); 179 luaL_check_type(L, 1, LUA_TTABLE);
205 lua_pushvalue(L, 1); /* new table of globals */ 180 lua_pushvalue(L, 1); /* new table of globals */
206 lua_setglobals(L); 181 lua_setglobals(L);
207 } 182 }
@@ -209,43 +184,20 @@ static int luaB_globals (lua_State *L) {
209} 184}
210 185
211static int luaB_rawget (lua_State *L) { 186static int luaB_rawget (lua_State *L) {
212 luaL_check_rawtype(L, 1, LUA_TTABLE); 187 luaL_check_type(L, 1, LUA_TTABLE);
213 luaL_check_any(L, 2); 188 luaL_check_any(L, 2);
214 lua_rawget(L, -2); 189 lua_rawget(L, -2);
215 return 1; 190 return 1;
216} 191}
217 192
218static int luaB_rawset (lua_State *L) { 193static int luaB_rawset (lua_State *L) {
219 luaL_check_rawtype(L, 1, LUA_TTABLE); 194 luaL_check_type(L, 1, LUA_TTABLE);
220 luaL_check_any(L, 2); 195 luaL_check_any(L, 2);
221 luaL_check_any(L, 3); 196 luaL_check_any(L, 3);
222 lua_rawset(L, -3); 197 lua_rawset(L, -3);
223 return 1; 198 return 1;
224} 199}
225 200
226static int luaB_settagmethod (lua_State *L) {
227 int tag = gettag(L, 1);
228 const char *event = luaL_check_string(L, 2);
229 luaL_arg_check(L, lua_isfunction(L, 3) || lua_isnil(L, 3), 3,
230 "function or nil expected");
231 if (strcmp(event, "gc") == 0)
232 lua_error(L, "cannot set `gc' tag method from Lua");
233 lua_gettagmethod(L, tag, event);
234 lua_pushvalue(L, 3);
235 lua_settagmethod(L, tag, event);
236 return 1;
237}
238
239
240static int luaB_gettagmethod (lua_State *L) {
241 int tag = gettag(L, 1);
242 const char *event = luaL_check_string(L, 2);
243 if (strcmp(event, "gc") == 0)
244 lua_error(L, "cannot get `gc' tag method from Lua");
245 lua_gettagmethod(L, tag, event);
246 return 1;
247}
248
249 201
250static int luaB_gcinfo (lua_State *L) { 202static int luaB_gcinfo (lua_State *L) {
251 lua_pushnumber(L, lua_getgccount(L)); 203 lua_pushnumber(L, lua_getgccount(L));
@@ -262,20 +214,20 @@ static int luaB_collectgarbage (lua_State *L) {
262 214
263static int luaB_type (lua_State *L) { 215static int luaB_type (lua_State *L) {
264 luaL_check_any(L, 1); 216 luaL_check_any(L, 1);
265 lua_pushstring(L, lua_type(L, 1)); 217 if (lua_isnull(L, 2))
266 return 1; 218 lua_pushstring(L, lua_typename(L, lua_type(L, 1)));
267} 219 else {
268 220 if (strcmp(lua_typename(L, lua_type(L, 1)), luaL_check_string(L, 2)) == 0)
269 221 lua_pushnumber(L, 1);
270static int luaB_rawtype (lua_State *L) { 222 else
271 luaL_check_any(L, 1); 223 lua_pushnil(L);
272 lua_pushstring(L, lua_tag2name(L, lua_rawtag(L, 1))); 224 }
273 return 1; 225 return 1;
274} 226}
275 227
276 228
277static int luaB_next (lua_State *L) { 229static int luaB_next (lua_State *L) {
278 luaL_check_rawtype(L, 1, LUA_TTABLE); 230 luaL_check_type(L, 1, LUA_TTABLE);
279 lua_settop(L, 2); /* create a 2nd argument if there isn't one */ 231 lua_settop(L, 2); /* create a 2nd argument if there isn't one */
280 if (lua_next(L, 1)) 232 if (lua_next(L, 1))
281 return 2; 233 return 2;
@@ -393,7 +345,7 @@ static int luaB_require (lua_State *L) {
393 345
394static int aux_unpack (lua_State *L, int arg) { 346static int aux_unpack (lua_State *L, int arg) {
395 int n, i; 347 int n, i;
396 luaL_check_rawtype(L, arg, LUA_TTABLE); 348 luaL_check_type(L, arg, LUA_TTABLE);
397 n = lua_getn(L, arg); 349 n = lua_getn(L, arg);
398 luaL_check_stack(L, n, "table too big to unpack"); 350 luaL_check_stack(L, n, "table too big to unpack");
399 for (i=1; i<=n; i++) /* push arg[1...n] */ 351 for (i=1; i<=n; i++) /* push arg[1...n] */
@@ -443,7 +395,7 @@ static int luaB_call (lua_State *L) {
443 395
444static int luaB_tostring (lua_State *L) { 396static int luaB_tostring (lua_State *L) {
445 char buff[64]; 397 char buff[64];
446 switch (lua_rawtag(L, 1)) { 398 switch (lua_type(L, 1)) {
447 case LUA_TNUMBER: 399 case LUA_TNUMBER:
448 lua_pushstring(L, lua_tostring(L, 1)); 400 lua_pushstring(L, lua_tostring(L, 1));
449 return 1; 401 return 1;
@@ -451,16 +403,15 @@ static int luaB_tostring (lua_State *L) {
451 lua_pushvalue(L, 1); 403 lua_pushvalue(L, 1);
452 return 1; 404 return 1;
453 case LUA_TTABLE: 405 case LUA_TTABLE:
454 sprintf(buff, "%.40s: %p", lua_type(L, 1), lua_topointer(L, 1)); 406 sprintf(buff, "%.40s: %p", lua_typename(L, lua_type(L, 1)), lua_topointer(L, 1));
455 break; 407 break;
456 case LUA_TFUNCTION: 408 case LUA_TFUNCTION:
457 sprintf(buff, "function: %p", lua_topointer(L, 1)); 409 sprintf(buff, "function: %p", lua_topointer(L, 1));
458 break; 410 break;
459 case LUA_TUSERDATA: { 411 case LUA_TUSERDATA: {
460 const char *t = lua_type(L, 1); 412 const char *t = lua_typename(L, lua_type(L, 1));
461 if (strcmp(t, "userdata") == 0) 413 if (strcmp(t, "userdata") == 0)
462 sprintf(buff, "userdata(%d): %p", lua_tag(L, 1), 414 sprintf(buff, "userdata: %p", lua_touserdata(L, 1));
463 lua_touserdata(L, 1));
464 else 415 else
465 sprintf(buff, "%.40s: %p", t, lua_touserdata(L, 1)); 416 sprintf(buff, "%.40s: %p", t, lua_touserdata(L, 1));
466 break; 417 break;
@@ -478,8 +429,8 @@ static int luaB_tostring (lua_State *L) {
478 429
479static int luaB_foreachi (lua_State *L) { 430static int luaB_foreachi (lua_State *L) {
480 int n, i; 431 int n, i;
481 luaL_check_rawtype(L, 1, LUA_TTABLE); 432 luaL_check_type(L, 1, LUA_TTABLE);
482 luaL_check_rawtype(L, 2, LUA_TFUNCTION); 433 luaL_check_type(L, 2, LUA_TFUNCTION);
483 n = lua_getn(L, 1); 434 n = lua_getn(L, 1);
484 for (i=1; i<=n; i++) { 435 for (i=1; i<=n; i++) {
485 lua_pushvalue(L, 2); /* function */ 436 lua_pushvalue(L, 2); /* function */
@@ -495,8 +446,8 @@ static int luaB_foreachi (lua_State *L) {
495 446
496 447
497static int luaB_foreach (lua_State *L) { 448static int luaB_foreach (lua_State *L) {
498 luaL_check_rawtype(L, 1, LUA_TTABLE); 449 luaL_check_type(L, 1, LUA_TTABLE);
499 luaL_check_rawtype(L, 2, LUA_TFUNCTION); 450 luaL_check_type(L, 2, LUA_TFUNCTION);
500 lua_pushnil(L); /* first index */ 451 lua_pushnil(L); /* first index */
501 for (;;) { 452 for (;;) {
502 if (lua_next(L, 1) == 0) 453 if (lua_next(L, 1) == 0)
@@ -523,7 +474,7 @@ static int luaB_assert (lua_State *L) {
523 474
524 475
525static int luaB_getn (lua_State *L) { 476static int luaB_getn (lua_State *L) {
526 luaL_check_rawtype(L, 1, LUA_TTABLE); 477 luaL_check_type(L, 1, LUA_TTABLE);
527 lua_pushnumber(L, lua_getn(L, 1)); 478 lua_pushnumber(L, lua_getn(L, 1));
528 return 1; 479 return 1;
529} 480}
@@ -532,7 +483,7 @@ static int luaB_getn (lua_State *L) {
532static int luaB_tinsert (lua_State *L) { 483static int luaB_tinsert (lua_State *L) {
533 int v = lua_gettop(L); /* number of arguments */ 484 int v = lua_gettop(L); /* number of arguments */
534 int n, pos; 485 int n, pos;
535 luaL_check_rawtype(L, 1, LUA_TTABLE); 486 luaL_check_type(L, 1, LUA_TTABLE);
536 n = lua_getn(L, 1); 487 n = lua_getn(L, 1);
537 if (v == 2) /* called with only 2 arguments */ 488 if (v == 2) /* called with only 2 arguments */
538 pos = n+1; 489 pos = n+1;
@@ -553,7 +504,7 @@ static int luaB_tinsert (lua_State *L) {
553 504
554static int luaB_tremove (lua_State *L) { 505static int luaB_tremove (lua_State *L) {
555 int pos, n; 506 int pos, n;
556 luaL_check_rawtype(L, 1, LUA_TTABLE); 507 luaL_check_type(L, 1, LUA_TTABLE);
557 n = lua_getn(L, 1); 508 n = lua_getn(L, 1);
558 pos = luaL_opt_int(L, 2, n); 509 pos = luaL_opt_int(L, 2, n);
559 if (n <= 0) return 0; /* table is `empty' */ 510 if (n <= 0) return 0; /* table is `empty' */
@@ -665,10 +616,10 @@ static void auxsort (lua_State *L, int l, int u) {
665 616
666static int luaB_sort (lua_State *L) { 617static int luaB_sort (lua_State *L) {
667 int n; 618 int n;
668 luaL_check_rawtype(L, 1, LUA_TTABLE); 619 luaL_check_type(L, 1, LUA_TTABLE);
669 n = lua_getn(L, 1); 620 n = lua_getn(L, 1);
670 if (!lua_isnull(L, 2)) /* is there a 2nd argument? */ 621 if (!lua_isnull(L, 2)) /* is there a 2nd argument? */
671 luaL_check_rawtype(L, 2, LUA_TFUNCTION); 622 luaL_check_type(L, 2, LUA_TFUNCTION);
672 lua_settop(L, 2); /* make sure there is two arguments */ 623 lua_settop(L, 2); /* make sure there is two arguments */
673 auxsort(L, 1, n); 624 auxsort(L, 1, n);
674 return 0; 625 return 0;
@@ -686,28 +637,19 @@ static const luaL_reg base_funcs[] = {
686 {"dofile", luaB_dofile}, 637 {"dofile", luaB_dofile},
687 {"dostring", luaB_dostring}, 638 {"dostring", luaB_dostring},
688 {"error", luaB_error}, 639 {"error", luaB_error},
640 {"eventtable", luaB_eventtable},
689 {"foreach", luaB_foreach}, 641 {"foreach", luaB_foreach},
690 {"foreachi", luaB_foreachi}, 642 {"foreachi", luaB_foreachi},
691 {"gcinfo", luaB_gcinfo}, 643 {"gcinfo", luaB_gcinfo},
692 {"getglobal", luaB_getglobal}, 644 {"getglobal", luaB_getglobal}, /* compatibility with 4.0 */
693 {"gettagmethod", luaB_gettagmethod},
694 {"globals", luaB_globals}, 645 {"globals", luaB_globals},
695 {"loadfile", luaB_loadfile}, 646 {"loadfile", luaB_loadfile},
696 {"loadstring", luaB_loadstring}, 647 {"loadstring", luaB_loadstring},
697 {"newtype", luaB_newtype},
698 {"newtag", luaB_newtype}, /* for compatibility 4.0 */
699 {"next", luaB_next}, 648 {"next", luaB_next},
700 {"print", luaB_print}, 649 {"print", luaB_print},
701 {"rawget", luaB_rawget}, 650 {"rawget", luaB_rawget},
702 {"rawset", luaB_rawset}, 651 {"rawset", luaB_rawset},
703 {"rawgettable", luaB_rawget}, /* for compatibility 3.2 */ 652 {"setglobal", luaB_setglobal}, /* compatibility with 4.0 */
704 {"rawsettable", luaB_rawset}, /* for compatibility 3.2 */
705 {"rawtype", luaB_rawtype},
706 {"setglobal", luaB_setglobal},
707 {"settag", luaB_settype}, /* for compatibility 4.0 */
708 {"settype", luaB_settype},
709 {"settagmethod", luaB_settagmethod},
710 {"tag", luaB_tag},
711 {"tonumber", luaB_tonumber}, 653 {"tonumber", luaB_tonumber},
712 {"tostring", luaB_tostring}, 654 {"tostring", luaB_tostring},
713 {"type", luaB_type}, 655 {"type", luaB_type},
diff --git a/ldebug.c b/ldebug.c
index 5537fcd3..954c68c0 100644
--- a/ldebug.c
+++ b/ldebug.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldebug.c,v 1.92 2001/10/31 19:58:11 roberto Exp $ 2** $Id: ldebug.c,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $
3** Debug Interface 3** Debug Interface
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -205,22 +205,8 @@ static void funcinfo (lua_State *L, lua_Debug *ar, StkId func) {
205} 205}
206 206
207 207
208static const char *travtagmethods (global_State *G, const TObject *o) {
209 if (ttype(o) == LUA_TFUNCTION) {
210 int e;
211 for (e=0; e<TM_N; e++) {
212 int t;
213 for (t=0; t<G->ntag; t++)
214 if (clvalue(o) == luaT_gettm(G, t, e))
215 return luaT_eventname[e];
216 }
217 }
218 return NULL;
219}
220
221
222static const char *travglobals (lua_State *L, const TObject *o) { 208static const char *travglobals (lua_State *L, const TObject *o) {
223 Table *g = hvalue(&L->gt); 209 Table *g = hvalue(gt(L));
224 int i = sizenode(g); 210 int i = sizenode(g);
225 while (i--) { 211 while (i--) {
226 Node *n = node(g, i); 212 Node *n = node(g, i);
@@ -235,10 +221,7 @@ static void getname (lua_State *L, const TObject *f, lua_Debug *ar) {
235 /* try to find a name for given function */ 221 /* try to find a name for given function */
236 if ((ar->name = travglobals(L, f)) != NULL) 222 if ((ar->name = travglobals(L, f)) != NULL)
237 ar->namewhat = "global"; 223 ar->namewhat = "global";
238 /* not found: try tag methods */ 224 else ar->namewhat = ""; /* not found */
239 else if ((ar->name = travtagmethods(G(L), f)) != NULL)
240 ar->namewhat = "tag-method";
241 else ar->namewhat = ""; /* not found at all */
242} 225}
243 226
244 227
@@ -531,7 +514,7 @@ static const char *getfuncname (lua_State *L, CallInfo *ci,
531void luaG_typeerror (lua_State *L, StkId o, const char *op) { 514void luaG_typeerror (lua_State *L, StkId o, const char *op) {
532 const char *name; 515 const char *name;
533 const char *kind = getobjname(L, o, &name); 516 const char *kind = getobjname(L, o, &name);
534 const char *t = luaT_typename(G(L), o); 517 const char *t = luaT_typenames[ttype(o)];
535 if (kind) 518 if (kind)
536 luaO_verror(L, "attempt to %.30s %.20s `%.40s' (a %.10s value)", 519 luaO_verror(L, "attempt to %.30s %.20s `%.40s' (a %.10s value)",
537 op, kind, name, t); 520 op, kind, name, t);
@@ -556,8 +539,8 @@ void luaG_aritherror (lua_State *L, StkId p1, TObject *p2) {
556 539
557 540
558void luaG_ordererror (lua_State *L, const TObject *p1, const TObject *p2) { 541void luaG_ordererror (lua_State *L, const TObject *p1, const TObject *p2) {
559 const char *t1 = luaT_typename(G(L), p1); 542 const char *t1 = luaT_typenames[ttype(p1)];
560 const char *t2 = luaT_typename(G(L), p2); 543 const char *t2 = luaT_typenames[ttype(p2)];
561 if (t1[2] == t2[2]) 544 if (t1[2] == t2[2])
562 luaO_verror(L, "attempt to compare two %.10s values", t1); 545 luaO_verror(L, "attempt to compare two %.10s values", t1);
563 else 546 else
diff --git a/ldo.c b/ldo.c
index 4e7722e3..aaf4de55 100644
--- a/ldo.c
+++ b/ldo.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldo.c,v 1.144 2001/11/27 20:56:47 roberto Exp $ 2** $Id: ldo.c,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $
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*/
@@ -43,8 +43,7 @@ void luaD_init (lua_State *L, int stacksize) {
43 stacksize += EXTRA_STACK; 43 stacksize += EXTRA_STACK;
44 L->stack = luaM_newvector(L, stacksize, TObject); 44 L->stack = luaM_newvector(L, stacksize, TObject);
45 L->stacksize = stacksize; 45 L->stacksize = stacksize;
46 setnilvalue(L->stack); /* the `initial' function */ 46 L->top = L->basefunc.base = L->stack + RESERVED_STACK_PREFIX;
47 L->top = L->basefunc.base = L->stack + 1;
48 restore_stack_limit(L); 47 restore_stack_limit(L);
49} 48}
50 49
@@ -143,12 +142,13 @@ void luaD_call (lua_State *L, StkId func) {
143 CallInfo ci; 142 CallInfo ci;
144 if (ttype(func) != LUA_TFUNCTION) { 143 if (ttype(func) != LUA_TFUNCTION) {
145 /* `func' is not a function; check the `function' tag method */ 144 /* `func' is not a function; check the `function' tag method */
146 Closure *tm = luaT_gettmbyObj(G(L), func, TM_FUNCTION); 145 const TObject *tm = luaT_gettmbyobj(L, func, TM_CALL);
147 if (tm == NULL) 146 if (tm == NULL || ttype(tm) != LUA_TFUNCTION)
148 luaG_typeerror(L, func, "call"); 147 luaG_typeerror(L, func, "call");
149 luaD_openstack(L, func); 148 luaD_openstack(L, func);
150 setclvalue(func, tm); /* tag method is the new function to be called */ 149 setobj(func, tm); /* tag method is the new function to be called */
151 } 150 }
151 lua_assert(ttype(func) == LUA_TFUNCTION);
152 ci.prev = L->ci; /* chain new callinfo */ 152 ci.prev = L->ci; /* chain new callinfo */
153 L->ci = &ci; 153 L->ci = &ci;
154 ci.base = func+1; 154 ci.base = func+1;
@@ -300,9 +300,12 @@ struct lua_longjmp {
300 300
301 301
302static void message (lua_State *L, const char *s) { 302static void message (lua_State *L, const char *s) {
303 StkId top = L->top; 303 TObject o, m;
304 luaV_getglobal(L, luaS_newliteral(L, LUA_ERRORMESSAGE), top); 304 setsvalue(&o, luaS_newliteral(L, LUA_ERRORMESSAGE));
305 if (ttype(top) == LUA_TFUNCTION) { 305 luaV_gettable(L, gt(L), &o, &m);
306 if (ttype(&m) == LUA_TFUNCTION) {
307 StkId top = L->top;
308 setobj(top, &m);
306 incr_top; 309 incr_top;
307 setsvalue(top+1, luaS_new(L, s)); 310 setsvalue(top+1, luaS_new(L, s));
308 incr_top; 311 incr_top;
diff --git a/lfunc.c b/lfunc.c
index 25a8bb07..d1eaa2f9 100644
--- a/lfunc.c
+++ b/lfunc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lfunc.c,v 1.49 2001/11/06 21:41:53 roberto Exp $ 2** $Id: lfunc.c,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $
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*/
@@ -54,7 +54,6 @@ UpVal *luaF_findupval (lua_State *L, StkId level) {
54 } 54 }
55 p = luaM_new(L, UpVal); /* not found: create a new one */ 55 p = luaM_new(L, UpVal); /* not found: create a new one */
56 p->v = level; /* current value lives in the stack */ 56 p->v = level; /* current value lives in the stack */
57 p->mark = 1; /* won't participate in GC while open */
58 p->next = *pp; /* chain it in the proper position */ 57 p->next = *pp; /* chain it in the proper position */
59 *pp = p; 58 *pp = p;
60 return p; 59 return p;
@@ -68,7 +67,6 @@ void luaF_close (lua_State *L, StkId level) {
68 p->v = &p->value; /* now current value lives here */ 67 p->v = &p->value; /* now current value lives here */
69 L->openupval = p->next; /* remove from `open' list */ 68 L->openupval = p->next; /* remove from `open' list */
70 p->next = G(L)->rootupval; /* chain in `closed' list */ 69 p->next = G(L)->rootupval; /* chain in `closed' list */
71 p->mark = 0; /* now it can be collected */
72 G(L)->rootupval = p; 70 G(L)->rootupval = p;
73 } 71 }
74} 72}
diff --git a/lgc.c b/lgc.c
index 5ea01c77..3aa9f98d 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.c,v 1.116 2001/11/06 21:41:53 roberto Exp $ 2** $Id: lgc.c,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $
3** Garbage Collector 3** Garbage Collector
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -30,6 +30,15 @@ typedef struct GCState {
30#define strmark(s) {if ((s)->tsv.marked == 0) (s)->tsv.marked = 1;} 30#define strmark(s) {if ((s)->tsv.marked == 0) (s)->tsv.marked = 1;}
31 31
32 32
33/* mark tricks for userdata */
34#define isudmarked(u) (u->uv.len & 1)
35#define markud(u) (u->uv.len |= 1)
36#define unmarkud(u) (u->uv.len--)
37
38
39/* mark tricks for upvalues (assume that open upvalues are always marked) */
40#define isupvalmarked(uv) ((uv)->v != &(uv)->value)
41
33 42
34static void markobject (GCState *st, TObject *o); 43static void markobject (GCState *st, TObject *o);
35 44
@@ -66,9 +75,9 @@ static void markclosure (GCState *st, Closure *cl) {
66 protomark(cl->l.p); 75 protomark(cl->l.p);
67 for (i=0; i<cl->l.nupvalues; i++) { /* mark its upvalues */ 76 for (i=0; i<cl->l.nupvalues; i++) { /* mark its upvalues */
68 UpVal *u = cl->l.upvals[i]; 77 UpVal *u = cl->l.upvals[i];
69 if (!u->mark) { 78 if (!isupvalmarked(u)) {
70 u->mark = 1; 79 markobject(st, &u->value);
71 markobject(st, u->v); 80 u->v = NULL; /* mark it! */
72 } 81 }
73 } 82 }
74 } 83 }
@@ -90,8 +99,8 @@ static void markobject (GCState *st, TObject *o) {
90 strmark(tsvalue(o)); 99 strmark(tsvalue(o));
91 break; 100 break;
92 case LUA_TUSERDATA: 101 case LUA_TUSERDATA:
93 if (!ismarkedudata(uvalue(o))) 102 if (!isudmarked(uvalue(o)))
94 switchudatamark(uvalue(o)); 103 markud(uvalue(o));
95 break; 104 break;
96 case LUA_TFUNCTION: 105 case LUA_TFUNCTION:
97 markclosure(st, clvalue(o)); 106 markclosure(st, clvalue(o));
@@ -112,7 +121,6 @@ static void markstacks (lua_State *L, GCState *st) {
112 lua_State *L1 = L; 121 lua_State *L1 = L;
113 do { /* for each thread */ 122 do { /* for each thread */
114 StkId o, lim; 123 StkId o, lim;
115 markobject(st, &L1->gt); /* mark table of globals */
116 for (o=L1->stack; o<L1->top; o++) 124 for (o=L1->stack; o<L1->top; o++)
117 markobject(st, o); 125 markobject(st, o);
118 lim = (L1->stack_last - L1->ci->base > MAXSTACK) ? L1->ci->base+MAXSTACK 126 lim = (L1->stack_last - L1->ci->base > MAXSTACK) ? L1->ci->base+MAXSTACK
@@ -124,17 +132,10 @@ static void markstacks (lua_State *L, GCState *st) {
124} 132}
125 133
126 134
127static void marktagmethods (global_State *G, GCState *st) { 135static void markudet (lua_State *L, GCState *st) {
128 int t; 136 Udata *u;
129 for (t=0; t<G->ntag; t++) { 137 for (u = G(L)->rootudata; u; u = u->uv.next)
130 struct TM *tm = &G->TMtable[t]; 138 marktable(st, u->uv.eventtable);
131 int e;
132 if (tm->name) strmark(tm->name);
133 for (e=0; e<TM_N; e++) {
134 Closure *cl = tm->method[e];
135 if (cl) markclosure(st, cl);
136 }
137 }
138} 139}
139 140
140 141
@@ -152,6 +153,7 @@ static void traversetable (GCState *st, Table *h) {
152 h->mark = st->toclear; /* put in the appropriate list */ 153 h->mark = st->toclear; /* put in the appropriate list */
153 st->toclear = h; 154 st->toclear = h;
154 } 155 }
156 marktable(st, h->eventtable);
155 if (!(mode & LUA_WEAK_VALUE)) { 157 if (!(mode & LUA_WEAK_VALUE)) {
156 i = sizearray(h); 158 i = sizearray(h);
157 while (i--) 159 while (i--)
@@ -172,11 +174,9 @@ static void traversetable (GCState *st, Table *h) {
172 174
173 175
174static void markall (lua_State *L, GCState *st) { 176static void markall (lua_State *L, GCState *st) {
175 marktagmethods(G(L), st); /* mark tag methods */
176 markstacks(L, st); /* mark all stacks */ 177 markstacks(L, st); /* mark all stacks */
177 marktable(st, G(L)->type2tag); 178 markudet(L, st); /* mark userdata's event tables */
178 markobject(st, &G(L)->registry); 179 while (st->tmark) { /* traverse marked tables */
179 while (st->tmark) { /* mark tables */
180 Table *h = st->tmark; /* get first table from list */ 180 Table *h = st->tmark; /* get first table from list */
181 st->tmark = h->mark; /* remove it from list */ 181 st->tmark = h->mark; /* remove it from list */
182 traversetable(st, h); 182 traversetable(st, h);
@@ -189,7 +189,7 @@ static int hasmark (const TObject *o) {
189 case LUA_TSTRING: 189 case LUA_TSTRING:
190 return tsvalue(o)->tsv.marked; 190 return tsvalue(o)->tsv.marked;
191 case LUA_TUSERDATA: 191 case LUA_TUSERDATA:
192 return ismarkedudata(uvalue(o)); 192 return isudmarked(uvalue(o));
193 case LUA_TTABLE: 193 case LUA_TTABLE:
194 return ismarked(hvalue(o)); 194 return ismarked(hvalue(o));
195 case LUA_TFUNCTION: 195 case LUA_TFUNCTION:
@@ -261,8 +261,9 @@ static void collectupval (lua_State *L) {
261 UpVal **v = &G(L)->rootupval; 261 UpVal **v = &G(L)->rootupval;
262 UpVal *curr; 262 UpVal *curr;
263 while ((curr = *v) != NULL) { 263 while ((curr = *v) != NULL) {
264 if (curr->mark) { 264 if (isupvalmarked(curr)) {
265 curr->mark = 0; 265 lua_assert(curr->v == NULL);
266 curr->v = &curr->value; /* unmark */
266 v = &curr->next; /* next */ 267 v = &curr->next; /* next */
267 } 268 }
268 else { 269 else {
@@ -289,26 +290,27 @@ static void collecttable (lua_State *L) {
289} 290}
290 291
291 292
292static void collectudata (lua_State *L, int keep) { 293static Udata *collectudata (lua_State *L, int keep) {
293 Udata **p = &G(L)->rootudata; 294 Udata **p = &G(L)->rootudata;
294 Udata *curr; 295 Udata *curr;
296 Udata *collected = NULL;
295 while ((curr = *p) != NULL) { 297 while ((curr = *p) != NULL) {
296 if (ismarkedudata(curr)) { 298 if (isudmarked(curr)) {
297 switchudatamark(curr); /* unmark */ 299 unmarkud(curr);
298 p = &curr->uv.next; 300 p = &curr->uv.next;
299 } 301 }
300 else { /* collect */ 302 else { /* collect */
301 int tag = curr->uv.tag; 303 const TObject *tm = fasttm(L, curr->uv.eventtable, TM_GC);
302 *p = curr->uv.next; 304 *p = curr->uv.next;
303 if (keep || /* must keep all of them (to close state)? */ 305 if (keep || tm != NULL) {
304 luaT_gettm(G(L), tag, TM_GC)) { /* or is there a GC tag method? */ 306 curr->uv.next = collected;
305 curr->uv.next = G(L)->TMtable[tag].collected; /* chain udata ... */ 307 collected = curr;
306 G(L)->TMtable[tag].collected = curr; /* ... to call its TM later */
307 } 308 }
308 else /* no tag method; delete udata */ 309 else /* no gc action; delete udata */
309 luaM_free(L, curr, sizeudata(curr->uv.len)); 310 luaM_free(L, curr, sizeudata(curr->uv.len));
310 } 311 }
311 } 312 }
313 return collected;
312} 314}
313 315
314 316
@@ -347,14 +349,14 @@ static void checkMbuffer (lua_State *L) {
347} 349}
348 350
349 351
350static void callgcTM (lua_State *L, const TObject *obj) { 352static void callgcTM (lua_State *L, Udata *udata) {
351 Closure *tm = luaT_gettmbyObj(G(L), obj, TM_GC); 353 const TObject *tm = fasttm(L, udata->uv.eventtable, TM_GC);
352 if (tm != NULL) { 354 if (tm != NULL && ttype(tm) == LUA_TFUNCTION) {
353 int oldah = L->allowhooks; 355 int oldah = L->allowhooks;
354 StkId top = L->top; 356 StkId top = L->top;
355 L->allowhooks = 0; /* stop debug hooks during GC tag methods */ 357 L->allowhooks = 0; /* stop debug hooks during GC tag methods */
356 setclvalue(top, tm); 358 setobj(top, tm);
357 setobj(top+1, obj); 359 setuvalue(top+1, udata);
358 L->top += 2; 360 L->top += 2;
359 luaD_call(L, top); 361 luaD_call(L, top);
360 L->top = top; /* restore top */ 362 L->top = top; /* restore top */
@@ -363,53 +365,52 @@ static void callgcTM (lua_State *L, const TObject *obj) {
363} 365}
364 366
365 367
366static void callgcTMudata (lua_State *L) { 368static void callgcTMudata (lua_State *L, Udata *c) {
367 int tag;
368 luaD_checkstack(L, 3); 369 luaD_checkstack(L, 3);
369 for (tag=G(L)->ntag-1; tag>=0; tag--) { /* for each tag (in reverse order) */ 370 L->top++; /* reserve space to keep udata while runs its gc method */
370 Udata *udata; 371 while (c != NULL) {
371 while ((udata = G(L)->TMtable[tag].collected) != NULL) { 372 Udata *udata = c;
372 G(L)->TMtable[tag].collected = udata->uv.next; /* remove it from list */ 373 c = udata->uv.next; /* remove udata from list */
373 udata->uv.next = G(L)->rootudata; /* resurect it */ 374 udata->uv.next = G(L)->rootudata; /* resurect it */
374 G(L)->rootudata = udata; 375 G(L)->rootudata = udata;
375 setuvalue(L->top, udata); 376 setuvalue(L->top - 1, udata);
376 L->top++; /* keep it in stack to avoid being (recursively) collected */ 377 callgcTM(L, udata);
377 callgcTM(L, L->top-1); 378 /* mark udata as finalized (default event table) */
378 uvalue(L->top-1)->uv.tag = 0; /* default tag (udata is `finalized') */ 379 uvalue(L->top-1)->uv.eventtable = hvalue(defaultet(L));
379 L->top--;
380 }
381 } 380 }
381 L->top--;
382} 382}
383 383
384 384
385void luaC_callallgcTM (lua_State *L) { 385void luaC_callallgcTM (lua_State *L) {
386 if (G(L)->rootudata) { /* avoid problems with incomplete states */ 386 if (G(L)->rootudata) { /* avoid problems with incomplete states */
387 collectudata(L, 1); /* collect all udata into tag lists */ 387 Udata *c = collectudata(L, 1); /* collect all udata */
388 callgcTMudata(L); /* call their GC tag methods */ 388 callgcTMudata(L, c); /* call their GC tag methods */
389 } 389 }
390} 390}
391 391
392 392
393void luaC_collect (lua_State *L, int all) { 393Udata *luaC_collect (lua_State *L, int all) {
394 collectudata(L, 0); 394 Udata *c = collectudata(L, 0);
395 collectstrings(L, all); 395 collectstrings(L, all);
396 collecttable(L); 396 collecttable(L);
397 collectproto(L); 397 collectproto(L);
398 collectupval(L); 398 collectupval(L);
399 collectclosures(L); 399 collectclosures(L);
400 return c;
400} 401}
401 402
402 403
403void luaC_collectgarbage (lua_State *L) { 404void luaC_collectgarbage (lua_State *L) {
405 Udata *c;
404 GCState st; 406 GCState st;
405 st.tmark = NULL; 407 st.tmark = NULL;
406 st.toclear = NULL; 408 st.toclear = NULL;
407 markall(L, &st); 409 markall(L, &st);
408 cleartables(st.toclear); 410 cleartables(st.toclear);
409 luaC_collect(L, 0); 411 c = luaC_collect(L, 0);
410 checkMbuffer(L); 412 checkMbuffer(L);
411 G(L)->GCthreshold = 2*G(L)->nblocks; /* new threshold */ 413 G(L)->GCthreshold = 2*G(L)->nblocks; /* new threshold */
412 callgcTMudata(L); 414 callgcTMudata(L, c);
413 callgcTM(L, &luaO_nilobject);
414} 415}
415 416
diff --git a/lgc.h b/lgc.h
index 7e1e5478..a5baebcb 100644
--- a/lgc.h
+++ b/lgc.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.h,v 1.11 2001/06/12 18:43:13 roberto Exp roberto $ 2** $Id: lgc.h,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $
3** Garbage Collector 3** Garbage Collector
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -16,7 +16,7 @@
16 16
17 17
18void luaC_callallgcTM (lua_State *L); 18void luaC_callallgcTM (lua_State *L);
19void luaC_collect (lua_State *L, int all); 19Udata *luaC_collect (lua_State *L, int all);
20void luaC_collectgarbage (lua_State *L); 20void luaC_collectgarbage (lua_State *L);
21 21
22 22
diff --git a/liolib.c b/liolib.c
index 16adf983..a4f6eed5 100644
--- a/liolib.c
+++ b/liolib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: liolib.c,v 1.124 2001/10/26 17:33:30 roberto Exp $ 2** $Id: liolib.c,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $
3** Standard I/O (and system) library 3** Standard I/O (and system) library
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -61,6 +61,7 @@ static int pushresult (lua_State *L, int i) {
61} 61}
62 62
63 63
64
64/* 65/*
65** {====================================================== 66** {======================================================
66** FILE Operations 67** FILE Operations
@@ -68,14 +69,30 @@ static int pushresult (lua_State *L, int i) {
68*/ 69*/
69 70
70 71
71#define checkfile(L,f) (strcmp(lua_type(L,(f)), FILEHANDLE) == 0) 72
73static int checkfile (lua_State *L, int findex, const char *tname) {
74 int res;
75 lua_geteventtable(L, findex);
76 lua_pushstring(L, tname);
77 lua_gettable(L, LUA_REGISTRYINDEX);
78 res = lua_equal(L, -1, -2);
79 lua_pop(L, 2);
80 return res;
81}
82
83
84/* temporary?? should be in auxlib... */
85static void *luaL_check_userdata (lua_State *L, int findex, const char *tn) {
86 luaL_arg_check(L, checkfile(L, findex, tn), findex, "bad file");
87 return lua_touserdata(L, findex);
88}
72 89
73 90
74static FILE *getopthandle (lua_State *L, int inout) { 91static FILE *getopthandle (lua_State *L, int inout) {
75 FILE *p = (FILE *)(lua_touserdata(L, 1)); 92 FILE *p = (FILE *)(lua_touserdata(L, 1));
76 if (p != NULL) { /* is it a userdata ? */ 93 if (p != NULL) { /* is it a userdata ? */
77 if (!checkfile(L, 1)) { /* not a valid file handle? */ 94 if (!checkfile(L, 1, FILEHANDLE)) { /* not a valid file handle? */
78 if (strcmp(lua_type(L, 1), CLOSEDFILEHANDLE) == 0) 95 if (checkfile(L, 1, CLOSEDFILEHANDLE))
79 luaL_argerror(L, 1, "file is closed"); 96 luaL_argerror(L, 1, "file is closed");
80 else 97 else
81 luaL_argerror(L, 1, "(invalid value)"); 98 luaL_argerror(L, 1, "(invalid value)");
@@ -84,7 +101,7 @@ static FILE *getopthandle (lua_State *L, int inout) {
84 } 101 }
85 else { /* try global value */ 102 else { /* try global value */
86 lua_getglobal(L, filenames[inout]); 103 lua_getglobal(L, filenames[inout]);
87 if (!checkfile(L,-1)) 104 if (!checkfile(L, -1, FILEHANDLE))
88 luaL_verror(L, "global variable `%.10s' is not a valid file handle", 105 luaL_verror(L, "global variable `%.10s' is not a valid file handle",
89 filenames[inout]); 106 filenames[inout]);
90 p = (FILE *)(lua_touserdata(L, -1)); 107 p = (FILE *)(lua_touserdata(L, -1));
@@ -95,7 +112,9 @@ static FILE *getopthandle (lua_State *L, int inout) {
95 112
96static void newfile (lua_State *L, FILE *f) { 113static void newfile (lua_State *L, FILE *f) {
97 lua_newuserdatabox(L, f); 114 lua_newuserdatabox(L, f);
98 lua_settag(L, lua_name2tag(L, FILEHANDLE)); 115 lua_pushliteral(L, FILEHANDLE);
116 lua_gettable(L, LUA_REGISTRYINDEX);
117 lua_seteventtable(L, -2);
99} 118}
100 119
101 120
@@ -130,7 +149,9 @@ static int io_close (lua_State *L) {
130 int status = 1; 149 int status = 1;
131 if (f != stdin && f != stdout && f != stderr) { 150 if (f != stdin && f != stdout && f != stderr) {
132 lua_settop(L, 1); /* make sure file is on top */ 151 lua_settop(L, 1); /* make sure file is on top */
133 lua_settag(L, lua_name2tag(L, CLOSEDFILEHANDLE)); 152 lua_pushliteral(L, CLOSEDFILEHANDLE);
153 lua_gettable(L, LUA_REGISTRYINDEX);
154 lua_seteventtable(L, 1);
134 status = (CLOSEFILE(L, f) == 0); 155 status = (CLOSEFILE(L, f) == 0);
135 } 156 }
136 return pushresult(L, status); 157 return pushresult(L, status);
@@ -301,7 +322,7 @@ static int io_read (lua_State *L) {
301 luaL_check_stack(L, nargs+LUA_MINSTACK, "too many arguments"); 322 luaL_check_stack(L, nargs+LUA_MINSTACK, "too many arguments");
302 success = 1; 323 success = 1;
303 for (n = 1; n<=nargs && success; n++) { 324 for (n = 1; n<=nargs && success; n++) {
304 if (lua_rawtag(L, n) == LUA_TNUMBER) { 325 if (lua_type(L, n) == LUA_TNUMBER) {
305 size_t l = (size_t)lua_tonumber(L, n); 326 size_t l = (size_t)lua_tonumber(L, n);
306 success = (l == 0) ? test_eof(L, f) : read_chars(L, f, l); 327 success = (l == 0) ? test_eof(L, f) : read_chars(L, f, l);
307 } 328 }
@@ -353,7 +374,7 @@ static int io_write (lua_State *L) {
353 int arg; 374 int arg;
354 int status = 1; 375 int status = 1;
355 for (arg=1; arg<=nargs; arg++) { 376 for (arg=1; arg<=nargs; arg++) {
356 if (lua_rawtag(L, arg) == LUA_TNUMBER) { 377 if (lua_type(L, arg) == LUA_TNUMBER) {
357 /* optimization: could be done exactly as for strings */ 378 /* optimization: could be done exactly as for strings */
358 status = status && 379 status = status &&
359 fprintf(f, LUA_NUMBER_FMT, lua_tonumber(L, arg)) > 0; 380 fprintf(f, LUA_NUMBER_FMT, lua_tonumber(L, arg)) > 0;
@@ -514,7 +535,7 @@ static int io_time (lua_State *L) {
514 else { 535 else {
515 time_t t; 536 time_t t;
516 struct tm ts; 537 struct tm ts;
517 luaL_check_rawtype(L, 1, LUA_TTABLE); 538 luaL_check_type(L, 1, LUA_TTABLE);
518 lua_settop(L, 1); /* make sure table is at the top */ 539 lua_settop(L, 1); /* make sure table is at the top */
519 ts.tm_sec = getfield(L, "sec", 0); 540 ts.tm_sec = getfield(L, "sec", 0);
520 ts.tm_min = getfield(L, "min", 0); 541 ts.tm_min = getfield(L, "min", 0);
@@ -677,8 +698,18 @@ static const luaL_reg iolib[] = {
677 698
678 699
679LUALIB_API int lua_iolibopen (lua_State *L) { 700LUALIB_API int lua_iolibopen (lua_State *L) {
680 int iotag = lua_newtype(L, FILEHANDLE, LUA_TUSERDATA); 701 lua_pushliteral(L, FILEHANDLE);
681 lua_newtype(L, CLOSEDFILEHANDLE, LUA_TUSERDATA); 702 lua_newtable(L); /* event table for FILEHANDLE */
703 /* close files when collected */
704 lua_pushliteral(L, "gc");
705 lua_pushcfunction(L, file_collect);
706 lua_settable(L, -3);
707 /* put new eventtable into registry */
708 lua_settable(L, LUA_REGISTRYINDEX); /* registry.FILEHANDLE = eventtable */
709 lua_pushliteral(L, CLOSEDFILEHANDLE);
710 /* event table for CLOSEDFILEHANDLE */
711 lua_newtable(L);
712 lua_settable(L, LUA_REGISTRYINDEX);
682 luaL_openl(L, iolib); 713 luaL_openl(L, iolib);
683 /* predefined file handles */ 714 /* predefined file handles */
684 newfilewithname(L, stdin, basicfiles[INFILE]); 715 newfilewithname(L, stdin, basicfiles[INFILE]);
@@ -686,9 +717,6 @@ LUALIB_API int lua_iolibopen (lua_State *L) {
686 newfilewithname(L, stderr, "_STDERR"); 717 newfilewithname(L, stderr, "_STDERR");
687 resetfile(L, INFILE); 718 resetfile(L, INFILE);
688 resetfile(L, OUTFILE); 719 resetfile(L, OUTFILE);
689 /* close files when collected */
690 lua_pushcfunction(L, file_collect);
691 lua_settagmethod(L, iotag, "gc");
692 return 0; 720 return 0;
693} 721}
694 722
diff --git a/lmathlib.c b/lmathlib.c
index eb05fef2..e5be054a 100644
--- a/lmathlib.c
+++ b/lmathlib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lmathlib.c,v 1.38 2001/03/26 14:31:49 roberto Exp $ 2** $Id: lmathlib.c,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $
3** Standard mathematical library 3** Standard mathematical library
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -220,6 +220,7 @@ static const luaL_reg mathlib[] = {
220{"log10", math_log10}, 220{"log10", math_log10},
221{"exp", math_exp}, 221{"exp", math_exp},
222{"deg", math_deg}, 222{"deg", math_deg},
223{"pow", math_pow},
223{"rad", math_rad}, 224{"rad", math_rad},
224{"random", math_random}, 225{"random", math_random},
225{"randomseed", math_randomseed} 226{"randomseed", math_randomseed}
@@ -230,8 +231,6 @@ static const luaL_reg mathlib[] = {
230*/ 231*/
231LUALIB_API int lua_mathlibopen (lua_State *L) { 232LUALIB_API int lua_mathlibopen (lua_State *L) {
232 luaL_openl(L, mathlib); 233 luaL_openl(L, mathlib);
233 lua_pushcfunction(L, math_pow);
234 lua_settagmethod(L, LUA_TNUMBER, "pow");
235 lua_pushnumber(L, PI); 234 lua_pushnumber(L, PI);
236 lua_setglobal(L, "PI"); 235 lua_setglobal(L, "PI");
237 return 0; 236 return 0;
diff --git a/lobject.h b/lobject.h
index beb6574f..bf07e3db 100644
--- a/lobject.h
+++ b/lobject.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lobject.h,v 1.116 2001/11/06 21:41:53 roberto Exp $ 2** $Id: lobject.h,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $
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*/
@@ -31,15 +31,6 @@
31#define NUM_TAGS 6 31#define NUM_TAGS 6
32 32
33 33
34/*
35** extra tags:
36** first is used locally when moving an upvalue from the stack to the heap;
37** second prefixes upvalues in the heap
38*/
39#define LUA_TUPVAL 6
40#define LUA_HEAPUPVAL 7
41
42
43typedef union { 34typedef union {
44 union TString *ts; 35 union TString *ts;
45 union Udata *u; 36 union Udata *u;
@@ -122,17 +113,14 @@ typedef union TString {
122typedef union Udata { 113typedef union Udata {
123 union L_Umaxalign dummy; /* ensures maximum alignment for `local' udata */ 114 union L_Umaxalign dummy; /* ensures maximum alignment for `local' udata */
124 struct { 115 struct {
125 int tag; /* negative means `marked' (only during GC) */ 116 struct Table *eventtable;
126 void *value; 117 void *value;
127 size_t len; 118 size_t len; /* least bit reserved for gc mark */
128 union Udata *next; /* chain for list of all udata */ 119 union Udata *next; /* chain for list of all udata */
129 } uv; 120 } uv;
130} Udata; 121} Udata;
131 122
132 123
133#define switchudatamark(u) ((u)->uv.tag = (-((u)->uv.tag+1)))
134#define ismarkedudata(u) ((u)->uv.tag < 0)
135
136 124
137 125
138/* 126/*
@@ -175,7 +163,6 @@ typedef struct LocVar {
175 163
176typedef struct UpVal { 164typedef struct UpVal {
177 TObject *v; /* points to stack or to its own value */ 165 TObject *v; /* points to stack or to its own value */
178 int mark;
179 struct UpVal *next; 166 struct UpVal *next;
180 TObject value; /* the value (when closed) */ 167 TObject value; /* the value (when closed) */
181} UpVal; 168} UpVal;
@@ -227,12 +214,13 @@ typedef struct Node {
227 214
228 215
229typedef struct Table { 216typedef struct Table {
217 struct Table *eventtable;
230 TObject *array; /* array part */ 218 TObject *array; /* array part */
231 Node *node; 219 Node *node;
232 int htag;
233 int sizearray; /* size of `array' array */ 220 int sizearray; /* size of `array' array */
234 lu_byte lsizenode; /* log2 of size of `node' array */ 221 lu_byte lsizenode; /* log2 of size of `node' array */
235 lu_byte weakmode; 222 lu_byte weakmode;
223 unsigned short flags; /* 1<<p means tagmethod(p) is not present */
236 Node *firstfree; /* this position is free; all positions after it are full */ 224 Node *firstfree; /* this position is free; all positions after it are full */
237 struct Table *next; 225 struct Table *next;
238 struct Table *mark; /* marked tables (point to itself when not marked) */ 226 struct Table *mark; /* marked tables (point to itself when not marked) */
diff --git a/lstate.c b/lstate.c
index 6e2ba8f1..7777b7a1 100644
--- a/lstate.c
+++ b/lstate.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstate.c,v 1.72 2001/11/06 21:40:51 roberto Exp $ 2** $Id: lstate.c,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $
3** Global State 3** Global State
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -40,12 +40,14 @@ static void f_luaopen (lua_State *L, void *ud) {
40 so->stacksize += LUA_MINSTACK; 40 so->stacksize += LUA_MINSTACK;
41 if (so->L != NULL) { /* shared global state? */ 41 if (so->L != NULL) { /* shared global state? */
42 L->_G = G(so->L); 42 L->_G = G(so->L);
43 L->gt = so->L->gt; /* share table of globals */
44 so->L->next->previous = L; /* insert L into linked list */ 43 so->L->next->previous = L; /* insert L into linked list */
45 L->next = so->L->next; 44 L->next = so->L->next;
46 so->L->next = L; 45 so->L->next = L;
47 L->previous = so->L; 46 L->previous = so->L;
48 luaD_init(L, so->stacksize); /* init stack */ 47 luaD_init(L, so->stacksize); /* init stack */
48 setobj(defaultet(L), defaultet(so->L)); /* share default event table */
49 setobj(gt(L), gt(so->L)); /* share table of globals */
50 setobj(registry(L), registry(so->L)); /* share registry */
49 } 51 }
50 else { /* create a new global state */ 52 else { /* create a new global state */
51 L->_G = luaM_new(L, global_State); 53 L->_G = luaM_new(L, global_State);
@@ -59,17 +61,17 @@ static void f_luaopen (lua_State *L, void *ud) {
59 G(L)->roottable = NULL; 61 G(L)->roottable = NULL;
60 G(L)->rootudata = NULL; 62 G(L)->rootudata = NULL;
61 G(L)->rootupval = NULL; 63 G(L)->rootupval = NULL;
62 G(L)->TMtable = NULL;
63 G(L)->sizeTM = 0;
64 G(L)->ntag = 0;
65 G(L)->nblocks = sizeof(lua_State) + sizeof(global_State); 64 G(L)->nblocks = sizeof(lua_State) + sizeof(global_State);
66 luaD_init(L, so->stacksize); /* init stack */ 65 luaD_init(L, so->stacksize); /* init stack */
67 sethvalue(&L->gt, luaH_new(L, 0, 4)); /* table of globals */ 66 /* create default event table with a dummy table, and then close the loop */
68 G(L)->type2tag = luaH_new(L, 0, 3); 67 sethvalue(defaultet(L), NULL);
69 sethvalue(&G(L)->registry, luaH_new(L, 0, 0)); 68 sethvalue(defaultet(L), luaH_new(L, 0, 4));
69 hvalue(defaultet(L))->eventtable = hvalue(defaultet(L));
70 sethvalue(gt(L), luaH_new(L, 0, 4)); /* table of globals */
71 sethvalue(registry(L), luaH_new(L, 0, 0)); /* registry */
70 luaS_resize(L, 4); /* initial size of string table */ 72 luaS_resize(L, 4); /* initial size of string table */
71 luaX_init(L);
72 luaT_init(L); 73 luaT_init(L);
74 luaX_init(L);
73 G(L)->GCthreshold = 4*G(L)->nblocks; 75 G(L)->GCthreshold = 4*G(L)->nblocks;
74 } 76 }
75} 77}
@@ -122,7 +124,6 @@ static void close_state (lua_State *L, lua_State *OL) {
122 lua_assert(G(L)->rootupval == NULL); 124 lua_assert(G(L)->rootupval == NULL);
123 lua_assert(G(L)->roottable == NULL); 125 lua_assert(G(L)->roottable == NULL);
124 luaS_freeall(L); 126 luaS_freeall(L);
125 luaM_freearray(L, G(L)->TMtable, G(L)->sizeTM, struct TM);
126 luaM_freearray(L, G(L)->Mbuffer, G(L)->Mbuffsize, char); 127 luaM_freearray(L, G(L)->Mbuffer, G(L)->Mbuffsize, char);
127 luaM_freelem(NULL, L->_G); 128 luaM_freelem(NULL, L->_G);
128 } 129 }
diff --git a/lstate.h b/lstate.h
index 981e28fe..84d3358e 100644
--- a/lstate.h
+++ b/lstate.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstate.h,v 1.64 2001/11/06 21:40:51 roberto Exp $ 2** $Id: lstate.h,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $
3** Global State 3** Global State
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -7,8 +7,10 @@
7#ifndef lstate_h 7#ifndef lstate_h
8#define lstate_h 8#define lstate_h
9 9
10#include "lobject.h"
11#include "lua.h" 10#include "lua.h"
11
12#include "lobject.h"
13#include "ltm.h"
12#include "luadebug.h" 14#include "luadebug.h"
13 15
14 16
@@ -40,7 +42,24 @@
40 42
41 43
42struct lua_longjmp; /* defined in ldo.c */ 44struct lua_longjmp; /* defined in ldo.c */
43struct TM; /* defined in ltm.h */ 45
46
47
48/*
49** reserve init of stack to store some global values
50*/
51
52/* default event table (both for tables and udata) */
53#define defaultet(L) (L->stack)
54
55/* table of globals */
56#define gt(L) (L->stack + 1)
57
58/* registry */
59#define registry(L) (L->stack + 2)
60
61#define RESERVED_STACK_PREFIX 3
62
44 63
45 64
46typedef struct stringtable { 65typedef struct stringtable {
@@ -57,11 +76,6 @@ typedef struct global_State {
57 void *Mbuffer; /* global buffer */ 76 void *Mbuffer; /* global buffer */
58 size_t Mbuffsize; /* size of Mbuffer */ 77 size_t Mbuffsize; /* size of Mbuffer */
59 stringtable strt; /* hash table for strings */ 78 stringtable strt; /* hash table for strings */
60 Table *type2tag; /* hash table from type names to tags */
61 TObject registry; /* registry table */
62 struct TM *TMtable; /* table for tag methods */
63 int sizeTM; /* size of TMtable */
64 int ntag; /* number of tags in TMtable */
65 lu_mem GCthreshold; 79 lu_mem GCthreshold;
66 lu_mem nblocks; /* number of `bytes' currently allocated */ 80 lu_mem nblocks; /* number of `bytes' currently allocated */
67 Proto *rootproto; /* list of all prototypes */ 81 Proto *rootproto; /* list of all prototypes */
@@ -69,6 +83,7 @@ typedef struct global_State {
69 Table *roottable; /* list of all tables */ 83 Table *roottable; /* list of all tables */
70 Udata *rootudata; /* list of all userdata */ 84 Udata *rootudata; /* list of all userdata */
71 UpVal *rootupval; /* list of closed up values */ 85 UpVal *rootupval; /* list of closed up values */
86 TString *tmname[TM_N]; /* array with tag-method names */
72} global_State; 87} global_State;
73 88
74 89
@@ -80,10 +95,9 @@ struct lua_State {
80 StkId top; /* first free slot in the stack */ 95 StkId top; /* first free slot in the stack */
81 CallInfo *ci; /* call info for current function */ 96 CallInfo *ci; /* call info for current function */
82 StkId stack_last; /* last free slot in the stack */ 97 StkId stack_last; /* last free slot in the stack */
83 TObject gt; /* table for globals */
84 global_State *_G;
85 StkId stack; /* stack base */ 98 StkId stack; /* stack base */
86 int stacksize; 99 int stacksize;
100 global_State *_G;
87 lua_Hook callhook; 101 lua_Hook callhook;
88 lua_Hook linehook; 102 lua_Hook linehook;
89 int allowhooks; 103 int allowhooks;
diff --git a/lstring.c b/lstring.c
index 5f69aafc..d12b6f0f 100644
--- a/lstring.c
+++ b/lstring.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstring.c,v 1.67 2001/08/31 19:46:07 roberto Exp $ 2** $Id: lstring.c,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $
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*/
@@ -84,9 +84,11 @@ TString *luaS_newlstr (lua_State *L, const char *str, size_t l) {
84 84
85 85
86Udata *luaS_newudata (lua_State *L, size_t s) { 86Udata *luaS_newudata (lua_State *L, size_t s) {
87 Udata *u = cast(Udata *, luaM_malloc(L, sizeudata(s))); 87 Udata *u;
88 if (s & 1) s++; /* make sure size is even */
89 u = cast(Udata *, luaM_malloc(L, sizeudata(s)));
88 u->uv.len = s; 90 u->uv.len = s;
89 u->uv.tag = 0; 91 u->uv.eventtable = hvalue(defaultet(L));
90 u->uv.value = u + 1; 92 u->uv.value = u + 1;
91 /* chain it on udata list */ 93 /* chain it on udata list */
92 u->uv.next = G(L)->rootudata; 94 u->uv.next = G(L)->rootudata;
diff --git a/lstrlib.c b/lstrlib.c
index 8ce5e9ba..2172a09c 100644
--- a/lstrlib.c
+++ b/lstrlib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstrlib.c,v 1.73 2001/10/26 17:33:30 roberto Exp $ 2** $Id: lstrlib.c,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $
3** Standard library for string operations and pattern-matching 3** Standard library for string operations and pattern-matching
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -97,7 +97,7 @@ static int str_concat (lua_State *L) {
97 size_t lsep; 97 size_t lsep;
98 const char *sep = luaL_opt_lstr(L, 2, "", &lsep); 98 const char *sep = luaL_opt_lstr(L, 2, "", &lsep);
99 int n, i; 99 int n, i;
100 luaL_check_rawtype(L, 1, LUA_TTABLE); 100 luaL_check_type(L, 1, LUA_TTABLE);
101 luaL_buffinit(L, &b); 101 luaL_buffinit(L, &b);
102 n = lua_getn(L, 1); 102 n = lua_getn(L, 1);
103 for (i=1; i<=n; i++) { 103 for (i=1; i<=n; i++) {
diff --git a/ltable.c b/ltable.c
index 61a5866d..25d62e41 100644
--- a/ltable.c
+++ b/ltable.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltable.c,v 1.88 2001/11/16 16:29:51 roberto Exp $ 2** $Id: ltable.c,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $
3** Lua tables (hash) 3** Lua tables (hash)
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -258,11 +258,12 @@ static void rehash (lua_State *L, Table *t) {
258 258
259Table *luaH_new (lua_State *L, int narray, int lnhash) { 259Table *luaH_new (lua_State *L, int narray, int lnhash) {
260 Table *t = luaM_new(L, Table); 260 Table *t = luaM_new(L, Table);
261 t->htag = TagDefault; 261 t->eventtable = hvalue(defaultet(L));
262 t->next = G(L)->roottable; 262 t->next = G(L)->roottable;
263 G(L)->roottable = t; 263 G(L)->roottable = t;
264 t->mark = t; 264 t->mark = t;
265 t->weakmode = 0; 265 t->weakmode = 0;
266 t->flags = ~0;
266 /* temporary values (kept only if some malloc fails) */ 267 /* temporary values (kept only if some malloc fails) */
267 t->array = NULL; 268 t->array = NULL;
268 t->sizearray = 0; 269 t->sizearray = 0;
@@ -419,19 +420,7 @@ void luaH_set (lua_State *L, Table *t, const TObject *key, const TObject *val) {
419 if (ttype(key) == LUA_TNIL) luaD_error(L, "table index is nil"); 420 if (ttype(key) == LUA_TNIL) luaD_error(L, "table index is nil");
420 newkey(L, t, key, val); 421 newkey(L, t, key, val);
421 } 422 }
422} 423 t->flags = 0;
423
424
425void luaH_setstr (lua_State *L, Table *t, TString *key, const TObject *val) {
426 const TObject *p = luaH_getstr(t, key);
427 if (p != &luaO_nilobject) {
428 settableval(p, val);
429 }
430 else {
431 TObject k;
432 setsvalue(&k, key);
433 newkey(L, t, &k, val);
434 }
435} 424}
436 425
437 426
diff --git a/ltable.h b/ltable.h
index 4d0faf55..67199ad2 100644
--- a/ltable.h
+++ b/ltable.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltable.h,v 1.37 2001/10/25 19:14:14 roberto Exp $ 2** $Id: ltable.h,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $
3** Lua tables (hash) 3** Lua tables (hash)
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -20,7 +20,6 @@
20const TObject *luaH_getnum (Table *t, int key); 20const TObject *luaH_getnum (Table *t, int key);
21void luaH_setnum (lua_State *L, Table *t, int key, const TObject *val); 21void luaH_setnum (lua_State *L, Table *t, int key, const TObject *val);
22const TObject *luaH_getstr (Table *t, TString *key); 22const TObject *luaH_getstr (Table *t, TString *key);
23void luaH_setstr (lua_State *L, Table *t, TString *key, const TObject *val);
24const TObject *luaH_get (Table *t, const TObject *key); 23const TObject *luaH_get (Table *t, const TObject *key);
25void luaH_set (lua_State *L, Table *t, const TObject *key, const TObject *val); 24void luaH_set (lua_State *L, Table *t, const TObject *key, const TObject *val);
26Table *luaH_new (lua_State *L, int narray, int lnhash); 25Table *luaH_new (lua_State *L, int narray, int lnhash);
diff --git a/ltests.c b/ltests.c
index e51ff23f..282c58b6 100644
--- a/ltests.c
+++ b/ltests.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltests.c,v 1.96 2001/11/06 21:41:43 roberto Exp $ 2** $Id: ltests.c,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $
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*/
@@ -240,13 +240,13 @@ static int mem_query (lua_State *L) {
240 240
241static int hash_query (lua_State *L) { 241static int hash_query (lua_State *L) {
242 if (lua_isnull(L, 2)) { 242 if (lua_isnull(L, 2)) {
243 luaL_arg_check(L, lua_tag(L, 1) == LUA_TSTRING, 1, "string expected"); 243 luaL_arg_check(L, lua_type(L, 1) == LUA_TSTRING, 1, "string expected");
244 lua_pushnumber(L, tsvalue(luaA_index(L, 1))->tsv.hash); 244 lua_pushnumber(L, tsvalue(luaA_index(L, 1))->tsv.hash);
245 } 245 }
246 else { 246 else {
247 TObject *o = luaA_index(L, 1); 247 TObject *o = luaA_index(L, 1);
248 Table *t; 248 Table *t;
249 luaL_check_rawtype(L, 2, LUA_TTABLE); 249 luaL_check_type(L, 2, LUA_TTABLE);
250 t = hvalue(luaA_index(L, 2)); 250 t = hvalue(luaA_index(L, 2));
251 lua_pushnumber(L, luaH_mainposition(t, o) - t->node); 251 lua_pushnumber(L, luaH_mainposition(t, o) - t->node);
252 } 252 }
@@ -257,7 +257,7 @@ static int hash_query (lua_State *L) {
257static int table_query (lua_State *L) { 257static int table_query (lua_State *L) {
258 const Table *t; 258 const Table *t;
259 int i = luaL_opt_int(L, 2, -1); 259 int i = luaL_opt_int(L, 2, -1);
260 luaL_check_rawtype(L, 1, LUA_TTABLE); 260 luaL_check_type(L, 1, LUA_TTABLE);
261 t = hvalue(luaA_index(L, 1)); 261 t = hvalue(luaA_index(L, 1));
262 if (i == -1) { 262 if (i == -1) {
263 lua_pushnumber(L, t->sizearray); 263 lua_pushnumber(L, t->sizearray);
@@ -333,6 +333,18 @@ static int unref (lua_State *L) {
333 return 0; 333 return 0;
334} 334}
335 335
336static int eventtable (lua_State *L) {
337 luaL_check_any(L, 1);
338 if (lua_isnull(L, 2))
339 lua_geteventtable(L, 1);
340 else {
341 lua_settop(L, 2);
342 luaL_check_type(L, 2, LUA_TTABLE);
343 lua_seteventtable(L, 1);
344 }
345 return 1;
346}
347
336static int newuserdata (lua_State *L) { 348static int newuserdata (lua_State *L) {
337 size_t size = luaL_check_int(L, 1); 349 size_t size = luaL_check_int(L, 1);
338 char *p = cast(char *, lua_newuserdata(L, size)); 350 char *p = cast(char *, lua_newuserdata(L, size));
@@ -345,24 +357,13 @@ static int newuserdatabox (lua_State *L) {
345 return 1; 357 return 1;
346} 358}
347 359
348static int settag (lua_State *L) {
349 luaL_check_any(L, 1);
350 lua_pushvalue(L, 1); /* push value */
351 lua_settag(L, luaL_check_int(L, 2));
352 return 1; /* return value */
353}
354 360
355static int udataval (lua_State *L) { 361static int udataval (lua_State *L) {
356 luaL_check_rawtype(L, 1, LUA_TUSERDATA); 362 luaL_check_type(L, 1, LUA_TUSERDATA);
357 lua_pushnumber(L, cast(int, lua_touserdata(L, 1))); 363 lua_pushnumber(L, cast(int, lua_touserdata(L, 1)));
358 return 1; 364 return 1;
359} 365}
360 366
361static int newtag (lua_State *L) {
362 lua_pushnumber(L, lua_newtype(L, lua_tostring(L, 1),
363 cast(int, lua_tonumber(L, 2))));
364 return 1;
365}
366 367
367static int doonnewstack (lua_State *L) { 368static int doonnewstack (lua_State *L) {
368 lua_State *L1 = lua_newthread(L, luaL_check_int(L, 1)); 369 lua_State *L1 = lua_newthread(L, luaL_check_int(L, 1));
@@ -435,16 +436,6 @@ static int doremote (lua_State *L) {
435 } 436 }
436} 437}
437 438
438static int settagmethod (lua_State *L) {
439 int tag = luaL_check_int(L, 1);
440 const char *event = luaL_check_string(L, 2);
441 luaL_check_any(L, 3);
442 lua_gettagmethod(L, tag, event);
443 lua_pushvalue(L, 3);
444 lua_settagmethod(L, tag, event);
445 return 1;
446}
447
448 439
449static int log2_aux (lua_State *L) { 440static int log2_aux (lua_State *L) {
450 lua_pushnumber(L, luaO_log2(luaL_check_int(L, 1))); 441 lua_pushnumber(L, luaO_log2(luaL_check_int(L, 1)));
@@ -614,18 +605,14 @@ static int testC (lua_State *L) {
614 else if EQ("dostring") { 605 else if EQ("dostring") {
615 lua_dostring(L, luaL_check_string(L, getnum)); 606 lua_dostring(L, luaL_check_string(L, getnum));
616 } 607 }
617 else if EQ("settagmethod") { 608 else if EQ("seteventtable") {
618 int tag = getnum; 609 lua_seteventtable(L, getnum);
619 const char *event = getname;
620 lua_settagmethod(L, tag, event);
621 } 610 }
622 else if EQ("gettagmethod") { 611 else if EQ("geteventtable") {
623 int tag = getnum; 612 lua_geteventtable(L, getnum);
624 const char *event = getname;
625 lua_gettagmethod(L, tag, event);
626 } 613 }
627 else if EQ("type") { 614 else if EQ("type") {
628 lua_pushstring(L, lua_type(L, getnum)); 615 lua_pushstring(L, lua_typename(L, lua_type(L, getnum)));
629 } 616 }
630 else luaL_verror(L, "unknown instruction %.30s", buff); 617 else luaL_verror(L, "unknown instruction %.30s", buff);
631 } 618 }
@@ -651,16 +638,14 @@ static const struct luaL_reg tests_funcs[] = {
651 {"unref", unref}, 638 {"unref", unref},
652 {"d2s", d2s}, 639 {"d2s", d2s},
653 {"s2d", s2d}, 640 {"s2d", s2d},
641 {"eventtable", eventtable},
654 {"newuserdata", newuserdata}, 642 {"newuserdata", newuserdata},
655 {"newuserdatabox", newuserdatabox}, 643 {"newuserdatabox", newuserdatabox},
656 {"settag", settag},
657 {"udataval", udataval}, 644 {"udataval", udataval},
658 {"newtag", newtag},
659 {"doonnewstack", doonnewstack}, 645 {"doonnewstack", doonnewstack},
660 {"newstate", newstate}, 646 {"newstate", newstate},
661 {"closestate", closestate}, 647 {"closestate", closestate},
662 {"doremote", doremote}, 648 {"doremote", doremote},
663 {"settagmethod", settagmethod},
664 {"log2", log2_aux}, 649 {"log2", log2_aux},
665 {"totalmem", mem_query} 650 {"totalmem", mem_query}
666}; 651};
diff --git a/ltm.c b/ltm.c
index ef0f89e1..5d1c83d1 100644
--- a/ltm.c
+++ b/ltm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltm.c,v 1.80 2001/10/11 21:41:21 roberto Exp $ 2** $Id: ltm.c,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $
3** Tag methods 3** Tag methods
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -10,8 +10,6 @@
10 10
11#include "lua.h" 11#include "lua.h"
12 12
13#include "ldo.h"
14#include "lmem.h"
15#include "lobject.h" 13#include "lobject.h"
16#include "lstate.h" 14#include "lstate.h"
17#include "lstring.h" 15#include "lstring.h"
@@ -19,161 +17,46 @@
19#include "ltm.h" 17#include "ltm.h"
20 18
21 19
22const char *const luaT_eventname[] = { /* ORDER TM */
23 "gettable", "settable", "index", "getglobal",
24 "setglobal", "add", "sub", "mul", "div",
25 "pow", "unm", "lt", "concat", "gc",
26 "function",
27 NULL
28};
29
30
31static int findevent (const char *name) {
32 int i;
33 for (i=0; luaT_eventname[i]; i++)
34 if (strcmp(luaT_eventname[i], name) == 0)
35 return i;
36 return -1; /* name not found */
37}
38
39
40static int luaI_checkevent (lua_State *L, const char *name) {
41 int e = findevent(name);
42 if (e < 0)
43 luaO_verror(L, "`%.50s' is not a valid event name", name);
44 return e;
45}
46 20
47 21const char *const luaT_typenames[] = {
48 22 "userdata", "nil", "number", "string", "table", "function"
49/* events in LUA_TNIL are all allowed, since this is used as a
50* `placeholder' for default fallbacks
51*/
52/* ORDER LUA_T, ORDER TM */
53static const lu_byte luaT_validevents[NUM_TAGS][TM_N] = {
54 {1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1}, /* LUA_TUSERDATA */
55 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, /* LUA_TNIL */
56 {1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}, /* LUA_TNUMBER */
57 {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, /* LUA_TSTRING */
58 {0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1}, /* LUA_TTABLE */
59 {1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0} /* LUA_TFUNCTION */
60}; 23};
61 24
62static int luaT_validevent (int t, int e) { /* ORDER LUA_T */
63 return (t >= NUM_TAGS) ? 1 : cast(int, luaT_validevents[t][e]);
64}
65
66 25
67void luaT_init (lua_State *L) { 26void luaT_init (lua_State *L) {
68 static const char *const typenames[NUM_TAGS] = { 27 static const char *const luaT_eventname[] = { /* ORDER TM */
69 "userdata", "nil", "number", "string", 28 "gettable", "settable", "index",
70 "table", "function" 29 "gc",
30 "add", "sub", "mul", "div",
31 "pow", "unm", "lt", "concat",
32 "call"
71 }; 33 };
72 int i; 34 int i;
73 for (i=0; i<NUM_TAGS; i++) 35 for (i=0; i<TM_N; i++) {
74 luaT_newtag(L, typenames[i], i); 36 G(L)->tmname[i] = luaS_new(L, luaT_eventname[i]);
75} 37 G(L)->tmname[i]->tsv.marked = FIXMARK; /* never collect these names */
76
77
78int luaT_newtag (lua_State *L, const char *name, int basictype) {
79 int tag;
80 int i;
81 TString *ts = NULL;
82 luaM_growvector(L, G(L)->TMtable, G(L)->ntag, G(L)->sizeTM, struct TM,
83 MAX_INT, "tag table overflow");
84 tag = G(L)->ntag;
85 if (name) {
86 const TObject *v;
87 TObject otag;
88 ts = luaS_new(L, name);
89 v = luaH_getstr(G(L)->type2tag, ts);
90 if (ttype(v) == LUA_TNUMBER) return cast(int, nvalue(v));
91 setnvalue(&otag, tag);
92 luaH_setstr(L, G(L)->type2tag, ts, &otag);
93 } 38 }
94 for (i=0; i<TM_N; i++)
95 luaT_gettm(G(L), tag, i) = NULL;
96 G(L)->TMtable[tag].collected = NULL;
97 G(L)->TMtable[tag].name = ts;
98 G(L)->TMtable[tag].basictype = basictype;
99 G(L)->ntag++;
100 return tag;
101}
102
103
104static void checktag (lua_State *L, int tag) {
105 if (!(0 <= tag && tag < G(L)->ntag))
106 luaO_verror(L, "%d is not a valid tag", tag);
107} 39}
108 40
109 41
110int luaT_tag (const TObject *o) { 42const TObject *luaT_gettm (Table *events, TMS event, TString *ename) {
111 int t = ttype(o); 43 const TObject *tm = luaH_getstr(events, ename);
112 switch (t) { 44 if (ttype(tm) == LUA_TNIL) { /* no tag method? */
113 case LUA_TUSERDATA: return uvalue(o)->uv.tag; 45 events->flags |= (1<<event); /* cache this fact */
114 case LUA_TTABLE: return hvalue(o)->htag; 46 return NULL;
115 default: return t;
116 } 47 }
48 else return tm;
117} 49}
118 50
119 51
120const char *luaT_typename (global_State *G, const TObject *o) { 52const TObject *luaT_gettmbyobj (lua_State *L, const TObject *o, TMS event) {
121 int t = ttype(o); 53 switch (ttype(o)) {
122 int tag;
123 TString *ts;
124 switch (t) {
125 case LUA_TUSERDATA:
126 tag = uvalue(o)->uv.tag;
127 break;
128 case LUA_TTABLE: 54 case LUA_TTABLE:
129 tag = hvalue(o)->htag; 55 return fasttm(L, hvalue(o)->eventtable, event);
130 break; 56 case LUA_TUSERDATA:
131 default: 57 return fasttm(L, uvalue(o)->uv.eventtable, event);
132 tag = t;
133 }
134 ts = G->TMtable[tag].name;
135 if (ts == NULL)
136 ts = G->TMtable[t].name;
137 return getstr(ts);
138}
139
140
141LUA_API void lua_gettagmethod (lua_State *L, int t, const char *event) {
142 int e;
143 lua_lock(L);
144 e = luaI_checkevent(L, event);
145 checktag(L, t);
146 if (luaT_validevent(t, e) && luaT_gettm(G(L), t, e)) {
147 setclvalue(L->top, luaT_gettm(G(L), t, e));
148 }
149 else
150 setnilvalue(L->top);
151 incr_top;
152 lua_unlock(L);
153}
154
155
156LUA_API void lua_settagmethod (lua_State *L, int t, const char *event) {
157 int e;
158 lua_lock(L);
159 e = luaI_checkevent(L, event);
160 checktag(L, t);
161 if (!luaT_validevent(t, e))
162 luaO_verror(L, "cannot change `%.20s' tag method for type `%.20s'%.20s",
163 luaT_eventname[e], typenamebytag(G(L), t),
164 (t == LUA_TTABLE || t == LUA_TUSERDATA) ?
165 " with default tag" : "");
166 switch (ttype(L->top - 1)) {
167 case LUA_TNIL:
168 luaT_gettm(G(L), t, e) = NULL;
169 break;
170 case LUA_TFUNCTION:
171 luaT_gettm(G(L), t, e) = clvalue(L->top - 1);
172 break;
173 default: 58 default:
174 luaD_error(L, "tag method must be a function (or nil)"); 59 return NULL;
175 } 60 }
176 L->top--;
177 lua_unlock(L);
178} 61}
179 62
diff --git a/ltm.h b/ltm.h
index 797dd9a6..053b6f90 100644
--- a/ltm.h
+++ b/ltm.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltm.h,v 1.28 2001/10/02 16:43:54 roberto Exp $ 2** $Id: ltm.h,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $
3** Tag methods 3** Tag methods
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -9,7 +9,6 @@
9 9
10 10
11#include "lobject.h" 11#include "lobject.h"
12#include "lstate.h"
13 12
14/* 13/*
15* WARNING: if you change the order of this enumeration, 14* WARNING: if you change the order of this enumeration,
@@ -19,8 +18,7 @@ typedef enum {
19 TM_GETTABLE = 0, 18 TM_GETTABLE = 0,
20 TM_SETTABLE, 19 TM_SETTABLE,
21 TM_INDEX, 20 TM_INDEX,
22 TM_GETGLOBAL, 21 TM_GC,
23 TM_SETGLOBAL,
24 TM_ADD, 22 TM_ADD,
25 TM_SUB, 23 TM_SUB,
26 TM_MUL, 24 TM_MUL,
@@ -29,51 +27,20 @@ typedef enum {
29 TM_UNM, 27 TM_UNM,
30 TM_LT, 28 TM_LT,
31 TM_CONCAT, 29 TM_CONCAT,
32 TM_GC, 30 TM_CALL,
33 TM_FUNCTION,
34 TM_N /* number of elements in the enum */ 31 TM_N /* number of elements in the enum */
35} TMS; 32} TMS;
36 33
37 34
38 35
39/* 36#define fasttm(l,et,e) \
40** masks for allowable tag methods 37 (((et)->flags & (1<<(e))) ? NULL : luaT_gettm(et, e, G(l)->tmname[e]))
41** (see `luaT_validevents')
42*/
43#define HAS_TM_GETGLOBAL(L,t) ((1<<(t)) & ((1<<LUA_TUSERDATA) | \
44 (1<<LUA_TTABLE) | \
45 (1<<LUA_TNIL)))
46
47#define HAS_TM_SETGLOBAL(L,t) ((1<<(t)) & ((1<<LUA_TUSERDATA) | \
48 (1<<LUA_TTABLE) | \
49 (1<<LUA_TNIL) | \
50 (1<<LUA_TFUNCTION)))
51
52
53
54struct TM {
55 Closure *method[TM_N];
56 Udata *collected; /* list of garbage-collected udata with this tag */
57 TString *name; /* type name */
58 int basictype;
59};
60
61
62#define luaT_gettm(G,tag,event) (G->TMtable[tag].method[event])
63#define luaT_gettmbyObj(G,o,e) (luaT_gettm((G),luaT_tag(o),(e)))
64
65#define typenamebytag(G, t) getstr(G->TMtable[t].name)
66
67
68#define validtag(G,t) (NUM_TAGS <= (t) && (t) < G->ntag)
69
70extern const char *const luaT_eventname[];
71 38
72 39
40const TObject *luaT_gettm (Table *events, TMS event, TString *ename);
41const TObject *luaT_gettmbyobj (lua_State *L, const TObject *o, TMS event);
73void luaT_init (lua_State *L); 42void luaT_init (lua_State *L);
74int luaT_newtag (lua_State *L, const char *name, int basictype);
75const char *luaT_typename (global_State *G, const TObject *o);
76int luaT_tag (const TObject *o);
77 43
44extern const char *const luaT_typenames[];
78 45
79#endif 46#endif
diff --git a/lua.h b/lua.h
index 52179b84..5c63a770 100644
--- a/lua.h
+++ b/lua.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lua.h,v 1.107 2001/10/31 19:58:11 roberto Exp $ 2** $Id: lua.h,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $
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: info@lua.org 5** e-mail: info@lua.org
@@ -55,15 +55,11 @@ typedef struct lua_State lua_State;
55typedef int (*lua_CFunction) (lua_State *L); 55typedef int (*lua_CFunction) (lua_State *L);
56 56
57 57
58/*
59** an invalid `tag'
60*/
61#define LUA_NOTAG (-1)
62 58
63/* 59/*
64** tags for basic types 60** basic types
65*/ 61*/
66#define LUA_TNONE LUA_NOTAG 62#define LUA_TNONE (-1)
67 63
68#define LUA_TUSERDATA 0 64#define LUA_TUSERDATA 0
69#define LUA_TNIL 1 65#define LUA_TNIL 1
@@ -120,12 +116,11 @@ LUA_API int lua_stackspace (lua_State *L);
120** access functions (stack -> C) 116** access functions (stack -> C)
121*/ 117*/
122 118
123LUA_API const char *lua_type (lua_State *L, int index);
124LUA_API int lua_isnumber (lua_State *L, int index); 119LUA_API int lua_isnumber (lua_State *L, int index);
125LUA_API int lua_isstring (lua_State *L, int index); 120LUA_API int lua_isstring (lua_State *L, int index);
126LUA_API int lua_iscfunction (lua_State *L, int index); 121LUA_API int lua_iscfunction (lua_State *L, int index);
127LUA_API int lua_tag (lua_State *L, int index); 122LUA_API int lua_type (lua_State *L, int index);
128LUA_API int lua_rawtag (lua_State *L, int index); 123LUA_API const char *lua_typename (lua_State *L, int type);
129 124
130LUA_API int lua_equal (lua_State *L, int index1, int index2); 125LUA_API int lua_equal (lua_State *L, int index1, int index2);
131LUA_API int lua_lessthan (lua_State *L, int index1, int index2); 126LUA_API int lua_lessthan (lua_State *L, int index1, int index2);
@@ -155,9 +150,9 @@ LUA_API void lua_getglobal (lua_State *L, const char *name);
155LUA_API void lua_gettable (lua_State *L, int index); 150LUA_API void lua_gettable (lua_State *L, int index);
156LUA_API void lua_rawget (lua_State *L, int index); 151LUA_API void lua_rawget (lua_State *L, int index);
157LUA_API void lua_rawgeti (lua_State *L, int index, int n); 152LUA_API void lua_rawgeti (lua_State *L, int index, int n);
158LUA_API void lua_gettagmethod (lua_State *L, int tag, const char *event);
159LUA_API void lua_newtable (lua_State *L); 153LUA_API void lua_newtable (lua_State *L);
160LUA_API void lua_getweakregistry (lua_State *L); 154LUA_API void lua_getweakregistry (lua_State *L);
155LUA_API void lua_geteventtable (lua_State *L, int objindex);
161 156
162 157
163/* 158/*
@@ -168,7 +163,7 @@ LUA_API void lua_settable (lua_State *L, int index);
168LUA_API void lua_rawset (lua_State *L, int index); 163LUA_API void lua_rawset (lua_State *L, int index);
169LUA_API void lua_rawseti (lua_State *L, int index, int n); 164LUA_API void lua_rawseti (lua_State *L, int index, int n);
170LUA_API void lua_setglobals (lua_State *L); 165LUA_API void lua_setglobals (lua_State *L);
171LUA_API void lua_settagmethod (lua_State *L, int tag, const char *event); 166LUA_API void lua_seteventtable (lua_State *L, int objindex);
172 167
173 168
174/* 169/*
@@ -194,11 +189,6 @@ LUA_API void lua_setgcthreshold (lua_State *L, int newthreshold);
194/* 189/*
195** miscellaneous functions 190** miscellaneous functions
196*/ 191*/
197LUA_API int lua_newtype (lua_State *L, const char *name, int basictype);
198LUA_API void lua_settag (lua_State *L, int tag);
199
200LUA_API int lua_name2tag (lua_State *L, const char *name);
201LUA_API const char *lua_tag2name (lua_State *L, int tag);
202 192
203LUA_API void lua_error (lua_State *L, const char *s); 193LUA_API void lua_error (lua_State *L, const char *s);
204 194
@@ -228,11 +218,11 @@ LUA_API int lua_getweakmode (lua_State *L, int index);
228#define lua_register(L,n,f) (lua_pushcfunction(L, f), lua_setglobal(L, n)) 218#define lua_register(L,n,f) (lua_pushcfunction(L, f), lua_setglobal(L, n))
229#define lua_pushcfunction(L,f) lua_pushcclosure(L, f, 0) 219#define lua_pushcfunction(L,f) lua_pushcclosure(L, f, 0)
230 220
231#define lua_isfunction(L,n) (lua_rawtag(L,n) == LUA_TFUNCTION) 221#define lua_isfunction(L,n) (lua_type(L,n) == LUA_TFUNCTION)
232#define lua_istable(L,n) (lua_rawtag(L,n) == LUA_TTABLE) 222#define lua_istable(L,n) (lua_type(L,n) == LUA_TTABLE)
233#define lua_isuserdata(L,n) (lua_rawtag(L,n) == LUA_TUSERDATA) 223#define lua_isuserdata(L,n) (lua_type(L,n) == LUA_TUSERDATA)
234#define lua_isnil(L,n) (lua_rawtag(L,n) == LUA_TNIL) 224#define lua_isnil(L,n) (lua_type(L,n) == LUA_TNIL)
235#define lua_isnull(L,n) (lua_rawtag(L,n) == LUA_TNONE) 225#define lua_isnull(L,n) (lua_type(L,n) == LUA_TNONE)
236 226
237#define lua_pushliteral(L, s) lua_pushlstring(L, "" s, \ 227#define lua_pushliteral(L, s) lua_pushlstring(L, "" s, \
238 (sizeof(s)/sizeof(char))-1) 228 (sizeof(s)/sizeof(char))-1)
@@ -245,8 +235,6 @@ LUA_API int lua_getweakmode (lua_State *L, int index);
245/* 235/*
246** compatibility macros and functions 236** compatibility macros and functions
247*/ 237*/
248#define lua_newtag(L) lua_newtype(L, NULL, LUA_TNONE)
249#define lua_typename lua_tag2name
250 238
251LUA_API void lua_pushupvalues (lua_State *L); 239LUA_API void lua_pushupvalues (lua_State *L);
252 240
diff --git a/lvm.c b/lvm.c
index c4281e44..ea1ba100 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.c,v 1.198 2001/11/06 21:41:53 roberto Exp $ 2** $Id: lvm.c,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $
3** Lua virtual machine 3** Lua virtual machine
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -85,69 +85,66 @@ static void traceexec (lua_State *L, lua_Hook linehook) {
85/* maximum stack used by a call to a tag method (func + args) */ 85/* maximum stack used by a call to a tag method (func + args) */
86#define MAXSTACK_TM 4 86#define MAXSTACK_TM 4
87 87
88static StkId callTM (lua_State *L, Closure *f, const char *fmt, ...) { 88static void callTM (lua_State *L, const TObject *f,
89 va_list argp; 89 const TObject *p1, const TObject *p2, const TObject *p3, TObject *result ) {
90 StkId base = L->top; 90 StkId base = L->top;
91 lua_assert(strlen(fmt)+1 <= MAXSTACK_TM);
92 luaD_checkstack(L, MAXSTACK_TM); 91 luaD_checkstack(L, MAXSTACK_TM);
93 va_start(argp, fmt); 92 setobj(base, f); /* push function */
94 setclvalue(L->top, f); /* push function */ 93 setobj(base+1, p1); /* 1st argument */
95 L->top++; 94 setobj(base+2, p2); /* 2nd argument */
96 while (*fmt) { 95 L->top += 3;
97 if (*fmt++ == 'o') { 96 if (p3) {
98 setobj(L->top, va_arg(argp, TObject *)); 97 setobj(base+3, p3); /* 3th argument */
99 }
100 else {
101 lua_assert(*(fmt-1) == 's');
102 setsvalue(L->top, va_arg(argp, TString *));
103 }
104 L->top++; 98 L->top++;
105 } 99 }
106 luaD_call(L, base); 100 luaD_call(L, base);
107 va_end(argp); 101 if (result) { /* need a result? */
108 return base; 102 if (L->top == base) { /* are there valid results? */
109} 103 setnilvalue(result); /* function had no results */
110 104 }
111 105 else {
112#define setTM(L, base) (L->top = (base)) 106 setobj(result, base); /* get first result */
113 107 }
114static void setTMresult (lua_State *L, TObject *result, StkId base) {
115 if (L->top == base) { /* are there valid results? */
116 setnilvalue(result); /* function had no results */
117 }
118 else {
119 setobj(result, base); /* get first result */
120 } 108 }
121 L->top = base; /* restore top */ 109 L->top = base; /* restore top */
122} 110}
123 111
124 112
113
125/* 114/*
126** Function to index a table. 115** Function to index a table.
127** Receives the table at `t' and the key at the `key'. 116** Receives the table at `t' and the key at the `key'.
128** leaves the result at `res'. 117** leaves the result at `res'.
129*/ 118*/
130void luaV_gettable (lua_State *L, StkId t, TObject *key, StkId res) { 119void luaV_gettable (lua_State *L, StkId t, TObject *key, StkId res) {
131 Closure *tm; 120 const TObject *tm;
121 init:
132 if (ttype(t) == LUA_TTABLE) { /* `t' is a table? */ 122 if (ttype(t) == LUA_TTABLE) { /* `t' is a table? */
133 int tg = hvalue(t)->htag; 123 Table *et = hvalue(t)->eventtable;
134 if (tg == LUA_TTABLE || /* with default tag? */ 124 if ((tm = fasttm(L, et, TM_GETTABLE)) == NULL) { /* no gettable TM? */
135 (tm = luaT_gettm(G(L), tg, TM_GETTABLE)) == NULL) { /* or no TM? */
136 const TObject *h = luaH_get(hvalue(t), key); /* do a primitive get */ 125 const TObject *h = luaH_get(hvalue(t), key); /* do a primitive get */
137 /* result is no nil or there is no `index' tag method? */ 126 /* result is no nil or there is no `index' tag method? */
138 if (ttype(h) != LUA_TNIL || /* no nil? */ 127 if (ttype(h) != LUA_TNIL || /* no nil? */
139 ((tm=luaT_gettm(G(L), tg, TM_INDEX)) == NULL)) { /* or no index TM? */ 128 (tm = fasttm(L, et, TM_INDEX)) == NULL) { /* or no index TM? */
140 setobj(res, h); /* default get */ 129 setobj(res, h); /* default get */
141 return; 130 return;
142 } 131 }
143 } 132 }
144 /* else will call the tag method */ 133 /* else will call the tag method */
145 } else { /* not a table; try a `gettable' tag method */ 134 } else { /* not a table; try a `gettable' tag method */
146 tm = luaT_gettmbyObj(G(L), t, TM_GETTABLE); 135 if (ttype(t) != LUA_TUSERDATA ||
147 if (tm == NULL) /* no tag method? */ 136 (tm = fasttm(L, uvalue(t)->uv.eventtable, TM_GETTABLE)) == NULL) {
148 luaG_typeerror(L, t, "index"); 137 luaG_typeerror(L, t, "index");
138 return; /* to avoid warnings */
139 }
140 }
141 lua_assert(tm != NULL);
142 if (ttype(tm) == LUA_TFUNCTION)
143 callTM(L, tm, t, key, NULL, res);
144 else {
145 t = tm;
146 goto init; /* return luaV_gettable(L, tm, key, res); */
149 } 147 }
150 setTMresult(L, res, callTM(L, tm, "oo", t, key));
151} 148}
152 149
153 150
@@ -156,63 +153,44 @@ void luaV_gettable (lua_State *L, StkId t, TObject *key, StkId res) {
156** Receives table at `t', key at `key' and value at `val'. 153** Receives table at `t', key at `key' and value at `val'.
157*/ 154*/
158void luaV_settable (lua_State *L, StkId t, TObject *key, StkId val) { 155void luaV_settable (lua_State *L, StkId t, TObject *key, StkId val) {
159 Closure *tm; 156 const TObject *tm;
157 init:
160 if (ttype(t) == LUA_TTABLE) { /* `t' is a table? */ 158 if (ttype(t) == LUA_TTABLE) { /* `t' is a table? */
161 int tg = hvalue(t)->htag; 159 Table *et = hvalue(t)->eventtable;
162 if (hvalue(t)->htag == LUA_TTABLE || /* with default tag? */ 160 if ((tm = fasttm(L, et, TM_SETTABLE)) == NULL) { /* no TM? */
163 (tm = luaT_gettm(G(L), tg, TM_SETTABLE)) == NULL) { /* or no TM? */
164 luaH_set(L, hvalue(t), key, val); /* do a primitive set */ 161 luaH_set(L, hvalue(t), key, val); /* do a primitive set */
165 return; 162 return;
166 } 163 }
167 /* else will call the tag method */ 164 /* else will call the tag method */
168 } else { /* not a table; try a `settable' tag method */ 165 } else { /* not a table; try a `settable' tag method */
169 tm = luaT_gettmbyObj(G(L), t, TM_SETTABLE); 166 if (ttype(t) != LUA_TUSERDATA ||
170 if (tm == NULL) /* no tag method? */ 167 (tm = fasttm(L, uvalue(t)->uv.eventtable, TM_SETTABLE)) == NULL) {
171 luaG_typeerror(L, t, "index"); 168 luaG_typeerror(L, t, "index");
169 return; /* to avoid warnings */
170 }
172 } 171 }
173 setTM(L, callTM(L, tm, "ooo", t, key, val)); 172 lua_assert(tm != NULL);
174} 173 if (ttype(tm) == LUA_TFUNCTION)
175 174 callTM(L, tm, t, key, val, NULL);
176 175 else {
177void luaV_getglobal (lua_State *L, TString *name, StkId res) { 176 t = tm;
178 const TObject *value = luaH_getstr(hvalue(&L->gt), name); 177 goto init; /* luaV_settable(L, tm, key, val); */
179 Closure *tm;
180 if (!HAS_TM_GETGLOBAL(L, ttype(value)) || /* is there a tag method? */
181 (tm = luaT_gettmbyObj(G(L), value, TM_GETGLOBAL)) == NULL) {
182 setobj(res, value); /* default behavior */
183 }
184 else
185 setTMresult(L, res, callTM(L, tm, "so", name, value));
186}
187
188
189void luaV_setglobal (lua_State *L, TString *name, StkId val) {
190 const TObject *oldvalue = luaH_getstr(hvalue(&L->gt), name);
191 Closure *tm;
192 if (!HAS_TM_SETGLOBAL(L, ttype(oldvalue)) || /* no tag methods? */
193 (tm = luaT_gettmbyObj(G(L), oldvalue, TM_SETGLOBAL)) == NULL) {
194 if (oldvalue == &luaO_nilobject)
195 luaH_setstr(L, hvalue(&L->gt), name, val); /* raw set */
196 else
197 settableval(oldvalue, val); /* warning: tricky optimization! */
198 } 178 }
199 else
200 setTM(L, callTM(L, tm, "soo", name, oldvalue, val));
201} 179}
202 180
203 181
204static int call_binTM (lua_State *L, const TObject *p1, const TObject *p2, 182static int call_binTM (lua_State *L, const TObject *p1, const TObject *p2,
205 TObject *res, TMS event) { 183 TObject *res, TMS event) {
206 Closure *tm = luaT_gettmbyObj(G(L), p1, event); /* try first operand */ 184 const TObject *tm = luaT_gettmbyobj(L, p1, event); /* try first operand */
207 if (tm == NULL) { 185 if (tm == NULL) {
208 tm = luaT_gettmbyObj(G(L), p2, event); /* try second operand */ 186 tm = luaT_gettmbyobj(L, p2, event); /* try second operand */
209 if (tm == NULL) { 187 if (tm == NULL) {
210 tm = luaT_gettm(G(L), 0, event); /* try a `global' method */ 188 tm = fasttm(L, hvalue(gt(L)), event);
211 if (tm == NULL) 189 if (tm == NULL) return 0; /* no tag method */
212 return 0; /* no tag method */
213 } 190 }
214 } 191 }
215 setTMresult(L, res, callTM(L, tm, "oo", p1, p2)); 192 if (ttype(tm) != LUA_TFUNCTION) return 0;
193 callTM(L, tm, p1, p2, NULL, res);
216 return 1; 194 return 1;
217} 195}
218 196
@@ -295,12 +273,13 @@ void luaV_strconc (lua_State *L, int total, StkId top) {
295static void luaV_pack (lua_State *L, StkId firstelem) { 273static void luaV_pack (lua_State *L, StkId firstelem) {
296 int i; 274 int i;
297 Table *htab = luaH_new(L, 0, 0); 275 Table *htab = luaH_new(L, 0, 0);
298 TObject n; 276 TObject n, nname;
299 for (i=0; firstelem+i<L->top; i++) 277 for (i=0; firstelem+i<L->top; i++)
300 luaH_setnum(L, htab, i+1, firstelem+i); 278 luaH_setnum(L, htab, i+1, firstelem+i);
301 /* store counter in field `n' */ 279 /* store counter in field `n' */
302 setnvalue(&n, i); 280 setnvalue(&n, i);
303 luaH_setstr(L, htab, luaS_newliteral(L, "n"), &n); 281 setsvalue(&nname, luaS_newliteral(L, "n"));
282 luaH_set(L, htab, &nname, &n);
304 L->top = firstelem; /* remove elements from the stack */ 283 L->top = firstelem; /* remove elements from the stack */
305 sethvalue(L->top, htab); 284 sethvalue(L->top, htab);
306 incr_top; 285 incr_top;
@@ -395,7 +374,7 @@ StkId luaV_execute (lua_State *L, const LClosure *cl, StkId base) {
395 } 374 }
396 case OP_GETGLOBAL: { 375 case OP_GETGLOBAL: {
397 lua_assert(ttype(KBc(i)) == LUA_TSTRING); 376 lua_assert(ttype(KBc(i)) == LUA_TSTRING);
398 luaV_getglobal(L, tsvalue(KBc(i)), ra); 377 luaV_gettable(L, gt(L), KBc(i), ra);
399 break; 378 break;
400 } 379 }
401 case OP_GETTABLE: { 380 case OP_GETTABLE: {
@@ -404,7 +383,7 @@ StkId luaV_execute (lua_State *L, const LClosure *cl, StkId base) {
404 } 383 }
405 case OP_SETGLOBAL: { 384 case OP_SETGLOBAL: {
406 lua_assert(ttype(KBc(i)) == LUA_TSTRING); 385 lua_assert(ttype(KBc(i)) == LUA_TSTRING);
407 luaV_setglobal(L, tsvalue(KBc(i)), ra); 386 luaV_settable(L, gt(L), KBc(i), ra);
408 break; 387 break;
409 } 388 }
410 case OP_SETUPVAL: { 389 case OP_SETUPVAL: {
diff --git a/lvm.h b/lvm.h
index a9378de1..1e0369fc 100644
--- a/lvm.h
+++ b/lvm.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.h,v 1.31 2001/09/07 17:39:10 roberto Exp $ 2** $Id: lvm.h,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $
3** Lua virtual machine 3** Lua virtual machine
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -20,8 +20,6 @@ const TObject *luaV_tonumber (const TObject *obj, TObject *n);
20int luaV_tostring (lua_State *L, TObject *obj); 20int luaV_tostring (lua_State *L, TObject *obj);
21void luaV_gettable (lua_State *L, StkId t, TObject *key, StkId res); 21void luaV_gettable (lua_State *L, StkId t, TObject *key, StkId res);
22void luaV_settable (lua_State *L, StkId t, TObject *key, StkId val); 22void luaV_settable (lua_State *L, StkId t, TObject *key, StkId val);
23void luaV_getglobal (lua_State *L, TString *s, StkId res);
24void luaV_setglobal (lua_State *L, TString *s, StkId val);
25StkId luaV_execute (lua_State *L, const LClosure *cl, StkId base); 23StkId luaV_execute (lua_State *L, const LClosure *cl, StkId base);
26int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r); 24int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r);
27void luaV_strconc (lua_State *L, int total, StkId top); 25void luaV_strconc (lua_State *L, int total, StkId top);