Sorry, previous patch has problems on system which without dynamic lua.
Attached new patch have fixed it.  Please check it.

-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
# HG changeset patch
# Parent 2e546d787ee8d12f7ea1b22172b9d491652c1ed7
Fix confused references related with an environment table

diff -r 2e546d787ee8 src/if_lua.c
--- a/src/if_lua.c	Thu Jan 05 09:14:30 2012 +0900
+++ b/src/if_lua.c	Sun Jan 08 19:19:42 2012 +0900
@@ -73,6 +73,7 @@
 #define lua_gettop dll_lua_gettop
 #define lua_settop dll_lua_settop
 #define lua_pushvalue dll_lua_pushvalue
+#define lua_insert dll_lua_insert
 #define lua_replace dll_lua_replace
 #define lua_isnumber dll_lua_isnumber
 #define lua_isstring dll_lua_isstring
@@ -135,6 +136,7 @@
 int (*dll_lua_gettop) (lua_State *L);
 void (*dll_lua_settop) (lua_State *L, int idx);
 void (*dll_lua_pushvalue) (lua_State *L, int idx);
+void (*dll_lua_insert) (lua_State *L, int idx);
 void (*dll_lua_replace) (lua_State *L, int idx);
 int (*dll_lua_isnumber) (lua_State *L, int idx);
 int (*dll_lua_isstring) (lua_State *L, int idx);
@@ -204,6 +206,7 @@
     {"lua_gettop", (luaV_function) &dll_lua_gettop},
     {"lua_settop", (luaV_function) &dll_lua_settop},
     {"lua_pushvalue", (luaV_function) &dll_lua_pushvalue},
+    {"lua_insert", (luaV_function) &dll_lua_insert},
     {"lua_replace", (luaV_function) &dll_lua_replace},
     {"lua_isnumber", (luaV_function) &dll_lua_isnumber},
     {"lua_isstring", (luaV_function) &dll_lua_isstring},
@@ -297,6 +300,143 @@
 
 /* =======   Internal   ======= */
 
