Skip to content

Instantly share code, notes, and snippets.

@koron
Created January 7, 2012 12:21
Show Gist options
  • Save koron/1574612 to your computer and use it in GitHub Desktop.
Save koron/1574612 to your computer and use it in GitHub Desktop.
# HG changeset patch
# Parent 2e546d787ee8d12f7ea1b22172b9d491652c1ed7
support lua 5.2 (intermediate #4)
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 Sat Jan 07 21:18:35 2012 +0900
@@ -13,6 +13,9 @@
#include <lua.h>
#include <lualib.h>
+#if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM >= 502
+# define LUA_COMPAT_MODULE 1
+#endif
#include <lauxlib.h>
/* Only do the following when the feature is enabled. Needed for "make
@@ -38,6 +41,11 @@
#define luaV_msg(L) luaV_msgfunc((L), (msgfunc_T) msg)
#define luaV_emsg(L) luaV_msgfunc((L), (msgfunc_T) emsg)
+/*
+ * LUA_VERSION_NUM macro: be defined in lua.h. Its values are...
+ * - 501 for 5.1.x
+ * - 502 for 5.2.x
+ */
#ifdef DYNAMIC_LUA
@@ -54,20 +62,27 @@
#endif
/* lauxlib */
-#define luaL_register dll_luaL_register
-#define luaL_typerror dll_luaL_typerror
#define luaL_checklstring dll_luaL_checklstring
#define luaL_checkinteger dll_luaL_checkinteger
#define luaL_optinteger dll_luaL_optinteger
#define luaL_checktype dll_luaL_checktype
#define luaL_error dll_luaL_error
-#define luaL_loadfile dll_luaL_loadfile
-#define luaL_loadbuffer dll_luaL_loadbuffer
#define luaL_newstate dll_luaL_newstate
#define luaL_buffinit dll_luaL_buffinit
-#define luaL_prepbuffer dll_luaL_prepbuffer
#define luaL_addlstring dll_luaL_addlstring
#define luaL_pushresult dll_luaL_pushresult
+#if !defined(LUA_VERSION_NUM) || LUA_VERSION_NUM < 502
+# define luaL_register dll_luaL_register
+# define luaL_typerror dll_luaL_typerror
+# define luaL_loadfile dll_luaL_loadfile
+# define luaL_loadbuffer dll_luaL_loadbuffer
+# define luaL_prepbuffer dll_luaL_prepbuffer
+#else
+# define luaL_openlib dll_luaL_openlib
+# define luaL_loadfilex dll_luaL_loadfilex
+# define luaL_loadbufferx dll_luaL_loadbufferx
+# define luaL_prepbuffsize dll_luaL_prepbuffsize
+#endif
/* lua */
#define lua_close dll_lua_close
#define lua_gettop dll_lua_gettop
@@ -78,8 +93,6 @@
#define lua_isstring dll_lua_isstring
#define lua_type dll_lua_type
#define lua_rawequal dll_lua_rawequal
-#define lua_tonumber dll_lua_tonumber
-#define lua_tointeger dll_lua_tointeger
#define lua_toboolean dll_lua_toboolean
#define lua_tolstring dll_lua_tolstring
#define lua_touserdata dll_lua_touserdata
@@ -102,8 +115,22 @@
#define lua_rawseti dll_lua_rawseti
#define lua_remove dll_lua_remove
#define lua_setmetatable dll_lua_setmetatable
-#define lua_call dll_lua_call
-#define lua_pcall dll_lua_pcall
+#if !defined(LUA_VERSION_NUM) || LUA_VERSION_NUM < 502
+# define lua_tonumber dll_lua_tonumber
+# define lua_tointeger dll_lua_tointeger
+# define lua_call dll_lua_call
+# define lua_pcall dll_lua_pcall
+#else
+# define lua_tonumberx dll_lua_tonumberx
+# define lua_tointegerx dll_lua_tointegerx
+# define lua_callk dll_lua_callk
+# define lua_pcallk dll_lua_pcallk
+# define lua_getuservalue dll_lua_getuservalue
+# define lua_setuservalue dll_lua_setuservalue
+# define lua_getglobal dll_lua_getglobal
+# define lua_setglobal dll_lua_setglobal
+# define lua_insert dll_lua_insert
+#endif
/* libs */
#define luaopen_base dll_luaopen_base
#define luaopen_table dll_luaopen_table
@@ -116,20 +143,27 @@
#define luaL_openlibs dll_luaL_openlibs
/* lauxlib */
-void (*dll_luaL_register) (lua_State *L, const char *libname, const luaL_Reg *l);
-int (*dll_luaL_typerror) (lua_State *L, int narg, const char *tname);
const char *(*dll_luaL_checklstring) (lua_State *L, int numArg, size_t *l);
lua_Integer (*dll_luaL_checkinteger) (lua_State *L, int numArg);
lua_Integer (*dll_luaL_optinteger) (lua_State *L, int nArg, lua_Integer def);
void (*dll_luaL_checktype) (lua_State *L, int narg, int t);
int (*dll_luaL_error) (lua_State *L, const char *fmt, ...);
+lua_State *(*dll_luaL_newstate) (void);
+void (*dll_luaL_buffinit) (lua_State *L, luaL_Buffer *B);
+void (*dll_luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l);
+void (*dll_luaL_pushresult) (luaL_Buffer *B);
+#if !defined(LUA_VERSION_NUM) || LUA_VERSION_NUM < 502
+void (*dll_luaL_register) (lua_State *L, const char *libname, const luaL_Reg *l);
+int (*dll_luaL_typerror) (lua_State *L, int narg, const char *tname);
int (*dll_luaL_loadfile) (lua_State *L, const char *filename);
int (*dll_luaL_loadbuffer) (lua_State *L, const char *buff, size_t sz, const char *name);
-lua_State *(*dll_luaL_newstate) (void);
-void (*dll_luaL_buffinit) (lua_State *L, luaL_Buffer *B);
char *(*dll_luaL_prepbuffer) (luaL_Buffer *B);
-void (*dll_luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l);
-void (*dll_luaL_pushresult) (luaL_Buffer *B);
+#else
+void (*dll_luaL_openlib) (lua_State *L, const char *libname, const luaL_Reg *l, int nup);
+int (*dll_luaL_loadfilex) (lua_State *L, const char *filename, const char *mode);
+int (*dll_luaL_loadbufferx) (lua_State *L, const char *buff, size_t sz, const char *name, const char *mode);
+char *(*dll_luaL_prepbuffsize) (luaL_Buffer *B, size_t sz);
+#endif
/* lua */
void (*dll_lua_close) (lua_State *L);
int (*dll_lua_gettop) (lua_State *L);
@@ -140,8 +174,6 @@
int (*dll_lua_isstring) (lua_State *L, int idx);
int (*dll_lua_type) (lua_State *L, int idx);
int (*dll_lua_rawequal) (lua_State *L, int idx1, int idx2);
-lua_Number (*dll_lua_tonumber) (lua_State *L, int idx);
-lua_Integer (*dll_lua_tointeger) (lua_State *L, int idx);
int (*dll_lua_toboolean) (lua_State *L, int idx);
const char *(*dll_lua_tolstring) (lua_State *L, int idx, size_t *len);
void *(*dll_lua_touserdata) (lua_State *L, int idx);
@@ -164,8 +196,22 @@
void (*dll_lua_rawseti) (lua_State *L, int idx, int n);
void (*dll_lua_remove) (lua_State *L, int idx);
int (*dll_lua_setmetatable) (lua_State *L, int objindex);
+#if !defined(LUA_VERSION_NUM) || LUA_VERSION_NUM < 502
+lua_Number (*dll_lua_tonumber) (lua_State *L, int idx);
+lua_Integer (*dll_lua_tointeger) (lua_State *L, int idx);
void (*dll_lua_call) (lua_State *L, int nargs, int nresults);
int (*dll_lua_pcall) (lua_State *L, int nargs, int nresults, int errfunc);
+#else
+lua_Number (*dll_lua_tonumberx) (lua_State *L, int idx, int *isnum);
+lua_Integer (*dll_lua_tointegerx) (lua_State *L, int idx, int *isnum);
+void (*dll_lua_callk) (lua_State *L, int nargs, int nresults, int ctx, lua_CFunction k);
+int (*dll_lua_pcallk) (lua_State *L, int nargs, int nresults, int errfunc, int ctx, lua_CFunction k);
+void (*dll_lua_getuservalue) (lua_State *L, int idx);
+void (*dll_lua_setuservalue) (lua_State *L, int idx);
+void (*dll_lua_getglobal) (lua_State *L, const char *var);
+void (*dll_lua_setglobal) (lua_State *L, const char *var);
+void (*dll_lua_insert) (lua_State *L, int idx);
+#endif
/* libs */
int (*dll_luaopen_base) (lua_State *L);
int (*dll_luaopen_table) (lua_State *L);
@@ -185,20 +231,27 @@
static const luaV_Reg luaV_dll[] = {
/* lauxlib */
- {"luaL_register", (luaV_function) &dll_luaL_register},
- {"luaL_typerror", (luaV_function) &dll_luaL_typerror},
{"luaL_checklstring", (luaV_function) &dll_luaL_checklstring},
{"luaL_checkinteger", (luaV_function) &dll_luaL_checkinteger},
{"luaL_optinteger", (luaV_function) &dll_luaL_optinteger},
{"luaL_checktype", (luaV_function) &dll_luaL_checktype},
{"luaL_error", (luaV_function) &dll_luaL_error},
+ {"luaL_newstate", (luaV_function) &dll_luaL_newstate},
+ {"luaL_buffinit", (luaV_function) &dll_luaL_buffinit},
+ {"luaL_addlstring", (luaV_function) &dll_luaL_addlstring},
+ {"luaL_pushresult", (luaV_function) &dll_luaL_pushresult},
+#if !defined(LUA_VERSION_NUM) || LUA_VERSION_NUM < 502
+ {"luaL_register", (luaV_function) &dll_luaL_register},
+ {"luaL_typerror", (luaV_function) &dll_luaL_typerror},
{"luaL_loadfile", (luaV_function) &dll_luaL_loadfile},
{"luaL_loadbuffer", (luaV_function) &dll_luaL_loadbuffer},
- {"luaL_newstate", (luaV_function) &dll_luaL_newstate},
- {"luaL_buffinit", (luaV_function) &dll_luaL_buffinit},
{"luaL_prepbuffer", (luaV_function) &dll_luaL_prepbuffer},
- {"luaL_addlstring", (luaV_function) &dll_luaL_addlstring},
- {"luaL_pushresult", (luaV_function) &dll_luaL_pushresult},
+#else
+ {"luaL_openlib", (luaV_function) &dll_luaL_openlib},
+ {"luaL_loadfilex", (luaV_function) &dll_luaL_loadfilex},
+ {"luaL_loadbufferx", (luaV_function) &dll_luaL_loadbufferx},
+ {"luaL_prepbuffsize", (luaV_function) &dll_luaL_prepbuffsize},
+#endif
/* lua */
{"lua_close", (luaV_function) &dll_lua_close},
{"lua_gettop", (luaV_function) &dll_lua_gettop},
@@ -209,8 +262,6 @@
{"lua_isstring", (luaV_function) &dll_lua_isstring},
{"lua_type", (luaV_function) &dll_lua_type},
{"lua_rawequal", (luaV_function) &dll_lua_rawequal},
- {"lua_tonumber", (luaV_function) &dll_lua_tonumber},
- {"lua_tointeger", (luaV_function) &dll_lua_tointeger},
{"lua_toboolean", (luaV_function) &dll_lua_toboolean},
{"lua_tolstring", (luaV_function) &dll_lua_tolstring},
{"lua_touserdata", (luaV_function) &dll_lua_touserdata},
@@ -233,8 +284,22 @@
{"lua_rawseti", (luaV_function) &dll_lua_rawseti},
{"lua_remove", (luaV_function) &dll_lua_remove},
{"lua_setmetatable", (luaV_function) &dll_lua_setmetatable},
+#if !defined(LUA_VERSION_NUM) || LUA_VERSION_NUM < 502
+ {"lua_tonumber", (luaV_function) &dll_lua_tonumber},
+ {"lua_tointeger", (luaV_function) &dll_lua_tointeger},
{"lua_call", (luaV_function) &dll_lua_call},
{"lua_pcall", (luaV_function) &dll_lua_pcall},
+#else
+ {"lua_tonumberx", (luaV_function) &dll_lua_tonumberx},
+ {"lua_tointegerx", (luaV_function) &dll_lua_tointegerx},
+ {"lua_callk", (luaV_function) &dll_lua_callk},
+ {"lua_pcallk", (luaV_function) &dll_lua_pcallk},
+ {"lua_getuservalue", (luaV_function) &dll_lua_getuservalue},
+ {"lua_setuservalue", (luaV_function) &dll_lua_setuservalue},
+ {"lua_getglobal", (luaV_function) &dll_lua_getglobal},
+ {"lua_setglobal", (luaV_function) &dll_lua_setglobal},
+ {"lua_insert", (luaV_function) &dll_lua_insert},
+#endif
/* libs */
{"luaopen_base", (luaV_function) &dll_luaopen_base},
{"luaopen_table", (luaV_function) &dll_luaopen_table},
@@ -250,6 +315,10 @@
static HANDLE hinstLua = NULL;
+static void luaV_getuservalue(lua_State *L, int idx);
+static void luaV_setuservalue(lua_State *L, int idx);
+static void luaV_pop_below_the_top(lua_State* L);
+
static void
end_dynamic_lua(void)
{
@@ -330,7 +399,14 @@
luaV_checkudata(lua_State *L, int ud, const char *tname)
{
void *p = luaV_toudata(L, ud, tname);
- if (p == NULL) luaL_typerror(L, ud, tname);
+ if (p == NULL)
+ {
+#if !defined(LUA_VERSION_NUM) || LUA_VERSION_NUM < 502
+ luaL_typerror(L, ud, tname);
+#else
+ luaL_error(L, "type error: %d %s", ud, tname);
+#endif
+ }
return p;
}
@@ -358,7 +434,7 @@
{
/* check cache */
lua_pushlightuserdata(L, (void *) l);
- lua_rawget(L, LUA_ENVIRONINDEX);
+ luaV_getuservalue(L, -1);
if (lua_isnil(L, -1)) /* not interned? */
{
listitem_T *li;
@@ -367,13 +443,17 @@
lua_newtable(L);
lua_pushlightuserdata(L, (void *) l);
lua_pushvalue(L, -2);
- lua_rawset(L, LUA_ENVIRONINDEX);
+ luaV_setuservalue(L, -2);
+ lua_pop(L, 1); /* l */
for (li = l->lv_first; li != NULL; li = li->li_next)
{
luaV_pushtypval(L, &li->li_tv);
lua_rawseti(L, -2, ++n);
}
}
+
+ /* Pop a value just below the top. */
+ luaV_pop_below_the_top(L); /* l */
}
else lua_pushnil(L);
break;
@@ -385,7 +465,7 @@
{
/* check cache */
lua_pushlightuserdata(L, (void *) d);
- lua_rawget(L, LUA_ENVIRONINDEX);
+ luaV_getuservalue(L, -1);
if (lua_isnil(L, -1)) /* not interned? */
{
hashtab_T *ht = &d->dv_hashtab;
@@ -395,7 +475,8 @@
lua_newtable(L);
lua_pushlightuserdata(L, (void *) d);
lua_pushvalue(L, -2);
- lua_rawset(L, LUA_ENVIRONINDEX);
+ luaV_setuservalue(L, -2);
+ lua_pop(L, 1); /* d */
for (hi = ht->ht_array; n > 0; hi++)
{
if (!HASHITEM_EMPTY(hi))
@@ -407,6 +488,9 @@
}
}
}
+
+ /* Pop a value just below the top. */
+ luaV_pop_below_the_top(L); /* d */
}
else lua_pushnil(L);
break;
@@ -491,11 +575,14 @@
*b = buf;
lua_pushlightuserdata(L, (void *) buf);
lua_pushvalue(L, -2);
- lua_rawset(L, LUA_ENVIRONINDEX); /* env[buf] = udata */
+ luaV_setuservalue(L, -2); /* env[buf] = udata */
+ lua_pop(L, 1);
+#if !defined(LUA_VERSION_NUM) || LUA_VERSION_NUM < 502
/* to avoid GC, store as key in env */
lua_pushvalue(L, -1);
lua_pushboolean(L, 1);
lua_rawset(L, LUA_ENVIRONINDEX); /* env[udata] = true */
+#endif
/* set metatable */
luaV_getfield(L, LUAVIM_BUFFER);
lua_setmetatable(L, -2);
@@ -508,9 +595,10 @@
luaV_Buffer *b = NULL;
if (buf == NULL)
lua_pushnil(L);
- else {
+ else
+ {
lua_pushlightuserdata(L, (void *) buf);
- lua_rawget(L, LUA_ENVIRONINDEX);
+ luaV_getuservalue(L, -1);
if (lua_isnil(L, -1)) /* not interned? */
{
lua_pop(L, 1);
@@ -518,6 +606,7 @@
}
else
b = (luaV_Buffer *) lua_touserdata(L, -1);
+ luaV_pop_below_the_top(L); /* buf */
}
return b;
}
@@ -703,8 +792,9 @@
{
luaV_Buffer *b = luaV_checkudata(L, 1, LUAVIM_BUFFER);
lua_pushlightuserdata(L, (void *) (*b));
- lua_rawget(L, LUA_ENVIRONINDEX);
+ luaV_getuservalue(L, -1);
lua_pushboolean(L, !lua_isnil(L, -1));
+ luaV_pop_below_the_top(L);
return 1;
}
@@ -731,11 +821,14 @@
*w = win;
lua_pushlightuserdata(L, (void *) win);
lua_pushvalue(L, -2);
- lua_rawset(L, LUA_ENVIRONINDEX); /* env[win] = udata */
+ luaV_setuservalue(L, -2); /* env[win] = udata */
+ lua_pop(L, 1);
+#if !defined(LUA_VERSION_NUM) || LUA_VERSION_NUM < 502
/* to avoid GC, store as key in env */
lua_pushvalue(L, -1);
lua_pushboolean(L, 1);
lua_rawset(L, LUA_ENVIRONINDEX); /* env[udata] = true */
+#endif
/* set metatable */
luaV_getfield(L, LUAVIM_WINDOW);
lua_setmetatable(L, -2);
@@ -748,15 +841,18 @@
luaV_Window *w = NULL;
if (win == NULL)
lua_pushnil(L);
- else {
+ else
+ {
lua_pushlightuserdata(L, (void *) win);
- lua_rawget(L, LUA_ENVIRONINDEX);
+ luaV_getuservalue(L, -1);
if (lua_isnil(L, -1)) /* not interned? */
{
lua_pop(L, 1);
w = luaV_newwindow(L, win);
}
- else w = (luaV_Window *) lua_touserdata(L, -1);
+ else
+ w = (luaV_Window *) lua_touserdata(L, -1);
+ luaV_pop_below_the_top(L);
}
return w;
}
@@ -881,8 +977,9 @@
{
luaV_Window *w = luaV_checkudata(L, 1, LUAVIM_WINDOW);
lua_pushlightuserdata(L, (void *) (*w));
- lua_rawget(L, LUA_ENVIRONINDEX);
+ luaV_getuservalue(L, -1);
lua_pushboolean(L, !lua_isnil(L, -1));
+ luaV_pop_below_the_top(L);
return 1;
}
@@ -1072,14 +1169,24 @@
luaV_free(lua_State *L)
{
lua_pushvalue(L, 1); /* lightudata */
- lua_rawget(L, LUA_ENVIRONINDEX);
+ /* TODO: support 5.2 */
+ luaV_getuservalue(L, -1);
if (!lua_isnil(L, -1))
{
+#if !defined(LUA_VERSION_NUM) || LUA_VERSION_NUM < 502
lua_pushnil(L);
lua_rawset(L, LUA_ENVIRONINDEX); /* env[udata] = nil */
lua_pushnil(L);
lua_rawset(L, LUA_ENVIRONINDEX); /* env[lightudata] = nil */
+#else
+ lua_pop(L, 1); /* udata */
+ lua_pushnil(L);
+ luaV_setuservalue(L, -2);
+ lua_pop(L, 1); /* lightudata */
+#endif
}
+ else
+ lua_pop(L, 1); /* lightudata */
return 0;
}
@@ -1099,13 +1206,16 @@
static int
luaopen_vim(lua_State *L)
{
- /* set environment */
+#if !defined(LUA_VERSION_NUM) || LUA_VERSION_NUM < 502
+ /* set environment, as "value" weak table*/
lua_newtable(L);
lua_newtable(L);
lua_pushliteral(L, "v");
lua_setfield(L, -2, "__mode");
lua_setmetatable(L, -2);
lua_replace(L, LUA_ENVIRONINDEX);
+#endif
+
/* print */
lua_pushcfunction(L, luaV_print);
lua_setglobal(L, "print");
@@ -1293,4 +1403,47 @@
lua_call(L, 1, 0);
}
+/**
+ * Pushes onto the stack the Lua value associated with userdata at the given
+ * index. This Lua value must be a table or nil.
+ *
+ * Wrapper of lua_getuservalue() from Lua 5.2.
+ */
+ void
+luaV_getuservalue(lua_State *L, int idx)
+{
+#if !defined(LUA_VERSION_NUM) || LUA_VERSION_NUM < 502
+ lua_pushvalue(L, idx);
+ lua_rawget(L, LUA_ENVIRONINDEX);
+#else
+ lua_getuservalue(L, idx);
#endif
+}
+
+/**
+ * Pops a table or nil from the stack and sets it as the new value associated
+ * to the userdata at the given index.
+ *
+ * Wrapper of lua_setuservalue() from Lua 5.2.
+ */
+ void
+luaV_setuservalue(lua_State *L, int idx)
+{
+#if !defined(LUA_VERSION_NUM) || LUA_VERSION_NUM < 502
+ lua_pushvalue(L, idx);
+ lua_pushvalue(L, -2);
+ lua_rawset(L, LUA_ENVIRONINDEX);
+ lua_pop(L, 1);
+#else
+ lua_setuservalue(L, idx);
+#endif
+}
+
+ void
+luaV_pop_below_the_top(lua_State* L)
+{
+ lua_insert(L, -2);
+ lua_pop(L, 1);
+}
+
+#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment