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; }