+/**
+ * Push a lua object which associated to the pointer to the stack, and return
+ * 1.  If no objects associated, nil is pushed to the stack, and return 0.
+ *
+ * [+1, 0, -]
+ */
+    static int
+luaV_get_associated_luavalue(lua_State *L, void *rawptr)
+{
+    lua_pushlightuserdata(L, rawptr);
+    lua_rawget(L, LUA_REGISTRYINDEX);
+    return lua_isnil(L, -1) ? 0 : 1;
+}
+
+/**
+ * A lua object is associated with a C native pointer return 1, otherwise 0.
+ *
+ * [0, 0, -]
+ */
+    static int
+luaV_is_associated_luavalue(lua_State *L, void *rawptr)
+{
+    int retval = luaV_get_associated_luavalue(L, rawptr);
+    lua_pop(L, 1); /* obj */
+    return retval;
+}
+
+/**
+ * Associate a lua object which specified by index with a C native pointer.
+ *
+ * [0, 0, -]
+ */
+    static void
+luaV_set_associated_luavalue(lua_State *L, void *rawptr, int idx)
+{
+    lua_pushvalue(L, idx);
+    lua_pushlightuserdata(L, rawptr);
+    lua_pushvalue(L, -2);
+    lua_rawset(L, LUA_REGISTRYINDEX);
+    lua_pop(L, 1);
+}
+
+/**
+ * Reset any associated values to associated with a C native pointer.
+ *
+ * [0, 0, -]
+ */
+    static void
+luaV_reset_associated_luavalue(lua_State *L, void *rawptr)
+{
+    lua_pushnil(L);
+    luaV_set_associated_luavalue(L, rawptr, -1);
+    lua_pop(L, 1);
+}
+
+/**
+ * Setup a cache table be identified by cacheKey.
+ *
+ * [0, 0, -]
+ */
+    static void
+luaV_open_cachetable(lua_State *L, void *cacheKey)
+{
+    lua_pushlightuserdata(L, cacheKey);
+    lua_newtable(L);
+    lua_rawset(L, LUA_REGISTRYINDEX);
+}
+
+/**
+ * Dispose a cache table be identified by cacheKey.
+ *
+ * [0, 0, -]
+ */
+    static void
+luaV_close_cachetable(lua_State *L, void *cacheKey)
+{
+    lua_pushlightuserdata(L, cacheKey);
+    lua_pushnil(L);
+    lua_rawset(L, LUA_REGISTRYINDEX);
+}
+
+/**
+ * Push a lua object associated with a pointer in the cachetable which
+ * associated with cacheKey to the stack, and return 1.  If no objects
+ * associated, nil is pushed to the stack, and return 0.
+ *
+ * [+1, 0, -]
+ */
+    static int
+luaV_get_cachetable(lua_State *L, void *cacheKey, void *rawptr)
+{
+    lua_pushlightuserdata(L, cacheKey);
+    lua_rawget(L, LUA_REGISTRYINDEX);
+    if (!lua_istable(L, -1))
+    {
+        /*
+         * FIXME: This will causes if luaV_open_cachetable() isn't called.  It
+         * may be failed by assertion or so.
+         */
+        lua_pop(L, 1); /* {not table} */
+        lua_pushnil(L);
+        return 0;
+    }
+    else
+    {
+        lua_pushlightuserdata(L, rawptr);
+        lua_rawget(L, -2);
+        lua_insert(L, -2); /* (table, object) -> (object, table) */
+        lua_pop(L, 1); /* table */
+        return lua_isnil(L, -1) ? 0 : 1;
+    }
+}
+
+/**
+ * [0, 0, -]
+ */
+    static void
+luaV_set_cachetable(lua_State *L, void *cacheKey, void *rawptr, int idx)
+{
+    lua_pushvalue(L, idx);
+
+    /* Push a cacheable for cacheKey. */
+    lua_pushlightuserdata(L, cacheKey);
+    lua_rawget(L, LUA_REGISTRYINDEX);
+    if (!lua_istable(L, -1))
+    {
+        lua_pop(L, 2); /* idx, {not table} */
+    }
+    else
+    {
+        lua_pushlightuserdata(L, rawptr);
+        lua_pushvalue(L, -3);
+        lua_rawset(L, -3);
+        lua_pop(L, 2); /* idx, table */
+    }
+}
+
     static void
 luaV_newmetatable(lua_State *L, const char *tname)
 {
@@ -335,7 +475,7 @@
 }
 
     static void
