mirror of
https://github.com/lua/lua
synced 2025-02-19 22:53:59 +03:00
new functions to manipulate upvales (get/setupvalue)
This commit is contained in:
parent
28021c5c66
commit
dd8edecae1
48
lapi.c
48
lapi.c
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lapi.c,v 1.225 2002/12/04 17:28:27 roberto Exp roberto $
|
** $Id: lapi.c,v 1.226 2002/12/04 17:38:31 roberto Exp roberto $
|
||||||
** Lua API
|
** Lua API
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@ -866,3 +866,49 @@ LUA_API int lua_pushupvalues (lua_State *L) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static const char *aux_upvalue (lua_State *L, int funcindex, int n,
|
||||||
|
TObject **val) {
|
||||||
|
Closure *f;
|
||||||
|
StkId fi = luaA_index(L, funcindex);
|
||||||
|
if (!ttisfunction(fi)) return NULL;
|
||||||
|
f = clvalue(fi);
|
||||||
|
if (n > f->l.nupvalues) return NULL;
|
||||||
|
if (f->c.isC) {
|
||||||
|
*val = &f->c.upvalue[n-1];
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*val = f->l.upvals[n-1]->v;
|
||||||
|
return getstr(f->l.p->upvalues[n-1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) {
|
||||||
|
const char *name;
|
||||||
|
TObject *val;
|
||||||
|
lua_lock(L);
|
||||||
|
name = aux_upvalue(L, funcindex, n, &val);
|
||||||
|
if (name) {
|
||||||
|
setobj2s(L->top, val);
|
||||||
|
api_incr_top(L);
|
||||||
|
}
|
||||||
|
lua_unlock(L);
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) {
|
||||||
|
const char *name;
|
||||||
|
TObject *val;
|
||||||
|
lua_lock(L);
|
||||||
|
api_checknelems(L, 1);
|
||||||
|
name = aux_upvalue(L, funcindex, n, &val);
|
||||||
|
if (name) {
|
||||||
|
L->top--;
|
||||||
|
setobj(val, L->top); /* write barrier */
|
||||||
|
}
|
||||||
|
lua_unlock(L);
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
28
ldblib.c
28
ldblib.c
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: ldblib.c,v 1.74 2002/12/04 17:38:31 roberto Exp roberto $
|
** $Id: ldblib.c,v 1.75 2002/12/05 17:50:10 roberto Exp roberto $
|
||||||
** Interface from Lua to its debug API
|
** Interface from Lua to its debug API
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@ -108,6 +108,30 @@ static int setlocal (lua_State *L) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int auxupvalue (lua_State *L, int get) {
|
||||||
|
const char *name;
|
||||||
|
int n = luaL_checkint(L, 2);
|
||||||
|
luaL_checktype(L, 1, LUA_TFUNCTION);
|
||||||
|
if (lua_iscfunction(L, 1)) return 0; /* cannot touch C upvalues from Lua */
|
||||||
|
name = get ? lua_getupvalue(L, 1, n) : lua_setupvalue(L, 1, n);
|
||||||
|
if (name == NULL) return 0;
|
||||||
|
lua_pushstring(L, name);
|
||||||
|
lua_insert(L, -(get+1));
|
||||||
|
return get + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int getupvalue (lua_State *L) {
|
||||||
|
return auxupvalue(L, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int setupvalue (lua_State *L) {
|
||||||
|
luaL_checkany(L, 3);
|
||||||
|
return auxupvalue(L, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static const char KEY_HOOK = 'h';
|
static const char KEY_HOOK = 'h';
|
||||||
|
|
||||||
@ -253,8 +277,10 @@ static const luaL_reg dblib[] = {
|
|||||||
{"getlocal", getlocal},
|
{"getlocal", getlocal},
|
||||||
{"getinfo", getinfo},
|
{"getinfo", getinfo},
|
||||||
{"gethook", gethook},
|
{"gethook", gethook},
|
||||||
|
{"getupvalue", getupvalue},
|
||||||
{"sethook", sethook},
|
{"sethook", sethook},
|
||||||
{"setlocal", setlocal},
|
{"setlocal", setlocal},
|
||||||
|
{"setupvalue", setupvalue},
|
||||||
{"debug", debug},
|
{"debug", debug},
|
||||||
{"traceback", errorfb},
|
{"traceback", errorfb},
|
||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
|
4
lfunc.c
4
lfunc.c
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lfunc.c,v 1.63 2002/11/14 16:15:53 roberto Exp roberto $
|
** $Id: lfunc.c,v 1.64 2002/12/04 17:38:31 roberto Exp roberto $
|
||||||
** Auxiliary functions to manipulate prototypes and closures
|
** Auxiliary functions to manipulate prototypes and closures
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@ -85,6 +85,7 @@ Proto *luaF_newproto (lua_State *L) {
|
|||||||
f->sizecode = 0;
|
f->sizecode = 0;
|
||||||
f->sizelineinfo = 0;
|
f->sizelineinfo = 0;
|
||||||
f->nupvalues = 0;
|
f->nupvalues = 0;
|
||||||
|
f->upvalues = NULL;
|
||||||
f->numparams = 0;
|
f->numparams = 0;
|
||||||
f->is_vararg = 0;
|
f->is_vararg = 0;
|
||||||
f->maxstacksize = 0;
|
f->maxstacksize = 0;
|
||||||
@ -103,6 +104,7 @@ void luaF_freeproto (lua_State *L, Proto *f) {
|
|||||||
luaM_freearray(L, f->k, f->sizek, TObject);
|
luaM_freearray(L, f->k, f->sizek, TObject);
|
||||||
luaM_freearray(L, f->lineinfo, f->sizelineinfo, int);
|
luaM_freearray(L, f->lineinfo, f->sizelineinfo, int);
|
||||||
luaM_freearray(L, f->locvars, f->sizelocvars, struct LocVar);
|
luaM_freearray(L, f->locvars, f->sizelocvars, struct LocVar);
|
||||||
|
luaM_freearray(L, f->upvalues, f->nupvalues, TString *);
|
||||||
luaM_freelem(L, f);
|
luaM_freelem(L, f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
8
lgc.c
8
lgc.c
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lgc.c,v 1.165 2002/12/02 12:06:10 roberto Exp roberto $
|
** $Id: lgc.c,v 1.166 2002/12/04 17:38:31 roberto Exp roberto $
|
||||||
** Garbage Collector
|
** Garbage Collector
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@ -186,11 +186,13 @@ static void traversetable (GCState *st, Table *h) {
|
|||||||
static void traverseproto (GCState *st, Proto *f) {
|
static void traverseproto (GCState *st, Proto *f) {
|
||||||
int i;
|
int i;
|
||||||
stringmark(f->source);
|
stringmark(f->source);
|
||||||
for (i=0; i<f->sizek; i++) {
|
for (i=0; i<f->sizek; i++) { /* mark literal strings */
|
||||||
if (ttisstring(f->k+i))
|
if (ttisstring(f->k+i))
|
||||||
stringmark(tsvalue(f->k+i));
|
stringmark(tsvalue(f->k+i));
|
||||||
}
|
}
|
||||||
for (i=0; i<f->sizep; i++)
|
for (i=0; i<f->nupvalues; i++) /* mark upvalue names */
|
||||||
|
stringmark(f->upvalues[i]);
|
||||||
|
for (i=0; i<f->sizep; i++) /* mark nested protos */
|
||||||
markvalue(st, f->p[i]);
|
markvalue(st, f->p[i]);
|
||||||
for (i=0; i<f->sizelocvars; i++) /* mark local-variable names */
|
for (i=0; i<f->sizelocvars; i++) /* mark local-variable names */
|
||||||
stringmark(f->locvars[i].varname);
|
stringmark(f->locvars[i].varname);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lobject.h,v 1.154 2002/11/14 11:51:50 roberto Exp roberto $
|
** $Id: lobject.h,v 1.155 2002/11/14 16:16:21 roberto Exp roberto $
|
||||||
** Type definitions for Lua objects
|
** Type definitions for Lua objects
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@ -214,7 +214,9 @@ typedef struct Proto {
|
|||||||
struct Proto **p; /* functions defined inside the function */
|
struct Proto **p; /* functions defined inside the function */
|
||||||
int *lineinfo; /* map from opcodes to source lines */
|
int *lineinfo; /* map from opcodes to source lines */
|
||||||
struct LocVar *locvars; /* information about local variables */
|
struct LocVar *locvars; /* information about local variables */
|
||||||
|
TString **upvalues; /* upvalue names */
|
||||||
TString *source;
|
TString *source;
|
||||||
|
int nupvalues; /* (also size of `upvals') */
|
||||||
int sizek; /* size of `k' */
|
int sizek; /* size of `k' */
|
||||||
int sizecode;
|
int sizecode;
|
||||||
int sizelineinfo;
|
int sizelineinfo;
|
||||||
@ -222,7 +224,6 @@ typedef struct Proto {
|
|||||||
int sizelocvars;
|
int sizelocvars;
|
||||||
int lineDefined;
|
int lineDefined;
|
||||||
GCObject *gclist;
|
GCObject *gclist;
|
||||||
lu_byte nupvalues;
|
|
||||||
lu_byte numparams;
|
lu_byte numparams;
|
||||||
lu_byte is_vararg;
|
lu_byte is_vararg;
|
||||||
lu_byte maxstacksize;
|
lu_byte maxstacksize;
|
||||||
|
28
lparser.c
28
lparser.c
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lparser.c,v 1.201 2002/12/06 17:09:00 roberto Exp roberto $
|
** $Id: lparser.c,v 1.202 2002/12/11 12:34:22 roberto Exp roberto $
|
||||||
** Lua Parser
|
** Lua Parser
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@ -179,16 +179,21 @@ static void create_local (LexState *ls, const char *name) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int indexupvalue (FuncState *fs, expdesc *v) {
|
static int indexupvalue (FuncState *fs, TString *name, expdesc *v) {
|
||||||
int i;
|
int i;
|
||||||
for (i=0; i<fs->f->nupvalues; i++) {
|
for (i=0; i<fs->nu; i++) {
|
||||||
if (fs->upvalues[i].k == v->k && fs->upvalues[i].info == v->info)
|
if (fs->upvalues[i].k == v->k && fs->upvalues[i].info == v->info) {
|
||||||
|
lua_assert(fs->f->upvalues[i] == name);
|
||||||
return i;
|
return i;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/* new one */
|
/* new one */
|
||||||
luaX_checklimit(fs->ls, fs->f->nupvalues+1, MAXUPVALUES, "upvalues");
|
luaX_checklimit(fs->ls, fs->nu + 1, MAXUPVALUES, "upvalues");
|
||||||
fs->upvalues[fs->f->nupvalues] = *v;
|
luaM_growvector(fs->L, fs->f->upvalues, fs->nu, fs->f->nupvalues,
|
||||||
return fs->f->nupvalues++;
|
TString *, MAX_INT, "");
|
||||||
|
fs->f->upvalues[fs->nu] = name;
|
||||||
|
fs->upvalues[fs->nu] = *v;
|
||||||
|
return fs->nu++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -226,7 +231,7 @@ static void singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) {
|
|||||||
var->info = luaK_stringK(fs, n); /* info points to global name */
|
var->info = luaK_stringK(fs, n); /* info points to global name */
|
||||||
}
|
}
|
||||||
else { /* LOCAL or UPVAL */
|
else { /* LOCAL or UPVAL */
|
||||||
var->info = indexupvalue(fs, var);
|
var->info = indexupvalue(fs, n, var);
|
||||||
var->k = VUPVAL; /* upvalue in this level */
|
var->k = VUPVAL; /* upvalue in this level */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -302,7 +307,7 @@ static void pushclosure (LexState *ls, FuncState *func, expdesc *v) {
|
|||||||
MAXARG_Bx, "constant table overflow");
|
MAXARG_Bx, "constant table overflow");
|
||||||
f->p[fs->np++] = func->f;
|
f->p[fs->np++] = func->f;
|
||||||
init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np-1));
|
init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np-1));
|
||||||
for (i=0; i<func->f->nupvalues; i++) {
|
for (i=0; i<func->nu; i++) {
|
||||||
OpCode o = (func->upvalues[i].k == VLOCAL) ? OP_MOVE : OP_GETUPVAL;
|
OpCode o = (func->upvalues[i].k == VLOCAL) ? OP_MOVE : OP_GETUPVAL;
|
||||||
luaK_codeABC(fs, o, 0, func->upvalues[i].info, 0);
|
luaK_codeABC(fs, o, 0, func->upvalues[i].info, 0);
|
||||||
}
|
}
|
||||||
@ -321,6 +326,7 @@ static void open_func (LexState *ls, FuncState *fs) {
|
|||||||
fs->jpc = NO_JUMP;
|
fs->jpc = NO_JUMP;
|
||||||
fs->freereg = 0;
|
fs->freereg = 0;
|
||||||
fs->nk = 0;
|
fs->nk = 0;
|
||||||
|
fs->nu = 0;
|
||||||
fs->h = luaH_new(ls->L, 0, 0);
|
fs->h = luaH_new(ls->L, 0, 0);
|
||||||
fs->np = 0;
|
fs->np = 0;
|
||||||
fs->nlocvars = 0;
|
fs->nlocvars = 0;
|
||||||
@ -350,6 +356,8 @@ static void close_func (LexState *ls) {
|
|||||||
f->sizep = fs->np;
|
f->sizep = fs->np;
|
||||||
luaM_reallocvector(L, f->locvars, f->sizelocvars, fs->nlocvars, LocVar);
|
luaM_reallocvector(L, f->locvars, f->sizelocvars, fs->nlocvars, LocVar);
|
||||||
f->sizelocvars = fs->nlocvars;
|
f->sizelocvars = fs->nlocvars;
|
||||||
|
luaM_reallocvector(L, f->upvalues, f->nupvalues, fs->nu, TString *);
|
||||||
|
f->nupvalues = fs->nu;
|
||||||
lua_assert(luaG_checkcode(f));
|
lua_assert(luaG_checkcode(f));
|
||||||
lua_assert(fs->bl == NULL);
|
lua_assert(fs->bl == NULL);
|
||||||
ls->fs = fs->prev;
|
ls->fs = fs->prev;
|
||||||
@ -368,7 +376,7 @@ Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff) {
|
|||||||
check_condition(&lexstate, (lexstate.t.token == TK_EOS), "<eof> expected");
|
check_condition(&lexstate, (lexstate.t.token == TK_EOS), "<eof> expected");
|
||||||
close_func(&lexstate);
|
close_func(&lexstate);
|
||||||
lua_assert(funcstate.prev == NULL);
|
lua_assert(funcstate.prev == NULL);
|
||||||
lua_assert(funcstate.f->nupvalues == 0);
|
lua_assert(funcstate.nu == 0);
|
||||||
lua_assert(lexstate.nestlevel == 0);
|
lua_assert(lexstate.nestlevel == 0);
|
||||||
return funcstate.f;
|
return funcstate.f;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lparser.h,v 1.44 2002/05/14 17:52:22 roberto Exp roberto $
|
** $Id: lparser.h,v 1.45 2002/10/08 18:46:08 roberto Exp roberto $
|
||||||
** Lua Parser
|
** Lua Parser
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@ -58,6 +58,7 @@ typedef struct FuncState {
|
|||||||
int freereg; /* first free register */
|
int freereg; /* first free register */
|
||||||
int nk; /* number of elements in `k' */
|
int nk; /* number of elements in `k' */
|
||||||
int np; /* number of elements in `p' */
|
int np; /* number of elements in `p' */
|
||||||
|
int nu; /* number of elements in `upvalues' */
|
||||||
int nlocvars; /* number of elements in `locvars' */
|
int nlocvars; /* number of elements in `locvars' */
|
||||||
int nactvar; /* number of active local variables */
|
int nactvar; /* number of active local variables */
|
||||||
expdesc upvalues[MAXUPVALUES]; /* upvalues */
|
expdesc upvalues[MAXUPVALUES]; /* upvalues */
|
||||||
|
21
ltests.c
21
ltests.c
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: ltests.c,v 1.147 2002/12/04 17:29:05 roberto Exp roberto $
|
** $Id: ltests.c,v 1.148 2002/12/04 17:38:31 roberto Exp roberto $
|
||||||
** Internal Module for Debugging of the Lua Implementation
|
** Internal Module for Debugging of the Lua Implementation
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@ -384,6 +384,24 @@ static int metatable (lua_State *L) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int upvalue (lua_State *L) {
|
||||||
|
int n = luaL_checkint(L, 2);
|
||||||
|
luaL_checktype(L, 1, LUA_TFUNCTION);
|
||||||
|
if (lua_isnone(L, 3)) {
|
||||||
|
const char *name = lua_getupvalue(L, 1, n);
|
||||||
|
if (name == NULL) return 0;
|
||||||
|
lua_pushstring(L, name);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const char *name = lua_setupvalue(L, 1, n);
|
||||||
|
lua_pushstring(L, name);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int newuserdata (lua_State *L) {
|
static int newuserdata (lua_State *L) {
|
||||||
size_t size = luaL_checkint(L, 1);
|
size_t size = luaL_checkint(L, 1);
|
||||||
char *p = cast(char *, lua_newuserdata(L, size));
|
char *p = cast(char *, lua_newuserdata(L, size));
|
||||||
@ -754,6 +772,7 @@ static const struct luaL_reg tests_funcs[] = {
|
|||||||
{"d2s", d2s},
|
{"d2s", d2s},
|
||||||
{"s2d", s2d},
|
{"s2d", s2d},
|
||||||
{"metatable", metatable},
|
{"metatable", metatable},
|
||||||
|
{"upvalue", upvalue},
|
||||||
{"newuserdata", newuserdata},
|
{"newuserdata", newuserdata},
|
||||||
{"pushuserdata", pushuserdata},
|
{"pushuserdata", pushuserdata},
|
||||||
{"udataval", udataval},
|
{"udataval", udataval},
|
||||||
|
4
lua.h
4
lua.h
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lua.h,v 1.168 2002/11/26 12:53:29 roberto Exp roberto $
|
** $Id: lua.h,v 1.169 2002/12/04 17:28:27 roberto Exp roberto $
|
||||||
** Lua - An Extensible Extension Language
|
** Lua - An Extensible Extension Language
|
||||||
** Tecgraf: Computer Graphics Technology Group, PUC-Rio, Brazil
|
** Tecgraf: Computer Graphics Technology Group, PUC-Rio, Brazil
|
||||||
** http://www.lua.org mailto:info@lua.org
|
** 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);
|
|||||||
LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar);
|
LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar);
|
||||||
LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n);
|
LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n);
|
||||||
LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n);
|
LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n);
|
||||||
|
LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n);
|
||||||
|
LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n);
|
||||||
|
|
||||||
LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count);
|
LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count);
|
||||||
LUA_API lua_Hook lua_gethook (lua_State *L);
|
LUA_API lua_Hook lua_gethook (lua_State *L);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user