aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBenoit Germain <bnt.germain@gmail.com>2013-11-04 11:27:04 +0100
committerBenoit Germain <bnt.germain@gmail.com>2013-11-04 11:27:04 +0100
commit39243fa43e43c15613c7f2dd9de8de6ab4daaa4e (patch)
treeb4f391a877c15b9c30c1264ba9462db91e5a8102 /src
parent41864c0725ec5e9c929911fd8f41c34c4cbacf27 (diff)
downloadlanes-39243fa43e43c15613c7f2dd9de8de6ab4daaa4e.tar.gz
lanes-39243fa43e43c15613c7f2dd9de8de6ab4daaa4e.tar.bz2
lanes-39243fa43e43c15613c7f2dd9de8de6ab4daaa4e.zip
Fix lanes.nameof() crashing when encountering a light userdata
Diffstat (limited to 'src')
-rw-r--r--src/tools.c32
1 files changed, 20 insertions, 12 deletions
diff --git a/src/tools.c b/src/tools.c
index 95104d6..f445068 100644
--- a/src/tools.c
+++ b/src/tools.c
@@ -1359,12 +1359,12 @@ static int discover_object_name_recur( lua_State* L, int shortest_, int depth_)
1359 lua_pushinteger( L, 1); // o "r" {c} {fqn} ... {?} {?} 1 1359 lua_pushinteger( L, 1); // o "r" {c} {fqn} ... {?} {?} 1
1360 lua_rawset( L, cache); // o "r" {c} {fqn} ... {?} 1360 lua_rawset( L, cache); // o "r" {c} {fqn} ... {?}
1361 // scan table contents 1361 // scan table contents
1362 STACK_CHECK( L);
1363 lua_pushnil( L); // o "r" {c} {fqn} ... {?} nil 1362 lua_pushnil( L); // o "r" {c} {fqn} ... {?} nil
1364 while( lua_next( L, -2)) // o "r" {c} {fqn} ... {?} k v 1363 while( lua_next( L, -2)) // o "r" {c} {fqn} ... {?} k v
1365 { 1364 {
1366 //char const *const strKey = (lua_type( L, -2) == LUA_TSTRING) ? lua_tostring( L, -2) : NULL; // only for debugging 1365 //char const *const strKey = (lua_type( L, -2) == LUA_TSTRING) ? lua_tostring( L, -2) : NULL; // only for debugging
1367 //lua_Number const numKey = (lua_type( L, -2) == LUA_TNUMBER) ? lua_tonumber( L, -2) : -6666; // only for debugging 1366 //lua_Number const numKey = (lua_type( L, -2) == LUA_TNUMBER) ? lua_tonumber( L, -2) : -6666; // only for debugging
1367 STACK_MID( L, 2);
1368 // append key name to fqn stack 1368 // append key name to fqn stack
1369 ++ depth_; 1369 ++ depth_;
1370 lua_pushvalue( L, -2); // o "r" {c} {fqn} ... {?} k v k 1370 lua_pushvalue( L, -2); // o "r" {c} {fqn} ... {?} k v k
@@ -1384,8 +1384,12 @@ static int discover_object_name_recur( lua_State* L, int shortest_, int depth_)
1384 STACK_MID( L, 0); 1384 STACK_MID( L, 0);
1385 break; 1385 break;
1386 } 1386 }
1387 else if( lua_istable( L, -1)) // o "r" {c} {fqn} ... {?} k {} 1387 switch( lua_type( L, -1)) // o "r" {c} {fqn} ... {?} k v
1388 { 1388 {
1389 default: // nil, boolean, light userdata, number and string aren't identifiable
1390 break;
1391
1392 case LUA_TTABLE: // o "r" {c} {fqn} ... {?} k {}
1389 STACK_MID( L, 2); 1393 STACK_MID( L, 2);
1390 shortest_ = discover_object_name_recur( L, shortest_, depth_); 1394 shortest_ = discover_object_name_recur( L, shortest_, depth_);
1391 // search in the table's metatable too 1395 // search in the table's metatable too
@@ -1402,11 +1406,11 @@ static int discover_object_name_recur( lua_State* L, int shortest_, int depth_)
1402 -- depth_; 1406 -- depth_;
1403 } 1407 }
1404 lua_pop( L, 1); // o "r" {c} {fqn} ... {?} k {} 1408 lua_pop( L, 1); // o "r" {c} {fqn} ... {?} k {}
1405 STACK_MID( L, 2);
1406 } 1409 }
1407 } 1410 STACK_MID( L, 2);
1408 else if( lua_isthread( L, -1)) // o "r" {c} {fqn} ... {?} k T 1411 break;
1409 { 1412
1413 case LUA_TTHREAD: // o "r" {c} {fqn} ... {?} k T
1410 // search in the object's uservalue if it is a table 1414 // search in the object's uservalue if it is a table
1411 lua_getuservalue( L, -1); // o "r" {c} {fqn} ... {?} k T {u} 1415 lua_getuservalue( L, -1); // o "r" {c} {fqn} ... {?} k T {u}
1412 if( lua_istable( L, -1)) 1416 if( lua_istable( L, -1))
@@ -1415,9 +1419,9 @@ static int discover_object_name_recur( lua_State* L, int shortest_, int depth_)
1415 } 1419 }
1416 lua_pop( L, 1); // o "r" {c} {fqn} ... {?} k T 1420 lua_pop( L, 1); // o "r" {c} {fqn} ... {?} k T
1417 STACK_MID( L, 2); 1421 STACK_MID( L, 2);
1418 } 1422 break;
1419 else if( lua_isuserdata( L, -1)) // o "r" {c} {fqn} ... {?} k U 1423
1420 { 1424 case LUA_TUSERDATA: // o "r" {c} {fqn} ... {?} k U
1421 STACK_MID( L, 2); 1425 STACK_MID( L, 2);
1422 // search in the object's metatable (some modules are built that way) 1426 // search in the object's metatable (some modules are built that way)
1423 if( lua_getmetatable( L, -1)) // o "r" {c} {fqn} ... {?} k U {mt} 1427 if( lua_getmetatable( L, -1)) // o "r" {c} {fqn} ... {?} k U {mt}
@@ -1433,8 +1437,8 @@ static int discover_object_name_recur( lua_State* L, int shortest_, int depth_)
1433 -- depth_; 1437 -- depth_;
1434 } 1438 }
1435 lua_pop( L, 1); // o "r" {c} {fqn} ... {?} k U 1439 lua_pop( L, 1); // o "r" {c} {fqn} ... {?} k U
1436 STACK_MID( L, 2);
1437 } 1440 }
1441 STACK_MID( L, 2);
1438 // search in the object's uservalue if it is a table 1442 // search in the object's uservalue if it is a table
1439 lua_getuservalue( L, -1); // o "r" {c} {fqn} ... {?} k U {u} 1443 lua_getuservalue( L, -1); // o "r" {c} {fqn} ... {?} k U {u}
1440 if( lua_istable( L, -1)) 1444 if( lua_istable( L, -1))
@@ -1449,15 +1453,17 @@ static int discover_object_name_recur( lua_State* L, int shortest_, int depth_)
1449 } 1453 }
1450 lua_pop( L, 1); // o "r" {c} {fqn} ... {?} k U 1454 lua_pop( L, 1); // o "r" {c} {fqn} ... {?} k U
1451 STACK_MID( L, 2); 1455 STACK_MID( L, 2);
1456 break;
1452 } 1457 }
1453 // make ready for next iteration 1458 // make ready for next iteration
1454 lua_pop( L, 1); // o "r" {c} {fqn} ... {?} k 1459 lua_pop( L, 1); // o "r" {c} {fqn} ... {?} k
1455 // remove name from fqn stack 1460 // remove name from fqn stack
1456 lua_pushnil( L); // o "r" {c} {fqn} ... {?} k nil 1461 lua_pushnil( L); // o "r" {c} {fqn} ... {?} k nil
1457 lua_rawseti( L, fqn, depth_); // o "r" {c} {fqn} ... {?} k 1462 lua_rawseti( L, fqn, depth_); // o "r" {c} {fqn} ... {?} k
1463 STACK_MID( L, 1);
1458 -- depth_; 1464 -- depth_;
1459 } // o "r" {c} {fqn} ... {?} 1465 } // o "r" {c} {fqn} ... {?}
1460 STACK_END( L, 0); 1466 STACK_MID( L, 0);
1461 // remove the visited table from the cache, in case a shorter path to the searched object exists 1467 // remove the visited table from the cache, in case a shorter path to the searched object exists
1462 lua_pushvalue( L, -1); // o "r" {c} {fqn} ... {?} {?} 1468 lua_pushvalue( L, -1); // o "r" {c} {fqn} ... {?} {?}
1463 lua_pushnil( L); // o "r" {c} {fqn} ... {?} {?} nil 1469 lua_pushnil( L); // o "r" {c} {fqn} ... {?} {?} nil
@@ -1477,7 +1483,7 @@ int luaG_nameof( lua_State* L)
1477 luaL_argerror( L, what, "too many arguments."); 1483 luaL_argerror( L, what, "too many arguments.");
1478 } 1484 }
1479 1485
1480 // numbers, strings, booleans and nil can't be identified 1486 // nil, boolean, light userdata, number and string aren't identifiable
1481 if( lua_type( L, 1) < LUA_TTABLE) 1487 if( lua_type( L, 1) < LUA_TTABLE)
1482 { 1488 {
1483 lua_pushstring( L, luaL_typename( L, 1)); // o "type" 1489 lua_pushstring( L, luaL_typename( L, 1)); // o "type"
@@ -1486,6 +1492,7 @@ int luaG_nameof( lua_State* L)
1486 } 1492 }
1487 1493
1488 STACK_GROW( L, 4); 1494 STACK_GROW( L, 4);
1495 STACK_CHECK( L);
1489 // this slot will contain the shortest name we found when we are done 1496 // this slot will contain the shortest name we found when we are done
1490 lua_pushnil( L); // o nil 1497 lua_pushnil( L); // o nil
1491 // push a cache that will contain all already visited tables 1498 // push a cache that will contain all already visited tables
@@ -1496,6 +1503,7 @@ int luaG_nameof( lua_State* L)
1496 lua_pushglobaltable( L); // o nil {c} {fqn} _G 1503 lua_pushglobaltable( L); // o nil {c} {fqn} _G
1497 (void) discover_object_name_recur( L, 6666, 0); 1504 (void) discover_object_name_recur( L, 6666, 0);
1498 lua_pop( L, 3); // o "result" 1505 lua_pop( L, 3); // o "result"
1506 STACK_END( L, 1);
1499 lua_pushstring( L, luaL_typename( L, 1)); // o "result" "type" 1507 lua_pushstring( L, luaL_typename( L, 1)); // o "result" "type"
1500 lua_replace( L, -3); // "type" "result" 1508 lua_replace( L, -3); // "type" "result"
1501 return 2; 1509 return 2;