-luaV_pushtypval(lua_State *L, typval_T *tv)
+luaV_pushtypval2(lua_State *L, void *cacheKey, typval_T *tv)
 {
     if (tv == NULL) luaL_error(L, "null type");
     switch (tv->v_type)
@@ -357,20 +497,17 @@
 	    if (l != NULL)
 	    {
 		/* check cache */
-		lua_pushlightuserdata(L, (void *) l);
-		lua_rawget(L, LUA_ENVIRONINDEX);
-		if (lua_isnil(L, -1)) /* not interned? */
-		{
+                if (!luaV_get_cachetable(L, cacheKey, (void *)l))
+                {
+                    /* Push a new table (array) to the stack. */
 		    listitem_T *li;
 		    int n = 0;
 		    lua_pop(L, 1); /* nil */
 		    lua_newtable(L);
-		    lua_pushlightuserdata(L, (void *) l);
-		    lua_pushvalue(L, -2);
-		    lua_rawset(L, LUA_ENVIRONINDEX);
+                    luaV_set_cachetable(L, cacheKey, (void *)l, -1);
 		    for (li = l->lv_first; li != NULL; li = li->li_next)
 		    {
-			luaV_pushtypval(L, &li->li_tv);
+			luaV_pushtypval2(L, cacheKey, &li->li_tv);
 			lua_rawseti(L, -2, ++n);
 		    }
 		}
@@ -384,24 +521,21 @@
 	    if (d != NULL)
 	    {
 		/* check cache */
-		lua_pushlightuserdata(L, (void *) d);
-		lua_rawget(L, LUA_ENVIRONINDEX);
-		if (lua_isnil(L, -1)) /* not interned? */
-		{
+                if (!luaV_get_cachetable(L, cacheKey, (void *)d))
+                {
+                    /* Push a new table (dict) to the stack. */
 		    hashtab_T *ht = &d->dv_hashtab;
 		    hashitem_T *hi;
 		    int n = ht->ht_used; /* remaining items */
 		    lua_pop(L, 1); /* nil */
 		    lua_newtable(L);
-		    lua_pushlightuserdata(L, (void *) d);
-		    lua_pushvalue(L, -2);
-		    lua_rawset(L, LUA_ENVIRONINDEX);
+                    luaV_set_cachetable(L, cacheKey, (void *)d, -1);
 		    for (hi = ht->ht_array; n > 0; hi++)
 		    {
 			if (!HASHITEM_EMPTY(hi))
 			{
 			    dictitem_T *di = dict_lookup(hi);
-			    luaV_pushtypval(L, &di->di_tv);
+			    luaV_pushtypval2(L, cacheKey, &di->di_tv);
 			    lua_setfield(L, -2, (char *) hi->hi_key);
 			    n--;
 			}
@@ -416,6 +550,19 @@
     }
 }
 
+/**
+ * [+1, 0, -]
+ */
+    static void
+luaV_pushtypval(lua_State *L, typval_T *tv)
+{
+    void *cacheKey = (void *)tv;
+
+    luaV_open_cachetable(L, cacheKey);
+    luaV_pushtypval2(L, cacheKey, tv);
+    luaV_close_cachetable(L, cacheKey);
+}
+
 /* similar to luaL_addlstring, but replaces \0 with \n if toline and
  * \n with \0 otherwise */
     static void
@@ -489,13 +636,9 @@
 {
     luaV_Buffer *b = (luaV_Buffer *) lua_newuserdata(L, sizeof(luaV_Buffer));
     *b = buf;
-    lua_pushlightuserdata(L, (void *) buf);
-    lua_pushvalue(L, -2);
-    lua_rawset(L, LUA_ENVIRONINDEX); /* env[buf] = udata */
-    /* to avoid GC, store as key in env */
-    lua_pushvalue(L, -1);
-    lua_pushboolean(L, 1);
-    lua_rawset(L, LUA_ENVIRONINDEX); /* env[udata] = true */
+
+    luaV_set_associated_luavalue(L, (void *)buf, -1);
+
     /* set metatable */
     luaV_getfield(L, LUAVIM_BUFFER);
     lua_setmetatable(L, -2);
@@ -508,12 +651,11 @@
     luaV_Buffer *b = NULL;
     if (buf == NULL)
 	lua_pushnil(L);
-    else {
-	lua_pushlightuserdata(L, (void *) buf);
-	lua_rawget(L, LUA_ENVIRONINDEX);
-	if (lua_isnil(L, -1)) /* not interned? */
-	{
-	    lua_pop(L, 1);
+    else
+    {
+        if (!luaV_get_associated_luavalue(L, (void *)buf))
+        {
+	    lua_pop(L, 1); /* nil */
 	    b = luaV_newbuffer(L, buf);
 	}
 	else
@@ -553,6 +695,14 @@
 {
     luaV_Buffer *b = (luaV_Buffer *) lua_touserdata(L, 1);
     linenr_T n = (linenr_T) lua_tointeger(L, 2);
+
+    /* Check validity of a buffer. */
+    if (!luaV_is_associated_luavalue(L, (void *)(*b)))
+    {
+        lua_pushnil(L);
+        return 1;
+    }
+
     if (n > 0 && n <= (*b)->b_ml.ml_line_count)
 	luaV_pushline(L, *b, n);
     else if (lua_isstring(L, 2))
@@ -702,9 +852,8 @@
 luaV_buffer_isvalid(lua_State *L)
 {
     luaV_Buffer *b = luaV_checkudata(L, 1, LUAVIM_BUFFER);
-    lua_pushlightuserdata(L, (void *) (*b));
-    lua_rawget(L, LUA_ENVIRONINDEX);
-    lua_pushboolean(L, !lua_isnil(L, -1));
+    lua_pushboolean(L,
+            luaV_get_associated_luavalue(L, (void *)(*b)));
     return 1;
 }
 
@@ -729,13 +878,9 @@
 {
     luaV_Window *w = (luaV_Window *) lua_newuserdata(L, sizeof(luaV_Window));
     *w = win;
-    lua_pushlightuserdata(L, (void *) win);
-    lua_pushvalue(L, -2);
-    lua_rawset(L, LUA_ENVIRONINDEX); /* env[win] = udata */
-    /* to avoid GC, store as key in env */
-    lua_pushvalue(L, -1);
-    lua_pushboolean(L, 1);
-    lua_rawset(L, LUA_ENVIRONINDEX); /* env[udata] = true */
+
+    luaV_set_associated_luavalue(L, (void *)win, -1);
+
     /* set metatable */
     luaV_getfield(L, LUAVIM_WINDOW);
     lua_setmetatable(L, -2);
@@ -748,15 +893,15 @@
     luaV_Window *w = NULL;
     if (win == NULL)
 	lua_pushnil(L);
-    else {
-	lua_pushlightuserdata(L, (void *) win);
-	lua_rawget(L, LUA_ENVIRONINDEX);
-	if (lua_isnil(L, -1)) /* not interned? */
-	{
-	    lua_pop(L, 1);
+    else
+    {
+        if (!luaV_get_associated_luavalue(L, (void *)win))
+        {
+	    lua_pop(L, 1); /* nil */
 	    w = luaV_newwindow(L, win);
 	}
-	else w = (luaV_Window *) lua_touserdata(L, -1);
+	else
+            w = (luaV_Window *) lua_touserdata(L, -1);
     }
     return w;
 }
@@ -784,6 +929,14 @@
 {
     luaV_Window *w = (luaV_Window *) lua_touserdata(L, 1);
     const char *s = luaL_checkstring(L, 2);
+
+    /* Check validity of a window. */
+    if (!luaV_is_associated_luavalue(L, (void *)(*w)))
+    {
+        lua_pushnil(L);
+        return 1;
+    }
+
     if (strncmp(s, "buffer", 6) == 0)
 	luaV_pushbuffer(L, (*w)->w_buffer);
     else if (strncmp(s, "line", 4) == 0)
@@ -880,9 +1033,8 @@
 luaV_window_isvalid(lua_State *L)
 {
     luaV_Window *w = luaV_checkudata(L, 1, LUAVIM_WINDOW);
-    lua_pushlightuserdata(L, (void *) (*w));
-    lua_rawget(L, LUA_ENVIRONINDEX);
-    lua_pushboolean(L, !lua_isnil(L, -1));
+    lua_pushboolean(L,
+            luaV_get_associated_luavalue(L, (void *)(*w)));
     return 1;
 }
 
@@ -1071,15 +1223,7 @@
     static int
 luaV_free(lua_State *L)
 {
-    lua_pushvalue(L, 1); /* lightudata */
-    lua_rawget(L, LUA_ENVIRONINDEX);
-    if (!lua_isnil(L, -1))
-    {
-	lua_pushnil(L);
-	lua_rawset(L, LUA_ENVIRONINDEX); /* env[udata] = nil */
-	lua_pushnil(L);
-	lua_rawset(L, LUA_ENVIRONINDEX); /* env[lightudata] = nil */
-    }
+    luaV_reset_associated_luavalue(L, lua_touserdata(L, 1));
     return 0;
 }
 
@@ -1099,13 +1243,6 @@
     static int
 luaopen_vim(lua_State *L)
 {
-    /* set environment */
-    lua_newtable(L);
-    lua_newtable(L);
-    lua_pushliteral(L, "v");
-    lua_setfield(L, -2, "__mode");
-    lua_setmetatable(L, -2);
-    lua_replace(L, LUA_ENVIRONINDEX);
     /* print */
     lua_pushcfunction(L, luaV_print);
     lua_setglobal(L, "print");

Raspunde prin e-mail lui