diff --git a/rts/lib/lua/src/lbaselib.cpp b/rts/lib/lua/src/lbaselib.cpp
index 8dbfda6795..70a2192fdf 100644
--- a/rts/lib/lua/src/lbaselib.cpp
+++ b/rts/lib/lua/src/lbaselib.cpp
@@ -235,11 +235,23 @@ static int luaB_next (lua_State *L) {
}
+/***
+ * Meta __pairs
backported from Lua 5.2,
+ * originally lua_pushvalue(L, lua_upvalueindex(1));
was lua_pushcfunction(L, luaB_next);
+ *
+ * but that requires "light C function" support,
+ * which makes lua_pushcfunction not allocate extra memory for the GC to clean up.
+ */
static int luaB_pairs (lua_State *L) {
- luaL_checktype(L, 1, LUA_TTABLE);
- lua_pushvalue(L, lua_upvalueindex(1)); /* return generator, */
- lua_pushvalue(L, 1); /* state, */
- lua_pushnil(L); /* and initial value */
+ luaL_checkany(L, 1);
+ if (luaL_getmetafield(L, 1, "__pairs") == LUA_TNIL) { /* no metamethod? */
+ lua_pushvalue(L, lua_upvalueindex(1)); /* return generator, */
+ lua_pushvalue(L, 1); /* state, */
+ lua_pushnil(L); /* and initial value */
+ } else {
+ lua_pushvalue(L, 1); /* argument 'self' to metamethod */
+ lua_call(L, 1, 3); /* get 3 values from metamethod */
+ }
return 3;
}