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