diff options
| -rw-r--r-- | lapi.c | 66 | ||||
| -rw-r--r-- | lbaselib.c | 11 | ||||
| -rw-r--r-- | ldblib.c | 40 | ||||
| -rw-r--r-- | ldo.c | 4 | ||||
| -rw-r--r-- | lfunc.c | 9 | ||||
| -rw-r--r-- | lfunc.h | 6 | ||||
| -rw-r--r-- | lgc.c | 5 | ||||
| -rw-r--r-- | linit.c | 4 | ||||
| -rw-r--r-- | liolib.c | 34 | ||||
| -rw-r--r-- | loadlib.c | 12 | ||||
| -rw-r--r-- | lobject.h | 7 | ||||
| -rw-r--r-- | lstate.h | 3 | ||||
| -rw-r--r-- | lstring.c | 5 | ||||
| -rw-r--r-- | lstring.h | 4 | ||||
| -rw-r--r-- | ltests.c | 86 | ||||
| -rw-r--r-- | lua.h | 5 | ||||
| -rw-r--r-- | lvm.c | 16 |
17 files changed, 206 insertions, 111 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lapi.c,v 2.25 2005/01/07 19:53:32 roberto Exp roberto $ | 2 | ** $Id: lapi.c,v 2.26 2005/01/14 14:19:42 roberto Exp roberto $ |
| 3 | ** Lua API | 3 | ** Lua API |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -58,6 +58,11 @@ static TValue *index2adr (lua_State *L, int idx) { | |||
| 58 | } | 58 | } |
| 59 | else switch (idx) { /* pseudo-indices */ | 59 | else switch (idx) { /* pseudo-indices */ |
| 60 | case LUA_REGISTRYINDEX: return registry(L); | 60 | case LUA_REGISTRYINDEX: return registry(L); |
| 61 | case LUA_ENVIRONINDEX: { | ||
| 62 | Closure *func = curr_func(L); | ||
| 63 | sethvalue(L, &L->env, func->c.env); | ||
| 64 | return &L->env; | ||
| 65 | } | ||
| 61 | case LUA_GLOBALSINDEX: return gt(L); | 66 | case LUA_GLOBALSINDEX: return gt(L); |
| 62 | default: { | 67 | default: { |
| 63 | Closure *func = curr_func(L); | 68 | Closure *func = curr_func(L); |
| @@ -70,6 +75,16 @@ static TValue *index2adr (lua_State *L, int idx) { | |||
| 70 | } | 75 | } |
| 71 | 76 | ||
| 72 | 77 | ||
| 78 | static Table *getcurrenv (lua_State *L) { | ||
| 79 | if (L->ci == L->base_ci) /* no enclosing function? */ | ||
| 80 | return hvalue(gt(L)); /* use global table as environment */ | ||
| 81 | else { | ||
| 82 | Closure *func = curr_func(L); | ||
| 83 | return func->c.env; | ||
| 84 | } | ||
| 85 | } | ||
| 86 | |||
| 87 | |||
| 73 | void luaA_pushobject (lua_State *L, const TValue *o) { | 88 | void luaA_pushobject (lua_State *L, const TValue *o) { |
| 74 | setobj2s(L, L->top, o); | 89 | setobj2s(L, L->top, o); |
| 75 | incr_top(L); | 90 | incr_top(L); |
| @@ -186,9 +201,17 @@ LUA_API void lua_replace (lua_State *L, int idx) { | |||
| 186 | api_checknelems(L, 1); | 201 | api_checknelems(L, 1); |
| 187 | o = index2adr(L, idx); | 202 | o = index2adr(L, idx); |
| 188 | api_checkvalidindex(L, o); | 203 | api_checkvalidindex(L, o); |
| 189 | setobj(L, o, L->top - 1); | 204 | if (idx == LUA_ENVIRONINDEX) { |
| 190 | if (idx < LUA_GLOBALSINDEX) /* function upvalue? */ | 205 | Closure *func = curr_func(L); |
| 191 | luaC_barrier(L, curr_func(L), L->top - 1); | 206 | api_check(L, ttistable(L->top - 1)); |
| 207 | func->c.env = hvalue(L->top - 1); | ||
| 208 | luaC_barrier(L, func, L->top - 1); | ||
| 209 | } | ||
| 210 | else { | ||
| 211 | setobj(L, o, L->top - 1); | ||
| 212 | if (idx < LUA_GLOBALSINDEX) /* function upvalue? */ | ||
| 213 | luaC_barrier(L, curr_func(L), L->top - 1); | ||
| 214 | } | ||
| 192 | L->top--; | 215 | L->top--; |
| 193 | lua_unlock(L); | 216 | lua_unlock(L); |
| 194 | } | 217 | } |
| @@ -452,7 +475,7 @@ LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) { | |||
| 452 | lua_lock(L); | 475 | lua_lock(L); |
| 453 | luaC_checkGC(L); | 476 | luaC_checkGC(L); |
| 454 | api_checknelems(L, n); | 477 | api_checknelems(L, n); |
| 455 | cl = luaF_newCclosure(L, n); | 478 | cl = luaF_newCclosure(L, n, getcurrenv(L)); |
| 456 | cl->c.f = fn; | 479 | cl->c.f = fn; |
| 457 | L->top -= n; | 480 | L->top -= n; |
| 458 | while (n--) | 481 | while (n--) |
| @@ -579,7 +602,17 @@ LUA_API void lua_getfenv (lua_State *L, int idx) { | |||
| 579 | lua_lock(L); | 602 | lua_lock(L); |
| 580 | o = index2adr(L, idx); | 603 | o = index2adr(L, idx); |
| 581 | api_checkvalidindex(L, o); | 604 | api_checkvalidindex(L, o); |
| 582 | setobj2s(L, L->top, isLfunction(o) ? &clvalue(o)->l.g : gt(L)); | 605 | switch (ttype(o)) { |
| 606 | case LUA_TFUNCTION: | ||
| 607 | sethvalue(L, L->top, clvalue(o)->c.env); | ||
| 608 | break; | ||
| 609 | case LUA_TUSERDATA: | ||
| 610 | sethvalue(L, L->top, uvalue(o)->env); | ||
| 611 | break; | ||
| 612 | default: | ||
| 613 | setnilvalue(L->top); | ||
| 614 | break; | ||
| 615 | } | ||
| 583 | api_incr_top(L); | 616 | api_incr_top(L); |
| 584 | lua_unlock(L); | 617 | lua_unlock(L); |
| 585 | } | 618 | } |
| @@ -682,17 +715,24 @@ LUA_API int lua_setmetatable (lua_State *L, int objindex) { | |||
| 682 | 715 | ||
| 683 | LUA_API int lua_setfenv (lua_State *L, int idx) { | 716 | LUA_API int lua_setfenv (lua_State *L, int idx) { |
| 684 | StkId o; | 717 | StkId o; |
| 685 | int res = 0; | 718 | int res = 1; |
| 686 | lua_lock(L); | 719 | lua_lock(L); |
| 687 | api_checknelems(L, 1); | 720 | api_checknelems(L, 1); |
| 688 | o = index2adr(L, idx); | 721 | o = index2adr(L, idx); |
| 689 | api_checkvalidindex(L, o); | 722 | api_checkvalidindex(L, o); |
| 690 | api_check(L, ttistable(L->top - 1)); | 723 | api_check(L, ttistable(L->top - 1)); |
| 691 | if (isLfunction(o)) { | 724 | switch (ttype(o)) { |
| 692 | res = 1; | 725 | case LUA_TFUNCTION: |
| 693 | clvalue(o)->l.g = *(L->top - 1); | 726 | clvalue(o)->c.env = hvalue(L->top - 1); |
| 694 | luaC_objbarrier(L, clvalue(o), hvalue(L->top - 1)); | 727 | break; |
| 728 | case LUA_TUSERDATA: | ||
| 729 | uvalue(o)->env = hvalue(L->top - 1); | ||
| 730 | break; | ||
| 731 | default: | ||
| 732 | res = 0; | ||
| 733 | break; | ||
| 695 | } | 734 | } |
| 735 | luaC_objbarrier(L, gcvalue(o), hvalue(L->top - 1)); | ||
| 696 | L->top--; | 736 | L->top--; |
| 697 | lua_unlock(L); | 737 | lua_unlock(L); |
| 698 | return res; | 738 | return res; |
| @@ -776,7 +816,7 @@ struct CCallS { /* data to `f_Ccall' */ | |||
| 776 | static void f_Ccall (lua_State *L, void *ud) { | 816 | static void f_Ccall (lua_State *L, void *ud) { |
| 777 | struct CCallS *c = cast(struct CCallS *, ud); | 817 | struct CCallS *c = cast(struct CCallS *, ud); |
| 778 | Closure *cl; | 818 | Closure *cl; |
| 779 | cl = luaF_newCclosure(L, 0); | 819 | cl = luaF_newCclosure(L, 0, getcurrenv(L)); |
| 780 | cl->c.f = c->func; | 820 | cl->c.f = c->func; |
| 781 | setclvalue(L, L->top, cl); /* push function */ | 821 | setclvalue(L, L->top, cl); /* push function */ |
| 782 | incr_top(L); | 822 | incr_top(L); |
| @@ -943,7 +983,7 @@ LUA_API void *lua_newuserdata (lua_State *L, size_t size) { | |||
| 943 | Udata *u; | 983 | Udata *u; |
| 944 | lua_lock(L); | 984 | lua_lock(L); |
| 945 | luaC_checkGC(L); | 985 | luaC_checkGC(L); |
| 946 | u = luaS_newudata(L, size); | 986 | u = luaS_newudata(L, size, getcurrenv(L)); |
| 947 | setuvalue(L, L->top, u); | 987 | setuvalue(L, L->top, u); |
| 948 | api_incr_top(L); | 988 | api_incr_top(L); |
| 949 | lua_unlock(L); | 989 | lua_unlock(L); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lbaselib.c,v 1.165 2005/01/14 14:19:42 roberto Exp roberto $ | 2 | ** $Id: lbaselib.c,v 1.166 2005/02/14 13:19:44 roberto Exp roberto $ |
| 3 | ** Basic library | 3 | ** Basic library |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -131,7 +131,10 @@ static void getfunc (lua_State *L) { | |||
| 131 | 131 | ||
| 132 | static int luaB_getfenv (lua_State *L) { | 132 | static int luaB_getfenv (lua_State *L) { |
| 133 | getfunc(L); | 133 | getfunc(L); |
| 134 | lua_getfenv(L, -1); | 134 | if (lua_iscfunction(L, -1)) /* is a C function? */ |
| 135 | lua_pushvalue(L, LUA_GLOBALSINDEX); /* return the global env. */ | ||
| 136 | else | ||
| 137 | lua_getfenv(L, -1); | ||
| 135 | return 1; | 138 | return 1; |
| 136 | } | 139 | } |
| 137 | 140 | ||
| @@ -144,8 +147,8 @@ static int luaB_setfenv (lua_State *L) { | |||
| 144 | lua_replace(L, LUA_GLOBALSINDEX); | 147 | lua_replace(L, LUA_GLOBALSINDEX); |
| 145 | return 0; | 148 | return 0; |
| 146 | } | 149 | } |
| 147 | else if (lua_setfenv(L, -2) == 0) | 150 | else if (lua_iscfunction(L, -2) || lua_setfenv(L, -2) == 0) |
| 148 | luaL_error(L, "`setfenv' cannot change environment of given function"); | 151 | luaL_error(L, "`setfenv' cannot change environment of given object"); |
| 149 | return 1; | 152 | return 1; |
| 150 | } | 153 | } |
| 151 | 154 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ldblib.c,v 1.91 2005/01/10 17:21:10 roberto Exp roberto $ | 2 | ** $Id: ldblib.c,v 1.92 2005/01/18 17:23:25 roberto Exp roberto $ |
| 3 | ** Interface from Lua to its debug API | 3 | ** Interface from Lua to its debug API |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -19,6 +19,40 @@ | |||
| 19 | 19 | ||
| 20 | 20 | ||
| 21 | 21 | ||
| 22 | static int getmetatable (lua_State *L) { | ||
| 23 | luaL_checkany(L, 1); | ||
| 24 | if (!lua_getmetatable(L, 1)) { | ||
| 25 | lua_pushnil(L); /* no metatable */ | ||
| 26 | } | ||
| 27 | return 1; | ||
| 28 | } | ||
| 29 | |||
| 30 | |||
| 31 | static int setmetatable (lua_State *L) { | ||
| 32 | int t = lua_type(L, 2); | ||
| 33 | luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2, | ||
| 34 | "nil or table expected"); | ||
| 35 | lua_settop(L, 2); | ||
| 36 | lua_pushboolean(L, lua_setmetatable(L, 1)); | ||
| 37 | return 1; | ||
| 38 | } | ||
| 39 | |||
| 40 | |||
| 41 | static int getfenv (lua_State *L) { | ||
| 42 | lua_getfenv(L, 1); | ||
| 43 | return 1; | ||
| 44 | } | ||
| 45 | |||
| 46 | |||
| 47 | static int setfenv (lua_State *L) { | ||
| 48 | luaL_checktype(L, 2, LUA_TTABLE); | ||
| 49 | lua_settop(L, 2); | ||
| 50 | if (lua_setfenv(L, 1) == 0) | ||
| 51 | luaL_error(L, "`setfenv' cannot change environment of given object"); | ||
| 52 | return 1; | ||
| 53 | } | ||
| 54 | |||
| 55 | |||
| 22 | static void settabss (lua_State *L, const char *i, const char *v) { | 56 | static void settabss (lua_State *L, const char *i, const char *v) { |
| 23 | lua_pushstring(L, v); | 57 | lua_pushstring(L, v); |
| 24 | lua_setfield(L, -2, i); | 58 | lua_setfield(L, -2, i); |
| @@ -328,6 +362,10 @@ static int errorfb (lua_State *L) { | |||
| 328 | 362 | ||
| 329 | 363 | ||
| 330 | static const luaL_reg dblib[] = { | 364 | static const luaL_reg dblib[] = { |
| 365 | {"getmetatable", getmetatable}, | ||
| 366 | {"setmetatable", setmetatable}, | ||
| 367 | {"getfenv", getfenv}, | ||
| 368 | {"setfenv", setfenv}, | ||
| 331 | {"getlocal", getlocal}, | 369 | {"getlocal", getlocal}, |
| 332 | {"getinfo", getinfo}, | 370 | {"getinfo", getinfo}, |
| 333 | {"gethook", gethook}, | 371 | {"gethook", gethook}, |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ldo.c,v 2.12 2004/12/01 15:52:54 roberto Exp roberto $ | 2 | ** $Id: ldo.c,v 2.13 2004/12/03 20:35:33 roberto Exp roberto $ |
| 3 | ** Stack and Call structure of Lua | 3 | ** Stack and Call structure of Lua |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -474,7 +474,7 @@ static void f_parser (lua_State *L, void *ud) { | |||
| 474 | luaC_checkGC(L); | 474 | luaC_checkGC(L); |
| 475 | tf = ((c == LUA_SIGNATURE[0]) ? luaU_undump : luaY_parser)(L, p->z, | 475 | tf = ((c == LUA_SIGNATURE[0]) ? luaU_undump : luaY_parser)(L, p->z, |
| 476 | &p->buff, p->name); | 476 | &p->buff, p->name); |
| 477 | cl = luaF_newLclosure(L, tf->nups, gt(L)); | 477 | cl = luaF_newLclosure(L, tf->nups, hvalue(gt(L))); |
| 478 | cl->l.p = tf; | 478 | cl->l.p = tf; |
| 479 | for (i = 0; i < tf->nups; i++) /* initialize eventual upvalues */ | 479 | for (i = 0; i < tf->nups; i++) /* initialize eventual upvalues */ |
| 480 | cl->l.upvals[i] = luaF_newupval(L); | 480 | cl->l.upvals[i] = luaF_newupval(L); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lfunc.c,v 2.7 2005/01/19 15:54:26 roberto Exp roberto $ | 2 | ** $Id: lfunc.c,v 2.8 2005/02/10 13:25:02 roberto Exp roberto $ |
| 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 | */ |
| @@ -20,20 +20,21 @@ | |||
| 20 | 20 | ||
| 21 | 21 | ||
| 22 | 22 | ||
| 23 | Closure *luaF_newCclosure (lua_State *L, int nelems) { | 23 | Closure *luaF_newCclosure (lua_State *L, int nelems, Table *e) { |
| 24 | Closure *c = cast(Closure *, luaM_malloc(L, sizeCclosure(nelems))); | 24 | Closure *c = cast(Closure *, luaM_malloc(L, sizeCclosure(nelems))); |
| 25 | luaC_link(L, obj2gco(c), LUA_TFUNCTION); | 25 | luaC_link(L, obj2gco(c), LUA_TFUNCTION); |
| 26 | c->c.isC = 1; | 26 | c->c.isC = 1; |
| 27 | c->c.env = e; | ||
| 27 | c->c.nupvalues = cast(lu_byte, nelems); | 28 | c->c.nupvalues = cast(lu_byte, nelems); |
| 28 | return c; | 29 | return c; |
| 29 | } | 30 | } |
| 30 | 31 | ||
| 31 | 32 | ||
| 32 | Closure *luaF_newLclosure (lua_State *L, int nelems, TValue *e) { | 33 | Closure *luaF_newLclosure (lua_State *L, int nelems, Table *e) { |
| 33 | Closure *c = cast(Closure *, luaM_malloc(L, sizeLclosure(nelems))); | 34 | Closure *c = cast(Closure *, luaM_malloc(L, sizeLclosure(nelems))); |
| 34 | luaC_link(L, obj2gco(c), LUA_TFUNCTION); | 35 | luaC_link(L, obj2gco(c), LUA_TFUNCTION); |
| 35 | c->l.isC = 0; | 36 | c->l.isC = 0; |
| 36 | c->l.g = *e; | 37 | c->l.env = e; |
| 37 | c->l.nupvalues = cast(lu_byte, nelems); | 38 | c->l.nupvalues = cast(lu_byte, nelems); |
| 38 | while (nelems--) c->l.upvals[nelems] = NULL; | 39 | while (nelems--) c->l.upvals[nelems] = NULL; |
| 39 | return c; | 40 | return c; |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lfunc.h,v 2.1 2003/12/10 12:13:36 roberto Exp $ | 2 | ** $Id: lfunc.h,v 2.2 2005/01/18 17:18:09 roberto Exp roberto $ |
| 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 | */ |
| @@ -19,8 +19,8 @@ | |||
| 19 | 19 | ||
| 20 | 20 | ||
| 21 | Proto *luaF_newproto (lua_State *L); | 21 | Proto *luaF_newproto (lua_State *L); |
| 22 | Closure *luaF_newCclosure (lua_State *L, int nelems); | 22 | Closure *luaF_newCclosure (lua_State *L, int nelems, Table *e); |
| 23 | Closure *luaF_newLclosure (lua_State *L, int nelems, TValue *e); | 23 | Closure *luaF_newLclosure (lua_State *L, int nelems, Table *e); |
| 24 | UpVal *luaF_newupval (lua_State *L); | 24 | UpVal *luaF_newupval (lua_State *L); |
| 25 | UpVal *luaF_findupval (lua_State *L, StkId level); | 25 | UpVal *luaF_findupval (lua_State *L, StkId level); |
| 26 | void luaF_close (lua_State *L, StkId level); | 26 | void luaF_close (lua_State *L, StkId level); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lgc.c,v 2.24 2005/02/11 20:03:35 roberto Exp roberto $ | 2 | ** $Id: lgc.c,v 2.25 2005/02/14 13:19:50 roberto Exp roberto $ |
| 3 | ** Garbage Collector | 3 | ** Garbage Collector |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -79,6 +79,7 @@ static void reallymarkobject (global_State *g, GCObject *o) { | |||
| 79 | Table *mt = gco2u(o)->metatable; | 79 | Table *mt = gco2u(o)->metatable; |
| 80 | gray2black(o); /* udata are never gray */ | 80 | gray2black(o); /* udata are never gray */ |
| 81 | if (mt) markobject(g, mt); | 81 | if (mt) markobject(g, mt); |
| 82 | markobject(g, gco2u(o)->env); | ||
| 82 | return; | 83 | return; |
| 83 | } | 84 | } |
| 84 | case LUA_TUPVAL: { | 85 | case LUA_TUPVAL: { |
| @@ -223,6 +224,7 @@ static void traverseproto (global_State *g, Proto *f) { | |||
| 223 | 224 | ||
| 224 | 225 | ||
| 225 | static void traverseclosure (global_State *g, Closure *cl) { | 226 | static void traverseclosure (global_State *g, Closure *cl) { |
| 227 | markobject(g, cl->c.env); | ||
| 226 | if (cl->c.isC) { | 228 | if (cl->c.isC) { |
| 227 | int i; | 229 | int i; |
| 228 | for (i=0; i<cl->c.nupvalues; i++) /* mark its upvalues */ | 230 | for (i=0; i<cl->c.nupvalues; i++) /* mark its upvalues */ |
| @@ -231,7 +233,6 @@ static void traverseclosure (global_State *g, Closure *cl) { | |||
| 231 | else { | 233 | else { |
| 232 | int i; | 234 | int i; |
| 233 | lua_assert(cl->l.nupvalues == cl->l.p->nups); | 235 | lua_assert(cl->l.nupvalues == cl->l.p->nups); |
| 234 | markobject(g, hvalue(&cl->l.g)); | ||
| 235 | markobject(g, cl->l.p); | 236 | markobject(g, cl->l.p); |
| 236 | for (i=0; i<cl->l.nupvalues; i++) /* mark its upvalues */ | 237 | for (i=0; i<cl->l.nupvalues; i++) /* mark its upvalues */ |
| 237 | markobject(g, cl->l.upvals[i]); | 238 | markobject(g, cl->l.upvals[i]); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: linit.c,v 1.7 2004/07/09 14:29:29 roberto Exp roberto $ | 2 | ** $Id: linit.c,v 1.8 2004/07/09 15:47:48 roberto Exp roberto $ |
| 3 | ** Initialization of libraries for lua.c | 3 | ** Initialization of libraries for lua.c |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -32,6 +32,8 @@ LUALIB_API int luaopen_stdlibs (lua_State *L) { | |||
| 32 | for (; lib->func; lib++) { | 32 | for (; lib->func; lib++) { |
| 33 | lib->func(L); /* open library */ | 33 | lib->func(L); /* open library */ |
| 34 | lua_settop(L, 0); /* discard any results */ | 34 | lua_settop(L, 0); /* discard any results */ |
| 35 | lua_pushvalue(L, LUA_GLOBALSINDEX); | ||
| 36 | lua_replace(L, LUA_ENVIRONINDEX); /* restore environment */ | ||
| 35 | } | 37 | } |
| 36 | return 0; | 38 | return 0; |
| 37 | } | 39 | } |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: liolib.c,v 2.56 2004/08/09 14:35:59 roberto Exp roberto $ | 2 | ** $Id: liolib.c,v 2.57 2004/08/13 19:52:13 roberto Exp roberto $ |
| 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 | */ |
| @@ -105,8 +105,8 @@ static int aux_close (lua_State *L) { | |||
| 105 | 105 | ||
| 106 | 106 | ||
| 107 | static int io_close (lua_State *L) { | 107 | static int io_close (lua_State *L) { |
| 108 | if (lua_isnone(L, 1) && lua_type(L, lua_upvalueindex(1)) == LUA_TTABLE) | 108 | if (lua_isnone(L, 1)) |
| 109 | lua_rawgeti(L, lua_upvalueindex(1), IO_OUTPUT); | 109 | lua_rawgeti(L, LUA_ENVIRONINDEX, IO_OUTPUT); |
| 110 | return pushresult(L, aux_close(L), NULL); | 110 | return pushresult(L, aux_close(L), NULL); |
| 111 | } | 111 | } |
| 112 | 112 | ||
| @@ -147,7 +147,7 @@ static int io_tmpfile (lua_State *L) { | |||
| 147 | 147 | ||
| 148 | static FILE *getiofile (lua_State *L, int findex) { | 148 | static FILE *getiofile (lua_State *L, int findex) { |
| 149 | FILE *f; | 149 | FILE *f; |
| 150 | lua_rawgeti(L, lua_upvalueindex(1), findex); | 150 | lua_rawgeti(L, LUA_ENVIRONINDEX, findex); |
| 151 | lua_assert(luaL_checkudata(L, -1, LUA_FILEHANDLE)); | 151 | lua_assert(luaL_checkudata(L, -1, LUA_FILEHANDLE)); |
| 152 | f = *(FILE **)lua_touserdata(L, -1); | 152 | f = *(FILE **)lua_touserdata(L, -1); |
| 153 | if (f == NULL) | 153 | if (f == NULL) |
| @@ -170,10 +170,10 @@ static int g_iofile (lua_State *L, int f, const char *mode) { | |||
| 170 | lua_pushvalue(L, 1); | 170 | lua_pushvalue(L, 1); |
| 171 | } | 171 | } |
| 172 | lua_assert(luaL_checkudata(L, -1, LUA_FILEHANDLE)); | 172 | lua_assert(luaL_checkudata(L, -1, LUA_FILEHANDLE)); |
| 173 | lua_rawseti(L, lua_upvalueindex(1), f); | 173 | lua_rawseti(L, LUA_ENVIRONINDEX, f); |
| 174 | } | 174 | } |
| 175 | /* return current value */ | 175 | /* return current value */ |
| 176 | lua_rawgeti(L, lua_upvalueindex(1), f); | 176 | lua_rawgeti(L, LUA_ENVIRONINDEX, f); |
| 177 | return 1; | 177 | return 1; |
| 178 | } | 178 | } |
| 179 | 179 | ||
| @@ -192,10 +192,9 @@ static int io_readline (lua_State *L); | |||
| 192 | 192 | ||
| 193 | 193 | ||
| 194 | static void aux_lines (lua_State *L, int idx, int close) { | 194 | static void aux_lines (lua_State *L, int idx, int close) { |
| 195 | lua_getfield(L, LUA_REGISTRYINDEX, LUA_FILEHANDLE); | ||
| 196 | lua_pushvalue(L, idx); | 195 | lua_pushvalue(L, idx); |
| 197 | lua_pushboolean(L, close); /* close/not close file when finished */ | 196 | lua_pushboolean(L, close); /* close/not close file when finished */ |
| 198 | lua_pushcclosure(L, io_readline, 3); | 197 | lua_pushcclosure(L, io_readline, 2); |
| 199 | } | 198 | } |
| 200 | 199 | ||
| 201 | 200 | ||
| @@ -209,7 +208,7 @@ static int f_lines (lua_State *L) { | |||
| 209 | static int io_lines (lua_State *L) { | 208 | static int io_lines (lua_State *L) { |
| 210 | if (lua_isnoneornil(L, 1)) { /* no arguments? */ | 209 | if (lua_isnoneornil(L, 1)) { /* no arguments? */ |
| 211 | /* will iterate over default input */ | 210 | /* will iterate over default input */ |
| 212 | lua_rawgeti(L, lua_upvalueindex(1), IO_INPUT); | 211 | lua_rawgeti(L, LUA_ENVIRONINDEX, IO_INPUT); |
| 213 | return f_lines(L); | 212 | return f_lines(L); |
| 214 | } | 213 | } |
| 215 | else { | 214 | else { |
| @@ -349,7 +348,7 @@ static int f_read (lua_State *L) { | |||
| 349 | 348 | ||
| 350 | 349 | ||
| 351 | static int io_readline (lua_State *L) { | 350 | static int io_readline (lua_State *L) { |
| 352 | FILE *f = *(FILE **)lua_touserdata(L, lua_upvalueindex(2)); | 351 | FILE *f = *(FILE **)lua_touserdata(L, lua_upvalueindex(1)); |
| 353 | int sucess; | 352 | int sucess; |
| 354 | if (f == NULL) /* file is already closed? */ | 353 | if (f == NULL) /* file is already closed? */ |
| 355 | luaL_error(L, "file is already closed"); | 354 | luaL_error(L, "file is already closed"); |
| @@ -358,9 +357,9 @@ static int io_readline (lua_State *L) { | |||
| 358 | luaL_error(L, "%s", strerror(errno)); | 357 | luaL_error(L, "%s", strerror(errno)); |
| 359 | if (sucess) return 1; | 358 | if (sucess) return 1; |
| 360 | else { /* EOF */ | 359 | else { /* EOF */ |
| 361 | if (lua_toboolean(L, lua_upvalueindex(3))) { /* generator created file? */ | 360 | if (lua_toboolean(L, lua_upvalueindex(2))) { /* generator created file? */ |
| 362 | lua_settop(L, 0); | 361 | lua_settop(L, 0); |
| 363 | lua_pushvalue(L, lua_upvalueindex(2)); | 362 | lua_pushvalue(L, lua_upvalueindex(1)); |
| 364 | aux_close(L); /* close it */ | 363 | aux_close(L); /* close it */ |
| 365 | } | 364 | } |
| 366 | return 0; | 365 | return 0; |
| @@ -489,12 +488,13 @@ LUALIB_API int luaopen_io (lua_State *L) { | |||
| 489 | createmeta(L); | 488 | createmeta(L); |
| 490 | createupval(L); | 489 | createupval(L); |
| 491 | lua_pushvalue(L, -1); | 490 | lua_pushvalue(L, -1); |
| 492 | luaL_openlib(L, LUA_IOLIBNAME, iolib, 1); | 491 | lua_replace(L, LUA_ENVIRONINDEX); |
| 492 | luaL_openlib(L, LUA_IOLIBNAME, iolib, 0); | ||
| 493 | /* put predefined file handles into `io' table */ | 493 | /* put predefined file handles into `io' table */ |
| 494 | lua_rawgeti(L, -2, IO_INPUT); /* get current input from metatable */ | 494 | lua_rawgeti(L, -2, IO_INPUT); /* get current input from upval */ |
| 495 | lua_setfield(L, -2, "stdin"); /* io.stdin = metatable[IO_INPUT] */ | 495 | lua_setfield(L, -2, "stdin"); /* io.stdin = upval[IO_INPUT] */ |
| 496 | lua_rawgeti(L, -2, IO_OUTPUT); /* get current output from metatable */ | 496 | lua_rawgeti(L, -2, IO_OUTPUT); /* get current output from upval */ |
| 497 | lua_setfield(L, -2, "stdout"); /* io.stdout = metatable[IO_OUTPUT] */ | 497 | lua_setfield(L, -2, "stdout"); /* io.stdout = upval[IO_OUTPUT] */ |
| 498 | *newfile(L) = stderr; | 498 | *newfile(L) = stderr; |
| 499 | lua_setfield(L, -2, "stderr"); /* io.stderr = newfile(stderr) */ | 499 | lua_setfield(L, -2, "stderr"); /* io.stderr = newfile(stderr) */ |
| 500 | return 1; | 500 | return 1; |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: loadlib.c,v 1.15 2004/12/29 18:56:34 roberto Exp roberto $ | 2 | ** $Id: loadlib.c,v 1.16 2005/01/14 14:17:18 roberto Exp roberto $ |
| 3 | ** Dynamic library loader for Lua | 3 | ** Dynamic library loader for Lua |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | * | 5 | * |
| @@ -302,7 +302,7 @@ static int loader_Lua (lua_State *L) { | |||
| 302 | path = lua_tostring(L, -1); | 302 | path = lua_tostring(L, -1); |
| 303 | if (!path) { | 303 | if (!path) { |
| 304 | lua_pop(L, 1); | 304 | lua_pop(L, 1); |
| 305 | luaL_getfield(L, LUA_REGISTRYINDEX, "_PACKAGE.path"); | 305 | lua_getfield(L, LUA_ENVIRONINDEX, "path"); |
| 306 | path = lua_tostring(L, -1); | 306 | path = lua_tostring(L, -1); |
| 307 | } | 307 | } |
| 308 | if (path == NULL) | 308 | if (path == NULL) |
| @@ -320,7 +320,7 @@ static int loader_C (lua_State *L) { | |||
| 320 | const char *fname = luaL_gsub(L, name, ".", LUA_DIRSEP); | 320 | const char *fname = luaL_gsub(L, name, ".", LUA_DIRSEP); |
| 321 | const char *path; | 321 | const char *path; |
| 322 | const char *funcname; | 322 | const char *funcname; |
| 323 | luaL_getfield(L, LUA_REGISTRYINDEX, "_PACKAGE.cpath"); | 323 | lua_getfield(L, LUA_ENVIRONINDEX, "cpath"); |
| 324 | path = lua_tostring(L, -1); | 324 | path = lua_tostring(L, -1); |
| 325 | if (path == NULL) | 325 | if (path == NULL) |
| 326 | luaL_error(L, "`package.cpath' must be a string"); | 326 | luaL_error(L, "`package.cpath' must be a string"); |
| @@ -335,7 +335,7 @@ static int loader_C (lua_State *L) { | |||
| 335 | 335 | ||
| 336 | 336 | ||
| 337 | static int loader_preload (lua_State *L) { | 337 | static int loader_preload (lua_State *L) { |
| 338 | luaL_getfield(L, LUA_REGISTRYINDEX, "_PACKAGE.preload"); | 338 | lua_getfield(L, LUA_ENVIRONINDEX, "preload"); |
| 339 | if (!lua_istable(L, -1)) | 339 | if (!lua_istable(L, -1)) |
| 340 | luaL_error(L, "`package.preload' must be a table"); | 340 | luaL_error(L, "`package.preload' must be a table"); |
| 341 | lua_getfield(L, -1, luaL_checkstring(L, 1)); | 341 | lua_getfield(L, -1, luaL_checkstring(L, 1)); |
| @@ -355,7 +355,7 @@ static int ll_require (lua_State *L) { | |||
| 355 | lua_pushboolean(L, 1); | 355 | lua_pushboolean(L, 1); |
| 356 | lua_setfield(L, 2, name); /* _LOADED[name] = true */ | 356 | lua_setfield(L, 2, name); /* _LOADED[name] = true */ |
| 357 | /* iterate over available loaders */ | 357 | /* iterate over available loaders */ |
| 358 | luaL_getfield(L, LUA_REGISTRYINDEX, "_PACKAGE.loaders"); | 358 | lua_getfield(L, LUA_ENVIRONINDEX, "loaders"); |
| 359 | if (!lua_istable(L, -1)) | 359 | if (!lua_istable(L, -1)) |
| 360 | luaL_error(L, "`package.loaders' must be a table"); | 360 | luaL_error(L, "`package.loaders' must be a table"); |
| 361 | for (i=1;; i++) { | 361 | for (i=1;; i++) { |
| @@ -457,6 +457,8 @@ LUALIB_API int luaopen_loadlib (lua_State *L) { | |||
| 457 | lua_setglobal(L, "package"); | 457 | lua_setglobal(L, "package"); |
| 458 | lua_pushvalue(L, -1); | 458 | lua_pushvalue(L, -1); |
| 459 | lua_setfield(L, LUA_REGISTRYINDEX, "_PACKAGE"); | 459 | lua_setfield(L, LUA_REGISTRYINDEX, "_PACKAGE"); |
| 460 | lua_pushvalue(L, -1); | ||
| 461 | lua_replace(L, LUA_ENVIRONINDEX); | ||
| 460 | /* create `loaders' table */ | 462 | /* create `loaders' table */ |
| 461 | lua_newtable(L); | 463 | lua_newtable(L); |
| 462 | /* fill it with pre-defined loaders */ | 464 | /* fill it with pre-defined loaders */ |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lobject.h,v 2.9 2005/01/05 18:20:51 roberto Exp $ | 2 | ** $Id: lobject.h,v 2.10 2005/01/18 17:18:09 roberto Exp roberto $ |
| 3 | ** Type definitions for Lua objects | 3 | ** Type definitions for Lua objects |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -218,6 +218,7 @@ typedef union Udata { | |||
| 218 | struct { | 218 | struct { |
| 219 | CommonHeader; | 219 | CommonHeader; |
| 220 | struct Table *metatable; | 220 | struct Table *metatable; |
| 221 | struct Table *env; | ||
| 221 | size_t len; | 222 | size_t len; |
| 222 | } uv; | 223 | } uv; |
| 223 | } Udata; | 224 | } Udata; |
| @@ -286,7 +287,8 @@ typedef struct UpVal { | |||
| 286 | */ | 287 | */ |
| 287 | 288 | ||
| 288 | #define ClosureHeader \ | 289 | #define ClosureHeader \ |
| 289 | CommonHeader; lu_byte isC; lu_byte nupvalues; GCObject *gclist | 290 | CommonHeader; lu_byte isC; lu_byte nupvalues; GCObject *gclist; \ |
| 291 | struct Table *env | ||
| 290 | 292 | ||
| 291 | typedef struct CClosure { | 293 | typedef struct CClosure { |
| 292 | ClosureHeader; | 294 | ClosureHeader; |
| @@ -298,7 +300,6 @@ typedef struct CClosure { | |||
| 298 | typedef struct LClosure { | 300 | typedef struct LClosure { |
| 299 | ClosureHeader; | 301 | ClosureHeader; |
| 300 | struct Proto *p; | 302 | struct Proto *p; |
| 301 | TValue g; /* global table for this closure */ | ||
| 302 | UpVal *upvals[1]; | 303 | UpVal *upvals[1]; |
| 303 | } LClosure; | 304 | } LClosure; |
| 304 | 305 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lstate.h,v 2.13 2005/01/18 17:18:09 roberto Exp roberto $ | 2 | ** $Id: lstate.h,v 2.14 2005/02/11 20:03:35 roberto Exp roberto $ |
| 3 | ** Global State | 3 | ** Global State |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -116,6 +116,7 @@ struct lua_State { | |||
| 116 | int hookcount; | 116 | int hookcount; |
| 117 | lua_Hook hook; | 117 | lua_Hook hook; |
| 118 | TValue _gt; /* table of globals */ | 118 | TValue _gt; /* table of globals */ |
| 119 | TValue env; /* temporary place for environments */ | ||
| 119 | GCObject *openupval; /* list of open upvalues in this stack */ | 120 | GCObject *openupval; /* list of open upvalues in this stack */ |
| 120 | GCObject *gclist; | 121 | GCObject *gclist; |
| 121 | struct lua_longjmp *errorJmp; /* current error recover point */ | 122 | struct lua_longjmp *errorJmp; /* current error recover point */ |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lstring.c,v 2.5 2004/11/24 19:16:03 roberto Exp $ | 2 | ** $Id: lstring.c,v 2.6 2005/01/18 17:18:09 roberto Exp roberto $ |
| 3 | ** String table (keeps all strings handled by Lua) | 3 | ** String table (keeps all strings handled by Lua) |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -93,7 +93,7 @@ TString *luaS_newlstr (lua_State *L, const char *str, size_t l) { | |||
| 93 | } | 93 | } |
| 94 | 94 | ||
| 95 | 95 | ||
| 96 | Udata *luaS_newudata (lua_State *L, size_t s) { | 96 | Udata *luaS_newudata (lua_State *L, size_t s, Table *e) { |
| 97 | Udata *u; | 97 | Udata *u; |
| 98 | if (s > MAX_SIZET - sizeof(Udata)) | 98 | if (s > MAX_SIZET - sizeof(Udata)) |
| 99 | luaM_toobig(L); | 99 | luaM_toobig(L); |
| @@ -102,6 +102,7 @@ Udata *luaS_newudata (lua_State *L, size_t s) { | |||
| 102 | u->uv.tt = LUA_TUSERDATA; | 102 | u->uv.tt = LUA_TUSERDATA; |
| 103 | u->uv.len = s; | 103 | u->uv.len = s; |
| 104 | u->uv.metatable = NULL; | 104 | u->uv.metatable = NULL; |
| 105 | u->uv.env = e; | ||
| 105 | /* chain it on udata list (after main thread) */ | 106 | /* chain it on udata list (after main thread) */ |
| 106 | u->uv.next = G(L)->mainthread->next; | 107 | u->uv.next = G(L)->mainthread->next; |
| 107 | G(L)->mainthread->next = obj2gco(u); | 108 | G(L)->mainthread->next = obj2gco(u); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lstring.h,v 1.39 2004/08/24 20:12:06 roberto Exp roberto $ | 2 | ** $Id: lstring.h,v 1.40 2004/11/19 15:52:40 roberto Exp roberto $ |
| 3 | ** String table (keep all strings handled by Lua) | 3 | ** String table (keep all strings handled by Lua) |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -24,7 +24,7 @@ | |||
| 24 | #define luaS_fix(s) setbit((s)->tsv.marked, FIXEDBIT) | 24 | #define luaS_fix(s) setbit((s)->tsv.marked, FIXEDBIT) |
| 25 | 25 | ||
| 26 | void luaS_resize (lua_State *L, int newsize); | 26 | void luaS_resize (lua_State *L, int newsize); |
| 27 | Udata *luaS_newudata (lua_State *L, size_t s); | 27 | Udata *luaS_newudata (lua_State *L, size_t s, Table *e); |
| 28 | TString *luaS_newlstr (lua_State *L, const char *str, size_t l); | 28 | TString *luaS_newlstr (lua_State *L, const char *str, size_t l); |
| 29 | 29 | ||
| 30 | 30 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ltests.c,v 2.17 2005/01/14 14:19:42 roberto Exp $ | 2 | ** $Id: ltests.c,v 2.19 2005/01/19 15:54:26 roberto Exp roberto $ |
| 3 | ** Internal Module for Debugging of the Lua Implementation | 3 | ** Internal Module for Debugging of the Lua Implementation |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -249,6 +249,7 @@ static void checkproto (global_State *g, Proto *f) { | |||
| 249 | 249 | ||
| 250 | static void checkclosure (global_State *g, Closure *cl) { | 250 | static void checkclosure (global_State *g, Closure *cl) { |
| 251 | GCObject *clgc = obj2gco(cl); | 251 | GCObject *clgc = obj2gco(cl); |
| 252 | checkobjref(g, clgc, cl->l.env); | ||
| 252 | if (cl->c.isC) { | 253 | if (cl->c.isC) { |
| 253 | int i; | 254 | int i; |
| 254 | for (i=0; i<cl->c.nupvalues; i++) | 255 | for (i=0; i<cl->c.nupvalues; i++) |
| @@ -257,7 +258,6 @@ static void checkclosure (global_State *g, Closure *cl) { | |||
| 257 | else { | 258 | else { |
| 258 | int i; | 259 | int i; |
| 259 | lua_assert(cl->l.nupvalues == cl->l.p->nups); | 260 | lua_assert(cl->l.nupvalues == cl->l.p->nups); |
| 260 | checkobjref(g, clgc, hvalue(&cl->l.g)); | ||
| 261 | checkobjref(g, clgc, cl->l.p); | 261 | checkobjref(g, clgc, cl->l.p); |
| 262 | for (i=0; i<cl->l.nupvalues; i++) { | 262 | for (i=0; i<cl->l.nupvalues; i++) { |
| 263 | if (cl->l.upvals[i]) { | 263 | if (cl->l.upvals[i]) { |
| @@ -622,20 +622,6 @@ static int unref (lua_State *L) { | |||
| 622 | return 0; | 622 | return 0; |
| 623 | } | 623 | } |
| 624 | 624 | ||
| 625 | static int metatable (lua_State *L) { | ||
| 626 | luaL_checkany(L, 1); | ||
| 627 | if (lua_isnone(L, 2)) { | ||
| 628 | if (lua_getmetatable(L, 1) == 0) | ||
| 629 | lua_pushnil(L); | ||
| 630 | } | ||
| 631 | else { | ||
| 632 | lua_settop(L, 2); | ||
| 633 | luaL_checktype(L, 2, LUA_TTABLE); | ||
| 634 | lua_setmetatable(L, 1); | ||
| 635 | } | ||
| 636 | return 1; | ||
| 637 | } | ||
| 638 | |||
| 639 | 625 | ||
| 640 | static int upvalue (lua_State *L) { | 626 | static int upvalue (lua_State *L) { |
| 641 | int n = luaL_checkint(L, 2); | 627 | int n = luaL_checkint(L, 2); |
| @@ -814,10 +800,22 @@ static const char *getname_aux (char *buff, const char **pc) { | |||
| 814 | } | 800 | } |
| 815 | 801 | ||
| 816 | 802 | ||
| 803 | static int getindex_aux (lua_State *L, const char **pc) { | ||
| 804 | skip(pc); | ||
| 805 | switch (*(*pc)++) { | ||
| 806 | case 'R': return LUA_REGISTRYINDEX; | ||
| 807 | case 'G': return LUA_GLOBALSINDEX; | ||
| 808 | case 'E': return LUA_ENVIRONINDEX; | ||
| 809 | case 'U': return lua_upvalueindex(getnum_aux(L, pc)); | ||
| 810 | default: (*pc)--; return getnum_aux(L, pc); | ||
| 811 | } | ||
| 812 | } | ||
| 813 | |||
| 817 | #define EQ(s1) (strcmp(s1, inst) == 0) | 814 | #define EQ(s1) (strcmp(s1, inst) == 0) |
| 818 | 815 | ||
| 819 | #define getnum (getnum_aux(L, &pc)) | 816 | #define getnum (getnum_aux(L, &pc)) |
| 820 | #define getname (getname_aux(buff, &pc)) | 817 | #define getname (getname_aux(buff, &pc)) |
| 818 | #define getindex (getindex_aux(L, &pc)) | ||
| 821 | 819 | ||
| 822 | 820 | ||
| 823 | static int testC (lua_State *L) { | 821 | static int testC (lua_State *L) { |
| @@ -836,44 +834,44 @@ static int testC (lua_State *L) { | |||
| 836 | const char *inst = getname; | 834 | const char *inst = getname; |
| 837 | if EQ("") return 0; | 835 | if EQ("") return 0; |
| 838 | else if EQ("isnumber") { | 836 | else if EQ("isnumber") { |
| 839 | lua_pushinteger(L1, lua_isnumber(L1, getnum)); | 837 | lua_pushinteger(L1, lua_isnumber(L1, getindex)); |
| 840 | } | 838 | } |
| 841 | else if EQ("isstring") { | 839 | else if EQ("isstring") { |
| 842 | lua_pushinteger(L1, lua_isstring(L1, getnum)); | 840 | lua_pushinteger(L1, lua_isstring(L1, getindex)); |
| 843 | } | 841 | } |
| 844 | else if EQ("istable") { | 842 | else if EQ("istable") { |
| 845 | lua_pushinteger(L1, lua_istable(L1, getnum)); | 843 | lua_pushinteger(L1, lua_istable(L1, getindex)); |
| 846 | } | 844 | } |
| 847 | else if EQ("iscfunction") { | 845 | else if EQ("iscfunction") { |
| 848 | lua_pushinteger(L1, lua_iscfunction(L1, getnum)); | 846 | lua_pushinteger(L1, lua_iscfunction(L1, getindex)); |
| 849 | } | 847 | } |
| 850 | else if EQ("isfunction") { | 848 | else if EQ("isfunction") { |
| 851 | lua_pushinteger(L1, lua_isfunction(L1, getnum)); | 849 | lua_pushinteger(L1, lua_isfunction(L1, getindex)); |
| 852 | } | 850 | } |
| 853 | else if EQ("isuserdata") { | 851 | else if EQ("isuserdata") { |
| 854 | lua_pushinteger(L1, lua_isuserdata(L1, getnum)); | 852 | lua_pushinteger(L1, lua_isuserdata(L1, getindex)); |
| 855 | } | 853 | } |
| 856 | else if EQ("isudataval") { | 854 | else if EQ("isudataval") { |
| 857 | lua_pushinteger(L1, lua_islightuserdata(L1, getnum)); | 855 | lua_pushinteger(L1, lua_islightuserdata(L1, getindex)); |
| 858 | } | 856 | } |
| 859 | else if EQ("isnil") { | 857 | else if EQ("isnil") { |
| 860 | lua_pushinteger(L1, lua_isnil(L1, getnum)); | 858 | lua_pushinteger(L1, lua_isnil(L1, getindex)); |
| 861 | } | 859 | } |
| 862 | else if EQ("isnull") { | 860 | else if EQ("isnull") { |
| 863 | lua_pushinteger(L1, lua_isnone(L1, getnum)); | 861 | lua_pushinteger(L1, lua_isnone(L1, getindex)); |
| 864 | } | 862 | } |
| 865 | else if EQ("tonumber") { | 863 | else if EQ("tonumber") { |
| 866 | lua_pushnumber(L1, lua_tonumber(L1, getnum)); | 864 | lua_pushnumber(L1, lua_tonumber(L1, getindex)); |
| 867 | } | 865 | } |
| 868 | else if EQ("tostring") { | 866 | else if EQ("tostring") { |
| 869 | const char *s = lua_tostring(L1, getnum); | 867 | const char *s = lua_tostring(L1, getindex); |
| 870 | lua_pushstring(L1, s); | 868 | lua_pushstring(L1, s); |
| 871 | } | 869 | } |
| 872 | else if EQ("objsize") { | 870 | else if EQ("objsize") { |
| 873 | lua_pushinteger(L1, lua_objsize(L1, getnum)); | 871 | lua_pushinteger(L1, lua_objsize(L1, getindex)); |
| 874 | } | 872 | } |
| 875 | else if EQ("tocfunction") { | 873 | else if EQ("tocfunction") { |
| 876 | lua_pushcfunction(L1, lua_tocfunction(L1, getnum)); | 874 | lua_pushcfunction(L1, lua_tocfunction(L1, getindex)); |
| 877 | } | 875 | } |
| 878 | else if EQ("return") { | 876 | else if EQ("return") { |
| 879 | return getnum; | 877 | return getnum; |
| @@ -899,11 +897,14 @@ static int testC (lua_State *L) { | |||
| 899 | else if EQ("pushbool") { | 897 | else if EQ("pushbool") { |
| 900 | lua_pushboolean(L1, getnum); | 898 | lua_pushboolean(L1, getnum); |
| 901 | } | 899 | } |
| 900 | else if EQ("newuserdata") { | ||
| 901 | lua_newuserdata(L1, getnum); | ||
| 902 | } | ||
| 902 | else if EQ("tobool") { | 903 | else if EQ("tobool") { |
| 903 | lua_pushinteger(L1, lua_toboolean(L1, getnum)); | 904 | lua_pushinteger(L1, lua_toboolean(L1, getindex)); |
| 904 | } | 905 | } |
| 905 | else if EQ("pushvalue") { | 906 | else if EQ("pushvalue") { |
| 906 | lua_pushvalue(L1, getnum); | 907 | lua_pushvalue(L1, getindex); |
| 907 | } | 908 | } |
| 908 | else if EQ("pushcclosure") { | 909 | else if EQ("pushcclosure") { |
| 909 | lua_pushcclosure(L1, testC, getnum); | 910 | lua_pushcclosure(L1, testC, getnum); |
| @@ -915,13 +916,13 @@ static int testC (lua_State *L) { | |||
| 915 | lua_insert(L1, getnum); | 916 | lua_insert(L1, getnum); |
| 916 | } | 917 | } |
| 917 | else if EQ("replace") { | 918 | else if EQ("replace") { |
| 918 | lua_replace(L1, getnum); | 919 | lua_replace(L1, getindex); |
| 919 | } | 920 | } |
| 920 | else if EQ("gettable") { | 921 | else if EQ("gettable") { |
| 921 | lua_gettable(L1, getnum); | 922 | lua_gettable(L1, getindex); |
| 922 | } | 923 | } |
| 923 | else if EQ("settable") { | 924 | else if EQ("settable") { |
| 924 | lua_settable(L1, getnum); | 925 | lua_settable(L1, getindex); |
| 925 | } | 926 | } |
| 926 | else if EQ("next") { | 927 | else if EQ("next") { |
| 927 | lua_next(L1, -2); | 928 | lua_next(L1, -2); |
| @@ -930,12 +931,12 @@ static int testC (lua_State *L) { | |||
| 930 | lua_concat(L1, getnum); | 931 | lua_concat(L1, getnum); |
| 931 | } | 932 | } |
| 932 | else if EQ("lessthan") { | 933 | else if EQ("lessthan") { |
| 933 | int a = getnum; | 934 | int a = getindex; |
| 934 | lua_pushboolean(L1, lua_lessthan(L1, a, getnum)); | 935 | lua_pushboolean(L1, lua_lessthan(L1, a, getindex)); |
| 935 | } | 936 | } |
| 936 | else if EQ("equal") { | 937 | else if EQ("equal") { |
| 937 | int a = getnum; | 938 | int a = getindex; |
| 938 | lua_pushboolean(L1, lua_equal(L1, a, getnum)); | 939 | lua_pushboolean(L1, lua_equal(L1, a, getindex)); |
| 939 | } | 940 | } |
| 940 | else if EQ("rawcall") { | 941 | else if EQ("rawcall") { |
| 941 | int narg = getnum; | 942 | int narg = getnum; |
| @@ -956,21 +957,21 @@ static int testC (lua_State *L) { | |||
| 956 | luaL_loadfile(L1, luaL_checkstring(L1, getnum)); | 957 | luaL_loadfile(L1, luaL_checkstring(L1, getnum)); |
| 957 | } | 958 | } |
| 958 | else if EQ("setmetatable") { | 959 | else if EQ("setmetatable") { |
| 959 | lua_setmetatable(L1, getnum); | 960 | lua_setmetatable(L1, getindex); |
| 960 | } | 961 | } |
| 961 | else if EQ("getmetatable") { | 962 | else if EQ("getmetatable") { |
| 962 | if (lua_getmetatable(L1, getnum) == 0) | 963 | if (lua_getmetatable(L1, getindex) == 0) |
| 963 | lua_pushnil(L1); | 964 | lua_pushnil(L1); |
| 964 | } | 965 | } |
| 965 | else if EQ("type") { | 966 | else if EQ("type") { |
| 966 | lua_pushstring(L1, luaL_typename(L1, getnum)); | 967 | lua_pushstring(L1, luaL_typename(L1, getnum)); |
| 967 | } | 968 | } |
| 968 | else if EQ("getn") { | 969 | else if EQ("getn") { |
| 969 | int i = getnum; | 970 | int i = getindex; |
| 970 | lua_pushinteger(L1, luaL_getn(L1, i)); | 971 | lua_pushinteger(L1, luaL_getn(L1, i)); |
| 971 | } | 972 | } |
| 972 | else if EQ("setn") { | 973 | else if EQ("setn") { |
| 973 | int i = getnum; | 974 | int i = getindex; |
| 974 | int n = cast(int, lua_tonumber(L1, -1)); | 975 | int n = cast(int, lua_tonumber(L1, -1)); |
| 975 | luaL_setn(L1, i, n); | 976 | luaL_setn(L1, i, n); |
| 976 | lua_pop(L1, 1); | 977 | lua_pop(L1, 1); |
| @@ -1095,7 +1096,6 @@ static const struct luaL_reg tests_funcs[] = { | |||
| 1095 | {"unref", unref}, | 1096 | {"unref", unref}, |
| 1096 | {"d2s", d2s}, | 1097 | {"d2s", d2s}, |
| 1097 | {"s2d", s2d}, | 1098 | {"s2d", s2d}, |
| 1098 | {"metatable", metatable}, | ||
| 1099 | {"upvalue", upvalue}, | 1099 | {"upvalue", upvalue}, |
| 1100 | {"newuserdata", newuserdata}, | 1100 | {"newuserdata", newuserdata}, |
| 1101 | {"pushuserdata", pushuserdata}, | 1101 | {"pushuserdata", pushuserdata}, |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lua.h,v 1.200 2005/01/14 14:19:42 roberto Exp roberto $ | 2 | ** $Id: lua.h,v 1.201 2005/01/17 23:50:55 roberto Exp roberto $ |
| 3 | ** Lua - An Extensible Extension Language | 3 | ** Lua - An Extensible Extension Language |
| 4 | ** Tecgraf: Computer Graphics Technology Group, PUC-Rio, Brazil | 4 | ** Tecgraf: Computer Graphics Technology Group, PUC-Rio, Brazil |
| 5 | ** http://www.lua.org mailto:info@lua.org | 5 | ** http://www.lua.org mailto:info@lua.org |
| @@ -34,7 +34,8 @@ | |||
| 34 | ** pseudo-indices | 34 | ** pseudo-indices |
| 35 | */ | 35 | */ |
| 36 | #define LUA_REGISTRYINDEX (-10000) | 36 | #define LUA_REGISTRYINDEX (-10000) |
| 37 | #define LUA_GLOBALSINDEX (-10001) | 37 | #define LUA_ENVIRONINDEX (-10001) |
| 38 | #define LUA_GLOBALSINDEX (-10002) | ||
| 38 | #define lua_upvalueindex(i) (LUA_GLOBALSINDEX-(i)) | 39 | #define lua_upvalueindex(i) (LUA_GLOBALSINDEX-(i)) |
| 39 | 40 | ||
| 40 | 41 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lvm.c,v 2.22 2005/01/10 18:17:39 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 2.23 2005/01/10 18:33:37 roberto Exp roberto $ |
| 3 | ** Lua virtual machine | 3 | ** Lua virtual machine |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -428,9 +428,11 @@ StkId luaV_execute (lua_State *L, int nexeccalls) { | |||
| 428 | continue; | 428 | continue; |
| 429 | } | 429 | } |
| 430 | case OP_GETGLOBAL: { | 430 | case OP_GETGLOBAL: { |
| 431 | TValue g; | ||
| 431 | TValue *rb = KBx(i); | 432 | TValue *rb = KBx(i); |
| 432 | lua_assert(ttisstring(rb) && ttistable(&cl->g)); | 433 | sethvalue(L, &g, cl->env); |
| 433 | base = luaV_gettable(L, &cl->g, rb, ra, pc); /***/ | 434 | lua_assert(ttisstring(rb)); |
| 435 | base = luaV_gettable(L, &g, rb, ra, pc); /***/ | ||
| 434 | continue; | 436 | continue; |
| 435 | } | 437 | } |
| 436 | case OP_GETTABLE: { | 438 | case OP_GETTABLE: { |
| @@ -438,8 +440,10 @@ StkId luaV_execute (lua_State *L, int nexeccalls) { | |||
| 438 | continue; | 440 | continue; |
| 439 | } | 441 | } |
| 440 | case OP_SETGLOBAL: { | 442 | case OP_SETGLOBAL: { |
| 441 | lua_assert(ttisstring(KBx(i)) && ttistable(&cl->g)); | 443 | TValue g; |
| 442 | base = luaV_settable(L, &cl->g, KBx(i), ra, pc); /***/ | 444 | sethvalue(L, &g, cl->env); |
| 445 | lua_assert(ttisstring(KBx(i))); | ||
| 446 | base = luaV_settable(L, &g, KBx(i), ra, pc); /***/ | ||
| 443 | continue; | 447 | continue; |
| 444 | } | 448 | } |
| 445 | case OP_SETUPVAL: { | 449 | case OP_SETUPVAL: { |
| @@ -740,7 +744,7 @@ StkId luaV_execute (lua_State *L, int nexeccalls) { | |||
| 740 | int nup, j; | 744 | int nup, j; |
| 741 | p = cl->p->p[GETARG_Bx(i)]; | 745 | p = cl->p->p[GETARG_Bx(i)]; |
| 742 | nup = p->nups; | 746 | nup = p->nups; |
| 743 | ncl = luaF_newLclosure(L, nup, &cl->g); | 747 | ncl = luaF_newLclosure(L, nup, cl->env); |
| 744 | ncl->l.p = p; | 748 | ncl->l.p = p; |
| 745 | for (j=0; j<nup; j++, pc++) { | 749 | for (j=0; j<nup; j++, pc++) { |
| 746 | if (GET_OPCODE(*pc) == OP_GETUPVAL) | 750 | if (GET_OPCODE(*pc) == OP_GETUPVAL) |
