otimization: closures without upvalues don't need to be closures

This commit is contained in:
Roberto Ierusalimschy
1997-12-15 14:17:20 -02:00
parent 4daae2165d
commit 94144a7821

99
lapi.c
View File

@@ -1,5 +1,5 @@
/* /*
** $Id: lapi.c,v 1.12 1997/12/09 13:35:19 roberto Exp roberto $ ** $Id: lapi.c,v 1.13 1997/12/11 14:48:46 roberto Exp roberto $
** Lua API ** Lua API
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@@ -39,8 +39,12 @@ static int normalized_type (TObject *o)
{ {
int t = ttype(o); int t = ttype(o);
switch (t) { switch (t) {
case LUA_T_MARK: case LUA_T_CLMARK:
return LUA_T_FUNCTION; return LUA_T_CLOSURE;
case LUA_T_PMARK:
return LUA_T_PROTO;
case LUA_T_CMARK:
return LUA_T_CPROTO;
default: default:
return t; return t;
} }
@@ -54,6 +58,12 @@ static void set_normalized (TObject *d, TObject *s)
} }
static TObject *luaA_protovalue (TObject *o)
{
return (ttype(o) == LUA_T_CLOSURE) ? protovalue(o) : o;
}
void luaA_packresults (void) void luaA_packresults (void)
{ {
luaV_pack(L->Cstack.lua2C, L->Cstack.num, L->stack.top); luaV_pack(L->Cstack.lua2C, L->Cstack.num, L->stack.top);
@@ -247,7 +257,7 @@ int lua_isuserdata (lua_Object o)
int lua_iscfunction (lua_Object o) int lua_iscfunction (lua_Object o)
{ {
return (o != LUA_NOOBJECT) && (lua_tag(o) == LUA_T_CPROTO); return (lua_tag(o) == LUA_T_CPROTO);
} }
int lua_isnumber (lua_Object o) int lua_isnumber (lua_Object o)
@@ -263,7 +273,8 @@ int lua_isstring (lua_Object o)
int lua_isfunction (lua_Object o) int lua_isfunction (lua_Object o)
{ {
return (o != LUA_NOOBJECT) && (normalized_type(Address(o)) == LUA_T_FUNCTION); int t = lua_tag(o);
return (t == LUA_T_PROTO) || (t == LUA_T_CPROTO);
} }
@@ -292,7 +303,7 @@ lua_CFunction lua_getcfunction (lua_Object object)
{ {
if (!lua_iscfunction(object)) if (!lua_iscfunction(object))
return NULL; return NULL;
else return fvalue(protovalue(Address(object))); else return fvalue(luaA_protovalue(Address(object)));
} }
@@ -361,14 +372,29 @@ void lua_pushobject (lua_Object o)
int lua_tag (lua_Object lo) int lua_tag (lua_Object lo)
{ {
if (lo == LUA_NOOBJECT) return LUA_T_NIL; if (lo == LUA_NOOBJECT)
return LUA_T_NIL;
else { else {
TObject *o = Address(lo); TObject *o = Address(lo);
int t = luaT_efectivetag(o); int t;
if (t == LUA_T_USERDATA) switch (t = ttype(o)) {
return o->value.ts->u.d.tag; case LUA_T_USERDATA:
else return o->value.ts->u.d.tag;
return t; case LUA_T_ARRAY:
return o->value.a->htag;
case LUA_T_CLOSURE: case LUA_T_CLMARK:
return o->value.cl->consts[0].ttype;
case LUA_T_PMARK:
return LUA_T_PROTO;
case LUA_T_CMARK:
return LUA_T_CPROTO;
#ifdef DEBUG
case LUA_T_LINE:
lua_error("internal error");
#endif
default:
return t;
}
} }
} }
@@ -407,10 +433,12 @@ lua_LHFunction lua_linehook = NULL;
lua_Function lua_stackedfunction (int level) lua_Function lua_stackedfunction (int level)
{ {
StkId i; StkId i;
for (i = (L->stack.top-1)-L->stack.stack; i>=0; i--) for (i = (L->stack.top-1)-L->stack.stack; i>=0; i--) {
if (L->stack.stack[i].ttype == LUA_T_MARK) int t = L->stack.stack[i].ttype;
if (t == LUA_T_CLMARK || t == LUA_T_PMARK || t == LUA_T_CMARK)
if (level-- == 0) if (level-- == 0)
return Ref(L->stack.stack+i); return Ref(L->stack.stack+i);
}
return LUA_NOOBJECT; return LUA_NOOBJECT;
} }
@@ -418,18 +446,19 @@ lua_Function lua_stackedfunction (int level)
int lua_currentline (lua_Function func) int lua_currentline (lua_Function func)
{ {
TObject *f = Address(func); TObject *f = Address(func);
return (f+1 < L->stack.top && (f+1)->ttype == LUA_T_LINE) ? (f+1)->value.i : -1; return (f+1 < L->stack.top && (f+1)->ttype == LUA_T_LINE) ?
(f+1)->value.i : -1;
} }
lua_Object lua_getlocal (lua_Function func, int local_number, char **name) lua_Object lua_getlocal (lua_Function func, int local_number, char **name)
{ {
/* check whether func is a function */ /* check whether func is a Lua function */
if (!lua_isfunction(func)) if (lua_tag(func) != LUA_T_PROTO)
return LUA_NOOBJECT; return LUA_NOOBJECT;
else { else {
TObject *f = luaA_Address(func); TObject *f = Address(func);
TProtoFunc *fp = protovalue(f)->value.tf; TProtoFunc *fp = luaA_protovalue(f)->value.tf;
*name = luaF_getlocalname(fp, local_number, lua_currentline(func)); *name = luaF_getlocalname(fp, local_number, lua_currentline(func));
if (*name) { if (*name) {
/* if "*name", there must be a LUA_T_LINE */ /* if "*name", there must be a LUA_T_LINE */
@@ -444,19 +473,24 @@ lua_Object lua_getlocal (lua_Function func, int local_number, char **name)
int lua_setlocal (lua_Function func, int local_number) int lua_setlocal (lua_Function func, int local_number)
{ {
TObject *f = Address(func); /* check whether func is a Lua function */
TProtoFunc *fp = protovalue(f)->value.tf; if (lua_tag(func) != LUA_T_PROTO)
char *name = luaF_getlocalname(fp, local_number, lua_currentline(func));
checkCparams(1);
--L->stack.top;
if (name) {
/* if "name", there must be a LUA_T_LINE */
/* therefore, f+2 points to function base */
*((f+2)+(local_number-1)) = *L->stack.top;
return 1;
}
else
return 0; return 0;
else {
TObject *f = Address(func);
TProtoFunc *fp = luaA_protovalue(f)->value.tf;
char *name = luaF_getlocalname(fp, local_number, lua_currentline(func));
checkCparams(1);
--L->stack.top;
if (name) {
/* if "name", there must be a LUA_T_LINE */
/* therefore, f+2 points to function base */
*((f+2)+(local_number-1)) = *L->stack.top;
return 1;
}
else
return 0;
}
} }
@@ -465,7 +499,7 @@ void lua_funcinfo (lua_Object func, char **filename, int *linedefined)
if (!lua_isfunction(func)) if (!lua_isfunction(func))
lua_error("API - `funcinfo' called with a non-function value"); lua_error("API - `funcinfo' called with a non-function value");
else { else {
TObject *f = protovalue(Address(func)); TObject *f = luaA_protovalue(Address(func));
if (ttype(f) == LUA_T_PROTO) { if (ttype(f) == LUA_T_PROTO) {
*filename = tfvalue(f)->fileName->str; *filename = tfvalue(f)->fileName->str;
*linedefined = tfvalue(f)->lineDefined; *linedefined = tfvalue(f)->lineDefined;
@@ -548,7 +582,6 @@ static void do_unprotectedrun (lua_CFunction f, int nParams, int nResults)
luaD_openstack(nParams); luaD_openstack(nParams);
L->stack.stack[base].ttype = LUA_T_CPROTO; L->stack.stack[base].ttype = LUA_T_CPROTO;
L->stack.stack[base].value.f = f; L->stack.stack[base].value.f = f;
luaF_simpleclosure(L->stack.stack+base);
luaD_call(base+1, nResults); luaD_call(base+1, nResults);
} }