summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lapi.c66
-rw-r--r--lbaselib.c11
-rw-r--r--ldblib.c40
-rw-r--r--ldo.c4
-rw-r--r--lfunc.c9
-rw-r--r--lfunc.h6
-rw-r--r--lgc.c5
-rw-r--r--linit.c4
-rw-r--r--liolib.c34
-rw-r--r--loadlib.c12
-rw-r--r--lobject.h7
-rw-r--r--lstate.h3
-rw-r--r--lstring.c5
-rw-r--r--lstring.h4
-rw-r--r--ltests.c86
-rw-r--r--lua.h5
-rw-r--r--lvm.c16
17 files changed, 206 insertions, 111 deletions
diff --git a/lapi.c b/lapi.c
index f82b00dc..b08fa6ad 100644
--- a/lapi.c
+++ b/lapi.c
@@ -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
78static 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
73void luaA_pushobject (lua_State *L, const TValue *o) { 88void 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
683LUA_API int lua_setfenv (lua_State *L, int idx) { 716LUA_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' */
776static void f_Ccall (lua_State *L, void *ud) { 816static 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);
diff --git a/lbaselib.c b/lbaselib.c
index ae3ad956..7acbba4b 100644
--- a/lbaselib.c
+++ b/lbaselib.c
@@ -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
132static int luaB_getfenv (lua_State *L) { 132static 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
diff --git a/ldblib.c b/ldblib.c
index 919b2766..1686339a 100644
--- a/ldblib.c
+++ b/ldblib.c
@@ -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
22static 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
31static 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
41static int getfenv (lua_State *L) {
42 lua_getfenv(L, 1);
43 return 1;
44}
45
46
47static 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
22static void settabss (lua_State *L, const char *i, const char *v) { 56static 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
330static const luaL_reg dblib[] = { 364static 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},
diff --git a/ldo.c b/ldo.c
index 3dcb5ba9..a96cc388 100644
--- a/ldo.c
+++ b/ldo.c
@@ -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);
diff --git a/lfunc.c b/lfunc.c
index d69f75dd..9631f5dc 100644
--- a/lfunc.c
+++ b/lfunc.c
@@ -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
23Closure *luaF_newCclosure (lua_State *L, int nelems) { 23Closure *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
32Closure *luaF_newLclosure (lua_State *L, int nelems, TValue *e) { 33Closure *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;
diff --git a/lfunc.h b/lfunc.h
index fb542716..a69b5327 100644
--- a/lfunc.h
+++ b/lfunc.h
@@ -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
21Proto *luaF_newproto (lua_State *L); 21Proto *luaF_newproto (lua_State *L);
22Closure *luaF_newCclosure (lua_State *L, int nelems); 22Closure *luaF_newCclosure (lua_State *L, int nelems, Table *e);
23Closure *luaF_newLclosure (lua_State *L, int nelems, TValue *e); 23Closure *luaF_newLclosure (lua_State *L, int nelems, Table *e);
24UpVal *luaF_newupval (lua_State *L); 24UpVal *luaF_newupval (lua_State *L);
25UpVal *luaF_findupval (lua_State *L, StkId level); 25UpVal *luaF_findupval (lua_State *L, StkId level);
26void luaF_close (lua_State *L, StkId level); 26void luaF_close (lua_State *L, StkId level);
diff --git a/lgc.c b/lgc.c
index 127260c9..da03498a 100644
--- a/lgc.c
+++ b/lgc.c
@@ -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
225static void traverseclosure (global_State *g, Closure *cl) { 226static 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]);
diff --git a/linit.c b/linit.c
index a50b894e..da414468 100644
--- a/linit.c
+++ b/linit.c
@@ -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}
diff --git a/liolib.c b/liolib.c
index 4663dd78..87cc77e8 100644
--- a/liolib.c
+++ b/liolib.c
@@ -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
107static int io_close (lua_State *L) { 107static 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
148static FILE *getiofile (lua_State *L, int findex) { 148static 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
194static void aux_lines (lua_State *L, int idx, int close) { 194static 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) {
209static int io_lines (lua_State *L) { 208static 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
351static int io_readline (lua_State *L) { 350static 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;
diff --git a/loadlib.c b/loadlib.c
index 2c1d87f2..1fe4fc38 100644
--- a/loadlib.c
+++ b/loadlib.c
@@ -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
337static int loader_preload (lua_State *L) { 337static 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 */
diff --git a/lobject.h b/lobject.h
index 0c781ef3..ab0ddee7 100644
--- a/lobject.h
+++ b/lobject.h
@@ -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
291typedef struct CClosure { 293typedef struct CClosure {
292 ClosureHeader; 294 ClosureHeader;
@@ -298,7 +300,6 @@ typedef struct CClosure {
298typedef struct LClosure { 300typedef 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
diff --git a/lstate.h b/lstate.h
index 2ba5a91d..995733d9 100644
--- a/lstate.h
+++ b/lstate.h
@@ -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 */
diff --git a/lstring.c b/lstring.c
index 0c82220e..768d064f 100644
--- a/lstring.c
+++ b/lstring.c
@@ -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
96Udata *luaS_newudata (lua_State *L, size_t s) { 96Udata *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);
diff --git a/lstring.h b/lstring.h
index ec2972a1..1d2d752e 100644
--- a/lstring.h
+++ b/lstring.h
@@ -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
26void luaS_resize (lua_State *L, int newsize); 26void luaS_resize (lua_State *L, int newsize);
27Udata *luaS_newudata (lua_State *L, size_t s); 27Udata *luaS_newudata (lua_State *L, size_t s, Table *e);
28TString *luaS_newlstr (lua_State *L, const char *str, size_t l); 28TString *luaS_newlstr (lua_State *L, const char *str, size_t l);
29 29
30 30
diff --git a/ltests.c b/ltests.c
index 8686fa73..620b6a41 100644
--- a/ltests.c
+++ b/ltests.c
@@ -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
250static void checkclosure (global_State *g, Closure *cl) { 250static 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
625static 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
640static int upvalue (lua_State *L) { 626static 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
803static 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
823static int testC (lua_State *L) { 821static 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},
diff --git a/lua.h b/lua.h
index b3d7e83e..ac02d433 100644
--- a/lua.h
+++ b/lua.h
@@ -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
diff --git a/lvm.c b/lvm.c
index 9592a11a..9ab8aa38 100644
--- a/lvm.c
+++ b/lvm.c
@@ -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)