|
|
@ -1,5 +1,5 @@ |
|
|
|
/*
|
|
|
|
** $Id: ltests.c,v 2.140 2013/08/05 16:58:28 roberto Exp roberto $ |
|
|
|
** $Id: ltests.c,v 2.141 2013/08/07 12:18:11 roberto Exp roberto $ |
|
|
|
** Internal Module for Debugging of the Lua Implementation |
|
|
|
** See Copyright Notice in lua.h |
|
|
|
*/ |
|
|
@ -188,6 +188,25 @@ static int testobjref1 (global_State *g, GCObject *f, GCObject *t) { |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
** Check locality |
|
|
|
*/ |
|
|
|
static int testobjref2 (GCObject *f, GCObject *t) { |
|
|
|
/* not a local or pointed by a thread? */ |
|
|
|
if (!islocal(t) || gch(f)->tt == LUA_TTHREAD) |
|
|
|
return 1; /* ok */ |
|
|
|
if (gch(t)->tt == LUA_TUPVAL) { |
|
|
|
lua_assert(gch(f)->tt == LUA_TLCL); |
|
|
|
return 1; /* upvalue pointed by a closure */ |
|
|
|
} |
|
|
|
if (gch(f)->tt == LUA_TUPVAL) { |
|
|
|
UpVal *uv = gco2uv(f); |
|
|
|
return (uv->v != &uv->value); /* open upvalue can point to local stuff */ |
|
|
|
} |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void printobj (global_State *g, GCObject *o) { |
|
|
|
int i = 1; |
|
|
|
GCObject *p; |
|
|
@ -198,24 +217,30 @@ static void printobj (global_State *g, GCObject *o) { |
|
|
|
if (p == NULL) i = 0; /* zero means 'not found' */ |
|
|
|
else i = -i; /* negative means 'found in findobj list */ |
|
|
|
} |
|
|
|
printf("||%d:%s(%p)-%c(%02X)||", i, ttypename(gch(o)->tt), (void *)o, |
|
|
|
printf("||%d:%s(%p)-%s-%c(%02X)||", |
|
|
|
i, ttypename(novariant(gch(o)->tt)), (void *)o, |
|
|
|
islocal(o)?"L":"NL", |
|
|
|
isdead(g,o)?'d':isblack(o)?'b':iswhite(o)?'w':'g', gch(o)->marked); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static int testobjref (global_State *g, GCObject *f, GCObject *t) { |
|
|
|
int r = testobjref1(g,f,t); |
|
|
|
if (!r) { |
|
|
|
printf("%d(%02X) - ", g->gcstate, g->currentwhite); |
|
|
|
int r1 = testobjref1(g,f,t); |
|
|
|
int r2 = testobjref2(f,t); |
|
|
|
if (!r1 || !r2) { |
|
|
|
if (!r1) |
|
|
|
printf("%d(%02X) - ", g->gcstate, g->currentwhite); |
|
|
|
else |
|
|
|
printf("local violation - "); |
|
|
|
printobj(g, f); |
|
|
|
printf("\t-> "); |
|
|
|
printf(" -> "); |
|
|
|
printobj(g, t); |
|
|
|
printf("\n"); |
|
|
|
} |
|
|
|
return r; |
|
|
|
return r1 && r2; |
|
|
|
} |
|
|
|
|
|
|
|
#define checkobjref(g,f,t) lua_assert(testobjref(g,f,obj2gco(t))) |
|
|
|
#define checkobjref(g,f,t) lua_assert(testobjref(g,f,obj2gco(t))) |
|
|
|
|
|
|
|
|
|
|
|
static void checkvalref (global_State *g, GCObject *f, const TValue *t) { |
|
|
@ -349,6 +374,7 @@ static void checkobject (global_State *g, GCObject *o, int maybedead) { |
|
|
|
break; |
|
|
|
} |
|
|
|
case LUA_TTHREAD: { |
|
|
|
lua_assert(!islocal(o)); |
|
|
|
checkstack(g, gco2th(o)); |
|
|
|
break; |
|
|
|
} |
|
|
@ -617,22 +643,9 @@ static int get_gccolor (lua_State *L) { |
|
|
|
o = obj_at(L, 1); |
|
|
|
if (!iscollectable(o)) |
|
|
|
lua_pushstring(L, "no collectable"); |
|
|
|
else { |
|
|
|
int marked = gcvalue(o)->gch.marked; |
|
|
|
int n = 1; |
|
|
|
else |
|
|
|
lua_pushstring(L, iswhite(gcvalue(o)) ? "white" : |
|
|
|
isblack(gcvalue(o)) ? "black" : "grey"); |
|
|
|
if (testbit(marked, FINALIZEDBIT)) { |
|
|
|
lua_pushliteral(L, "/finalized"); n++; |
|
|
|
} |
|
|
|
if (testbit(marked, SEPARATED)) { |
|
|
|
lua_pushliteral(L, "/separated"); n++; |
|
|
|
} |
|
|
|
if (testbit(marked, FIXEDBIT)) { |
|
|
|
lua_pushliteral(L, "/fixed"); n++; |
|
|
|
} |
|
|
|
lua_concat(L, n); |
|
|
|
} |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|