From 6cf85dcc900c71687678bc316164142e76df7385 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Thu, 5 May 2005 12:34:03 -0300 Subject: [PATCH] metatables for all types --- lapi.c | 13 ++++++++----- lgc.c | 11 ++++++++++- lstate.c | 4 +++- lstate.h | 3 ++- lstrlib.c | 17 ++++++++++++++++- ltm.c | 8 ++++---- ltm.h | 3 ++- 7 files changed, 45 insertions(+), 14 deletions(-) diff --git a/lapi.c b/lapi.c index 05b801b2..f6244e39 100644 --- a/lapi.c +++ b/lapi.c @@ -1,5 +1,5 @@ /* -** $Id: lapi.c,v 2.37 2005/04/04 18:12:51 roberto Exp roberto $ +** $Id: lapi.c,v 2.38 2005/04/05 15:35:15 roberto Exp roberto $ ** Lua API ** See Copyright Notice in lua.h */ @@ -319,7 +319,8 @@ LUA_API lua_Integer lua_tointeger (lua_State *L, int idx) { const TValue *o = index2adr(L, idx); if (tonumber(o, &n)) { lua_Integer res; - lua_number2integer(res, nvalue(o)); + lua_Number num = nvalue(o); + lua_number2integer(res, num); return res; } else @@ -587,6 +588,9 @@ LUA_API int lua_getmetatable (lua_State *L, int objindex) { case LUA_TUSERDATA: mt = uvalue(obj)->metatable; break; + default: + mt = G(L)->mt[ttype(obj)]; + break; } if (mt == NULL) res = 0; @@ -681,7 +685,6 @@ LUA_API void lua_rawseti (lua_State *L, int idx, int n) { LUA_API int lua_setmetatable (lua_State *L, int objindex) { TValue *obj; Table *mt; - int res = 1; lua_lock(L); api_checknelems(L, 1); obj = index2adr(L, objindex); @@ -706,13 +709,13 @@ LUA_API int lua_setmetatable (lua_State *L, int objindex) { break; } default: { - res = 0; /* cannot set */ + G(L)->mt[ttype(obj)] = mt; break; } } L->top--; lua_unlock(L); - return res; + return 1; } diff --git a/lgc.c b/lgc.c index 8db5fb0d..3d3736f8 100644 --- a/lgc.c +++ b/lgc.c @@ -1,5 +1,5 @@ /* -** $Id: lgc.c,v 2.30 2005/03/16 17:00:21 roberto Exp roberto $ +** $Id: lgc.c,v 2.31 2005/03/22 16:04:29 roberto Exp roberto $ ** Garbage Collector ** See Copyright Notice in lua.h */ @@ -493,6 +493,13 @@ void luaC_freeall (lua_State *L) { } +static void markmt (global_State *g) { + int i; + for (i=0; imt[i]) markobject(g, g->mt[i]); +} + + /* mark root set */ static void markroot (lua_State *L) { global_State *g = G(L); @@ -503,6 +510,7 @@ static void markroot (lua_State *L) { /* make global table be traversed before main stack */ markvalue(g, gt(g->mainthread)); markvalue(g, registry(L)); + markmt(g); g->gcstate = GCSpropagate; } @@ -529,6 +537,7 @@ static void atomic (lua_State *L) { g->weak = NULL; lua_assert(!iswhite(obj2gco(g->mainthread))); markobject(g, L); /* mark running thread */ + markmt(g); /* mark basic metatables (again) */ propagateall(g); /* remark gray again */ g->gray = g->grayagain; diff --git a/lstate.c b/lstate.c index 872156ea..8bcd14fe 100644 --- a/lstate.c +++ b/lstate.c @@ -1,5 +1,5 @@ /* -** $Id: lstate.c,v 2.29 2005/04/05 13:41:29 roberto Exp roberto $ +** $Id: lstate.c,v 2.30 2005/04/05 15:57:59 roberto Exp roberto $ ** Global State ** See Copyright Notice in lua.h */ @@ -141,6 +141,7 @@ void luaE_freethread (lua_State *L, lua_State *L1) { LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { + int i; lua_State *L; global_State *g; void *l = (*f)(ud, NULL, 0, state_size(LG)); @@ -177,6 +178,7 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { g->gcpause = LUAI_GCPAUSE; g->gcstepmul = LUAI_GCMUL; g->gcdept = 0; + for (i=0; imt[i] = NULL; if (luaD_rawrunprotected(L, f_luaopen, NULL) != 0) { /* memory allocation error: free partial state */ close_state(L); diff --git a/lstate.h b/lstate.h index 908abf70..6742b4ca 100644 --- a/lstate.h +++ b/lstate.h @@ -1,5 +1,5 @@ /* -** $Id: lstate.h,v 2.19 2005/04/05 13:41:29 roberto Exp roberto $ +** $Id: lstate.h,v 2.20 2005/04/25 19:24:10 roberto Exp roberto $ ** Global State ** See Copyright Notice in lua.h */ @@ -89,6 +89,7 @@ typedef struct global_State { TValue _registry; struct lua_State *mainthread; UpVal uvhead; /* head of double-linked list of all open upvalues */ + struct Table *mt[NUM_TAGS]; /* metatables for basic types */ TString *tmname[TM_N]; /* array with tag-method names */ } global_State; diff --git a/lstrlib.c b/lstrlib.c index 1a2e6c29..93f8e776 100644 --- a/lstrlib.c +++ b/lstrlib.c @@ -1,5 +1,5 @@ /* -** $Id: lstrlib.c,v 1.110 2005/03/08 20:10:05 roberto Exp roberto $ +** $Id: lstrlib.c,v 1.111 2005/03/22 16:54:29 roberto Exp roberto $ ** Standard library for string operations and pattern-matching ** See Copyright Notice in lua.h */ @@ -772,11 +772,26 @@ static const luaL_reg strlib[] = { }; +static void createmetatable (lua_State *L) { + lua_newtable(L); /* create metatable for strings */ + lua_pushliteral(L, ""); /* dummy string */ + lua_pushvalue(L, -2); + lua_setmetatable(L, -2); /* set string metatable */ + lua_pop(L, 1); /* pop dummy string */ + lua_pushvalue(L, -2); /* string library... */ + lua_setfield(L, -2, "__index"); /* ...is the __index metamethod */ + lua_getfield(L, -2, "len"); + lua_setfield(L, -2, "__siz"); + lua_pop(L, 1); /* pop metatable */ +} + + /* ** Open string library */ LUALIB_API int luaopen_string (lua_State *L) { luaL_openlib(L, LUA_STRLIBNAME, strlib, 0); + createmetatable(L); return 1; } diff --git a/ltm.c b/ltm.c index ef023528..dc5db074 100644 --- a/ltm.c +++ b/ltm.c @@ -1,5 +1,5 @@ /* -** $Id: ltm.c,v 2.3 2004/04/30 20:13:38 roberto Exp roberto $ +** $Id: ltm.c,v 2.4 2005/03/08 18:00:16 roberto Exp roberto $ ** Tag methods ** See Copyright Notice in lua.h */ @@ -32,7 +32,7 @@ void luaT_init (lua_State *L) { "__index", "__newindex", "__gc", "__mode", "__eq", "__add", "__sub", "__mul", "__div", "__mod", - "__pow", "__unm", "__lt", "__le", + "__pow", "__unm", "__siz", "__lt", "__le", "__concat", "__call" }; int i; @@ -68,8 +68,8 @@ const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, TMS event) { mt = uvalue(o)->metatable; break; default: - mt = NULL; + mt = G(L)->mt[ttype(o)]; } - return (mt ? luaH_getstr(mt, G(L)->tmname[event]) : &luaO_nilobject); + return (mt ? luaH_getstr(mt, G(L)->tmname[event]) : &luaO_nilobject); } diff --git a/ltm.h b/ltm.h index bd007ee8..0039bea7 100644 --- a/ltm.h +++ b/ltm.h @@ -1,5 +1,5 @@ /* -** $Id: ltm.h,v 2.2 2005/03/08 18:00:16 roberto Exp roberto $ +** $Id: ltm.h,v 2.3 2005/04/25 19:24:10 roberto Exp roberto $ ** Tag methods ** See Copyright Notice in lua.h */ @@ -28,6 +28,7 @@ typedef enum { TM_MOD, TM_POW, TM_UNM, + TM_SIZ, TM_LT, TM_LE, TM_CONCAT,