lua

A copy of the Lua development repository
Log | Files | Refs | README

commit 634344d61fb4bd7ebd033d37b814a0083e55b5a2
parent a2fa48a570b01b2a2cd37f01799f08f693fc5892
Author: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
Date:   Tue,  6 Aug 2002 14:06:34 -0300

new API for weak mode

Diffstat:
Mlapi.c | 27++++++++++++++++++++++++++-
Mlbaselib.c | 25+++++++++++++++++++------
Mlgc.c | 63++++++++++++++++++++++++++-------------------------------------
Mlobject.h | 6+++++-
Mltable.c | 3++-
Mltablib.c | 8++------
Mltm.c | 6+++---
Mltm.h | 11++---------
Mlua.h | 4+++-
9 files changed, 88 insertions(+), 65 deletions(-)

diff --git a/lapi.c b/lapi.c @@ -1,5 +1,5 @@ /* -** $Id: lapi.c,v 1.206 2002/08/05 14:43:38 roberto Exp roberto $ +** $Id: lapi.c,v 1.207 2002/08/06 15:32:22 roberto Exp roberto $ ** Lua API ** See Copyright Notice in lua.h */ @@ -464,6 +464,20 @@ LUA_API void lua_newtable (lua_State *L) { } +LUA_API const char *lua_getmode (lua_State *L, int index) { + static const char *const modes[] = {"", "k", "v", "kv"}; + int mode = 0; + TObject *t; + lua_lock(L); + t = luaA_index(L, index); + api_check(L, ttistable(t)); + if (hvalue(t)->mode & WEAKKEY) mode += 1; + if (hvalue(t)->mode & WEAKVALUE) mode += 2; + lua_unlock(L); + return modes[mode]; +} + + LUA_API int lua_getmetatable (lua_State *L, int objindex) { StkId obj; Table *mt; @@ -555,6 +569,17 @@ LUA_API void lua_rawseti (lua_State *L, int index, int n) { } +LUA_API void lua_setmode (lua_State *L, int index, const char *mode) { + TObject *t; + lua_lock(L); + t = luaA_index(L, index); + api_check(L, ttistable(t)); + hvalue(t)->mode &= ~(WEAKKEY | WEAKVALUE); /* clear bits */ + if (strchr(mode, 'k')) hvalue(t)->mode |= WEAKKEY; + if (strchr(mode, 'v')) hvalue(t)->mode |= WEAKVALUE; + lua_unlock(L); +} + LUA_API int lua_setmetatable (lua_State *L, int objindex) { TObject *obj, *mt; int res = 1; diff --git a/lbaselib.c b/lbaselib.c @@ -1,5 +1,5 @@ /* -** $Id: lbaselib.c,v 1.92 2002/08/05 14:46:02 roberto Exp roberto $ +** $Id: lbaselib.c,v 1.93 2002/08/06 15:32:22 roberto Exp roberto $ ** Basic library ** See Copyright Notice in lua.h */ @@ -81,6 +81,21 @@ static int luaB_error (lua_State *L) { } +static int luaB_getmode (lua_State *L) { + luaL_check_type(L, 1, LUA_TTABLE); + lua_pushstring(L, lua_getmode(L, 1)); + return 1; +} + + +static int luaB_setmode (lua_State *L) { + luaL_check_type(L, 1, LUA_TTABLE); + lua_setmode(L, 1, luaL_check_string(L, 2)); + lua_settop(L, 1); + return 1; +} + + static int luaB_getmetatable (lua_State *L) { luaL_check_any(L, 1); if (!lua_getmetatable(L, 1)) { @@ -460,6 +475,8 @@ static const luaL_reg base_funcs[] = { {"setmetatable", luaB_setmetatable}, {"getglobals", luaB_getglobals}, {"setglobals", luaB_setglobals}, + {"getmode", luaB_getmode}, + {"setmode", luaB_setmode}, {"next", luaB_next}, {"ipairs", luaB_ipairs}, {"pairs", luaB_pairs}, @@ -572,11 +589,7 @@ static void base_open (lua_State *L) { /* `newproxy' needs a weaktable as upvalue */ lua_pushliteral(L, "newproxy"); lua_newtable(L); /* new table `w' */ - lua_pushvalue(L, -1); /* `w' will be its own metatable */ - lua_setmetatable(L, -2); - lua_pushliteral(L, "__mode"); - lua_pushliteral(L, "k"); - lua_rawset(L, -3); /* metatable(w).__mode = "k" */ + lua_setmode(L, -1, "k"); lua_pushcclosure(L, luaB_newproxy, 1); lua_rawset(L, -3); /* set global `newproxy' */ lua_rawset(L, -1); /* set global _G */ diff --git a/lgc.c b/lgc.c @@ -1,5 +1,5 @@ /* -** $Id: lgc.c,v 1.143 2002/07/17 16:25:13 roberto Exp $ +** $Id: lgc.c,v 1.144 2002/08/05 14:50:39 roberto Exp roberto $ ** Garbage Collector ** See Copyright Notice in lua.h */ @@ -35,12 +35,6 @@ typedef struct GCState { #define ismarked(x) ((x)->mark != (x)) -/* `Table.flag' bits to indicate whether table is key-weak and/or value-weak */ -#define KEYWEAKBIT (TM_MODE+1) /* ORDER TM */ -#define VALUEWEAKBIT (TM_MODE+2) -#define KEYWEAK (1<<KEYWEAKBIT) -#define VALUEWEAK (1<<VALUEWEAKBIT) - /* mark tricks for userdata */ #define isudmarked(u) (u->uv.len & 1) @@ -221,19 +215,15 @@ static void removekey (Node *n) { static void traversetable (GCState *st, Table *h) { int i; - const TObject *mode; int weakkey = 0; int weakvalue = 0; marktable(st, h->metatable); lua_assert(h->lsizenode || h->node == G(st->L)->dummynode); - mode = fasttm(st->L, h->metatable, TM_MODE); - if (mode && ttisstring(mode)) { /* weak table? */ + if (h->mode & (WEAKKEY | WEAKVALUE)) { /* weak table? */ + weakkey = h->mode & WEAKKEY; + weakvalue = h->mode & WEAKVALUE; h->mark = st->toclear; /* must be cleared after GC, ... */ - st->toclear = h; /* ...put in the appropriate list */ - weakkey = (strchr(svalue(mode), 'k') != NULL); - weakvalue = (strchr(svalue(mode), 'v') != NULL); - h->flags &= ~(KEYWEAK | VALUEWEAK); /* clear bits */ - h->flags |= (weakkey << KEYWEAKBIT) | (weakvalue << VALUEWEAKBIT); + st->toclear = h; /* ... so put in the appropriate list */ } if (!weakvalue) { i = sizearray(h); @@ -284,14 +274,14 @@ static int hasmark (const TObject *o) { static void cleartablekeys (GCState *st) { Table *h; for (h = st->toclear; h; h = h->mark) { - int i; - if (!(h->flags & KEYWEAK)) continue; - lua_assert(strchr(svalue(fasttm(st->L, h->metatable, TM_MODE)), 'k')); - i = sizenode(h); - while (i--) { - Node *n = node(h, i); - if (!hasmark(key(n))) - removekey(n); /* ... and key */ + lua_assert(h->mode & (WEAKKEY | WEAKVALUE)); + if ((h->mode & WEAKKEY)) { /* table may have collected keys? */ + int i = sizenode(h); + while (i--) { + Node *n = node(h, i); + if (!hasmark(key(n))) /* key was collected? */ + removekey(n); /* remove entry from table */ + } } } } @@ -303,20 +293,19 @@ static void cleartablekeys (GCState *st) { static void cleartablevalues (GCState *st) { Table *h; for (h = st->toclear; h; h = h->mark) { - int i; - if (!(h->flags & VALUEWEAK)) continue; - lua_assert(strchr(svalue(fasttm(st->L, h->metatable, TM_MODE)), 'v')); - i = sizearray(h); - while (i--) { - TObject *o = &h->array[i]; - if (!hasmark(o)) - setnilvalue(o); /* remove value */ - } - i = sizenode(h); - while (i--) { - Node *n = node(h, i); - if (!hasmark(val(n))) - removekey(n); /* ... and key */ + if ((h->mode & WEAKVALUE)) { /* table may have collected values? */ + int i = sizearray(h); + while (i--) { + TObject *o = &h->array[i]; + if (!hasmark(o)) /* value was collected? */ + setnilvalue(o); /* remove value */ + } + i = sizenode(h); + while (i--) { + Node *n = node(h, i); + if (!hasmark(val(n))) /* value was collected? */ + removekey(n); /* remove entry from table */ + } } } } diff --git a/lobject.h b/lobject.h @@ -1,5 +1,5 @@ /* -** $Id: lobject.h,v 1.140 2002/07/17 16:25:13 roberto Exp $ +** $Id: lobject.h,v 1.141 2002/08/05 14:08:02 roberto Exp roberto $ ** Type definitions for Lua objects ** See Copyright Notice in lua.h */ @@ -223,8 +223,12 @@ typedef struct Table { int sizearray; /* size of `array' array */ lu_byte flags; /* 1<<p means tagmethod(p) is not present */ lu_byte lsizenode; /* log2 of size of `node' array */ + lu_byte mode; } Table; +/* bit masks for `mode' */ +#define WEAKKEY 1 +#define WEAKVALUE 2 /* diff --git a/ltable.c b/ltable.c @@ -1,5 +1,5 @@ /* -** $Id: ltable.c,v 1.114 2002/07/17 16:25:13 roberto Exp $ +** $Id: ltable.c,v 1.115 2002/08/05 14:45:32 roberto Exp roberto $ ** Lua tables (hash) ** See Copyright Notice in lua.h */ @@ -309,6 +309,7 @@ Table *luaH_new (lua_State *L, int narray, int lnhash) { G(L)->roottable = t; t->mark = t; t->flags = cast(lu_byte, ~0); + t->mode = 0; /* temporary values (kept only if some malloc fails) */ t->array = NULL; t->sizearray = 0; diff --git a/ltablib.c b/ltablib.c @@ -1,5 +1,5 @@ /* -** $Id: ltablib.c,v 1.9 2002/07/01 19:25:28 roberto Exp roberto $ +** $Id: ltablib.c,v 1.10 2002/07/08 16:51:20 roberto Exp roberto $ ** Library for Table Manipulation ** See Copyright Notice in lua.h */ @@ -288,11 +288,7 @@ static const luaL_reg tab_funcs[] = { LUALIB_API int lua_tablibopen (lua_State *L) { lua_newtable(L); /* create N (table to store num. elements in tables) */ - lua_pushvalue(L, -1); - lua_setmetatable(L, -2); /* make it its own metatable */ - lua_pushliteral(L, "__mode"); - lua_pushliteral(L, "k"); - lua_rawset(L, -3); /* make it a weak table */ + lua_setmode(L, -1, "k"); /* make it a weak table */ luaL_opennamedlib(L, LUA_TABLIBNAME, tab_funcs, 1); return 0; } diff --git a/ltm.c b/ltm.c @@ -1,5 +1,5 @@ /* -** $Id: ltm.c,v 1.98 2002/07/17 16:25:13 roberto Exp $ +** $Id: ltm.c,v 1.99 2002/08/05 14:09:06 roberto Exp roberto $ ** Tag methods ** See Copyright Notice in lua.h */ @@ -26,7 +26,7 @@ const char *const luaT_typenames[] = { void luaT_init (lua_State *L) { static const char *const luaT_eventname[] = { /* ORDER TM */ "__index", "__newindex", - "__gc", "__eq", "__mode", + "__gc", "__eq", "__gettable", "__settable", "__add", "__sub", "__mul", "__div", "__pow", "__unm", "__lt", "__le", @@ -46,7 +46,7 @@ void luaT_init (lua_State *L) { */ const TObject *luaT_gettm (Table *events, TMS event, TString *ename) { const TObject *tm = luaH_getstr(events, ename); - lua_assert(event <= TM_MODE); + lua_assert(event <= TM_EQ); if (ttisnil(tm)) { /* no tag method? */ events->flags |= (1u<<event); /* cache this fact */ return NULL; diff --git a/ltm.h b/ltm.h @@ -1,5 +1,5 @@ /* -** $Id: ltm.h,v 1.37 2002/06/25 19:17:22 roberto Exp roberto $ +** $Id: ltm.h,v 1.38 2002/07/01 17:06:58 roberto Exp roberto $ ** Tag methods ** See Copyright Notice in lua.h */ @@ -12,12 +12,6 @@ /* -** Important: garbage collection uses two extra bits of `Table.flags' -** (after TM_MODE), so the maximum number of `fast tag methods' is six -** (at least while `flags' is a byte). -*/ - -/* * WARNING: if you change the order of this enumeration, * grep "ORDER TM" */ @@ -25,8 +19,7 @@ typedef enum { TM_INDEX, TM_NEWINDEX, TM_GC, - TM_EQ, - TM_MODE, /* last tag method with `fast' access */ + TM_EQ, /* last tag method with `fast' access */ TM_GETTABLE, TM_SETTABLE, TM_ADD, diff --git a/lua.h b/lua.h @@ -1,5 +1,5 @@ /* -** $Id: lua.h,v 1.148 2002/08/05 14:51:47 roberto Exp roberto $ +** $Id: lua.h,v 1.149 2002/08/06 15:32:22 roberto Exp roberto $ ** Lua - An Extensible Extension Language ** Tecgraf: Computer Graphics Technology Group, PUC-Rio, Brazil ** http://www.lua.org mailto:info@lua.org @@ -166,6 +166,7 @@ LUA_API void lua_rawget (lua_State *L, int index); LUA_API void lua_rawgeti (lua_State *L, int index, int n); LUA_API void lua_newtable (lua_State *L); LUA_API int lua_getmetatable (lua_State *L, int objindex); +LUA_API const char *lua_getmode (lua_State *L, int index); LUA_API void lua_getglobals (lua_State *L, int level); @@ -175,6 +176,7 @@ LUA_API void lua_getglobals (lua_State *L, int level); LUA_API void lua_settable (lua_State *L, int index); LUA_API void lua_rawset (lua_State *L, int index); LUA_API void lua_rawseti (lua_State *L, int index, int n); +LUA_API void lua_setmode (lua_State *L, int index, const char *mode); LUA_API int lua_setmetatable (lua_State *L, int objindex); LUA_API int lua_setglobals (lua_State *L, int level);