From 7777b412deb46d051967b699697d1d6e6286a7b6 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Fri, 26 Feb 2016 16:20:15 -0300 Subject: When available, use metafield '__name' in error messages --- ldebug.c | 10 +++++----- ltm.c | 18 +++++++++++++++++- ltm.h | 5 +++-- 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/ldebug.c b/ldebug.c index 5daa3c02..1db451b7 100644 --- a/ldebug.c +++ b/ldebug.c @@ -1,5 +1,5 @@ /* -** $Id: ldebug.c,v 2.117 2015/11/02 18:48:07 roberto Exp roberto $ +** $Id: ldebug.c,v 2.118 2015/12/16 16:40:07 roberto Exp roberto $ ** Debug Interface ** See Copyright Notice in lua.h */ @@ -564,7 +564,7 @@ static const char *varinfo (lua_State *L, const TValue *o) { l_noret luaG_typeerror (lua_State *L, const TValue *o, const char *op) { - const char *t = objtypename(o); + const char *t = luaT_objtypename(L, o); luaG_runerror(L, "attempt to %s a %s value%s", op, t, varinfo(L, o)); } @@ -596,9 +596,9 @@ l_noret luaG_tointerror (lua_State *L, const TValue *p1, const TValue *p2) { l_noret luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) { - const char *t1 = objtypename(p1); - const char *t2 = objtypename(p2); - if (t1 == t2) + const char *t1 = luaT_objtypename(L, p1); + const char *t2 = luaT_objtypename(L, p2); + if (strcmp(t1, t2) == 0) luaG_runerror(L, "attempt to compare two %s values", t1); else luaG_runerror(L, "attempt to compare %s with %s", t1, t2); diff --git a/ltm.c b/ltm.c index 3f400d4b..cc28a414 100644 --- a/ltm.c +++ b/ltm.c @@ -1,5 +1,5 @@ /* -** $Id: ltm.c,v 2.35 2015/11/02 18:48:07 roberto Exp roberto $ +** $Id: ltm.c,v 2.36 2015/11/03 15:47:30 roberto Exp roberto $ ** Tag methods ** See Copyright Notice in lua.h */ @@ -83,6 +83,22 @@ const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, TMS event) { } +/* +** Return the name of the type of an object. For tables and userdata +** with metatable, use their '__name' metafield, if present. +*/ +const char *luaT_objtypename (lua_State *L, const TValue *o) { + Table *mt; + if ((ttistable(o) && (mt = hvalue(o)->metatable) != NULL) || + (ttisfulluserdata(o) && (mt = uvalue(o)->metatable) != NULL)) { + const TValue *name = luaH_getshortstr(mt, luaS_new(L, "__name")); + if (ttisstring(name)) /* is '__name' a string? */ + return getstr(tsvalue(name)); /* use it as type name */ + } + return ttypename(ttnov(o)); /* else use standard type name */ +} + + void luaT_callTM (lua_State *L, const TValue *f, const TValue *p1, const TValue *p2, TValue *p3, int hasres) { ptrdiff_t result = savestack(L, p3); diff --git a/ltm.h b/ltm.h index 19660b20..70569f82 100644 --- a/ltm.h +++ b/ltm.h @@ -1,5 +1,5 @@ /* -** $Id: ltm.h,v 2.20 2014/06/10 18:53:18 roberto Exp roberto $ +** $Id: ltm.h,v 2.21 2014/10/25 11:50:46 roberto Exp roberto $ ** Tag methods ** See Copyright Notice in lua.h */ @@ -51,11 +51,12 @@ typedef enum { #define fasttm(l,et,e) gfasttm(G(l), et, e) #define ttypename(x) luaT_typenames_[(x) + 1] -#define objtypename(x) ttypename(ttnov(x)) LUAI_DDEC const char *const luaT_typenames_[LUA_TOTALTAGS]; +LUAI_FUNC const char *luaT_objtypename (lua_State *L, const TValue *o); + LUAI_FUNC const TValue *luaT_gettm (Table *events, TMS event, TString *ename); LUAI_FUNC const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, TMS event); -- cgit v1.2.3-55-g6feb