mirror of
https://github.com/lua/lua
synced 2024-12-24 03:16:50 +03:00
stricter control (using tag variants) over closure kinds (Lua x C)
This commit is contained in:
parent
0214dab989
commit
3b44821334
117
lapi.c
117
lapi.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lapi.c,v 2.146 2011/05/31 18:24:36 roberto Exp roberto $
|
||||
** $Id: lapi.c,v 2.147 2011/05/31 18:27:56 roberto Exp roberto $
|
||||
** Lua API
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -59,9 +59,9 @@ static TValue *index2addr (lua_State *L, int idx) {
|
||||
if (ttislcf(ci->func)) /* light C function? */
|
||||
return cast(TValue *, luaO_nilobject); /* it has no upvalues */
|
||||
else {
|
||||
Closure *func = clvalue(ci->func);
|
||||
return (idx <= func->c.nupvalues)
|
||||
? &func->c.upvalue[idx-1]
|
||||
CClosure *func = clCvalue(ci->func);
|
||||
return (idx <= func->nupvalues)
|
||||
? &func->upvalue[idx-1]
|
||||
: cast(TValue *, luaO_nilobject);
|
||||
}
|
||||
}
|
||||
@ -195,10 +195,8 @@ static void moveto (lua_State *L, TValue *fr, int idx) {
|
||||
TValue *to = index2addr(L, idx);
|
||||
api_checkvalidindex(L, to);
|
||||
setobj(L, to, fr);
|
||||
if (idx < LUA_REGISTRYINDEX) { /* function upvalue? */
|
||||
lua_assert(ttisclosure(L->ci->func));
|
||||
luaC_barrier(L, clvalue(L->ci->func), fr);
|
||||
}
|
||||
if (idx < LUA_REGISTRYINDEX) /* function upvalue? */
|
||||
luaC_barrier(L, clCvalue(L->ci->func), fr);
|
||||
/* LUA_REGISTRYINDEX does not need gc barrier
|
||||
(collector revisits it before finishing collection) */
|
||||
}
|
||||
@ -251,7 +249,7 @@ LUA_API const char *lua_typename (lua_State *L, int t) {
|
||||
|
||||
LUA_API int lua_iscfunction (lua_State *L, int idx) {
|
||||
StkId o = index2addr(L, idx);
|
||||
return (ttislcf(o) || (ttisclosure(o) && clvalue(o)->c.isC));
|
||||
return (ttislcf(o) || (ttisCclosure(o)));
|
||||
}
|
||||
|
||||
|
||||
@ -398,7 +396,7 @@ LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) {
|
||||
|
||||
LUA_API size_t lua_rawlen (lua_State *L, int idx) {
|
||||
StkId o = index2addr(L, idx);
|
||||
switch (ttype(o)) {
|
||||
switch (ttypenv(o)) {
|
||||
case LUA_TSTRING: return tsvalue(o)->len;
|
||||
case LUA_TUSERDATA: return uvalue(o)->len;
|
||||
case LUA_TTABLE: return luaH_getn(hvalue(o));
|
||||
@ -410,15 +408,15 @@ LUA_API size_t lua_rawlen (lua_State *L, int idx) {
|
||||
LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) {
|
||||
StkId o = index2addr(L, idx);
|
||||
if (ttislcf(o)) return fvalue(o);
|
||||
else if (ttisclosure(o) && clvalue(o)->c.isC)
|
||||
return clvalue(o)->c.f;
|
||||
else if (ttisCclosure(o))
|
||||
return clCvalue(o)->f;
|
||||
else return NULL; /* not a C function */
|
||||
}
|
||||
|
||||
|
||||
LUA_API void *lua_touserdata (lua_State *L, int idx) {
|
||||
StkId o = index2addr(L, idx);
|
||||
switch (ttype(o)) {
|
||||
switch (ttypenv(o)) {
|
||||
case LUA_TUSERDATA: return (rawuvalue(o) + 1);
|
||||
case LUA_TLIGHTUSERDATA: return pvalue(o);
|
||||
default: return NULL;
|
||||
@ -436,7 +434,8 @@ LUA_API const void *lua_topointer (lua_State *L, int idx) {
|
||||
StkId o = index2addr(L, idx);
|
||||
switch (ttype(o)) {
|
||||
case LUA_TTABLE: return hvalue(o);
|
||||
case LUA_TFUNCTION: return clvalue(o);
|
||||
case LUA_TLCL: return clLvalue(o);
|
||||
case LUA_TCCL: return clCvalue(o);
|
||||
case LUA_TLCF: return cast(void *, cast(size_t, fvalue(o)));
|
||||
case LUA_TTHREAD: return thvalue(o);
|
||||
case LUA_TUSERDATA:
|
||||
@ -556,7 +555,7 @@ LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
|
||||
L->top -= n;
|
||||
while (n--)
|
||||
setobj2n(L, &cl->c.upvalue[n], L->top + n);
|
||||
setclvalue(L, L->top, cl);
|
||||
setclCvalue(L, L->top, cl);
|
||||
}
|
||||
api_incr_top(L);
|
||||
lua_unlock(L);
|
||||
@ -656,7 +655,7 @@ LUA_API int lua_getmetatable (lua_State *L, int objindex) {
|
||||
int res;
|
||||
lua_lock(L);
|
||||
obj = index2addr(L, objindex);
|
||||
switch (ttype(obj)) {
|
||||
switch (ttypenv(obj)) {
|
||||
case LUA_TTABLE:
|
||||
mt = hvalue(obj)->metatable;
|
||||
break;
|
||||
@ -763,7 +762,7 @@ LUA_API int lua_setmetatable (lua_State *L, int objindex) {
|
||||
api_check(L, ttistable(L->top - 1), "table expected");
|
||||
mt = hvalue(L->top - 1);
|
||||
}
|
||||
switch (ttype(obj)) {
|
||||
switch (ttypenv(obj)) {
|
||||
case LUA_TTABLE: {
|
||||
hvalue(obj)->metatable = mt;
|
||||
if (mt)
|
||||
@ -921,15 +920,14 @@ LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data,
|
||||
luaZ_init(L, &z, reader, data);
|
||||
status = luaD_protectedparser(L, &z, chunkname);
|
||||
if (status == LUA_OK) { /* no errors? */
|
||||
Closure *f = clvalue(L->top - 1); /* get newly created function */
|
||||
lua_assert(!f->c.isC);
|
||||
if (f->l.nupvalues == 1) { /* does it have one upvalue? */
|
||||
LClosure *f = clLvalue(L->top - 1); /* get newly created function */
|
||||
if (f->nupvalues == 1) { /* does it have one upvalue? */
|
||||
/* get global table from registry */
|
||||
Table *reg = hvalue(&G(L)->l_registry);
|
||||
const TValue *gt = luaH_getint(reg, LUA_RIDX_GLOBALS);
|
||||
/* set global table as 1st upvalue of 'f' (may be LUA_ENV) */
|
||||
setobj(L, f->l.upvals[0]->v, gt);
|
||||
luaC_barrier(L, f->l.upvals[0], gt);
|
||||
setobj(L, f->upvals[0]->v, gt);
|
||||
luaC_barrier(L, f->upvals[0], gt);
|
||||
}
|
||||
}
|
||||
lua_unlock(L);
|
||||
@ -1131,25 +1129,27 @@ LUA_API void *lua_newuserdata (lua_State *L, size_t size) {
|
||||
|
||||
static const char *aux_upvalue (StkId fi, int n, TValue **val,
|
||||
GCObject **owner) {
|
||||
Closure *f;
|
||||
if (!ttisclosure(fi)) return NULL;
|
||||
f = clvalue(fi);
|
||||
if (f->c.isC) {
|
||||
if (!(1 <= n && n <= f->c.nupvalues)) return NULL;
|
||||
*val = &f->c.upvalue[n-1];
|
||||
if (owner) *owner = obj2gco(f);
|
||||
return "";
|
||||
}
|
||||
else {
|
||||
const char *name;
|
||||
Proto *p = f->l.p;
|
||||
if (!(1 <= n && n <= p->sizeupvalues)) return NULL;
|
||||
*val = f->l.upvals[n-1]->v;
|
||||
if (owner) *owner = obj2gco(f->l.upvals[n - 1]);
|
||||
name = getstr(p->upvalues[n-1].name);
|
||||
if (name == NULL) /* no debug information? */
|
||||
name = "";
|
||||
return name;
|
||||
switch (ttype(fi)) {
|
||||
case LUA_TCCL: { /* C closure */
|
||||
CClosure *f = clCvalue(fi);
|
||||
if (!(1 <= n && n <= f->nupvalues)) return NULL;
|
||||
*val = &f->upvalue[n-1];
|
||||
if (owner) *owner = obj2gco(f);
|
||||
return "";
|
||||
}
|
||||
case LUA_TLCL: { /* Lua closure */
|
||||
LClosure *f = clLvalue(fi);
|
||||
const char *name;
|
||||
Proto *p = f->p;
|
||||
if (!(1 <= n && n <= p->sizeupvalues)) return NULL;
|
||||
*val = f->upvals[n-1]->v;
|
||||
if (owner) *owner = obj2gco(f->upvals[n - 1]);
|
||||
name = getstr(p->upvalues[n-1].name);
|
||||
if (name == NULL) /* no debug information? */
|
||||
name = "";
|
||||
return name;
|
||||
}
|
||||
default: return NULL; /* not a closure */
|
||||
}
|
||||
}
|
||||
|
||||
@ -1187,34 +1187,39 @@ LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) {
|
||||
}
|
||||
|
||||
|
||||
static UpVal **getupvalref (lua_State *L, int fidx, int n, Closure **pf) {
|
||||
Closure *f;
|
||||
static UpVal **getupvalref (lua_State *L, int fidx, int n, LClosure **pf) {
|
||||
LClosure *f;
|
||||
StkId fi = index2addr(L, fidx);
|
||||
api_check(L, ttisclosure(fi), "Lua function expected");
|
||||
f = clvalue(fi);
|
||||
api_check(L, !f->c.isC, "Lua function expected");
|
||||
api_check(L, (1 <= n && n <= f->l.p->sizeupvalues), "invalid upvalue index");
|
||||
api_check(L, ttisLclosure(fi), "Lua function expected");
|
||||
f = clLvalue(fi);
|
||||
api_check(L, (1 <= n && n <= f->p->sizeupvalues), "invalid upvalue index");
|
||||
if (pf) *pf = f;
|
||||
return &f->l.upvals[n - 1]; /* get its upvalue pointer */
|
||||
return &f->upvals[n - 1]; /* get its upvalue pointer */
|
||||
}
|
||||
|
||||
|
||||
LUA_API void *lua_upvalueid (lua_State *L, int fidx, int n) {
|
||||
Closure *f;
|
||||
StkId fi = index2addr(L, fidx);
|
||||
api_check(L, ttisclosure(fi), "function expected");
|
||||
f = clvalue(fi);
|
||||
if (f->c.isC) {
|
||||
api_check(L, 1 <= n && n <= f->c.nupvalues, "invalid upvalue index");
|
||||
return &f->c.upvalue[n - 1];
|
||||
switch (ttype(fi)) {
|
||||
case LUA_TLCL: { /* lua closure */
|
||||
return *getupvalref(L, fidx, n, NULL);
|
||||
}
|
||||
case LUA_TCCL: { /* C closure */
|
||||
CClosure *f = clCvalue(fi);
|
||||
api_check(L, 1 <= n && n <= f->nupvalues, "invalid upvalue index");
|
||||
return &f->upvalue[n - 1];
|
||||
}
|
||||
default: {
|
||||
api_check(L, 0, "closure expected");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else return *getupvalref(L, fidx, n, NULL);
|
||||
}
|
||||
|
||||
|
||||
LUA_API void lua_upvaluejoin (lua_State *L, int fidx1, int n1,
|
||||
int fidx2, int n2) {
|
||||
Closure *f1;
|
||||
LClosure *f1;
|
||||
UpVal **up1 = getupvalref(L, fidx1, n1, &f1);
|
||||
UpVal **up2 = getupvalref(L, fidx2, n2, NULL);
|
||||
*up1 = *up2;
|
||||
|
24
ldebug.c
24
ldebug.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: ldebug.c,v 2.80 2011/04/19 16:22:13 roberto Exp roberto $
|
||||
** $Id: ldebug.c,v 2.81 2011/04/28 14:00:11 roberto Exp roberto $
|
||||
** Debug Interface
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -35,12 +35,12 @@ static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name);
|
||||
|
||||
static int currentpc (CallInfo *ci) {
|
||||
lua_assert(isLua(ci));
|
||||
return pcRel(ci->u.l.savedpc, ci_func(ci)->l.p);
|
||||
return pcRel(ci->u.l.savedpc, ci_func(ci)->p);
|
||||
}
|
||||
|
||||
|
||||
static int currentline (CallInfo *ci) {
|
||||
return getfuncline(ci_func(ci)->l.p, currentpc(ci));
|
||||
return getfuncline(ci_func(ci)->p, currentpc(ci));
|
||||
}
|
||||
|
||||
|
||||
@ -95,7 +95,7 @@ LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) {
|
||||
|
||||
|
||||
static const char *findvararg (CallInfo *ci, int n, StkId *pos) {
|
||||
int nparams = clvalue(ci->func)->l.p->numparams;
|
||||
int nparams = clLvalue(ci->func)->p->numparams;
|
||||
if (n >= ci->u.l.base - ci->func - nparams)
|
||||
return NULL; /* no such vararg */
|
||||
else {
|
||||
@ -114,7 +114,7 @@ static const char *findlocal (lua_State *L, CallInfo *ci, int n,
|
||||
return findvararg(ci, -n, pos);
|
||||
else {
|
||||
base = ci->u.l.base;
|
||||
name = luaF_getlocalname(ci_func(ci)->l.p, n, currentpc(ci));
|
||||
name = luaF_getlocalname(ci_func(ci)->p, n, currentpc(ci));
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -138,7 +138,7 @@ LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) {
|
||||
if (!isLfunction(L->top - 1)) /* not a Lua function? */
|
||||
name = NULL;
|
||||
else /* consider live variables at function start (parameters) */
|
||||
name = luaF_getlocalname(clvalue(L->top - 1)->l.p, n, 0);
|
||||
name = luaF_getlocalname(clLvalue(L->top - 1)->p, n, 0);
|
||||
}
|
||||
else { /* active function; get information through 'ar' */
|
||||
StkId pos = 0; /* to avoid warnings */
|
||||
@ -294,7 +294,7 @@ static const char *getobjname (lua_State *L, CallInfo *ci, int reg,
|
||||
static void kname (lua_State *L, CallInfo *ci, int c, int oreg,
|
||||
const char *what, const char **name) {
|
||||
if (ISK(c)) { /* is 'c' a constant? */
|
||||
TValue *kvalue = &ci_func(ci)->l.p->k[INDEXK(c)];
|
||||
TValue *kvalue = &ci_func(ci)->p->k[INDEXK(c)];
|
||||
if (ttisstring(kvalue)) { /* literal constant? */
|
||||
*name = svalue(kvalue); /* it is its own name */
|
||||
return;
|
||||
@ -315,7 +315,7 @@ static void kname (lua_State *L, CallInfo *ci, int c, int oreg,
|
||||
|
||||
static const char *getobjname (lua_State *L, CallInfo *ci, int reg,
|
||||
const char **name) {
|
||||
Proto *p = ci_func(ci)->l.p;
|
||||
Proto *p = ci_func(ci)->p;
|
||||
const char *what = NULL;
|
||||
int lastpc = currentpc(ci);
|
||||
int pc;
|
||||
@ -421,9 +421,9 @@ static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) {
|
||||
if ((ci->callstatus & CIST_TAIL) || !isLua(ci->previous))
|
||||
return NULL; /* calling function is not Lua (or is unknown) */
|
||||
ci = ci->previous; /* calling function */
|
||||
i = ci_func(ci)->l.p->code[currentpc(ci)];
|
||||
i = ci_func(ci)->p->code[currentpc(ci)];
|
||||
if (GET_OPCODE(i) == OP_EXTRAARG) /* extra argument? */
|
||||
i = ci_func(ci)->l.p->code[currentpc(ci) - 1]; /* get 'real' instruction */
|
||||
i = ci_func(ci)->p->code[currentpc(ci) - 1]; /* get 'real' instruction */
|
||||
switch (GET_OPCODE(i)) {
|
||||
case OP_CALL:
|
||||
case OP_TAILCALL:
|
||||
@ -474,7 +474,7 @@ static int isinstack (CallInfo *ci, const TValue *o) {
|
||||
|
||||
static const char *getupvalname (CallInfo *ci, const TValue *o,
|
||||
const char **name) {
|
||||
LClosure *c = &ci_func(ci)->l;
|
||||
LClosure *c = ci_func(ci);
|
||||
int i;
|
||||
for (i = 0; i < c->nupvalues; i++) {
|
||||
if (c->upvals[i]->v == o) {
|
||||
@ -535,7 +535,7 @@ static void addinfo (lua_State *L, const char *msg) {
|
||||
if (isLua(ci)) { /* is Lua code? */
|
||||
char buff[LUA_IDSIZE]; /* add file:line information */
|
||||
int line = currentline(ci);
|
||||
TString *src = ci_func(ci)->l.p->source;
|
||||
TString *src = ci_func(ci)->p->source;
|
||||
if (src)
|
||||
luaO_chunkid(buff, getstr(src), LUA_IDSIZE);
|
||||
else { /* no source available; use "?" instead */
|
||||
|
5
ldebug.h
5
ldebug.h
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: ldebug.h,v 2.4 2009/04/30 17:42:21 roberto Exp roberto $
|
||||
** $Id: ldebug.h,v 2.5 2009/06/10 16:57:53 roberto Exp roberto $
|
||||
** Auxiliary functions from Debug Interface module
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -17,6 +17,9 @@
|
||||
|
||||
#define resethookcount(L) (L->hookcount = L->basehookcount)
|
||||
|
||||
/* Active Lua function (given call info) */
|
||||
#define ci_func(ci) (clLvalue((ci)->func))
|
||||
|
||||
|
||||
LUAI_FUNC void luaG_typeerror (lua_State *L, const TValue *o,
|
||||
const char *opname);
|
||||
|
108
ldo.c
108
ldo.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: ldo.c,v 2.93 2011/02/23 13:13:10 roberto Exp roberto $
|
||||
** $Id: ldo.c,v 2.94 2011/05/30 16:36:38 roberto Exp roberto $
|
||||
** Stack and Call structure of Lua
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -293,59 +293,59 @@ static StkId tryfuncTM (lua_State *L, StkId func) {
|
||||
** returns true if function has been executed (C function)
|
||||
*/
|
||||
int luaD_precall (lua_State *L, StkId func, int nresults) {
|
||||
Closure *cl;
|
||||
lua_CFunction f;
|
||||
ptrdiff_t funcr;
|
||||
if (!ttisfunction(func)) /* `func' is not a function? */
|
||||
func = tryfuncTM(L, func); /* check the `function' tag method */
|
||||
funcr = savestack(L, func);
|
||||
if (ttislcf(func) || (cl = clvalue(func), cl->c.isC)) { /* C function? */
|
||||
CallInfo *ci;
|
||||
int n;
|
||||
f = (ttislcf(func) ? fvalue(func) : cl->c.f);
|
||||
luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
|
||||
ci = next_ci(L); /* now 'enter' new function */
|
||||
ci->nresults = nresults;
|
||||
ci->func = restorestack(L, funcr);
|
||||
ci->top = L->top + LUA_MINSTACK;
|
||||
lua_assert(ci->top <= L->stack_last);
|
||||
ci->callstatus = 0;
|
||||
if (L->hookmask & LUA_MASKCALL)
|
||||
luaD_hook(L, LUA_HOOKCALL, -1);
|
||||
lua_unlock(L);
|
||||
n = (*f)(L); /* do the actual call */
|
||||
lua_lock(L);
|
||||
api_checknelems(L, n);
|
||||
luaD_poscall(L, L->top - n);
|
||||
return 1;
|
||||
}
|
||||
else { /* Lua function: prepare its call */
|
||||
CallInfo *ci;
|
||||
int nparams, nargs;
|
||||
StkId base;
|
||||
Proto *p = cl->l.p;
|
||||
luaD_checkstack(L, p->maxstacksize);
|
||||
func = restorestack(L, funcr);
|
||||
nargs = cast_int(L->top - func) - 1; /* number of real arguments */
|
||||
nparams = p->numparams; /* number of expected parameters */
|
||||
for (; nargs < nparams; nargs++)
|
||||
setnilvalue(L->top++); /* complete missing arguments */
|
||||
if (!p->is_vararg) /* no varargs? */
|
||||
base = func + 1;
|
||||
else /* vararg function */
|
||||
base = adjust_varargs(L, p, nargs);
|
||||
ci = next_ci(L); /* now 'enter' new function */
|
||||
ci->nresults = nresults;
|
||||
ci->func = func;
|
||||
ci->u.l.base = base;
|
||||
ci->top = base + p->maxstacksize;
|
||||
lua_assert(ci->top <= L->stack_last);
|
||||
ci->u.l.savedpc = p->code; /* starting point */
|
||||
ci->callstatus = CIST_LUA;
|
||||
L->top = ci->top;
|
||||
if (L->hookmask & LUA_MASKCALL)
|
||||
callhook(L, ci);
|
||||
return 0;
|
||||
CallInfo *ci;
|
||||
int n; /* number of arguments (Lua) or returns (C) */
|
||||
ptrdiff_t funcr = savestack(L, func);
|
||||
switch (ttype(func)) {
|
||||
case LUA_TLCF: /* light C function */
|
||||
f = fvalue(func);
|
||||
goto Cfunc;
|
||||
case LUA_TCCL: { /* C closure */
|
||||
f = clCvalue(func)->f;
|
||||
Cfunc:
|
||||
luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
|
||||
ci = next_ci(L); /* now 'enter' new function */
|
||||
ci->nresults = nresults;
|
||||
ci->func = restorestack(L, funcr);
|
||||
ci->top = L->top + LUA_MINSTACK;
|
||||
lua_assert(ci->top <= L->stack_last);
|
||||
ci->callstatus = 0;
|
||||
if (L->hookmask & LUA_MASKCALL)
|
||||
luaD_hook(L, LUA_HOOKCALL, -1);
|
||||
lua_unlock(L);
|
||||
n = (*f)(L); /* do the actual call */
|
||||
lua_lock(L);
|
||||
api_checknelems(L, n);
|
||||
luaD_poscall(L, L->top - n);
|
||||
return 1;
|
||||
}
|
||||
case LUA_TLCL: { /* Lua function: prepare its call */
|
||||
StkId base;
|
||||
Proto *p = clLvalue(func)->p;
|
||||
luaD_checkstack(L, p->maxstacksize);
|
||||
func = restorestack(L, funcr);
|
||||
n = cast_int(L->top - func) - 1; /* number of real arguments */
|
||||
for (; n < p->numparams; n++)
|
||||
setnilvalue(L->top++); /* complete missing arguments */
|
||||
base = (!p->is_vararg) ? func + 1 : adjust_varargs(L, p, n);
|
||||
ci = next_ci(L); /* now 'enter' new function */
|
||||
ci->nresults = nresults;
|
||||
ci->func = func;
|
||||
ci->u.l.base = base;
|
||||
ci->top = base + p->maxstacksize;
|
||||
lua_assert(ci->top <= L->stack_last);
|
||||
ci->u.l.savedpc = p->code; /* starting point */
|
||||
ci->callstatus = CIST_LUA;
|
||||
L->top = ci->top;
|
||||
if (L->hookmask & LUA_MASKCALL)
|
||||
callhook(L, ci);
|
||||
return 0;
|
||||
}
|
||||
default: { /* not a function */
|
||||
func = tryfuncTM(L, func); /* retry with 'function' tag method */
|
||||
return luaD_precall(L, func, nresults);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -626,7 +626,7 @@ static void f_parser (lua_State *L, void *ud) {
|
||||
setptvalue2s(L, L->top, tf);
|
||||
incr_top(L);
|
||||
cl = luaF_newLclosure(L, tf);
|
||||
setclvalue(L, L->top - 1, cl);
|
||||
setclLvalue(L, L->top - 1, cl);
|
||||
for (i = 0; i < tf->sizeupvalues; i++) /* initialize upvalues */
|
||||
cl->l.upvals[i] = luaF_newupval(L);
|
||||
}
|
||||
|
47
lobject.h
47
lobject.h
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lobject.h,v 2.55 2011/05/31 18:24:36 roberto Exp roberto $
|
||||
** $Id: lobject.h,v 2.56 2011/05/31 19:15:01 roberto Exp roberto $
|
||||
** Type definitions for Lua objects
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -32,17 +32,25 @@
|
||||
/*
|
||||
** tags for Tagged Values have the following use of bits:
|
||||
** bits 0-3: actual tag (a LUA_T* value)
|
||||
** bit 4: variant bit (for functions, means a light C function)
|
||||
** bit 5: whether value is collectable
|
||||
** bits 4-5: variant bits
|
||||
** bit 6: whether value is collectable
|
||||
*/
|
||||
|
||||
/* Variant tag for light C functions */
|
||||
#define BIT_ISVARIANT (1 << 4)
|
||||
#define LUA_TLCF (LUA_TFUNCTION | BIT_ISVARIANT)
|
||||
/*
|
||||
** LUA_TFUNCTION variants:
|
||||
** 0 - Lua function
|
||||
** 1 - light C function
|
||||
** 2 - regular C function (closure)
|
||||
*/
|
||||
|
||||
/* Variant tags for functions */
|
||||
#define LUA_TLCL (LUA_TFUNCTION | (0 << 4)) /* Lua closure */
|
||||
#define LUA_TLCF (LUA_TFUNCTION | (1 << 4)) /* light C function */
|
||||
#define LUA_TCCL (LUA_TFUNCTION | (2 << 4)) /* C closure */
|
||||
|
||||
|
||||
/* Bit mark for collectable types */
|
||||
#define BIT_ISCOLLECTABLE (1 << 5)
|
||||
#define BIT_ISCOLLECTABLE (1 << 6)
|
||||
|
||||
/* mark a tag as collectable */
|
||||
#define ctb(t) ((t) | BIT_ISCOLLECTABLE)
|
||||
@ -106,8 +114,8 @@ typedef struct lua_TValue {
|
||||
/* raw type tag of a TValue */
|
||||
#define rttype(o) ((o)->tt_)
|
||||
|
||||
/* type tag of a TValue (bits 0-3 for tags + variant bit) */
|
||||
#define ttype(o) (rttype(o) & 0x1F)
|
||||
/* type tag of a TValue (bits 0-3 for tags + variant bits 4-5) */
|
||||
#define ttype(o) (rttype(o) & 0x3F)
|
||||
|
||||
|
||||
/* type tag of a TValue with no variants (bits 0-3) */
|
||||
@ -123,7 +131,9 @@ typedef struct lua_TValue {
|
||||
#define ttisstring(o) checktag((o), ctb(LUA_TSTRING))
|
||||
#define ttistable(o) checktag((o), ctb(LUA_TTABLE))
|
||||
#define ttisfunction(o) (ttypenv(o) == LUA_TFUNCTION)
|
||||
#define ttisclosure(o) checktag((o), ctb(LUA_TFUNCTION))
|
||||
#define ttisclosure(o) ((rttype(o) & 0x1F) == LUA_TFUNCTION)
|
||||
#define ttisCclosure(o) checktag((o), ctb(LUA_TCCL))
|
||||
#define ttisLclosure(o) checktag((o), ctb(LUA_TLCL))
|
||||
#define ttislcf(o) checktag((o), LUA_TLCF)
|
||||
#define ttisuserdata(o) checktag((o), ctb(LUA_TUSERDATA))
|
||||
#define ttisthread(o) checktag((o), ctb(LUA_TTHREAD))
|
||||
@ -140,6 +150,8 @@ typedef struct lua_TValue {
|
||||
#define rawuvalue(o) check_exp(ttisuserdata(o), &val_(o).gc->u)
|
||||
#define uvalue(o) (&rawuvalue(o)->uv)
|
||||
#define clvalue(o) check_exp(ttisclosure(o), &val_(o).gc->cl)
|
||||
#define clLvalue(o) check_exp(ttisLclosure(o), &val_(o).gc->cl.l)
|
||||
#define clCvalue(o) check_exp(ttisCclosure(o), &val_(o).gc->cl.c)
|
||||
#define fvalue(o) check_exp(ttislcf(o), val_(o).f)
|
||||
#define hvalue(o) check_exp(ttistable(o), &val_(o).gc->h)
|
||||
#define bvalue(o) check_exp(ttisboolean(o), val_(o).b)
|
||||
@ -152,7 +164,7 @@ typedef struct lua_TValue {
|
||||
|
||||
|
||||
/* Macros for internal tests */
|
||||
#define righttt(obj) (ttype(obj) == gcvalue(obj)->gch.tt)
|
||||
#define righttt(obj) (ttypenv(obj) == gcvalue(obj)->gch.tt)
|
||||
|
||||
#define checkliveness(g,obj) \
|
||||
lua_longassert(!iscollectable(obj) || \
|
||||
@ -197,9 +209,14 @@ typedef struct lua_TValue {
|
||||
val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TTHREAD)); \
|
||||
checkliveness(G(L),io); }
|
||||
|
||||
#define setclvalue(L,obj,x) \
|
||||
#define setclLvalue(L,obj,x) \
|
||||
{ TValue *io=(obj); \
|
||||
val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TFUNCTION)); \
|
||||
val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TLCL)); \
|
||||
checkliveness(G(L),io); }
|
||||
|
||||
#define setclCvalue(L,obj,x) \
|
||||
{ TValue *io=(obj); \
|
||||
val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TCCL)); \
|
||||
checkliveness(G(L),io); }
|
||||
|
||||
#define sethvalue(L,obj,x) \
|
||||
@ -375,9 +392,9 @@ typedef union Closure {
|
||||
} Closure;
|
||||
|
||||
|
||||
#define isLfunction(o) (ttisclosure(o) && !clvalue(o)->c.isC)
|
||||
#define isLfunction(o) ttisLclosure(o)
|
||||
|
||||
#define getproto(o) (clvalue(o)->l.p)
|
||||
#define getproto(o) (clLvalue(o)->p)
|
||||
|
||||
|
||||
/*
|
||||
|
3
lstate.h
3
lstate.h
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lstate.h,v 2.70 2010/12/20 18:17:46 roberto Exp roberto $
|
||||
** $Id: lstate.h,v 2.71 2010/12/20 19:40:07 roberto Exp roberto $
|
||||
** Global State
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -104,7 +104,6 @@ typedef struct CallInfo {
|
||||
#define CIST_TAIL (1<<6) /* call was tail called */
|
||||
|
||||
|
||||
#define ci_func(ci) (clvalue((ci)->func))
|
||||
#define isLua(ci) ((ci)->callstatus & CIST_LUA)
|
||||
|
||||
|
||||
|
4
ltable.c
4
ltable.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: ltable.c,v 2.56 2011/05/31 18:24:36 roberto Exp roberto $
|
||||
** $Id: ltable.c,v 2.57 2011/05/31 18:27:56 roberto Exp roberto $
|
||||
** Lua tables (hash)
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -468,7 +468,7 @@ const TValue *luaH_getstr (Table *t, TString *key) {
|
||||
** main search function
|
||||
*/
|
||||
const TValue *luaH_get (Table *t, const TValue *key) {
|
||||
switch (ttype(key)) {
|
||||
switch (ttypenv(key)) {
|
||||
case LUA_TNIL: return luaO_nilobject;
|
||||
case LUA_TSTRING: return luaH_getstr(t, rawtsvalue(key));
|
||||
case LUA_TNUMBER: {
|
||||
|
4
ltests.c
4
ltests.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: ltests.c,v 2.117 2011/05/05 16:18:53 roberto Exp roberto $
|
||||
** $Id: ltests.c,v 2.118 2011/05/25 14:12:28 roberto Exp roberto $
|
||||
** Internal Module for Debugging of the Lua Implementation
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -291,7 +291,7 @@ static void checkclosure (global_State *g, Closure *cl) {
|
||||
static int lua_checkpc (pCallInfo ci) {
|
||||
if (!isLua(ci)) return 1;
|
||||
else {
|
||||
Proto *p = ci_func(ci)->l.p;
|
||||
Proto *p = ci_func(ci)->p;
|
||||
return p->code <= ci->u.l.savedpc &&
|
||||
ci->u.l.savedpc <= p->code + p->sizecode;
|
||||
}
|
||||
|
4
ltm.c
4
ltm.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: ltm.c,v 2.12 2010/04/13 20:48:12 roberto Exp roberto $
|
||||
** $Id: ltm.c,v 2.13 2011/02/28 17:32:10 roberto Exp roberto $
|
||||
** Tag methods
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -62,7 +62,7 @@ const TValue *luaT_gettm (Table *events, TMS event, TString *ename) {
|
||||
|
||||
const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, TMS event) {
|
||||
Table *mt;
|
||||
switch (ttype(o)) {
|
||||
switch (ttypenv(o)) {
|
||||
case LUA_TTABLE:
|
||||
mt = hvalue(o)->metatable;
|
||||
break;
|
||||
|
13
lvm.c
13
lvm.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lvm.c,v 2.138 2011/05/31 18:24:36 roberto Exp roberto $
|
||||
** $Id: lvm.c,v 2.139 2011/05/31 18:27:56 roberto Exp roberto $
|
||||
** Lua virtual machine
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -65,7 +65,7 @@ static void traceexec (lua_State *L) {
|
||||
luaD_hook(L, LUA_HOOKCOUNT, -1);
|
||||
}
|
||||
if (mask & LUA_MASKLINE) {
|
||||
Proto *p = ci_func(ci)->l.p;
|
||||
Proto *p = ci_func(ci)->p;
|
||||
int npc = pcRel(ci->u.l.savedpc, p);
|
||||
int newline = getfuncline(p, npc);
|
||||
if (npc == 0 || /* call linehook when enter a new function, */
|
||||
@ -315,7 +315,7 @@ void luaV_concat (lua_State *L, int total) {
|
||||
|
||||
void luaV_objlen (lua_State *L, StkId ra, const TValue *rb) {
|
||||
const TValue *tm;
|
||||
switch (ttype(rb)) {
|
||||
switch (ttypenv(rb)) {
|
||||
case LUA_TTABLE: {
|
||||
Table *h = hvalue(rb);
|
||||
tm = fasttm(L, h->metatable, TM_LEN);
|
||||
@ -385,7 +385,7 @@ static void pushclosure (lua_State *L, Proto *p, UpVal **encup, StkId base,
|
||||
Upvaldesc *uv = p->upvalues;
|
||||
int i;
|
||||
Closure *ncl = luaF_newLclosure(L, p);
|
||||
setclvalue(L, ra, ncl); /* anchor new closure in stack */
|
||||
setclLvalue(L, ra, ncl); /* anchor new closure in stack */
|
||||
for (i = 0; i < nup; i++) { /* fill in its upvalues */
|
||||
if (uv[i].instack) /* upvalue refers to local variable? */
|
||||
ncl->l.upvals[i] = luaF_findupval(L, base + uv[i].idx);
|
||||
@ -512,9 +512,8 @@ void luaV_execute (lua_State *L) {
|
||||
TValue *k;
|
||||
StkId base;
|
||||
newframe: /* reentry point when frame changes (call/return) */
|
||||
lua_assert(isLua(ci));
|
||||
lua_assert(ci == L->ci);
|
||||
cl = &clvalue(ci->func)->l;
|
||||
cl = clLvalue(ci->func);
|
||||
k = cl->p->k;
|
||||
base = ci->u.l.base;
|
||||
/* main loop of interpreter */
|
||||
@ -819,7 +818,7 @@ void luaV_execute (lua_State *L) {
|
||||
if (ncl == NULL) /* no match? */
|
||||
pushclosure(L, p, cl->upvals, base, ra); /* create a new one */
|
||||
else
|
||||
setclvalue(L, ra, ncl); /* push cashed closure */
|
||||
setclLvalue(L, ra, ncl); /* push cashed closure */
|
||||
checkGC(L,
|
||||
L->top = ra + 1; /* limit of live values */
|
||||
luaC_step(L);
|
||||
|
Loading…
Reference in New Issue
Block a user