diff options
-rw-r--r-- | lapi.c | 48 | ||||
-rw-r--r-- | ldblib.c | 28 | ||||
-rw-r--r-- | lfunc.c | 4 | ||||
-rw-r--r-- | lgc.c | 8 | ||||
-rw-r--r-- | lobject.h | 5 | ||||
-rw-r--r-- | lparser.c | 28 | ||||
-rw-r--r-- | lparser.h | 3 | ||||
-rw-r--r-- | ltests.c | 21 | ||||
-rw-r--r-- | lua.h | 4 |
9 files changed, 128 insertions, 21 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lapi.c,v 1.225 2002/12/04 17:28:27 roberto Exp roberto $ | 2 | ** $Id: lapi.c,v 1.226 2002/12/04 17:38:31 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 | */ |
@@ -866,3 +866,49 @@ LUA_API int lua_pushupvalues (lua_State *L) { | |||
866 | } | 866 | } |
867 | 867 | ||
868 | 868 | ||
869 | static const char *aux_upvalue (lua_State *L, int funcindex, int n, | ||
870 | TObject **val) { | ||
871 | Closure *f; | ||
872 | StkId fi = luaA_index(L, funcindex); | ||
873 | if (!ttisfunction(fi)) return NULL; | ||
874 | f = clvalue(fi); | ||
875 | if (n > f->l.nupvalues) return NULL; | ||
876 | if (f->c.isC) { | ||
877 | *val = &f->c.upvalue[n-1]; | ||
878 | return ""; | ||
879 | } | ||
880 | else { | ||
881 | *val = f->l.upvals[n-1]->v; | ||
882 | return getstr(f->l.p->upvalues[n-1]); | ||
883 | } | ||
884 | } | ||
885 | |||
886 | |||
887 | LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) { | ||
888 | const char *name; | ||
889 | TObject *val; | ||
890 | lua_lock(L); | ||
891 | name = aux_upvalue(L, funcindex, n, &val); | ||
892 | if (name) { | ||
893 | setobj2s(L->top, val); | ||
894 | api_incr_top(L); | ||
895 | } | ||
896 | lua_unlock(L); | ||
897 | return name; | ||
898 | } | ||
899 | |||
900 | |||
901 | LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) { | ||
902 | const char *name; | ||
903 | TObject *val; | ||
904 | lua_lock(L); | ||
905 | api_checknelems(L, 1); | ||
906 | name = aux_upvalue(L, funcindex, n, &val); | ||
907 | if (name) { | ||
908 | L->top--; | ||
909 | setobj(val, L->top); /* write barrier */ | ||
910 | } | ||
911 | lua_unlock(L); | ||
912 | return name; | ||
913 | } | ||
914 | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ldblib.c,v 1.74 2002/12/04 17:38:31 roberto Exp roberto $ | 2 | ** $Id: ldblib.c,v 1.75 2002/12/05 17:50:10 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 | */ |
@@ -108,6 +108,30 @@ static int setlocal (lua_State *L) { | |||
108 | } | 108 | } |
109 | 109 | ||
110 | 110 | ||
111 | static int auxupvalue (lua_State *L, int get) { | ||
112 | const char *name; | ||
113 | int n = luaL_checkint(L, 2); | ||
114 | luaL_checktype(L, 1, LUA_TFUNCTION); | ||
115 | if (lua_iscfunction(L, 1)) return 0; /* cannot touch C upvalues from Lua */ | ||
116 | name = get ? lua_getupvalue(L, 1, n) : lua_setupvalue(L, 1, n); | ||
117 | if (name == NULL) return 0; | ||
118 | lua_pushstring(L, name); | ||
119 | lua_insert(L, -(get+1)); | ||
120 | return get + 1; | ||
121 | } | ||
122 | |||
123 | |||
124 | static int getupvalue (lua_State *L) { | ||
125 | return auxupvalue(L, 1); | ||
126 | } | ||
127 | |||
128 | |||
129 | static int setupvalue (lua_State *L) { | ||
130 | luaL_checkany(L, 3); | ||
131 | return auxupvalue(L, 0); | ||
132 | } | ||
133 | |||
134 | |||
111 | 135 | ||
112 | static const char KEY_HOOK = 'h'; | 136 | static const char KEY_HOOK = 'h'; |
113 | 137 | ||
@@ -253,8 +277,10 @@ static const luaL_reg dblib[] = { | |||
253 | {"getlocal", getlocal}, | 277 | {"getlocal", getlocal}, |
254 | {"getinfo", getinfo}, | 278 | {"getinfo", getinfo}, |
255 | {"gethook", gethook}, | 279 | {"gethook", gethook}, |
280 | {"getupvalue", getupvalue}, | ||
256 | {"sethook", sethook}, | 281 | {"sethook", sethook}, |
257 | {"setlocal", setlocal}, | 282 | {"setlocal", setlocal}, |
283 | {"setupvalue", setupvalue}, | ||
258 | {"debug", debug}, | 284 | {"debug", debug}, |
259 | {"traceback", errorfb}, | 285 | {"traceback", errorfb}, |
260 | {NULL, NULL} | 286 | {NULL, NULL} |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lfunc.c,v 1.63 2002/11/14 16:15:53 roberto Exp roberto $ | 2 | ** $Id: lfunc.c,v 1.64 2002/12/04 17:38:31 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 | */ |
@@ -85,6 +85,7 @@ Proto *luaF_newproto (lua_State *L) { | |||
85 | f->sizecode = 0; | 85 | f->sizecode = 0; |
86 | f->sizelineinfo = 0; | 86 | f->sizelineinfo = 0; |
87 | f->nupvalues = 0; | 87 | f->nupvalues = 0; |
88 | f->upvalues = NULL; | ||
88 | f->numparams = 0; | 89 | f->numparams = 0; |
89 | f->is_vararg = 0; | 90 | f->is_vararg = 0; |
90 | f->maxstacksize = 0; | 91 | f->maxstacksize = 0; |
@@ -103,6 +104,7 @@ void luaF_freeproto (lua_State *L, Proto *f) { | |||
103 | luaM_freearray(L, f->k, f->sizek, TObject); | 104 | luaM_freearray(L, f->k, f->sizek, TObject); |
104 | luaM_freearray(L, f->lineinfo, f->sizelineinfo, int); | 105 | luaM_freearray(L, f->lineinfo, f->sizelineinfo, int); |
105 | luaM_freearray(L, f->locvars, f->sizelocvars, struct LocVar); | 106 | luaM_freearray(L, f->locvars, f->sizelocvars, struct LocVar); |
107 | luaM_freearray(L, f->upvalues, f->nupvalues, TString *); | ||
106 | luaM_freelem(L, f); | 108 | luaM_freelem(L, f); |
107 | } | 109 | } |
108 | 110 | ||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lgc.c,v 1.165 2002/12/02 12:06:10 roberto Exp roberto $ | 2 | ** $Id: lgc.c,v 1.166 2002/12/04 17:38:31 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 | */ |
@@ -186,11 +186,13 @@ static void traversetable (GCState *st, Table *h) { | |||
186 | static void traverseproto (GCState *st, Proto *f) { | 186 | static void traverseproto (GCState *st, Proto *f) { |
187 | int i; | 187 | int i; |
188 | stringmark(f->source); | 188 | stringmark(f->source); |
189 | for (i=0; i<f->sizek; i++) { | 189 | for (i=0; i<f->sizek; i++) { /* mark literal strings */ |
190 | if (ttisstring(f->k+i)) | 190 | if (ttisstring(f->k+i)) |
191 | stringmark(tsvalue(f->k+i)); | 191 | stringmark(tsvalue(f->k+i)); |
192 | } | 192 | } |
193 | for (i=0; i<f->sizep; i++) | 193 | for (i=0; i<f->nupvalues; i++) /* mark upvalue names */ |
194 | stringmark(f->upvalues[i]); | ||
195 | for (i=0; i<f->sizep; i++) /* mark nested protos */ | ||
194 | markvalue(st, f->p[i]); | 196 | markvalue(st, f->p[i]); |
195 | for (i=0; i<f->sizelocvars; i++) /* mark local-variable names */ | 197 | for (i=0; i<f->sizelocvars; i++) /* mark local-variable names */ |
196 | stringmark(f->locvars[i].varname); | 198 | stringmark(f->locvars[i].varname); |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lobject.h,v 1.154 2002/11/14 11:51:50 roberto Exp roberto $ | 2 | ** $Id: lobject.h,v 1.155 2002/11/14 16:16:21 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 | */ |
@@ -214,7 +214,9 @@ typedef struct Proto { | |||
214 | struct Proto **p; /* functions defined inside the function */ | 214 | struct Proto **p; /* functions defined inside the function */ |
215 | int *lineinfo; /* map from opcodes to source lines */ | 215 | int *lineinfo; /* map from opcodes to source lines */ |
216 | struct LocVar *locvars; /* information about local variables */ | 216 | struct LocVar *locvars; /* information about local variables */ |
217 | TString **upvalues; /* upvalue names */ | ||
217 | TString *source; | 218 | TString *source; |
219 | int nupvalues; /* (also size of `upvals') */ | ||
218 | int sizek; /* size of `k' */ | 220 | int sizek; /* size of `k' */ |
219 | int sizecode; | 221 | int sizecode; |
220 | int sizelineinfo; | 222 | int sizelineinfo; |
@@ -222,7 +224,6 @@ typedef struct Proto { | |||
222 | int sizelocvars; | 224 | int sizelocvars; |
223 | int lineDefined; | 225 | int lineDefined; |
224 | GCObject *gclist; | 226 | GCObject *gclist; |
225 | lu_byte nupvalues; | ||
226 | lu_byte numparams; | 227 | lu_byte numparams; |
227 | lu_byte is_vararg; | 228 | lu_byte is_vararg; |
228 | lu_byte maxstacksize; | 229 | lu_byte maxstacksize; |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lparser.c,v 1.201 2002/12/06 17:09:00 roberto Exp roberto $ | 2 | ** $Id: lparser.c,v 1.202 2002/12/11 12:34:22 roberto Exp roberto $ |
3 | ** Lua Parser | 3 | ** Lua Parser |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -179,16 +179,21 @@ static void create_local (LexState *ls, const char *name) { | |||
179 | } | 179 | } |
180 | 180 | ||
181 | 181 | ||
182 | static int indexupvalue (FuncState *fs, expdesc *v) { | 182 | static int indexupvalue (FuncState *fs, TString *name, expdesc *v) { |
183 | int i; | 183 | int i; |
184 | for (i=0; i<fs->f->nupvalues; i++) { | 184 | for (i=0; i<fs->nu; i++) { |
185 | if (fs->upvalues[i].k == v->k && fs->upvalues[i].info == v->info) | 185 | if (fs->upvalues[i].k == v->k && fs->upvalues[i].info == v->info) { |
186 | lua_assert(fs->f->upvalues[i] == name); | ||
186 | return i; | 187 | return i; |
188 | } | ||
187 | } | 189 | } |
188 | /* new one */ | 190 | /* new one */ |
189 | luaX_checklimit(fs->ls, fs->f->nupvalues+1, MAXUPVALUES, "upvalues"); | 191 | luaX_checklimit(fs->ls, fs->nu + 1, MAXUPVALUES, "upvalues"); |
190 | fs->upvalues[fs->f->nupvalues] = *v; | 192 | luaM_growvector(fs->L, fs->f->upvalues, fs->nu, fs->f->nupvalues, |
191 | return fs->f->nupvalues++; | 193 | TString *, MAX_INT, ""); |
194 | fs->f->upvalues[fs->nu] = name; | ||
195 | fs->upvalues[fs->nu] = *v; | ||
196 | return fs->nu++; | ||
192 | } | 197 | } |
193 | 198 | ||
194 | 199 | ||
@@ -226,7 +231,7 @@ static void singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) { | |||
226 | var->info = luaK_stringK(fs, n); /* info points to global name */ | 231 | var->info = luaK_stringK(fs, n); /* info points to global name */ |
227 | } | 232 | } |
228 | else { /* LOCAL or UPVAL */ | 233 | else { /* LOCAL or UPVAL */ |
229 | var->info = indexupvalue(fs, var); | 234 | var->info = indexupvalue(fs, n, var); |
230 | var->k = VUPVAL; /* upvalue in this level */ | 235 | var->k = VUPVAL; /* upvalue in this level */ |
231 | } | 236 | } |
232 | } | 237 | } |
@@ -302,7 +307,7 @@ static void pushclosure (LexState *ls, FuncState *func, expdesc *v) { | |||
302 | MAXARG_Bx, "constant table overflow"); | 307 | MAXARG_Bx, "constant table overflow"); |
303 | f->p[fs->np++] = func->f; | 308 | f->p[fs->np++] = func->f; |
304 | init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np-1)); | 309 | init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np-1)); |
305 | for (i=0; i<func->f->nupvalues; i++) { | 310 | for (i=0; i<func->nu; i++) { |
306 | OpCode o = (func->upvalues[i].k == VLOCAL) ? OP_MOVE : OP_GETUPVAL; | 311 | OpCode o = (func->upvalues[i].k == VLOCAL) ? OP_MOVE : OP_GETUPVAL; |
307 | luaK_codeABC(fs, o, 0, func->upvalues[i].info, 0); | 312 | luaK_codeABC(fs, o, 0, func->upvalues[i].info, 0); |
308 | } | 313 | } |
@@ -321,6 +326,7 @@ static void open_func (LexState *ls, FuncState *fs) { | |||
321 | fs->jpc = NO_JUMP; | 326 | fs->jpc = NO_JUMP; |
322 | fs->freereg = 0; | 327 | fs->freereg = 0; |
323 | fs->nk = 0; | 328 | fs->nk = 0; |
329 | fs->nu = 0; | ||
324 | fs->h = luaH_new(ls->L, 0, 0); | 330 | fs->h = luaH_new(ls->L, 0, 0); |
325 | fs->np = 0; | 331 | fs->np = 0; |
326 | fs->nlocvars = 0; | 332 | fs->nlocvars = 0; |
@@ -350,6 +356,8 @@ static void close_func (LexState *ls) { | |||
350 | f->sizep = fs->np; | 356 | f->sizep = fs->np; |
351 | luaM_reallocvector(L, f->locvars, f->sizelocvars, fs->nlocvars, LocVar); | 357 | luaM_reallocvector(L, f->locvars, f->sizelocvars, fs->nlocvars, LocVar); |
352 | f->sizelocvars = fs->nlocvars; | 358 | f->sizelocvars = fs->nlocvars; |
359 | luaM_reallocvector(L, f->upvalues, f->nupvalues, fs->nu, TString *); | ||
360 | f->nupvalues = fs->nu; | ||
353 | lua_assert(luaG_checkcode(f)); | 361 | lua_assert(luaG_checkcode(f)); |
354 | lua_assert(fs->bl == NULL); | 362 | lua_assert(fs->bl == NULL); |
355 | ls->fs = fs->prev; | 363 | ls->fs = fs->prev; |
@@ -368,7 +376,7 @@ Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff) { | |||
368 | check_condition(&lexstate, (lexstate.t.token == TK_EOS), "<eof> expected"); | 376 | check_condition(&lexstate, (lexstate.t.token == TK_EOS), "<eof> expected"); |
369 | close_func(&lexstate); | 377 | close_func(&lexstate); |
370 | lua_assert(funcstate.prev == NULL); | 378 | lua_assert(funcstate.prev == NULL); |
371 | lua_assert(funcstate.f->nupvalues == 0); | 379 | lua_assert(funcstate.nu == 0); |
372 | lua_assert(lexstate.nestlevel == 0); | 380 | lua_assert(lexstate.nestlevel == 0); |
373 | return funcstate.f; | 381 | return funcstate.f; |
374 | } | 382 | } |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lparser.h,v 1.44 2002/05/14 17:52:22 roberto Exp roberto $ | 2 | ** $Id: lparser.h,v 1.45 2002/10/08 18:46:08 roberto Exp roberto $ |
3 | ** Lua Parser | 3 | ** Lua Parser |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -58,6 +58,7 @@ typedef struct FuncState { | |||
58 | int freereg; /* first free register */ | 58 | int freereg; /* first free register */ |
59 | int nk; /* number of elements in `k' */ | 59 | int nk; /* number of elements in `k' */ |
60 | int np; /* number of elements in `p' */ | 60 | int np; /* number of elements in `p' */ |
61 | int nu; /* number of elements in `upvalues' */ | ||
61 | int nlocvars; /* number of elements in `locvars' */ | 62 | int nlocvars; /* number of elements in `locvars' */ |
62 | int nactvar; /* number of active local variables */ | 63 | int nactvar; /* number of active local variables */ |
63 | expdesc upvalues[MAXUPVALUES]; /* upvalues */ | 64 | expdesc upvalues[MAXUPVALUES]; /* upvalues */ |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ltests.c,v 1.147 2002/12/04 17:29:05 roberto Exp roberto $ | 2 | ** $Id: ltests.c,v 1.148 2002/12/04 17:38:31 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 | */ |
@@ -384,6 +384,24 @@ static int metatable (lua_State *L) { | |||
384 | return 1; | 384 | return 1; |
385 | } | 385 | } |
386 | 386 | ||
387 | |||
388 | static int upvalue (lua_State *L) { | ||
389 | int n = luaL_checkint(L, 2); | ||
390 | luaL_checktype(L, 1, LUA_TFUNCTION); | ||
391 | if (lua_isnone(L, 3)) { | ||
392 | const char *name = lua_getupvalue(L, 1, n); | ||
393 | if (name == NULL) return 0; | ||
394 | lua_pushstring(L, name); | ||
395 | return 2; | ||
396 | } | ||
397 | else { | ||
398 | const char *name = lua_setupvalue(L, 1, n); | ||
399 | lua_pushstring(L, name); | ||
400 | return 1; | ||
401 | } | ||
402 | } | ||
403 | |||
404 | |||
387 | static int newuserdata (lua_State *L) { | 405 | static int newuserdata (lua_State *L) { |
388 | size_t size = luaL_checkint(L, 1); | 406 | size_t size = luaL_checkint(L, 1); |
389 | char *p = cast(char *, lua_newuserdata(L, size)); | 407 | char *p = cast(char *, lua_newuserdata(L, size)); |
@@ -754,6 +772,7 @@ static const struct luaL_reg tests_funcs[] = { | |||
754 | {"d2s", d2s}, | 772 | {"d2s", d2s}, |
755 | {"s2d", s2d}, | 773 | {"s2d", s2d}, |
756 | {"metatable", metatable}, | 774 | {"metatable", metatable}, |
775 | {"upvalue", upvalue}, | ||
757 | {"newuserdata", newuserdata}, | 776 | {"newuserdata", newuserdata}, |
758 | {"pushuserdata", pushuserdata}, | 777 | {"pushuserdata", pushuserdata}, |
759 | {"udataval", udataval}, | 778 | {"udataval", udataval}, |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lua.h,v 1.168 2002/11/26 12:53:29 roberto Exp roberto $ | 2 | ** $Id: lua.h,v 1.169 2002/12/04 17:28: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 |
@@ -336,6 +336,8 @@ LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar); | |||
336 | LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar); | 336 | LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar); |
337 | LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n); | 337 | LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n); |
338 | LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n); | 338 | LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n); |
339 | LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n); | ||
340 | LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n); | ||
339 | 341 | ||
340 | LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count); | 342 | LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count); |
341 | LUA_API lua_Hook lua_gethook (lua_State *L); | 343 | LUA_API lua_Hook lua_gethook (lua_State *L); |