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