diff --git a/Examples/test-suite/lua/cpp_basic_runme.lua b/Examples/test-suite/lua/cpp_basic_runme.lua index c7e0325c5..5a0e1c699 100644 --- a/Examples/test-suite/lua/cpp_basic_runme.lua +++ b/Examples/test-suite/lua/cpp_basic_runme.lua @@ -86,3 +86,14 @@ f4_name = tostring(f4) assert( f2_name == "Foo" ) assert( f3_name == "Foo" ) assert( f4_name == "FooSubSub" ) + +-- Test __eq implementation supplied by default + +-- eq_f1 and eq_f2 must be different userdata with same Foo* pointer. If eq_f1 and eq_f2 are the same userdata (e.g.) +-- > eq_f1 = smth +-- > eq_f2 = eq_f1 +-- then default Lua equality comparison kicks in and considers them equal. Access to global_fptr is actually a +-- function call (internally) and it returns new userdata each time. +eq_f1 = cb.Bar.global_fptr +eq_f2 = cb.Bar.global_fptr +assert( eq_f1 == eq_f2 ) diff --git a/Lib/lua/luarun.swg b/Lib/lua/luarun.swg index 0728a0528..756c38d01 100644 --- a/Lib/lua/luarun.swg +++ b/Lib/lua/luarun.swg @@ -1037,6 +1037,23 @@ SWIGINTERN int SWIG_Lua_class_disown(lua_State *L) return 0; } +/* lua callable function to compare userdata's value +the issue is that two userdata may point to the same thing +but to lua, they are different objects */ +SWIGRUNTIME int SWIG_Lua_class_equal(lua_State *L) +{ + int result; + swig_lua_userdata *usr1,*usr2; + if (!lua_isuserdata(L,1) || !lua_isuserdata(L,2)) /* just in case */ + return 0; /* nil reply */ + usr1=(swig_lua_userdata*)lua_touserdata(L,1); /* get data */ + usr2=(swig_lua_userdata*)lua_touserdata(L,2); /* get data */ + /*result=(usr1->ptr==usr2->ptr && usr1->type==usr2->type); only works if type is the same*/ + result=(usr1->ptr==usr2->ptr); + lua_pushboolean(L,result); + return 1; +} + /* populate table at the top of the stack with metamethods that ought to be inherited */ SWIGINTERN void SWIG_Lua_populate_inheritable_metamethods(lua_State *L) { @@ -1471,6 +1488,18 @@ SWIGINTERN void SWIG_Lua_add_class_user_metamethods(lua_State *L, swig_lua_class lua_pop(L,1); /* remove copy of the key */ } + /* Special handling for __eq method */ + lua_pushstring(L, "__eq"); + lua_pushvalue(L,-1); + lua_rawget(L,metatable_index); + const int eq_undefined = lua_isnil(L,-1); + lua_pop(L,1); + if( eq_undefined ) { + lua_pushcfunction(L, SWIG_Lua_class_equal); + lua_rawset(L, metatable_index); + } else { + lua_pop(L,1); /* remove copy of the key */ + } /* Warning: __index and __newindex are SWIG-defined. For user-defined operator[] * a __getitem/__setitem method should be defined */ @@ -1788,23 +1817,6 @@ SWIGRUNTIME int SWIG_Lua_type(lua_State *L) return 1; } -/* lua callable function to compare userdata's value -the issue is that two userdata may point to the same thing -but to lua, they are different objects */ -SWIGRUNTIME int SWIG_Lua_equal(lua_State *L) -{ - int result; - swig_lua_userdata *usr1,*usr2; - if (!lua_isuserdata(L,1) || !lua_isuserdata(L,2)) /* just in case */ - return 0; /* nil reply */ - usr1=(swig_lua_userdata*)lua_touserdata(L,1); /* get data */ - usr2=(swig_lua_userdata*)lua_touserdata(L,2); /* get data */ - /*result=(usr1->ptr==usr2->ptr && usr1->type==usr2->type); only works if type is the same*/ - result=(usr1->ptr==usr2->ptr); - lua_pushboolean(L,result); - return 1; -} - /* ----------------------------------------------------------------------------- * global variable support code: class/struct typemap functions * ----------------------------------------------------------------------------- */ diff --git a/Lib/lua/luaruntime.swg b/Lib/lua/luaruntime.swg index 89908044b..8df46e8cb 100644 --- a/Lib/lua/luaruntime.swg +++ b/Lib/lua/luaruntime.swg @@ -40,7 +40,7 @@ SWIGEXPORT int SWIG_init(lua_State* L) /* default Lua action */ #if ((SWIG_LUA_TARGET != SWIG_LUA_FLAVOR_ELUA) && (SWIG_LUA_TARGET != SWIG_LUA_FLAVOR_ELUAC)) || defined(SWIG_LUA_ELUA_EMULATE) /* add a global fn */ SWIG_Lua_add_function(L,"swig_type",SWIG_Lua_type); - SWIG_Lua_add_function(L,"swig_equals",SWIG_Lua_equal); + SWIG_Lua_add_function(L,"swig_equals",SWIG_Lua_class_equal); #endif #if (SWIG_LUA_TARGET != SWIG_LUA_FLAVOR_ELUAC)