summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lapi.c67
-rw-r--r--lapi.h6
-rw-r--r--lbuiltin.c61
-rw-r--r--ldo.c5
-rw-r--r--lgc.c33
-rw-r--r--lobject.h27
-rw-r--r--lparser.c11
-rw-r--r--lstate.h4
-rw-r--r--lstring.c66
-rw-r--r--lstring.h5
-rw-r--r--lvm.c20
-rw-r--r--lvm.h6
12 files changed, 166 insertions, 145 deletions
diff --git a/lapi.c b/lapi.c
index 80e4d120..020a4642 100644
--- a/lapi.c
+++ b/lapi.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lapi.c,v 1.53 1999/10/11 16:13:11 roberto Exp roberto $ 2** $Id: lapi.c,v 1.54 1999/10/14 19:13:31 roberto Exp roberto $
3** Lua API 3** Lua API
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -60,18 +60,6 @@ static const TObject *luaA_protovalue (const TObject *o) {
60} 60}
61 61
62 62
63void luaA_packresults (void) {
64 luaV_pack(L->Cstack.lua2C, L->Cstack.num, L->stack.top);
65 incr_top;
66}
67
68
69int luaA_passresults (void) {
70 L->Cstack.base = L->Cstack.lua2C; /* position of first result */
71 return L->Cstack.num;
72}
73
74
75static void checkCparams (int nParams) { 63static void checkCparams (int nParams) {
76 if (L->stack.top-L->stack.stack < L->Cstack.base+nParams) 64 if (L->stack.top-L->stack.stack < L->Cstack.base+nParams)
77 lua_error("API error - wrong number of arguments in C2lua stack"); 65 lua_error("API error - wrong number of arguments in C2lua stack");
@@ -191,28 +179,28 @@ lua_Object lua_createtable (void) {
191 179
192lua_Object lua_getglobal (const char *name) { 180lua_Object lua_getglobal (const char *name) {
193 luaD_checkstack(2); /* may need that to call T.M. */ 181 luaD_checkstack(2); /* may need that to call T.M. */
194 luaV_getglobal(luaS_new(name)); 182 luaV_getglobal(luaS_assertglobalbyname(name));
195 return luaA_putObjectOnTop(); 183 return luaA_putObjectOnTop();
196} 184}
197 185
198 186
199lua_Object lua_rawgetglobal (const char *name) { 187lua_Object lua_rawgetglobal (const char *name) {
200 TaggedString *ts = luaS_new(name); 188 GlobalVar *gv = luaS_assertglobalbyname(name);
201 return put_luaObject(&ts->u.s.globalval); 189 return put_luaObject(&gv->value);
202} 190}
203 191
204 192
205void lua_setglobal (const char *name) { 193void lua_setglobal (const char *name) {
206 checkCparams(1); 194 checkCparams(1);
207 luaD_checkstack(2); /* may need that to call T.M. */ 195 luaD_checkstack(2); /* may need that to call T.M. */
208 luaV_setglobal(luaS_new(name)); 196 luaV_setglobal(luaS_assertglobalbyname(name));
209} 197}
210 198
211 199
212void lua_rawsetglobal (const char *name) { 200void lua_rawsetglobal (const char *name) {
213 TaggedString *ts = luaS_new(name); 201 GlobalVar *gv = luaS_assertglobalbyname(name);
214 checkCparams(1); 202 checkCparams(1);
215 luaS_rawsetglobal(ts, --L->stack.top); 203 gv->value = *(--L->stack.top);
216} 204}
217 205
218 206
@@ -274,7 +262,7 @@ long lua_strlen (lua_Object object) {
274void *lua_getuserdata (lua_Object object) { 262void *lua_getuserdata (lua_Object object) {
275 if (object == LUA_NOOBJECT || ttype(Address(object)) != LUA_T_USERDATA) 263 if (object == LUA_NOOBJECT || ttype(Address(object)) != LUA_T_USERDATA)
276 return NULL; 264 return NULL;
277 else return tsvalue(Address(object))->u.d.v; 265 else return tsvalue(Address(object))->u.d.value;
278} 266}
279 267
280lua_CFunction lua_getcfunction (lua_Object object) { 268lua_CFunction lua_getcfunction (lua_Object object) {
@@ -388,31 +376,32 @@ void lua_settag (int tag) {
388} 376}
389 377
390 378
391TaggedString *luaA_nextvar (TaggedString *g) { 379GlobalVar *luaA_nextvar (TaggedString *ts) {
392 if (g == NULL) 380 GlobalVar *gv;
393 g = L->rootglobal; /* first variable */ 381 if (ts == NULL)
382 gv = L->rootglobal; /* first variable */
394 else { 383 else {
395 /* check whether name is in global var list */ 384 /* check whether name is in global var list */
396 luaL_arg_check(g != g->nextglobal, 1, "variable name expected"); 385 luaL_arg_check(ts->u.s.gv, 1, "variable name expected");
397 g = g->nextglobal; /* get next */ 386 gv = ts->u.s.gv->next; /* get next */
398 } 387 }
399 while (g && g->u.s.globalval.ttype == LUA_T_NIL) /* skip globals with nil */ 388 while (gv && gv->value.ttype == LUA_T_NIL) /* skip globals with nil */
400 g = g->nextglobal; 389 gv = gv->next;
401 if (g) { 390 if (gv) {
402 ttype(L->stack.top) = LUA_T_STRING; tsvalue(L->stack.top) = g; 391 ttype(L->stack.top) = LUA_T_STRING; tsvalue(L->stack.top) = gv->name;
403 incr_top; 392 incr_top;
404 luaA_pushobject(&g->u.s.globalval); 393 luaA_pushobject(&gv->value);
405 } 394 }
406 return g; 395 return gv;
407} 396}
408 397
409 398
410const char *lua_nextvar (const char *varname) { 399const char *lua_nextvar (const char *varname) {
411 TaggedString *g = (varname == NULL) ? NULL : luaS_new(varname); 400 TaggedString *ts = (varname == NULL) ? NULL : luaS_new(varname);
412 g = luaA_nextvar(g); 401 GlobalVar *gv = luaA_nextvar(ts);
413 if (g) { 402 if (gv) {
414 top2LC(2); 403 top2LC(2);
415 return g->str; 404 return gv->name->str;
416 } 405 }
417 else { 406 else {
418 top2LC(0); 407 top2LC(0);
@@ -577,11 +566,11 @@ static int checkfunc (TObject *o) {
577 566
578const char *lua_getobjname (lua_Object o, const char **name) { 567const char *lua_getobjname (lua_Object o, const char **name) {
579 /* try to find a name for given function */ 568 /* try to find a name for given function */
580 TaggedString *g; 569 GlobalVar *g;
581 set_normalized(L->stack.top, Address(o)); /* to be accessed by "checkfunc" */ 570 set_normalized(L->stack.top, Address(o)); /* to be accessed by "checkfunc" */
582 for (g=L->rootglobal; g; g=g->nextglobal) { 571 for (g=L->rootglobal; g; g=g->next) {
583 if (checkfunc(&g->u.s.globalval)) { 572 if (checkfunc(&g->value)) {
584 *name = g->str; 573 *name = g->name->str;
585 return "global"; 574 return "global";
586 } 575 }
587 } 576 }
diff --git a/lapi.h b/lapi.h
index 274b4fb4..5d72060d 100644
--- a/lapi.h
+++ b/lapi.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lapi.h,v 1.6 1999/09/20 14:57:29 roberto Exp roberto $ 2** $Id: lapi.h,v 1.7 1999/09/21 16:10:13 roberto Exp roberto $
3** Auxiliary functions from Lua API 3** Auxiliary functions from Lua API
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -14,9 +14,7 @@
14 14
15TObject *luaA_Address (lua_Object o); 15TObject *luaA_Address (lua_Object o);
16void luaA_pushobject (const TObject *o); 16void luaA_pushobject (const TObject *o);
17void luaA_packresults (void); 17GlobalVar *luaA_nextvar (TaggedString *g);
18int luaA_passresults (void);
19TaggedString *luaA_nextvar (TaggedString *g);
20int luaA_next (const Hash *t, int i); 18int luaA_next (const Hash *t, int i);
21lua_Object luaA_putObjectOnTop (void); 19lua_Object luaA_putObjectOnTop (void);
22 20
diff --git a/lbuiltin.c b/lbuiltin.c
index c5fd233f..fce90a71 100644
--- a/lbuiltin.c
+++ b/lbuiltin.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lbuiltin.c,v 1.68 1999/10/19 13:33:22 roberto Exp roberto $ 2** $Id: lbuiltin.c,v 1.69 1999/10/26 10:53:40 roberto Exp roberto $
3** Built-in functions 3** Built-in functions
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -35,10 +35,9 @@
35 35
36 36
37static void pushtagstring (TaggedString *s) { 37static void pushtagstring (TaggedString *s) {
38 TObject o; 38 ttype(L->stack.top) = LUA_T_STRING;
39 o.ttype = LUA_T_STRING; 39 tsvalue(L->stack.top) = s;
40 o.value.ts = s; 40 incr_top;
41 luaA_pushobject(&o);
42} 41}
43 42
44 43
@@ -107,7 +106,7 @@ static void error_message (void) {
107 106
108 107
109/* 108/*
110** If your system does not support "stdout", just remove this function. 109** If your system does not support "stdout", you can just remove this function.
111** If you need, you can define your own "print" function, following this 110** If you need, you can define your own "print" function, following this
112** model but changing "fputs" to put the strings at a proper place 111** model but changing "fputs" to put the strings at a proper place
113** (a console window or a log file, for instance). 112** (a console window or a log file, for instance).
@@ -264,22 +263,29 @@ static void luaB_type (void) {
264** ======================================================= 263** =======================================================
265*/ 264*/
266 265
266
267static void passresults (void) {
268 L->Cstack.base = L->Cstack.lua2C; /* position of first result */
269 if (L->Cstack.num == 0)
270 lua_pushuserdata(NULL); /* at least one result to signal no errors */
271}
272
267static void luaB_dostring (void) { 273static void luaB_dostring (void) {
268 long l; 274 long l;
269 const char *s = luaL_check_lstr(1, &l); 275 const char *s = luaL_check_lstr(1, &l);
270 if (*s == ID_CHUNK) 276 if (*s == ID_CHUNK)
271 lua_error("`dostring' cannot run pre-compiled code"); 277 lua_error("`dostring' cannot run pre-compiled code");
272 if (lua_dobuffer(s, l, luaL_opt_string(2, s)) == 0) 278 if (lua_dobuffer(s, l, luaL_opt_string(2, s)) == 0)
273 if (luaA_passresults() == 0) 279 passresults();
274 lua_pushuserdata(NULL); /* at least one result to signal no errors */ 280 /* else return no value */
275} 281}
276 282
277 283
278static void luaB_dofile (void) { 284static void luaB_dofile (void) {
279 const char *fname = luaL_opt_string(1, NULL); 285 const char *fname = luaL_opt_string(1, NULL);
280 if (lua_dofile(fname) == 0) 286 if (lua_dofile(fname) == 0)
281 if (luaA_passresults() == 0) 287 passresults();
282 lua_pushuserdata(NULL); /* at least one result to signal no errors */ 288 /* else return no value */
283} 289}
284 290
285 291
@@ -312,10 +318,12 @@ static void luaB_call (void) {
312 lua_error(NULL); 318 lua_error(NULL);
313 } 319 }
314 else { /* no errors */ 320 else { /* no errors */
315 if (strchr(options, 'p')) 321 if (strchr(options, 'p')) { /* pack results? */
316 luaA_packresults(); 322 luaV_pack(L->Cstack.lua2C, L->Cstack.num, L->stack.top);
323 incr_top;
324 }
317 else 325 else
318 luaA_passresults(); 326 L->Cstack.base = L->Cstack.lua2C; /* position of first result */
319 } 327 }
320} 328}
321 329
@@ -373,7 +381,7 @@ static void luaB_tostring (void) {
373 sprintf(buff, "function: %p", (void *)o->value.f); 381 sprintf(buff, "function: %p", (void *)o->value.f);
374 break; 382 break;
375 case LUA_T_USERDATA: 383 case LUA_T_USERDATA:
376 sprintf(buff, "userdata: %p", o->value.ts->u.d.v); 384 sprintf(buff, "userdata: %p", o->value.ts->u.d.value);
377 break; 385 break;
378 case LUA_T_NIL: 386 case LUA_T_NIL:
379 lua_pushstring("nil"); 387 lua_pushstring("nil");
@@ -449,23 +457,23 @@ static void luaB_foreach (void) {
449 457
450 458
451static void luaB_foreachvar (void) { 459static void luaB_foreachvar (void) {
452 TaggedString *s; 460 GlobalVar *gv;
453 TObject f; /* see comment in 'foreachi' */ 461 TObject f; /* see comment in 'foreachi' */
454 f = *luaA_Address(luaL_functionarg(1)); 462 f = *luaA_Address(luaL_functionarg(1));
455 luaD_checkstack(4); /* for extra var name, f, var name, and globalval */ 463 luaD_checkstack(4); /* for extra var name, f, var name, and globalval */
456 for (s = L->rootglobal; s; s = s->nextglobal) { 464 for (gv = L->rootglobal; gv; gv = gv->next) {
457 if (s->u.s.globalval.ttype != LUA_T_NIL) { 465 if (gv->value.ttype != LUA_T_NIL) {
458 pushtagstring(s); /* keep (extra) s on stack to avoid GC */ 466 pushtagstring(gv->name); /* keep (extra) name on stack to avoid GC */
459 *(L->stack.top++) = f; 467 *(L->stack.top++) = f;
460 pushtagstring(s); 468 pushtagstring(gv->name);
461 *(L->stack.top++) = s->u.s.globalval; 469 *(L->stack.top++) = gv->value;
462 luaD_calln(2, 1); 470 luaD_calln(2, 1);
463 if (ttype(L->stack.top-1) != LUA_T_NIL) { 471 if (ttype(L->stack.top-1) != LUA_T_NIL) {
464 L->stack.top--; 472 L->stack.top--;
465 *(L->stack.top-1) = *L->stack.top; /* remove extra `s' */ 473 *(L->stack.top-1) = *L->stack.top; /* remove extra name */
466 return; 474 return;
467 } 475 }
468 L->stack.top-=2; /* remove result and extra `s' */ 476 L->stack.top-=2; /* remove result and extra name */
469 } 477 }
470 } 478 }
471} 479}
@@ -507,7 +515,8 @@ static void luaB_tremove (void) {
507} 515}
508 516
509 517
510/* { 518/*
519** {======================================================
511** Quicksort 520** Quicksort
512*/ 521*/
513 522
@@ -593,11 +602,10 @@ static void luaB_sort (void) {
593 lua_pushobject(t); 602 lua_pushobject(t);
594} 603}
595 604
596/* }}===================================================== */ 605/* }====================================================== */
597 606
598 607
599/* 608/* }====================================================== */
600** ====================================================== */
601 609
602 610
603 611
@@ -605,6 +613,7 @@ static void luaB_sort (void) {
605/* 613/*
606** {====================================================== 614** {======================================================
607** some DEBUG functions 615** some DEBUG functions
616** (for internal debugging of the Lua implementation)
608** ======================================================= 617** =======================================================
609*/ 618*/
610 619
diff --git a/ldo.c b/ldo.c
index 2bbfdd5f..c8797a7c 100644
--- a/ldo.c
+++ b/ldo.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldo.c,v 1.49 1999/10/14 17:53:35 roberto Exp roberto $ 2** $Id: ldo.c,v 1.50 1999/10/14 19:46:57 roberto Exp roberto $
3** Stack and Call structure of Lua 3** Stack and Call structure of Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -219,7 +219,7 @@ void luaD_calln (int nArgs, int nResults) {
219 219
220 220
221static void message (const char *s) { 221static void message (const char *s) {
222 const TObject *em = &(luaS_new("_ERRORMESSAGE")->u.s.globalval); 222 const TObject *em = &(luaS_assertglobalbyname("_ERRORMESSAGE")->value);
223 if (ttype(em) == LUA_T_PROTO || ttype(em) == LUA_T_CPROTO || 223 if (ttype(em) == LUA_T_PROTO || ttype(em) == LUA_T_CPROTO ||
224 ttype(em) == LUA_T_CLOSURE) { 224 ttype(em) == LUA_T_CLOSURE) {
225 *L->stack.top = *em; 225 *L->stack.top = *em;
@@ -237,7 +237,6 @@ void lua_error (const char *s) {
237 if (L->errorJmp) 237 if (L->errorJmp)
238 longjmp(L->errorJmp->b, 1); 238 longjmp(L->errorJmp->b, 1);
239 else { 239 else {
240 LUA_INTERNALERROR("exit!!");
241 message("exit(1). Unable to recover.\n"); 240 message("exit(1). Unable to recover.\n");
242 exit(1); 241 exit(1);
243 } 242 }
diff --git a/lgc.c b/lgc.c
index fc5c1739..c52e3f3b 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.c,v 1.28 1999/10/11 16:13:11 roberto Exp roberto $ 2** $Id: lgc.c,v 1.29 1999/10/14 19:13:31 roberto Exp roberto $
3** Garbage Collector 3** Garbage Collector
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -62,13 +62,13 @@ static void hashmark (Hash *h) {
62} 62}
63 63
64 64
65static void globalmark (void) { 65static void travglobal (void) {
66 TaggedString *g; 66 GlobalVar *gv;
67 for (g=L->rootglobal; g; g=g->nextglobal) { 67 for (gv=L->rootglobal; gv; gv=gv->next) {
68 LUA_ASSERT(g->constindex >= 0, "userdata in global list"); 68 LUA_ASSERT(gv->name->u.s.gv == gv, "inconsistent global name");
69 if (g->u.s.globalval.ttype != LUA_T_NIL) { 69 if (gv->value.ttype != LUA_T_NIL) {
70 markobject(&g->u.s.globalval); 70 strmark(gv->name); /* cannot collect non nil global variables */
71 strmark(g); /* cannot collect non nil global variables */ 71 markobject(&gv->value);
72 } 72 }
73 } 73 }
74} 74}
@@ -157,12 +157,16 @@ static void collecttable (void) {
157} 157}
158 158
159 159
160/*
161** remove from the global list globals whose names will be collected
162** (the global itself is freed when its name is freed)
163*/
160static void clear_global_list (int limit) { 164static void clear_global_list (int limit) {
161 TaggedString **p = &L->rootglobal; 165 GlobalVar **p = &L->rootglobal;
162 TaggedString *next; 166 GlobalVar *next;
163 while ((next = *p) != NULL) { 167 while ((next = *p) != NULL) {
164 if (next->marked >= limit) p = &next->nextglobal; 168 if (next->name->marked >= limit) p = &next->next;
165 else *p = next->nextglobal; 169 else *p = next->next;
166 } 170 }
167} 171}
168 172
@@ -226,7 +230,7 @@ static void tableTM (void) {
226 230
227static void markall (void) { 231static void markall (void) {
228 travstack(); /* mark stack objects */ 232 travstack(); /* mark stack objects */
229 globalmark(); /* mark global variable values and names */ 233 travglobal(); /* mark global variable values and names */
230 travlock(); /* mark locked objects */ 234 travlock(); /* mark locked objects */
231 luaT_travtagmethods(markobject); /* mark tag methods */ 235 luaT_travtagmethods(markobject); /* mark tag methods */
232} 236}
@@ -239,8 +243,6 @@ void luaC_collect (int all) {
239 collectstring(all?MAX_INT:1); 243 collectstring(all?MAX_INT:1);
240 collectproto(); 244 collectproto();
241 collectclosure(); 245 collectclosure();
242 if (!all)
243 luaD_gcIM(&luaO_nilobject); /* GC tag method for nil (signal end of GC) */
244} 246}
245 247
246 248
@@ -249,6 +251,7 @@ long lua_collectgarbage (long limit) {
249 markall(); 251 markall();
250 luaR_invalidaterefs(); 252 luaR_invalidaterefs();
251 luaC_collect(0); 253 luaC_collect(0);
254 luaD_gcIM(&luaO_nilobject); /* GC tag method for nil (signal end of GC) */
252 recovered = recovered - L->nblocks; 255 recovered = recovered - L->nblocks;
253 L->GCthreshold = (limit == 0) ? 2*L->nblocks : L->nblocks+limit; 256 L->GCthreshold = (limit == 0) ? 2*L->nblocks : L->nblocks+limit;
254 return recovered; 257 return recovered;
diff --git a/lobject.h b/lobject.h
index 181ab39e..364653a1 100644
--- a/lobject.h
+++ b/lobject.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lobject.h,v 1.33 1999/10/14 19:13:31 roberto Exp roberto $ 2** $Id: lobject.h,v 1.34 1999/10/19 13:33:22 roberto Exp roberto $
3** Type definitions for Lua objects 3** Type definitions for Lua objects
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -87,25 +87,30 @@ typedef struct TObject {
87 87
88 88
89 89
90typedef struct GlobalVar {
91 TObject value;
92 struct GlobalVar *next;
93 struct TaggedString *name;
94} GlobalVar;
95
96
90/* 97/*
91** String headers for string table 98** String headers for string table
92*/ 99*/
93
94typedef struct TaggedString { 100typedef struct TaggedString {
95 struct TaggedString *nexthash; /* chain hash table */
96 struct TaggedString *nextglobal; /* chain global variables */
97 unsigned long hash;
98 int constindex; /* hint to reuse constants (= -1 if this is a userdata) */
99 union { 101 union {
100 struct { 102 struct { /* for strings */
101 TObject globalval; 103 GlobalVar *gv; /* eventual global value with this name */
102 long len; /* if this is a string, here is its length */ 104 long len;
103 } s; 105 } s;
104 struct { 106 struct { /* for userdata */
105 int tag; 107 int tag;
106 void *v; /* if this is a userdata, here is its value */ 108 void *value;
107 } d; 109 } d;
108 } u; 110 } u;
111 struct TaggedString *nexthash; /* chain for hash table */
112 unsigned long hash;
113 int constindex; /* hint to reuse constants (= -1 if this is a userdata) */
109 unsigned char marked; 114 unsigned char marked;
110 char str[1]; /* \0 byte already reserved */ 115 char str[1]; /* \0 byte already reserved */
111} TaggedString; 116} TaggedString;
diff --git a/lparser.c b/lparser.c
index 06f21e81..740ab03a 100644
--- a/lparser.c
+++ b/lparser.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lparser.c,v 1.40 1999/09/02 13:13:22 roberto Exp roberto $ 2** $Id: lparser.c,v 1.41 1999/09/20 14:15:18 roberto Exp roberto $
3** LL(1) Parser and code generator for Lua 3** LL(1) Parser and code generator for Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -232,6 +232,13 @@ static void code_constant (LexState *ls, int c) {
232} 232}
233 233
234 234
235static void assertglobal (LexState *ls, int index) {
236 TObject *o = &ls->fs->f->consts[index];
237 LUA_ASSERT(ttype(o) == LUA_T_STRING, "global name is not a string");
238 luaS_assertglobal(tsvalue(o));
239}
240
241
235static int next_constant (FuncState *fs) { 242static int next_constant (FuncState *fs) {
236 TProtoFunc *f = fs->f; 243 TProtoFunc *f = fs->f;
237 luaM_growvector(f->consts, f->nconsts, 1, TObject, constantEM, MAX_ARG); 244 luaM_growvector(f->consts, f->nconsts, 1, TObject, constantEM, MAX_ARG);
@@ -478,6 +485,7 @@ static void lua_pushvar (LexState *ls, vardesc *var) {
478 break; 485 break;
479 case VGLOBAL: 486 case VGLOBAL:
480 code_oparg(ls, GETGLOBAL, var->info, 1); 487 code_oparg(ls, GETGLOBAL, var->info, 1);
488 assertglobal(ls, var->info); /* make sure that there is a global */
481 break; 489 break;
482 case VDOT: 490 case VDOT:
483 code_oparg(ls, GETDOTTED, var->info, 0); 491 code_oparg(ls, GETDOTTED, var->info, 0);
@@ -501,6 +509,7 @@ static void storevar (LexState *ls, const vardesc *var) {
501 break; 509 break;
502 case VGLOBAL: 510 case VGLOBAL:
503 code_oparg(ls, SETGLOBAL, var->info, -1); 511 code_oparg(ls, SETGLOBAL, var->info, -1);
512 assertglobal(ls, var->info); /* make sure that there is a global */
504 break; 513 break;
505 case VINDEXED: 514 case VINDEXED:
506 code_opcode(ls, SETTABLEPOP, -3); 515 code_opcode(ls, SETTABLEPOP, -3);
diff --git a/lstate.h b/lstate.h
index 0af3cc31..c0ccb1e1 100644
--- a/lstate.h
+++ b/lstate.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstate.h,v 1.19 1999/05/11 20:08:20 roberto Exp roberto $ 2** $Id: lstate.h,v 1.20 1999/10/04 17:51:04 roberto Exp roberto $
3** Global State 3** Global State
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -76,7 +76,7 @@ struct lua_State {
76 TProtoFunc *rootproto; /* list of all prototypes */ 76 TProtoFunc *rootproto; /* list of all prototypes */
77 Closure *rootcl; /* list of all closures */ 77 Closure *rootcl; /* list of all closures */
78 Hash *roottable; /* list of all tables */ 78 Hash *roottable; /* list of all tables */
79 TaggedString *rootglobal; /* list of strings with global values */ 79 GlobalVar *rootglobal; /* list of global variables */
80 stringtable *string_root; /* array of hash tables for strings and udata */ 80 stringtable *string_root; /* array of hash tables for strings and udata */
81 struct IM *IMtable; /* table for tag methods */ 81 struct IM *IMtable; /* table for tag methods */
82 int last_tag; /* last used tag in IMtable */ 82 int last_tag; /* last used tag in IMtable */
diff --git a/lstring.c b/lstring.c
index 6aaf6b82..f71425e8 100644
--- a/lstring.c
+++ b/lstring.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstring.c,v 1.24 1999/10/14 19:13:31 roberto Exp roberto $ 2** $Id: lstring.c,v 1.25 1999/10/19 13:33:22 roberto Exp roberto $
3** String table (keeps all strings handled by Lua) 3** String table (keeps all strings handled by Lua)
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -87,7 +87,6 @@ static TaggedString *newone (long l, unsigned long h) {
87 sizeof(TaggedString)+l*sizeof(char)); 87 sizeof(TaggedString)+l*sizeof(char));
88 ts->marked = 0; 88 ts->marked = 0;
89 ts->nexthash = NULL; 89 ts->nexthash = NULL;
90 ts->nextglobal = ts; /* signal it is not in global list */
91 ts->hash = h; 90 ts->hash = h;
92 return ts; 91 return ts;
93} 92}
@@ -97,7 +96,7 @@ static TaggedString *newone_s (const char *str, long l, unsigned long h) {
97 TaggedString *ts = newone(l, h); 96 TaggedString *ts = newone(l, h);
98 memcpy(ts->str, str, l); 97 memcpy(ts->str, str, l);
99 ts->str[l] = 0; /* ending 0 */ 98 ts->str[l] = 0; /* ending 0 */
100 ts->u.s.globalval.ttype = LUA_T_NIL; /* initialize global value */ 99 ts->u.s.gv = NULL; /* no global value */
101 ts->u.s.len = l; 100 ts->u.s.len = l;
102 ts->constindex = 0; 101 ts->constindex = 0;
103 L->nblocks += gcsizestring(l); 102 L->nblocks += gcsizestring(l);
@@ -107,7 +106,7 @@ static TaggedString *newone_s (const char *str, long l, unsigned long h) {
107 106
108static TaggedString *newone_u (void *buff, int tag, unsigned long h) { 107static TaggedString *newone_u (void *buff, int tag, unsigned long h) {
109 TaggedString *ts = newone(0, h); 108 TaggedString *ts = newone(0, h);
110 ts->u.d.v = buff; 109 ts->u.d.value = buff;
111 ts->u.d.tag = (tag == LUA_ANYTAG) ? 0 : tag; 110 ts->u.d.tag = (tag == LUA_ANYTAG) ? 0 : tag;
112 ts->constindex = -1; /* tag -> this is a userdata */ 111 ts->constindex = -1; /* tag -> this is a userdata */
113 L->nblocks++; 112 L->nblocks++;
@@ -131,13 +130,15 @@ static void newentry (stringtable *tb, TaggedString *ts, int h) {
131} 130}
132 131
133 132
134static TaggedString *insert_s (const char *str, long l, 133TaggedString *luaS_newlstr (const char *str, long l) {
135 stringtable *tb, unsigned long h) { 134 unsigned long h = hash_s(str, l);
135 stringtable *tb = &L->string_root[h%NUM_HASHSTR];
136 int h1 = h%tb->size; 136 int h1 = h%tb->size;
137 TaggedString *ts; 137 TaggedString *ts;
138 for (ts = tb->hash[h1]; ts; ts = ts->nexthash) 138 for (ts = tb->hash[h1]; ts; ts = ts->nexthash) {
139 if (ts->u.s.len == l && (memcmp(str, ts->str, l) == 0)) 139 if (ts->u.s.len == l && (memcmp(str, ts->str, l) == 0))
140 return ts; 140 return ts;
141 }
141 /* not found */ 142 /* not found */
142 ts = newone_s(str, l, h); /* create new entry */ 143 ts = newone_s(str, l, h); /* create new entry */
143 newentry(tb, ts, h1); /* insert it on table */ 144 newentry(tb, ts, h1); /* insert it on table */
@@ -145,30 +146,22 @@ static TaggedString *insert_s (const char *str, long l,
145} 146}
146 147
147 148
148static TaggedString *insert_u (void *buff, int tag, stringtable *tb) { 149TaggedString *luaS_createudata (void *udata, int tag) {
149 unsigned long h = (IntPoint)buff; 150 unsigned long h = (IntPoint)udata;
151 stringtable *tb = &L->string_root[(h%NUM_HASHUDATA)+NUM_HASHSTR];
150 int h1 = h%tb->size; 152 int h1 = h%tb->size;
151 TaggedString *ts; 153 TaggedString *ts;
152 for (ts = tb->hash[h1]; ts; ts = ts->nexthash) 154 for (ts = tb->hash[h1]; ts; ts = ts->nexthash) {
153 if ((tag == ts->u.d.tag || tag == LUA_ANYTAG) && buff == ts->u.d.v) 155 if (udata == ts->u.d.value && (tag == ts->u.d.tag || tag == LUA_ANYTAG))
154 return ts; 156 return ts;
157 }
155 /* not found */ 158 /* not found */
156 ts = newone_u(buff, tag, h); 159 ts = newone_u(udata, tag, h);
157 newentry(tb, ts, h1); 160 newentry(tb, ts, h1);
158 return ts; 161 return ts;
159} 162}
160 163
161 164
162TaggedString *luaS_createudata (void *udata, int tag) {
163 int t = ((IntPoint)udata%NUM_HASHUDATA)+NUM_HASHSTR;
164 return insert_u(udata, tag, &L->string_root[t]);
165}
166
167TaggedString *luaS_newlstr (const char *str, long l) {
168 unsigned long h = hash_s(str, l);
169 return insert_s(str, l, &L->string_root[h%NUM_HASHSTR], h);
170}
171
172TaggedString *luaS_new (const char *str) { 165TaggedString *luaS_new (const char *str) {
173 return luaS_newlstr(str, strlen(str)); 166 return luaS_newlstr(str, strlen(str));
174} 167}
@@ -181,23 +174,38 @@ TaggedString *luaS_newfixedstring (const char *str) {
181 174
182 175
183void luaS_free (TaggedString *t) { 176void luaS_free (TaggedString *t) {
184 L->nblocks -= (t->constindex == -1) ? 1 : gcsizestring(t->u.s.len); 177 if (t->constindex == -1) /* is userdata? */
178 L->nblocks--;
179 else { /* is string */
180 L->nblocks -= gcsizestring(t->u.s.len);
181 luaM_free(t->u.s.gv);
182 }
185 luaM_free(t); 183 luaM_free(t);
186} 184}
187 185
188 186
189void luaS_rawsetglobal (TaggedString *ts, const TObject *newval) { 187GlobalVar *luaS_assertglobal (TaggedString *ts) {
190 ts->u.s.globalval = *newval; 188 GlobalVar *gv = ts->u.s.gv;
191 if (ts->nextglobal == ts) { /* is not in list? */ 189 if (!gv) { /* no global value yet? */
192 ts->nextglobal = L->rootglobal; 190 gv = luaM_new(GlobalVar);
193 L->rootglobal = ts; 191 gv->value.ttype = LUA_T_NIL; /* initial value */
192 gv->name = ts;
193 gv->next = L->rootglobal; /* chain in global list */
194 L->rootglobal = gv;
195 ts->u.s.gv = gv;
194 } 196 }
197 return gv;
198}
199
200
201GlobalVar *luaS_assertglobalbyname (const char *name) {
202 return luaS_assertglobal(luaS_new(name));
195} 203}
196 204
197 205
198int luaS_globaldefined (const char *name) { 206int luaS_globaldefined (const char *name) {
199 TaggedString *ts = luaS_new(name); 207 TaggedString *ts = luaS_new(name);
200 return ts->u.s.globalval.ttype != LUA_T_NIL; 208 return ts->u.s.gv && ts->u.s.gv->value.ttype != LUA_T_NIL;
201} 209}
202 210
203 211
diff --git a/lstring.h b/lstring.h
index df0f079d..d39e1d27 100644
--- a/lstring.h
+++ b/lstring.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstring.h,v 1.10 1999/10/11 16:13:11 roberto Exp roberto $ 2** $Id: lstring.h,v 1.11 1999/10/14 19:13:31 roberto Exp roberto $
3** String table (keep all strings handled by Lua) 3** String table (keep all strings handled by Lua)
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -33,7 +33,8 @@ void luaS_free (TaggedString *ts);
33TaggedString *luaS_newlstr (const char *str, long l); 33TaggedString *luaS_newlstr (const char *str, long l);
34TaggedString *luaS_new (const char *str); 34TaggedString *luaS_new (const char *str);
35TaggedString *luaS_newfixedstring (const char *str); 35TaggedString *luaS_newfixedstring (const char *str);
36void luaS_rawsetglobal (TaggedString *ts, const TObject *newval); 36GlobalVar *luaS_assertglobal (TaggedString *ts);
37GlobalVar *luaS_assertglobalbyname (const char *name);
37int luaS_globaldefined (const char *name); 38int luaS_globaldefined (const char *name);
38 39
39 40
diff --git a/lvm.c b/lvm.c
index a2bb09e4..5d6ab840 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.c,v 1.63 1999/10/14 19:13:31 roberto Exp roberto $ 2** $Id: lvm.c,v 1.64 1999/10/14 19:46:57 roberto Exp roberto $
3** Lua virtual machine 3** Lua virtual machine
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -167,9 +167,9 @@ void luaV_rawsettable (const TObject *t) {
167} 167}
168 168
169 169
170void luaV_getglobal (TaggedString *ts) { 170void luaV_getglobal (GlobalVar *gv) {
171 /* WARNING: caller must assure stack space */ 171 /* WARNING: caller must assure stack space */
172 const TObject *value = &ts->u.s.globalval; 172 const TObject *value = &gv->value;
173 switch (ttype(value)) { 173 switch (ttype(value)) {
174 /* only userdata, tables and nil can have getglobal tag methods */ 174 /* only userdata, tables and nil can have getglobal tag methods */
175 case LUA_T_USERDATA: case LUA_T_ARRAY: case LUA_T_NIL: { 175 case LUA_T_USERDATA: case LUA_T_ARRAY: case LUA_T_NIL: {
@@ -177,7 +177,7 @@ void luaV_getglobal (TaggedString *ts) {
177 if (ttype(im) != LUA_T_NIL) { /* is there a tag method? */ 177 if (ttype(im) != LUA_T_NIL) { /* is there a tag method? */
178 struct Stack *S = &L->stack; 178 struct Stack *S = &L->stack;
179 ttype(S->top) = LUA_T_STRING; 179 ttype(S->top) = LUA_T_STRING;
180 tsvalue(S->top) = ts; 180 tsvalue(S->top) = gv->name; /* global name */
181 S->top++; 181 S->top++;
182 *S->top++ = *value; 182 *S->top++ = *value;
183 luaD_callTM(im, 2, 1); 183 luaD_callTM(im, 2, 1);
@@ -190,18 +190,18 @@ void luaV_getglobal (TaggedString *ts) {
190} 190}
191 191
192 192
193void luaV_setglobal (TaggedString *ts) { 193void luaV_setglobal (GlobalVar *gv) {
194 const TObject *oldvalue = &ts->u.s.globalval; 194 const TObject *oldvalue = &gv->value;
195 const TObject *im = luaT_getimbyObj(oldvalue, IM_SETGLOBAL); 195 const TObject *im = luaT_getimbyObj(oldvalue, IM_SETGLOBAL);
196 if (ttype(im) == LUA_T_NIL) /* is there a tag method? */ 196 if (ttype(im) == LUA_T_NIL) /* is there a tag method? */
197 luaS_rawsetglobal(ts, --L->stack.top); 197 gv->value = *(--L->stack.top);
198 else { 198 else {
199 /* WARNING: caller must assure stack space */ 199 /* WARNING: caller must assure stack space */
200 struct Stack *S = &L->stack; 200 struct Stack *S = &L->stack;
201 TObject newvalue; 201 TObject newvalue;
202 newvalue = *(S->top-1); 202 newvalue = *(S->top-1);
203 ttype(S->top-1) = LUA_T_STRING; 203 ttype(S->top-1) = LUA_T_STRING;
204 tsvalue(S->top-1) = ts; 204 tsvalue(S->top-1) = gv->name;
205 *S->top++ = *oldvalue; 205 *S->top++ = *oldvalue;
206 *S->top++ = newvalue; 206 *S->top++ = newvalue;
207 luaD_callTM(im, 3, 0); 207 luaD_callTM(im, 3, 0);
@@ -370,7 +370,7 @@ StkId luaV_execute (const Closure *cl, const TProtoFunc *tf, StkId base) {
370 370
371 case GETGLOBALW: aux += highbyte(*pc++); 371 case GETGLOBALW: aux += highbyte(*pc++);
372 case GETGLOBAL: aux += *pc++; 372 case GETGLOBAL: aux += *pc++;
373 luaV_getglobal(tsvalue(&consts[aux])); 373 luaV_getglobal(tsvalue(&consts[aux])->u.s.gv);
374 break; 374 break;
375 375
376 case GETTABLE: 376 case GETTABLE:
@@ -407,7 +407,7 @@ StkId luaV_execute (const Closure *cl, const TProtoFunc *tf, StkId base) {
407 407
408 case SETGLOBALW: aux += highbyte(*pc++); 408 case SETGLOBALW: aux += highbyte(*pc++);
409 case SETGLOBAL: aux += *pc++; 409 case SETGLOBAL: aux += *pc++;
410 luaV_setglobal(tsvalue(&consts[aux])); 410 luaV_setglobal(tsvalue(&consts[aux])->u.s.gv);
411 break; 411 break;
412 412
413 case SETTABLEPOP: 413 case SETTABLEPOP:
diff --git a/lvm.h b/lvm.h
index bef28ba8..77fd3c53 100644
--- a/lvm.h
+++ b/lvm.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.h,v 1.9 1999/08/16 20:52:00 roberto Exp roberto $ 2** $Id: lvm.h,v 1.10 1999/10/14 19:46:57 roberto Exp roberto $
3** Lua virtual machine 3** Lua virtual machine
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -24,8 +24,8 @@ void luaV_setn (Hash *t, int val);
24void luaV_gettable (void); 24void luaV_gettable (void);
25void luaV_settable (const TObject *t); 25void luaV_settable (const TObject *t);
26void luaV_rawsettable (const TObject *t); 26void luaV_rawsettable (const TObject *t);
27void luaV_getglobal (TaggedString *ts); 27void luaV_getglobal (GlobalVar *gv);
28void luaV_setglobal (TaggedString *ts); 28void luaV_setglobal (GlobalVar *gv);
29StkId luaV_execute (const Closure *cl, const TProtoFunc *tf, StkId base); 29StkId luaV_execute (const Closure *cl, const TProtoFunc *tf, StkId base);
30void luaV_closure (int nelems); 30void luaV_closure (int nelems);
31void luaV_comparison (lua_Type ttype_less, lua_Type ttype_equal, 31void luaV_comparison (lua_Type ttype_less, lua_Type ttype_equal,