aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lapi.c62
-rw-r--r--lbaselib.c66
-rw-r--r--ldo.c6
-rw-r--r--lfunc.c5
-rw-r--r--lfunc.h4
-rw-r--r--lgc.c19
-rw-r--r--lobject.h5
-rw-r--r--lua.h8
-rw-r--r--lvm.c12
9 files changed, 121 insertions, 66 deletions
diff --git a/lapi.c b/lapi.c
index 0d27a7e8..f4f56602 100644
--- a/lapi.c
+++ b/lapi.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lapi.c,v 1.199 2002/06/13 13:44:50 roberto Exp roberto $ 2** $Id: lapi.c,v 1.200 2002/06/18 15:19:27 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*/
@@ -487,6 +487,29 @@ LUA_API int lua_getmetatable (lua_State *L, int objindex) {
487} 487}
488 488
489 489
490static LClosure *getfunc (lua_State *L, int level) {
491 CallInfo *ci;
492 TObject *f;
493 if (L->ci - L->base_ci < level) ci = L->base_ci;
494 else ci = L->ci - level;
495 f = ci->base - 1;
496 if (isLfunction(f))
497 return &clvalue(f)->l;
498 else
499 return NULL;
500}
501
502
503LUA_API void lua_getglobals (lua_State *L, int level) {
504 LClosure *f;
505 lua_lock(L);
506 f = getfunc(L, level);
507 setobj(L->top, (f ? &f->g : gt(L)));
508 api_incr_top(L);
509 lua_unlock(L);
510}
511
512
490/* 513/*
491** set functions (stack -> Lua) 514** set functions (stack -> Lua)
492*/ 515*/
@@ -527,27 +550,44 @@ LUA_API void lua_rawseti (lua_State *L, int index, int n) {
527} 550}
528 551
529 552
530LUA_API void lua_setmetatable (lua_State *L, int objindex) { 553LUA_API int lua_setmetatable (lua_State *L, int objindex) {
531 StkId obj, mt; 554 TObject *obj, *mt;
555 int res = 1;
532 lua_lock(L); 556 lua_lock(L);
533 api_checknelems(L, 1); 557 api_checknelems(L, 1);
534 obj = luaA_index(L, objindex); 558 obj = luaA_index(L, objindex);
535 mt = --L->top; 559 mt = (ttype(L->top - 1) != LUA_TNIL) ? L->top - 1 : defaultmeta(L);
536 if (ttype(mt) == LUA_TNIL)
537 mt = defaultmeta(L);
538 api_check(L, ttype(mt) == LUA_TTABLE); 560 api_check(L, ttype(mt) == LUA_TTABLE);
539 switch (ttype(obj)) { 561 switch (ttype(obj)) {
540 case LUA_TTABLE: 562 case LUA_TTABLE: {
541 hvalue(obj)->metatable = hvalue(mt); 563 hvalue(obj)->metatable = hvalue(mt);
542 break; 564 break;
543 case LUA_TUSERDATA: 565 }
566 case LUA_TUSERDATA: {
544 uvalue(obj)->uv.metatable = hvalue(mt); 567 uvalue(obj)->uv.metatable = hvalue(mt);
545 break; 568 break;
546 default: 569 }
547 luaG_runerror(L, "cannot change the meta table of a %s", 570 default: {
548 luaT_typenames[ttype(obj)]); 571 res = 0; /* cannot set */
572 break;
573 }
549 } 574 }
575 L->top--;
576 lua_unlock(L);
577 return res;
578}
579
580
581LUA_API int lua_setglobals (lua_State *L, int level) {
582 LClosure *f;
583 lua_lock(L);
584 api_checknelems(L, 1);
585 f = getfunc(L, level);
586 L->top--;
587 api_check(L, ttype(L->top) == LUA_TTABLE);
588 if (f) f->g = *(L->top);
550 lua_unlock(L); 589 lua_unlock(L);
590 return (f != NULL);
551} 591}
552 592
553 593
diff --git a/lbaselib.c b/lbaselib.c
index 14843ace..67d95f8e 100644
--- a/lbaselib.c
+++ b/lbaselib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lbaselib.c,v 1.81 2002/06/13 13:44:50 roberto Exp roberto $ 2** $Id: lbaselib.c,v 1.82 2002/06/18 15:19:27 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*/
@@ -81,41 +81,51 @@ static int luaB_error (lua_State *L) {
81} 81}
82 82
83 83
84static int luaB_metatable (lua_State *L) { 84static int luaB_getmetatable (lua_State *L) {
85 luaL_check_any(L, 1); 85 luaL_check_any(L, 1);
86 if (lua_isnone(L, 2)) { 86 if (!lua_getmetatable(L, 1))
87 if (!lua_getmetatable(L, 1)) 87 return 0; /* no metatable */
88 return 0; /* no metatable */
89 else {
90 lua_pushliteral(L, "__metatable");
91 lua_rawget(L, -2);
92 if (lua_isnil(L, -1))
93 lua_pop(L, 1);
94 }
95 }
96 else { 88 else {
97 int t = lua_type(L, 2); 89 lua_pushliteral(L, "__metatable");
98 luaL_check_type(L, 1, LUA_TTABLE); 90 lua_rawget(L, -2);
99 luaL_arg_check(L, t == LUA_TNIL || t == LUA_TTABLE, 2, 91 if (lua_isnil(L, -1))
100 "nil or table expected"); 92 lua_pop(L, 1);
101 lua_settop(L, 2); 93 /* otherwise returns metatable.__metatable */
102 lua_setmetatable(L, 1);
103 } 94 }
104 return 1; 95 return 1;
105} 96}
106 97
107 98
108static int luaB_globals (lua_State *L) { 99static int luaB_setmetatable (lua_State *L) {
109 lua_getglobals(L); /* value to be returned */ 100 int t = lua_type(L, 2);
110 if (!lua_isnoneornil(L, 1)) { 101 luaL_check_type(L, 1, LUA_TTABLE);
111 luaL_check_type(L, 1, LUA_TTABLE); 102 luaL_arg_check(L, t == LUA_TNIL || t == LUA_TTABLE, 2,
112 lua_pushvalue(L, 1); /* new table of globals */ 103 "nil or table expected");
113 lua_setglobals(L); 104 lua_settop(L, 2);
114 } 105 lua_setmetatable(L, 1);
115 return 1; 106 return 1;
116} 107}
117 108
118 109
110static int luaB_getglobals (lua_State *L) {
111 int level = luaL_opt_int(L, 1, 1);
112 luaL_arg_check(L, level >= 1, 2, "level must be positive");
113 lua_getglobals(L, level); /* value to be returned */
114 return 1;
115}
116
117
118static int luaB_setglobals (lua_State *L) {
119 int level = luaL_opt_int(L, 2, 1);
120 luaL_arg_check(L, level >= 1, 2, "level must be positive");
121 luaL_check_type(L, 1, LUA_TTABLE);
122 lua_settop(L, 1);
123 if (lua_setglobals(L, level) == 0)
124 luaL_error(L, "cannot change global table at level %d", level);
125 return 0;
126}
127
128
119static int luaB_rawequal (lua_State *L) { 129static int luaB_rawequal (lua_State *L) {
120 luaL_check_any(L, 1); 130 luaL_check_any(L, 1);
121 luaL_check_any(L, 2); 131 luaL_check_any(L, 2);
@@ -385,8 +395,10 @@ static int luaB_require (lua_State *L) {
385 395
386static const luaL_reg base_funcs[] = { 396static const luaL_reg base_funcs[] = {
387 {"error", luaB_error}, 397 {"error", luaB_error},
388 {"metatable", luaB_metatable}, 398 {"getmetatable", luaB_getmetatable},
389 {"globals", luaB_globals}, 399 {"setmetatable", luaB_setmetatable},
400 {"getglobals", luaB_getglobals},
401 {"setglobals", luaB_setglobals},
390 {"next", luaB_next}, 402 {"next", luaB_next},
391 {"nexti", luaB_nexti}, 403 {"nexti", luaB_nexti},
392 {"print", luaB_print}, 404 {"print", luaB_print},
diff --git a/ldo.c b/ldo.c
index be9b3d4d..616a8e75 100644
--- a/ldo.c
+++ b/ldo.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldo.c,v 1.181 2002/06/18 17:10:43 roberto Exp roberto $ 2** $Id: ldo.c,v 1.182 2002/06/18 17:42:52 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*/
@@ -407,7 +407,7 @@ struct SParser { /* data to `f_parser' */
407static void f_parser (lua_State *L, void *ud) { 407static void f_parser (lua_State *L, void *ud) {
408 struct SParser *p = cast(struct SParser *, ud); 408 struct SParser *p = cast(struct SParser *, ud);
409 Proto *tf = p->bin ? luaU_undump(L, p->z) : luaY_parser(L, p->z); 409 Proto *tf = p->bin ? luaU_undump(L, p->z) : luaY_parser(L, p->z);
410 Closure *cl = luaF_newLclosure(L, 0); 410 Closure *cl = luaF_newLclosure(L, 0, gt(L));
411 cl->l.p = tf; 411 cl->l.p = tf;
412 setclvalue(L->top, cl); 412 setclvalue(L->top, cl);
413 incr_top(L); 413 incr_top(L);
@@ -467,8 +467,8 @@ static void seterrorobj (lua_State *L, int errcode, TObject *m) {
467 467
468 468
469void luaD_throw (lua_State *L, int errcode) { 469void luaD_throw (lua_State *L, int errcode) {
470 seterrorobj(L, errcode, L->errorJmp->err);
471 if (L->errorJmp) { 470 if (L->errorJmp) {
471 seterrorobj(L, errcode, L->errorJmp->err);
472 L->errorJmp->status = errcode; 472 L->errorJmp->status = errcode;
473 longjmp(L->errorJmp->b, 1); 473 longjmp(L->errorJmp->b, 1);
474 } 474 }
diff --git a/lfunc.c b/lfunc.c
index 720fb6e4..e973d850 100644
--- a/lfunc.c
+++ b/lfunc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lfunc.c,v 1.55 2002/03/25 17:47:14 roberto Exp roberto $ 2** $Id: lfunc.c,v 1.56 2002/05/02 13:06:20 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*/
@@ -34,12 +34,13 @@ Closure *luaF_newCclosure (lua_State *L, int nelems) {
34} 34}
35 35
36 36
37Closure *luaF_newLclosure (lua_State *L, int nelems) { 37Closure *luaF_newLclosure (lua_State *L, int nelems, TObject *gt) {
38 Closure *c = cast(Closure *, luaM_malloc(L, sizeLclosure(nelems))); 38 Closure *c = cast(Closure *, luaM_malloc(L, sizeLclosure(nelems)));
39 c->l.isC = 0; 39 c->l.isC = 0;
40 c->c.next = G(L)->rootcl; 40 c->c.next = G(L)->rootcl;
41 G(L)->rootcl = c; 41 G(L)->rootcl = c;
42 c->l.marked = 0; 42 c->l.marked = 0;
43 c->l.g = *gt;
43 c->l.nupvalues = cast(lu_byte, nelems); 44 c->l.nupvalues = cast(lu_byte, nelems);
44 return c; 45 return c;
45} 46}
diff --git a/lfunc.h b/lfunc.h
index f57df4c2..9daf115c 100644
--- a/lfunc.h
+++ b/lfunc.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lfunc.h,v 1.17 2001/10/02 16:45:03 roberto Exp $ 2** $Id: lfunc.h,v 1.19 2001/11/29 20:22:22 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*/
@@ -13,7 +13,7 @@
13 13
14Proto *luaF_newproto (lua_State *L); 14Proto *luaF_newproto (lua_State *L);
15Closure *luaF_newCclosure (lua_State *L, int nelems); 15Closure *luaF_newCclosure (lua_State *L, int nelems);
16Closure *luaF_newLclosure (lua_State *L, int nelems); 16Closure *luaF_newLclosure (lua_State *L, int nelems, TObject *gt);
17UpVal *luaF_findupval (lua_State *L, StkId level); 17UpVal *luaF_findupval (lua_State *L, StkId level);
18void luaF_close (lua_State *L, StkId level); 18void luaF_close (lua_State *L, StkId level);
19void luaF_freeproto (lua_State *L, Proto *f); 19void luaF_freeproto (lua_State *L, Proto *f);
diff --git a/lgc.c b/lgc.c
index 3ca610e6..3f9bcf86 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.c,v 1.135 2002/04/23 15:04:39 roberto Exp roberto $ 2** $Id: lgc.c,v 1.136 2002/05/08 17:34:23 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*/
@@ -72,6 +72,14 @@ static void protomark (Proto *f) {
72} 72}
73 73
74 74
75static void marktable (GCState *st, Table *h) {
76 if (!ismarked(h)) {
77 h->mark = st->tmark; /* chain it for later traversal */
78 st->tmark = h;
79 }
80}
81
82
75static void markclosure (GCState *st, Closure *cl) { 83static void markclosure (GCState *st, Closure *cl) {
76 if (!cl->c.marked) { 84 if (!cl->c.marked) {
77 cl->c.marked = 1; 85 cl->c.marked = 1;
@@ -83,6 +91,7 @@ static void markclosure (GCState *st, Closure *cl) {
83 else { 91 else {
84 int i; 92 int i;
85 lua_assert(cl->l.nupvalues == cl->l.p->nupvalues); 93 lua_assert(cl->l.nupvalues == cl->l.p->nupvalues);
94 marktable(st, hvalue(&cl->l.g));
86 protomark(cl->l.p); 95 protomark(cl->l.p);
87 for (i=0; i<cl->l.nupvalues; i++) { /* mark its upvalues */ 96 for (i=0; i<cl->l.nupvalues; i++) { /* mark its upvalues */
88 UpVal *u = cl->l.upvals[i]; 97 UpVal *u = cl->l.upvals[i];
@@ -96,14 +105,6 @@ static void markclosure (GCState *st, Closure *cl) {
96} 105}
97 106
98 107
99static void marktable (GCState *st, Table *h) {
100 if (!ismarked(h)) {
101 h->mark = st->tmark; /* chain it for later traversal */
102 st->tmark = h;
103 }
104}
105
106
107static void markudata (GCState *st, Udata *u) { 108static void markudata (GCState *st, Udata *u) {
108 markud(u); 109 markud(u);
109 marktable(st, u->uv.metatable); 110 marktable(st, u->uv.metatable);
diff --git a/lobject.h b/lobject.h
index 8438881f..75610c99 100644
--- a/lobject.h
+++ b/lobject.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lobject.h,v 1.134 2002/06/12 14:56:22 roberto Exp roberto $ 2** $Id: lobject.h,v 1.135 2002/06/13 13:39:55 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*/
@@ -178,6 +178,7 @@ typedef struct LClosure {
178 lu_byte marked; 178 lu_byte marked;
179 union Closure *next; /* first four fields must be equal to CClosure!! */ 179 union Closure *next; /* first four fields must be equal to CClosure!! */
180 struct Proto *p; 180 struct Proto *p;
181 TObject g; /* global table for this closure */
181 UpVal *upvals[1]; 182 UpVal *upvals[1];
182} LClosure; 183} LClosure;
183 184
@@ -189,7 +190,7 @@ typedef union Closure {
189 190
190 191
191#define iscfunction(o) (ttype(o) == LUA_TFUNCTION && clvalue(o)->c.isC) 192#define iscfunction(o) (ttype(o) == LUA_TFUNCTION && clvalue(o)->c.isC)
192 193#define isLfunction(o) (ttype(o) == LUA_TFUNCTION && !clvalue(o)->c.isC)
193 194
194 195
195/* 196/*
diff --git a/lua.h b/lua.h
index fd2856e8..a14d00d7 100644
--- a/lua.h
+++ b/lua.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lua.h,v 1.140 2002/06/13 13:44:50 roberto Exp roberto $ 2** $Id: lua.h,v 1.141 2002/06/18 15:19:27 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
@@ -169,6 +169,7 @@ LUA_API void lua_rawget (lua_State *L, int index);
169LUA_API void lua_rawgeti (lua_State *L, int index, int n); 169LUA_API void lua_rawgeti (lua_State *L, int index, int n);
170LUA_API void lua_newtable (lua_State *L); 170LUA_API void lua_newtable (lua_State *L);
171LUA_API int lua_getmetatable (lua_State *L, int objindex); 171LUA_API int lua_getmetatable (lua_State *L, int objindex);
172LUA_API void lua_getglobals (lua_State *L, int level);
172 173
173 174
174/* 175/*
@@ -177,7 +178,8 @@ LUA_API int lua_getmetatable (lua_State *L, int objindex);
177LUA_API void lua_settable (lua_State *L, int index); 178LUA_API void lua_settable (lua_State *L, int index);
178LUA_API void lua_rawset (lua_State *L, int index); 179LUA_API void lua_rawset (lua_State *L, int index);
179LUA_API void lua_rawseti (lua_State *L, int index, int n); 180LUA_API void lua_rawseti (lua_State *L, int index, int n);
180LUA_API void lua_setmetatable (lua_State *L, int objindex); 181LUA_API int lua_setmetatable (lua_State *L, int objindex);
182LUA_API int lua_setglobals (lua_State *L, int level);
181 183
182 184
183/* 185/*
@@ -259,8 +261,6 @@ LUA_API void *lua_newuserdata (lua_State *L, size_t size);
259LUA_API int lua_pushupvalues (lua_State *L); 261LUA_API int lua_pushupvalues (lua_State *L);
260 262
261#define lua_getregistry(L) lua_pushvalue(L, LUA_REGISTRYINDEX) 263#define lua_getregistry(L) lua_pushvalue(L, LUA_REGISTRYINDEX)
262#define lua_getglobals(L) lua_pushvalue(L, LUA_GLOBALSINDEX)
263#define lua_setglobals(L) lua_replace(L, LUA_GLOBALSINDEX)
264#define lua_setglobal(L,s) \ 264#define lua_setglobal(L,s) \
265 (lua_pushstring(L, s), lua_insert(L, -2), lua_settable(L, LUA_GLOBALSINDEX)) 265 (lua_pushstring(L, s), lua_insert(L, -2), lua_settable(L, LUA_GLOBALSINDEX))
266 266
diff --git a/lvm.c b/lvm.c
index 501c22be..9aeab5b4 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.c,v 1.238 2002/06/13 13:39:55 roberto Exp roberto $ 2** $Id: lvm.c,v 1.239 2002/06/14 17:21:32 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*/
@@ -401,8 +401,8 @@ StkId luaV_execute (lua_State *L) {
401 break; 401 break;
402 } 402 }
403 case OP_GETGLOBAL: { 403 case OP_GETGLOBAL: {
404 lua_assert(ttype(KBx(i)) == LUA_TSTRING); 404 lua_assert(ttype(KBx(i)) == LUA_TSTRING && ttype(&cl->g) == LUA_TTABLE);
405 luaV_gettable(L, gt(L), KBx(i), ra); 405 luaV_gettable(L, &cl->g, KBx(i), ra);
406 break; 406 break;
407 } 407 }
408 case OP_GETTABLE: { 408 case OP_GETTABLE: {
@@ -410,8 +410,8 @@ StkId luaV_execute (lua_State *L) {
410 break; 410 break;
411 } 411 }
412 case OP_SETGLOBAL: { 412 case OP_SETGLOBAL: {
413 lua_assert(ttype(KBx(i)) == LUA_TSTRING); 413 lua_assert(ttype(KBx(i)) == LUA_TSTRING && ttype(&cl->g) == LUA_TTABLE);
414 luaV_settable(L, gt(L), KBx(i), ra); 414 luaV_settable(L, &cl->g, KBx(i), ra);
415 break; 415 break;
416 } 416 }
417 case OP_SETUPVAL: { 417 case OP_SETUPVAL: {
@@ -642,7 +642,7 @@ StkId luaV_execute (lua_State *L) {
642 int nup, j; 642 int nup, j;
643 p = cl->p->p[GETARG_Bx(i)]; 643 p = cl->p->p[GETARG_Bx(i)];
644 nup = p->nupvalues; 644 nup = p->nupvalues;
645 ncl = luaF_newLclosure(L, nup); 645 ncl = luaF_newLclosure(L, nup, &cl->g);
646 ncl->l.p = p; 646 ncl->l.p = p;
647 for (j=0; j<nup; j++, pc++) { 647 for (j=0; j<nup; j++, pc++) {
648 if (GET_OPCODE(*pc) == OP_GETUPVAL) 648 if (GET_OPCODE(*pc) == OP_GETUPVAL)