lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


On 06 Jun 2012 14:00:46 +0200
steve donovan <steve.j.donovan@gmail.com> wrote:

> On Wed, Jun 6, 2012 at 1:54 PM, Neico <admin@neic0.de> wrote:
> > I belive that it's this one you wanted?
> 
> Yow, that's against a Lua version from 2003 - precisely which version was it?

I think it is the one for 5.0, I found it afer posting, it doesnt apply to 5.1
bu with a few changes it seems to work.
I attached the updated version for 5.1, no guaranties at all :)
diff -u -r -w ../../lua-5.1.4/src/ltm.c ./ltm.c
--- ../../lua-5.1.4/src/ltm.c	2007-12-27 14:02:25.000000000 +0100
+++ ./ltm.c	2012-06-06 12:18:59.000000000 +0200
@@ -29,7 +29,7 @@
 
 void luaT_init (lua_State *L) {
   static const char *const luaT_eventname[] = {  /* ORDER TM */
-    "__index", "__newindex",
+    "__index", "__newindex", "__usedindex",
     "__gc", "__mode", "__eq",
     "__add", "__sub", "__mul", "__div", "__mod",
     "__pow", "__unm", "__len", "__lt", "__le",
diff -u -r -w ../../lua-5.1.4/src/ltm.h ./ltm.h
--- ../../lua-5.1.4/src/ltm.h	2007-12-27 14:02:25.000000000 +0100
+++ ./ltm.h	2012-06-06 12:18:59.000000000 +0200
@@ -18,6 +18,7 @@
 typedef enum {
   TM_INDEX,
   TM_NEWINDEX,
+  TM_USEDINDEX,
   TM_GC,
   TM_MODE,
   TM_EQ,  /* last tag method with `fast' access */
diff -u -r -w ../../lua-5.1.4/src/lvm.c ./lvm.c
--- ../../lua-5.1.4/src/lvm.c	2007-12-28 16:32:23.000000000 +0100
+++ ./lvm.c	2012-06-06 12:20:08.000000000 +0200
@@ -138,14 +138,24 @@
     if (ttistable(t)) {  /* `t' is a table? */
       Table *h = hvalue(t);
       TValue *oldval = luaH_set(L, h, key); /* do a primitive set */
-      if (!ttisnil(oldval) ||  /* result is no nil? */
-          (tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL) { /* or no TM? */
-        setobj2t(L, oldval, val);
+      if (!ttisnil(oldval))  /* old is not nil? */ {
+	if ((tm = fasttm(L, h->metatable, TM_USEDINDEX)) == NULL) /* and no TM? */{
+	  setobj2t(L, oldval, val);  /* write barrier */
         luaC_barriert(L, h, val);
         return;
+	} else {
+	  /* else will try the tag method */
       }
+      } else /* old is nil? */ {
+	if ((tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL) { /* and no TM? */
+	  setobj2t(L, oldval, val);  /* write barrier */
+          luaC_barriert(L, h, val);
+	  return;
+	} else {
       /* else will try the tag method */
     }
+      }
+    }
     else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX)))
       luaG_typeerror(L, t, "index");
     if (ttisfunction(tm)) {