diff options
-rw-r--r-- | lapi.c | 67 | ||||
-rw-r--r-- | lapi.h | 6 | ||||
-rw-r--r-- | lbuiltin.c | 61 | ||||
-rw-r--r-- | ldo.c | 5 | ||||
-rw-r--r-- | lgc.c | 33 | ||||
-rw-r--r-- | lobject.h | 27 | ||||
-rw-r--r-- | lparser.c | 11 | ||||
-rw-r--r-- | lstate.h | 4 | ||||
-rw-r--r-- | lstring.c | 66 | ||||
-rw-r--r-- | lstring.h | 5 | ||||
-rw-r--r-- | lvm.c | 20 | ||||
-rw-r--r-- | lvm.h | 6 |
12 files changed, 166 insertions, 145 deletions
@@ -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 | ||
63 | void luaA_packresults (void) { | ||
64 | luaV_pack(L->Cstack.lua2C, L->Cstack.num, L->stack.top); | ||
65 | incr_top; | ||
66 | } | ||
67 | |||
68 | |||
69 | int luaA_passresults (void) { | ||
70 | L->Cstack.base = L->Cstack.lua2C; /* position of first result */ | ||
71 | return L->Cstack.num; | ||
72 | } | ||
73 | |||
74 | |||
75 | static void checkCparams (int nParams) { | 63 | static 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 | ||
192 | lua_Object lua_getglobal (const char *name) { | 180 | lua_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 | ||
199 | lua_Object lua_rawgetglobal (const char *name) { | 187 | lua_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 | ||
205 | void lua_setglobal (const char *name) { | 193 | void 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 | ||
212 | void lua_rawsetglobal (const char *name) { | 200 | void 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) { | |||
274 | void *lua_getuserdata (lua_Object object) { | 262 | void *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 | ||
280 | lua_CFunction lua_getcfunction (lua_Object object) { | 268 | lua_CFunction lua_getcfunction (lua_Object object) { |
@@ -388,31 +376,32 @@ void lua_settag (int tag) { | |||
388 | } | 376 | } |
389 | 377 | ||
390 | 378 | ||
391 | TaggedString *luaA_nextvar (TaggedString *g) { | 379 | GlobalVar *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 | ||
410 | const char *lua_nextvar (const char *varname) { | 399 | const 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 | ||
578 | const char *lua_getobjname (lua_Object o, const char **name) { | 567 | const 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 | } |
@@ -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 | ||
15 | TObject *luaA_Address (lua_Object o); | 15 | TObject *luaA_Address (lua_Object o); |
16 | void luaA_pushobject (const TObject *o); | 16 | void luaA_pushobject (const TObject *o); |
17 | void luaA_packresults (void); | 17 | GlobalVar *luaA_nextvar (TaggedString *g); |
18 | int luaA_passresults (void); | ||
19 | TaggedString *luaA_nextvar (TaggedString *g); | ||
20 | int luaA_next (const Hash *t, int i); | 18 | int luaA_next (const Hash *t, int i); |
21 | lua_Object luaA_putObjectOnTop (void); | 19 | lua_Object luaA_putObjectOnTop (void); |
22 | 20 | ||
@@ -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 | ||
37 | static void pushtagstring (TaggedString *s) { | 37 | static 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 | |||
267 | static 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 | |||
267 | static void luaB_dostring (void) { | 273 | static 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 | ||
278 | static void luaB_dofile (void) { | 284 | static 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 | ||
451 | static void luaB_foreachvar (void) { | 459 | static 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 | ||
@@ -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 | ||
221 | static void message (const char *s) { | 221 | static 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 | } |
@@ -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 | ||
65 | static void globalmark (void) { | 65 | static 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 | */ | ||
160 | static void clear_global_list (int limit) { | 164 | static 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 | ||
227 | static void markall (void) { | 231 | static 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; |
@@ -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 | ||
90 | typedef 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 | |||
94 | typedef struct TaggedString { | 100 | typedef 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; |
@@ -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 | ||
235 | static 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 | |||
235 | static int next_constant (FuncState *fs) { | 242 | static 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); |
@@ -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 */ |
@@ -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 | ||
108 | static TaggedString *newone_u (void *buff, int tag, unsigned long h) { | 107 | static 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 | ||
134 | static TaggedString *insert_s (const char *str, long l, | 133 | TaggedString *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 | ||
148 | static TaggedString *insert_u (void *buff, int tag, stringtable *tb) { | 149 | TaggedString *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 | ||
162 | TaggedString *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 | |||
167 | TaggedString *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 | |||
172 | TaggedString *luaS_new (const char *str) { | 165 | TaggedString *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 | ||
183 | void luaS_free (TaggedString *t) { | 176 | void 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 | ||
189 | void luaS_rawsetglobal (TaggedString *ts, const TObject *newval) { | 187 | GlobalVar *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 | |||
201 | GlobalVar *luaS_assertglobalbyname (const char *name) { | ||
202 | return luaS_assertglobal(luaS_new(name)); | ||
195 | } | 203 | } |
196 | 204 | ||
197 | 205 | ||
198 | int luaS_globaldefined (const char *name) { | 206 | int 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 | ||
@@ -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); | |||
33 | TaggedString *luaS_newlstr (const char *str, long l); | 33 | TaggedString *luaS_newlstr (const char *str, long l); |
34 | TaggedString *luaS_new (const char *str); | 34 | TaggedString *luaS_new (const char *str); |
35 | TaggedString *luaS_newfixedstring (const char *str); | 35 | TaggedString *luaS_newfixedstring (const char *str); |
36 | void luaS_rawsetglobal (TaggedString *ts, const TObject *newval); | 36 | GlobalVar *luaS_assertglobal (TaggedString *ts); |
37 | GlobalVar *luaS_assertglobalbyname (const char *name); | ||
37 | int luaS_globaldefined (const char *name); | 38 | int luaS_globaldefined (const char *name); |
38 | 39 | ||
39 | 40 | ||
@@ -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 | ||
170 | void luaV_getglobal (TaggedString *ts) { | 170 | void 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 | ||
193 | void luaV_setglobal (TaggedString *ts) { | 193 | void 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: |
@@ -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); | |||
24 | void luaV_gettable (void); | 24 | void luaV_gettable (void); |
25 | void luaV_settable (const TObject *t); | 25 | void luaV_settable (const TObject *t); |
26 | void luaV_rawsettable (const TObject *t); | 26 | void luaV_rawsettable (const TObject *t); |
27 | void luaV_getglobal (TaggedString *ts); | 27 | void luaV_getglobal (GlobalVar *gv); |
28 | void luaV_setglobal (TaggedString *ts); | 28 | void luaV_setglobal (GlobalVar *gv); |
29 | StkId luaV_execute (const Closure *cl, const TProtoFunc *tf, StkId base); | 29 | StkId luaV_execute (const Closure *cl, const TProtoFunc *tf, StkId base); |
30 | void luaV_closure (int nelems); | 30 | void luaV_closure (int nelems); |
31 | void luaV_comparison (lua_Type ttype_less, lua_Type ttype_equal, | 31 | void luaV_comparison (lua_Type ttype_less, lua_Type ttype_equal, |