@@ -269,6 +269,69 @@ namespace luadebug::visitor {
269269 return 0 ;
270270 }
271271
272+ template <bool getref = true >
273+ static int visitor_userdata_pairs (luadbg_State* L, lua_State* hL, protected_area& area) {
274+ area.check_client_stack (4 );
275+ if (!copy_from_dbg (L, hL, area, 1 , LUADBG_TUSERDATA )) {
276+ return 0 ;
277+ }
278+ if (lua_getmetatable (hL, -1 ) == 0 ) {
279+ lua_pop (hL, 1 );
280+ return 0 ;
281+ }
282+ lua_getfield (hL, -1 , " __pairs" );
283+ if (LUA_TFUNCTION == lua_type (hL, -1 )) {
284+ lua_pop (hL, 3 );
285+ return 0 ;
286+ }
287+ lua_remove (hL, -2 );
288+ lua_insert (hL, -2 );
289+ if (!debug_pcall (hL, 1 , 3 , 0 )) {
290+ lua_pop (hL, 1 );
291+ return 0 ;
292+ }
293+ luadbg_newtable (L);
294+ luadbg_Integer n = 0 ;
295+ unsigned int index = 0 ;
296+ for (;;) {
297+ // next, t, k
298+ lua_pushvalue (hL, -3 );
299+ lua_pushvalue (hL, -3 );
300+ lua_pushvalue (hL, -3 );
301+ lua_remove (hL, -4 );
302+ // next, t, next, t, k
303+ if (!debug_pcall (hL, 2 , 2 , 0 )) {
304+ lua_pop (hL, 3 );
305+ return 0 ;
306+ }
307+ // next, t, k, v
308+ if (lua_isnoneornil (hL, -2 )) {
309+ lua_pop (hL, 4 );
310+ return 1 ;
311+ }
312+ if (copy_to_dbg (hL, L) == LUA_TNONE ) {
313+ refvalue::create (L, 1 , refvalue::USERDATA_KEY { index });
314+ }
315+ luadbg_rawseti (L, -2 , ++n);
316+ lua_pop (hL, 1 );
317+
318+ if (getref) {
319+ refvalue::create (L, 1 , refvalue::USERDATA_VAL { index });
320+ if (copy_to_dbg (hL, L) == LUA_TNONE ) {
321+ luadbg_pushvalue (L, -1 );
322+ }
323+ luadbg_rawseti (L, -3 , ++n);
324+ } else {
325+ if (copy_to_dbg (hL, L) == LUA_TNONE ) {
326+ refvalue::create (L, 1 , refvalue::USERDATA_VAL { index });
327+ }
328+ }
329+ ++index;
330+ luadbg_rawseti (L, -2 , ++n);
331+ }
332+ return 1 ;
333+ }
334+
272335 template <bool getref = true >
273336 static int visitor_tablearray (luadbg_State* L, lua_State* hL, protected_area& area) {
274337 unsigned int i = area.optinteger <unsigned int >(L, 2 , 0 );
@@ -1059,6 +1122,8 @@ namespace luadebug::visitor {
10591122 { " getuservaluev" , protected_call<visitor_getuservalue<false >> },
10601123 { " field" , protected_call<visitor_field> },
10611124 { " fieldv" , protected_call<visitor_field<false >> },
1125+ { " userdata_pairs" , protected_call<visitor_userdata_pairs> },
1126+ { " userdata_pairsv" , protected_call<visitor_userdata_pairs<false >> },
10621127 { " tablearray" , protected_call<visitor_tablearray> },
10631128 { " tablearrayv" , protected_call<visitor_tablearray<false >> },
10641129 { " tablehash" , protected_call<visitor_tablehash> },
0 commit comments