commit b1b0c219f5255a0cd0921ebc0a77a81f99b72532
parent be3212de781786c0a68365dee1d3510407b5c325
Author: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
Date: Thu, 23 Dec 1999 16:19:35 -0200
new ttypes to distinguish between C closures and Lua closures.
Diffstat:
15 files changed, 180 insertions(+), 147 deletions(-)
diff --git a/lapi.c b/lapi.c
@@ -1,5 +1,5 @@
/*
-** $Id: lapi.c,v 1.63 1999/12/06 12:03:45 roberto Exp roberto $
+** $Id: lapi.c,v 1.64 1999/12/14 18:31:20 roberto Exp roberto $
** Lua API
** See Copyright Notice in lua.h
*/
@@ -30,19 +30,13 @@ const char lua_ident[] = "$Lua: " LUA_VERSION " " LUA_COPYRIGHT " $\n"
-lua_Type luaA_normalizedtype (const TObject *o) {
- int t = ttype(o);
- switch (t) {
- case LUA_T_PMARK:
- return LUA_T_PROTO;
- case LUA_T_CMARK:
- return LUA_T_CPROTO;
- case LUA_T_CLMARK:
- return LUA_T_CLOSURE;
- default:
- return t;
- }
-}
+const lua_Type luaA_normtype[] = { /* ORDER LUA_T */
+ LUA_T_USERDATA, LUA_T_NUMBER, LUA_T_STRING, LUA_T_ARRAY,
+ LUA_T_LPROTO, LUA_T_CPROTO, LUA_T_NIL,
+ LUA_T_LCLOSURE, LUA_T_CCLOSURE,
+ LUA_T_LCLOSURE, LUA_T_CCLOSURE, /* LUA_T_LCLMARK, LUA_T_CCLMARK */
+ LUA_T_LPROTO, LUA_T_CPROTO /* LUA_T_LMARK, LUA_T_CMARK */
+};
void luaA_setnormalized (TObject *d, const TObject *s) {
@@ -52,7 +46,15 @@ void luaA_setnormalized (TObject *d, const TObject *s) {
const TObject *luaA_protovalue (const TObject *o) {
- return (luaA_normalizedtype(o) == LUA_T_CLOSURE) ? protovalue(o) : o;
+ switch (luaA_normalizedtype(o)) {
+ case LUA_T_CCLOSURE: case LUA_T_LCLOSURE:
+ return protovalue(o);
+ default:
+ LUA_ASSERT(L, luaA_normalizedtype(o) == LUA_T_LPROTO ||
+ luaA_normalizedtype(o) == LUA_T_CPROTO,
+ "invalid `function'");
+ return o;
+ }
}
@@ -228,26 +230,32 @@ int lua_isnumber (lua_State *L, lua_Object o) {
}
int lua_isstring (lua_State *L, lua_Object o) {
- int t = lua_tag(L, o);
- return (t == LUA_T_STRING) || (t == LUA_T_NUMBER);
+ UNUSED(L);
+ return (o != LUA_NOOBJECT && (ttype(o) == LUA_T_STRING ||
+ ttype(o) == LUA_T_NUMBER));
}
int lua_isfunction (lua_State *L, lua_Object o) {
- int t = lua_tag(L, o);
- return (t == LUA_T_PROTO) || (t == LUA_T_CPROTO);
+ return *lua_type(L, o) == 'f';
}
int lua_equal(lua_State *L, lua_Object o1, lua_Object o2) {
UNUSED(L);
- if (o1 == LUA_NOOBJECT || o2 == LUA_NOOBJECT) return (o1 == o2);
- else return luaO_equalObj(o1, o2);
+ if (o1 == LUA_NOOBJECT || o2 == LUA_NOOBJECT)
+ return (o1 == o2);
+ else {
+ TObject obj1, obj2;
+ luaA_setnormalized(&obj1, o1);
+ luaA_setnormalized(&obj2, o2);
+ return luaO_equalObj(&obj1, &obj2);
+ }
}
double lua_getnumber (lua_State *L, lua_Object obj) {
UNUSED(L);
- if (obj == LUA_NOOBJECT) return 0.0;
- if (tonumber(obj)) return 0.0;
+ if (obj == LUA_NOOBJECT || tonumber(obj))
+ return 0.0;
else return (nvalue(obj));
}
@@ -339,28 +347,11 @@ void lua_pushobject (lua_State *L, lua_Object o) {
int lua_tag (lua_State *L, lua_Object o) {
UNUSED(L);
if (o == LUA_NOOBJECT)
- return LUA_T_NIL;
- else {
- int t;
- switch (t = ttype(o)) {
- case LUA_T_USERDATA:
- return o->value.ts->u.d.tag;
- case LUA_T_ARRAY:
- return o->value.a->htag;
- case LUA_T_PMARK:
- return LUA_T_PROTO;
- case LUA_T_CMARK:
- return LUA_T_CPROTO;
- case LUA_T_CLOSURE: case LUA_T_CLMARK:
- return o->value.cl->consts[0].ttype;
-#ifdef DEBUG
- case LUA_T_LINE:
- LUA_INTERNALERROR(L, "invalid type");
-#endif
- default:
- return t;
- }
- }
+ return LUA_T_NIL;
+ else if (ttype(o) == LUA_T_USERDATA) /* to allow `old' tags (deprecated) */
+ return o->value.ts->u.d.tag;
+ else
+ return luaT_effectivetag(o);
}
diff --git a/lapi.h b/lapi.h
@@ -1,5 +1,5 @@
/*
-** $Id: lapi.h,v 1.10 1999/12/02 16:24:45 roberto Exp roberto $
+** $Id: lapi.h,v 1.11 1999/12/14 18:33:29 roberto Exp roberto $
** Auxiliary functions from Lua API
** See Copyright Notice in lua.h
*/
@@ -11,7 +11,11 @@
#include "lobject.h"
-lua_Type luaA_normalizedtype (const TObject *o);
+extern const lua_Type luaA_normtype[];
+
+#define luaA_normalizedtype(o) (luaA_normtype[-ttype(o)])
+
+
void luaA_setnormalized (TObject *d, const TObject *s);
void luaA_checkCparams (lua_State *L, int nParams);
const TObject *luaA_protovalue (const TObject *o);
diff --git a/lbuiltin.c b/lbuiltin.c
@@ -1,5 +1,5 @@
/*
-** $Id: lbuiltin.c,v 1.85 1999/12/14 18:42:57 roberto Exp roberto $
+** $Id: lbuiltin.c,v 1.86 1999/12/20 13:10:38 roberto Exp roberto $
** Built-in functions
** See Copyright Notice in lua.h
*/
@@ -377,10 +377,10 @@ void luaB_tostring (lua_State *L) {
case LUA_T_ARRAY:
sprintf(buff, "table: %p", o->value.a);
break;
- case LUA_T_CLOSURE:
+ case LUA_T_LCLOSURE: case LUA_T_CCLOSURE:
sprintf(buff, "function: %p", o->value.cl);
break;
- case LUA_T_PROTO:
+ case LUA_T_LPROTO:
sprintf(buff, "function: %p", o->value.tf);
break;
case LUA_T_CPROTO:
diff --git a/ldebug.c b/ldebug.c
@@ -1,5 +1,5 @@
/*
-** $Id: $
+** $Id: ldebug.c,v 1.1 1999/12/14 18:31:20 roberto Exp roberto $
** Debug Interface
** See Copyright Notice in lua.h
*/
@@ -42,10 +42,11 @@ int lua_setdebug (lua_State *L, int debug) {
lua_Function lua_stackedfunction (lua_State *L, int level) {
int i;
for (i = (L->top-1)-L->stack; i>=0; i--) {
- int t = L->stack[i].ttype;
- if (t == LUA_T_CLMARK || t == LUA_T_PMARK || t == LUA_T_CMARK)
- if (level-- == 0)
+ if (is_T_MARK(L->stack[i].ttype)) {
+ if (level == 0)
return L->stack+i;
+ level--;
+ }
}
return LUA_NOOBJECT;
}
@@ -53,8 +54,12 @@ lua_Function lua_stackedfunction (lua_State *L, int level) {
int lua_nups (lua_State *L, lua_Function f) {
UNUSED(L);
- return (!f || luaA_normalizedtype(f) != LUA_T_CLOSURE) ? 0 :
- f->value.cl->nelems;
+ switch (luaA_normalizedtype(f)) {
+ case LUA_T_LCLOSURE: case LUA_T_CCLOSURE:
+ return f->value.cl->nelems;
+ default:
+ return 0;
+ }
}
@@ -66,7 +71,7 @@ int lua_currentline (lua_State *L, lua_Function f) {
lua_Object lua_getlocal (lua_State *L, lua_Function f, int local_number,
const char **name) {
/* check whether `f' is a Lua function */
- if (lua_tag(L, f) != LUA_T_PROTO)
+ if (lua_tag(L, f) != LUA_T_LPROTO)
return LUA_NOOBJECT;
else {
TProtoFunc *fp = luaA_protovalue(f)->value.tf;
@@ -84,7 +89,7 @@ lua_Object lua_getlocal (lua_State *L, lua_Function f, int local_number,
int lua_setlocal (lua_State *L, lua_Function f, int local_number) {
/* check whether `f' is a Lua function */
- if (lua_tag(L, f) != LUA_T_PROTO)
+ if (lua_tag(L, f) != LUA_T_LPROTO)
return 0;
else {
TProtoFunc *fp = luaA_protovalue(f)->value.tf;
@@ -110,7 +115,7 @@ void lua_funcinfo (lua_State *L, lua_Object func,
lua_error(L, "API error - `funcinfo' called with a non-function value");
else {
const TObject *f = luaA_protovalue(func);
- if (luaA_normalizedtype(f) == LUA_T_PROTO) {
+ if (luaA_normalizedtype(f) == LUA_T_LPROTO) {
*source = tfvalue(f)->source->str;
*linedefined = tfvalue(f)->lineDefined;
}
diff --git a/ldo.c b/ldo.c
@@ -1,5 +1,5 @@
/*
-** $Id: ldo.c,v 1.58 1999/12/06 12:03:45 roberto Exp roberto $
+** $Id: ldo.c,v 1.59 1999/12/21 18:04:41 roberto Exp roberto $
** Stack and Call structure of Lua
** See Copyright Notice in lua.h
*/
@@ -93,7 +93,8 @@ void luaD_adjusttop (lua_State *L, StkId base, int extra) {
** Open a hole inside the stack at `pos'
*/
void luaD_openstack (lua_State *L, StkId pos) {
- luaO_memup(pos+1, pos, (L->top-pos)*sizeof(TObject));
+ int i = L->top-pos;
+ while (i--) pos[i+1] = pos[i];
incr_top;
}
@@ -122,15 +123,18 @@ static void luaD_callHook (lua_State *L, StkId func, lua_CHFunction callhook,
if (isreturn)
callhook(L, LUA_NOOBJECT, "(return)", 0);
else {
- if (ttype(func) == LUA_T_PROTO)
- callhook(L, func, tfvalue(func)->source->str,
- tfvalue(func)->lineDefined);
- else if (ttype(func) == LUA_T_CLOSURE &&
- ttype(clvalue(func)->consts) == LUA_T_PROTO)
- callhook(L, func, tfvalue(protovalue(func))->source->str,
- tfvalue(protovalue(func))->lineDefined);
- else
- callhook(L, func, "(C)", -1);
+ switch (ttype(func)) {
+ case LUA_T_LPROTO:
+ callhook(L, func, tfvalue(func)->source->str,
+ tfvalue(func)->lineDefined);
+ break;
+ case LUA_T_LCLOSURE:
+ callhook(L, func, tfvalue(protovalue(func))->source->str,
+ tfvalue(protovalue(func))->lineDefined);
+ break;
+ default:
+ callhook(L, func, "(C)", -1);
+ }
}
L->allowhooks = 1;
L->top = old_top;
@@ -158,16 +162,16 @@ static StkId callC (lua_State *L, lua_CFunction f, StkId base) {
}
-static StkId callCclosure (lua_State *L, const struct Closure *cl,
- lua_CFunction f, StkId base) {
+static StkId callCclosure (lua_State *L, const struct Closure *cl, StkId base) {
int nup = cl->nelems; /* number of upvalues */
+ int n = L->top-base; /* number of arguments (to move up) */
luaD_checkstack(L, nup);
/* open space for upvalues as extra arguments */
- luaO_memup(base+nup, base, (L->top-base)*sizeof(TObject));
- /* copy upvalues into stack */
- memcpy(base, cl->consts+1, nup*sizeof(TObject));
+ while (n--) *(base+nup+n) = *(base+n);
L->top += nup;
- return callC(L, f, base);
+ /* copy upvalues into stack */
+ while (nup--) *(base+nup) = cl->consts[nup+1];
+ return callC(L, fvalue(cl->consts), base);
}
@@ -197,17 +201,20 @@ void luaD_call (lua_State *L, StkId func, int nResults) {
ttype(func) = LUA_T_CMARK;
firstResult = callC(L, fvalue(func), func+1);
break;
- case LUA_T_PROTO:
- ttype(func) = LUA_T_PMARK;
+ case LUA_T_LPROTO:
+ ttype(func) = LUA_T_LMARK;
firstResult = luaV_execute(L, NULL, tfvalue(func), func+1);
break;
- case LUA_T_CLOSURE: {
+ case LUA_T_LCLOSURE: {
Closure *c = clvalue(func);
- TObject *proto = c->consts;
- ttype(func) = LUA_T_CLMARK;
- firstResult = (ttype(proto) == LUA_T_CPROTO) ?
- callCclosure(L, c, fvalue(proto), func+1) :
- luaV_execute(L, c, tfvalue(proto), func+1);
+ ttype(func) = LUA_T_LCLMARK;
+ firstResult = luaV_execute(L, c, tfvalue(c->consts), func+1);
+ break;
+ }
+ case LUA_T_CCLOSURE: {
+ Closure *c = clvalue(func);
+ ttype(func) = LUA_T_CCLMARK;
+ firstResult = callCclosure(L, c, func+1);
break;
}
default: { /* `func' is not a function; check the `function' tag method */
@@ -226,16 +233,18 @@ void luaD_call (lua_State *L, StkId func, int nResults) {
nResults = L->top - firstResult;
else
luaD_adjusttop(L, firstResult, nResults);
- /* move results to func (to erase parameters and function) */
- luaO_memdown(func, firstResult, nResults*sizeof(TObject));
- L->top = func+nResults;
+ /* move results to `func' (to erase parameters and function) */
+ while (nResults) {
+ *func++ = *(L->top - nResults);
+ nResults--;
+ }
+ L->top = func;
}
static void message (lua_State *L, const char *s) {
const TObject *em = &(luaS_assertglobalbyname(L, "_ERRORMESSAGE")->value);
- if (ttype(em) == LUA_T_PROTO || ttype(em) == LUA_T_CPROTO ||
- ttype(em) == LUA_T_CLOSURE) {
+ if (*luaO_typename(em) == 'f') {
*L->top = *em;
incr_top;
lua_pushstring(L, s);
@@ -313,7 +322,7 @@ static int protectedparser (lua_State *L, ZIO *z, int bin) {
L->errorJmp = oldErr;
if (status) return 1; /* error code */
if (tf == NULL) return 2; /* `natural' end */
- L->top->ttype = LUA_T_PROTO; /* push new function on the stack */
+ L->top->ttype = LUA_T_LPROTO; /* push new function on the stack */
L->top->value.tf = tf;
incr_top;
return 0;
diff --git a/lgc.c b/lgc.c
@@ -1,5 +1,5 @@
/*
-** $Id: lgc.c,v 1.36 1999/12/14 18:31:20 roberto Exp roberto $
+** $Id: lgc.c,v 1.37 1999/12/21 18:04:41 roberto Exp roberto $
** Garbage Collector
** See Copyright Notice in lua.h
*/
@@ -100,10 +100,11 @@ static int markobject (lua_State *L, TObject *o) {
case LUA_T_ARRAY:
hashmark(L, avalue(o));
break;
- case LUA_T_CLOSURE: case LUA_T_CLMARK:
+ case LUA_T_LCLOSURE: case LUA_T_LCLMARK:
+ case LUA_T_CCLOSURE: case LUA_T_CCLMARK:
closuremark(L, o->value.cl);
break;
- case LUA_T_PROTO: case LUA_T_PMARK:
+ case LUA_T_LPROTO: case LUA_T_LMARK:
protomark(L, o->value.tf);
break;
default: break; /* numbers, cprotos, etc */
diff --git a/lobject.c b/lobject.c
@@ -1,5 +1,5 @@
/*
-** $Id: lobject.c,v 1.26 1999/11/26 18:59:20 roberto Exp roberto $
+** $Id: lobject.c,v 1.27 1999/12/14 18:31:20 roberto Exp roberto $
** Some generic functions over Lua objects
** See Copyright Notice in lua.h
*/
@@ -14,8 +14,9 @@
const char *const luaO_typenames[] = { /* ORDER LUA_T */
- "userdata", "number", "string", "table", "function", "function",
- "nil", "function", "mark", "mark", "mark", "line", NULL
+ "userdata", "number", "string", "table", "function", "function", "nil",
+ "function", "function", "function", "function", "function", "function",
+ "line", NULL
};
@@ -34,13 +35,20 @@ unsigned long luaO_power2 (unsigned long n) {
int luaO_equalval (const TObject *t1, const TObject *t2) {
switch (ttype(t1)) {
- case LUA_T_NIL: return 1;
- case LUA_T_NUMBER: return nvalue(t1) == nvalue(t2);
- case LUA_T_STRING: case LUA_T_USERDATA: return svalue(t1) == svalue(t2);
- case LUA_T_ARRAY: return avalue(t1) == avalue(t2);
- case LUA_T_PROTO: return tfvalue(t1) == tfvalue(t2);
- case LUA_T_CPROTO: return fvalue(t1) == fvalue(t2);
- case LUA_T_CLOSURE: return t1->value.cl == t2->value.cl;
+ case LUA_T_NIL:
+ return 1;
+ case LUA_T_NUMBER:
+ return nvalue(t1) == nvalue(t2);
+ case LUA_T_STRING: case LUA_T_USERDATA:
+ return svalue(t1) == svalue(t2);
+ case LUA_T_ARRAY:
+ return avalue(t1) == avalue(t2);
+ case LUA_T_LPROTO:
+ return tfvalue(t1) == tfvalue(t2);
+ case LUA_T_CPROTO:
+ return fvalue(t1) == fvalue(t2);
+ case LUA_T_CCLOSURE: case LUA_T_LCLOSURE:
+ return t1->value.cl == t2->value.cl;
default:
LUA_INTERNALERROR(L, "invalid type");
return 0; /* UNREACHABLE */
diff --git a/lobject.h b/lobject.h
@@ -1,5 +1,5 @@
/*
-** $Id: lobject.h,v 1.39 1999/12/02 16:24:45 roberto Exp roberto $
+** $Id: lobject.h,v 1.40 1999/12/14 18:33:29 roberto Exp roberto $
** Type definitions for Lua objects
** See Copyright Notice in lua.h
*/
@@ -69,25 +69,33 @@ typedef enum {
LUA_T_NUMBER = -1, /* fixed tag for numbers */
LUA_T_STRING = -2, /* fixed tag for strings */
LUA_T_ARRAY = -3, /* tag default for tables (or arrays) */
- LUA_T_PROTO = -4, /* fixed tag for functions */
- LUA_T_CPROTO = -5, /* fixed tag for Cfunctions */
+ LUA_T_LPROTO = -4, /* fixed tag for Lua functions */
+ LUA_T_CPROTO = -5, /* fixed tag for C functions */
LUA_T_NIL = -6, /* last "pre-defined" tag */
- LUA_T_CLOSURE = -7,
- LUA_T_CLMARK = -8, /* mark for closures */
- LUA_T_PMARK = -9, /* mark for Lua prototypes */
- LUA_T_CMARK = -10, /* mark for C prototypes */
- LUA_T_LINE = -11
+ LUA_T_LCLOSURE = -7, /* Lua closure */
+ LUA_T_CCLOSURE = -8, /* C closure */
+ LUA_T_LCLMARK = -9 ,/* mark for Lua closures */
+ LUA_T_CCLMARK = -10,/* mark for C closures */
+ LUA_T_LMARK = -11, /* mark for Lua prototypes */
+ LUA_T_CMARK = -12, /* mark for C prototypes */
+ LUA_T_LINE = -13
} lua_Type;
#define NUM_TAGS 7
+/*
+** chech whether t is a mark; ttypes are negative numbers, so the
+** comparisons look reversed. (ORDER LUA_T)
+*/
+#define is_T_MARK(t) (LUA_T_CMARK <= (t) && (t) <= LUA_T_LCLMARK)
+
typedef union {
lua_CFunction f; /* LUA_T_CPROTO, LUA_T_CMARK */
real n; /* LUA_T_NUMBER */
struct TaggedString *ts; /* LUA_T_STRING, LUA_T_USERDATA */
- struct TProtoFunc *tf; /* LUA_T_PROTO, LUA_T_PMARK */
- struct Closure *cl; /* LUA_T_CLOSURE, LUA_T_CLMARK */
+ struct TProtoFunc *tf; /* LUA_T_LPROTO, LUA_T_LMARK */
+ struct Closure *cl; /* LUA_T_[CL]CLOSURE, LUA_T_[CL]CLMARK */
struct Hash *a; /* LUA_T_ARRAY */
int i; /* LUA_T_LINE */
} Value;
diff --git a/lparser.c b/lparser.c
@@ -1,5 +1,5 @@
/*
-** $Id: lparser.c,v 1.48 1999/12/21 17:31:28 roberto Exp roberto $
+** $Id: lparser.c,v 1.49 1999/12/22 16:58:36 roberto Exp roberto $
** LL(1) Parser and code generator for Lua
** See Copyright Notice in lua.h
*/
@@ -547,7 +547,7 @@ static void func_onstack (LexState *ls, FuncState *func) {
FuncState *fs = ls->fs;
int i;
int c = next_constant(ls, fs->f);
- ttype(&fs->f->consts[c]) = LUA_T_PROTO;
+ ttype(&fs->f->consts[c]) = LUA_T_LPROTO;
fs->f->consts[c].value.tf = func->f;
if (func->nupvalues == 0)
code_constant(ls, c);
@@ -580,7 +580,7 @@ static void init_state (LexState *ls, FuncState *fs, TaggedString *source) {
code_byte(ls, 0); /* to be filled with arg information */
/* push function (to avoid GC) */
tfvalue(L->top) = f;
- ttype(L->top) = LUA_T_PROTO;
+ ttype(L->top) = LUA_T_LPROTO;
incr_top;
}
diff --git a/lref.c b/lref.c
@@ -1,5 +1,5 @@
/*
-** $Id: lref.c,v 1.3 1999/11/22 13:12:07 roberto Exp roberto $
+** $Id: lref.c,v 1.4 1999/12/14 18:31:20 roberto Exp roberto $
** REF mechanism
** See Copyright Notice in lua.h
*/
@@ -85,15 +85,10 @@ static int ismarked (const TObject *o) {
return o->value.ts->marked;
case LUA_T_ARRAY:
return o->value.a->marked;
- case LUA_T_CLOSURE:
+ case LUA_T_LCLOSURE: case LUA_T_CCLOSURE:
return o->value.cl->marked;
- case LUA_T_PROTO:
+ case LUA_T_LPROTO:
return o->value.tf->marked;
-#ifdef DEBUG
- case LUA_T_LINE: case LUA_T_CLMARK:
- case LUA_T_CMARK: case LUA_T_PMARK:
- LUA_INTERNALERROR(L, "invalid type");
-#endif
default: /* number or cproto */
return 1;
}
diff --git a/ltable.c b/ltable.c
@@ -1,5 +1,5 @@
/*
-** $Id: ltable.c,v 1.31 1999/11/26 18:59:20 roberto Exp roberto $
+** $Id: ltable.c,v 1.32 1999/12/07 12:05:34 roberto Exp roberto $
** Lua tables (hash)
** See Copyright Notice in lua.h
*/
@@ -52,13 +52,13 @@ Node *luaH_mainposition (const Hash *t, const TObject *key) {
case LUA_T_ARRAY:
h = IntPoint(L, avalue(key));
break;
- case LUA_T_PROTO:
+ case LUA_T_LPROTO:
h = IntPoint(L, tfvalue(key));
break;
case LUA_T_CPROTO:
h = IntPoint(L, fvalue(key));
break;
- case LUA_T_CLOSURE:
+ case LUA_T_LCLOSURE: case LUA_T_CCLOSURE:
h = IntPoint(L, clvalue(key));
break;
default:
diff --git a/ltests.c b/ltests.c
@@ -1,5 +1,5 @@
/*
-** $Id: lbuiltin.c,v 1.83 1999/12/07 12:05:34 roberto Exp $
+** $Id: ltests.c,v 1.1 1999/12/14 18:31:20 roberto Exp roberto $
** Internal Module for Debugging of the Lua Implementation
** See Copyright Notice in lua.h
*/
@@ -17,6 +17,7 @@
#include "lstring.h"
#include "ltable.h"
#include "lua.h"
+#include "luadebug.h"
void luaB_opentests (lua_State *L);
@@ -195,6 +196,12 @@ static void testC (lua_State *L) {
else if EQ("rawsettable") {
lua_rawsettable(L);
}
+ else if EQ("tag") {
+ lua_pushnumber(L, lua_tag(L, reg[getreg(L, &pc)]));
+ }
+ else if EQ("type") {
+ lua_pushstring(L, lua_type(L, reg[getreg(L, &pc)]));
+ }
else if EQ("nextvar") {
lua_pushstring(L, lua_nextvar(L, lua_getstring(L, reg[getreg(L, &pc)])));
}
@@ -223,6 +230,10 @@ static void testC (lua_State *L) {
int n = getreg(L, &pc);
lua_settagmethod(L, (int)lua_getnumber(L, reg[n]), getname(&pc));
}
+ else if EQ("getfunc") {
+ int n = getreg(L, &pc);
+ reg[n] = lua_stackedfunction(L, getnum(&pc));
+ }
else if EQ("beginblock") {
lua_beginblock(L);
}
diff --git a/ltm.c b/ltm.c
@@ -1,5 +1,5 @@
/*
-** $Id: ltm.c,v 1.28 1999/10/04 17:51:04 roberto Exp roberto $
+** $Id: ltm.c,v 1.29 1999/11/22 13:12:07 roberto Exp roberto $
** Tag methods
** See Copyright Notice in lua.h
*/
@@ -42,7 +42,7 @@ static const char luaT_validevents[NUM_TAGS][IM_N] = {
{1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1}, /* LUA_T_NUMBER */
{1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, /* LUA_T_STRING */
{0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1}, /* LUA_T_ARRAY */
-{1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, /* LUA_T_PROTO */
+{1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, /* LUA_T_LPROTO */
{1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, /* LUA_T_CPROTO */
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1} /* LUA_T_NIL */
};
@@ -104,23 +104,21 @@ int lua_copytagmethods (lua_State *L, int tagto, int tagfrom) {
int luaT_effectivetag (const TObject *o) {
+ static const int realtag[] = { /* ORDER LUA_T */
+ LUA_T_USERDATA, LUA_T_NUMBER, LUA_T_STRING, LUA_T_ARRAY,
+ LUA_T_LPROTO, LUA_T_CPROTO, LUA_T_NIL,
+ LUA_T_LPROTO, LUA_T_CPROTO, /* LUA_T_LCLOSURE, LUA_T_CCLOSURE */
+ LUA_T_LPROTO, LUA_T_CPROTO, /* LUA_T_LCLMARK, LUA_T_CCLMARK */
+ LUA_T_LPROTO, LUA_T_CPROTO /* LUA_T_LMARK, LUA_T_CMARK */
+ };
int t;
switch (t = ttype(o)) {
- case LUA_T_ARRAY:
- return o->value.a->htag;
case LUA_T_USERDATA: {
int tag = o->value.ts->u.d.tag;
- return (tag >= 0) ? LUA_T_USERDATA : tag;
+ return (tag >= 0) ? LUA_T_USERDATA : tag; /* deprecated test */
}
- case LUA_T_CLOSURE:
- return o->value.cl->consts[0].ttype;
-#ifdef DEBUG
- case LUA_T_PMARK: case LUA_T_CMARK:
- case LUA_T_CLMARK: case LUA_T_LINE:
- LUA_INTERNALERROR(L, "invalid type");
-#endif
- default:
- return t;
+ case LUA_T_ARRAY: return o->value.a->htag;
+ default: return realtag[-t];
}
}
diff --git a/lundump.c b/lundump.c
@@ -1,5 +1,5 @@
/*
-** $Id: lundump.c,v 1.24 1999/12/02 18:45:03 lhf Exp $
+** $Id: lundump.c,v 1.16 1999/12/02 19:11:51 roberto Exp roberto $
** load bytecodes from files
** See Copyright Notice in lua.h
*/
@@ -135,7 +135,7 @@ static void LoadConstants (lua_State* L, TProtoFunc* tf, ZIO* Z, int native)
case LUA_T_STRING:
tsvalue(o)=LoadTString(L,Z);
break;
- case LUA_T_PROTO:
+ case LUA_T_LPROTO:
tfvalue(o)=LoadFunction(L,Z,native);
break;
case LUA_T_NIL:
diff --git a/lvm.c b/lvm.c
@@ -1,5 +1,5 @@
/*
-** $Id: lvm.c,v 1.73 1999/12/14 18:31:20 roberto Exp roberto $
+** $Id: lvm.c,v 1.74 1999/12/21 18:04:41 roberto Exp roberto $
** Lua virtual machine
** See Copyright Notice in lua.h
*/
@@ -86,8 +86,10 @@ void luaV_closure (lua_State *L, int nelems) {
Closure *c = luaF_newclosure(L, nelems);
c->consts[0] = *(L->top-1);
L->top -= nelems;
- memcpy(&c->consts[1], L->top-1, nelems*sizeof(TObject));
- ttype(L->top-1) = LUA_T_CLOSURE;
+ while (nelems--)
+ c->consts[nelems+1] = *(L->top-1+nelems);
+ ttype(L->top-1) = (ttype(&c->consts[0]) == LUA_T_CPROTO) ?
+ LUA_T_CCLOSURE : LUA_T_LCLOSURE;
(L->top-1)->value.cl = c;
}
}
@@ -577,6 +579,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, const TProtoFunc *tf,
*top++ = consts[aux];
L->top = top;
aux = *pc++; /* number of upvalues */
+ LUA_ASSERT(L, aux>0, "closure with no upvalues");
luaV_closure(L, aux);
luaC_checkGC(L);
top -= aux;