diff options
Diffstat (limited to 'src/tools.c')
-rw-r--r-- | src/tools.c | 168 |
1 files changed, 120 insertions, 48 deletions
diff --git a/src/tools.c b/src/tools.c index d2dfdf5..a3cc6b7 100644 --- a/src/tools.c +++ b/src/tools.c | |||
@@ -42,6 +42,10 @@ THE SOFTWARE. | |||
42 | #include <string.h> | 42 | #include <string.h> |
43 | #include <ctype.h> | 43 | #include <ctype.h> |
44 | #include <stdlib.h> | 44 | #include <stdlib.h> |
45 | #include <malloc.h> | ||
46 | |||
47 | // for verbose errors | ||
48 | bool_t GVerboseErrors = FALSE; | ||
45 | 49 | ||
46 | /* | 50 | /* |
47 | ** Copied from Lua 5.2 loadlib.c | 51 | ** Copied from Lua 5.2 loadlib.c |
@@ -1285,9 +1289,9 @@ static bool_t push_cached_table( lua_State *L2, uint_t L2_cache_i, lua_State *L, | |||
1285 | * | 1289 | * |
1286 | * Always pushes a function to 'L2'. | 1290 | * Always pushes a function to 'L2'. |
1287 | */ | 1291 | */ |
1288 | static void inter_copy_func( lua_State* L2, uint_t L2_cache_i, lua_State* L, uint_t i); | 1292 | static void inter_copy_func( lua_State* L2, uint_t L2_cache_i, lua_State* L, uint_t i, char const* upName_); |
1289 | 1293 | ||
1290 | static void push_cached_func( lua_State* L2, uint_t L2_cache_i, lua_State* L, uint_t i) | 1294 | static void push_cached_func( lua_State* L2, uint_t L2_cache_i, lua_State* L, uint_t i, char const* upName_) |
1291 | { | 1295 | { |
1292 | void* const aspointer = (void*)lua_topointer( L, i); | 1296 | void* const aspointer = (void*)lua_topointer( L, i); |
1293 | // TBD: Merge this and same code for tables | 1297 | // TBD: Merge this and same code for tables |
@@ -1319,7 +1323,7 @@ static void push_cached_func( lua_State* L2, uint_t L2_cache_i, lua_State* L, ui | |||
1319 | // via upvalues | 1323 | // via upvalues |
1320 | // | 1324 | // |
1321 | // pushes a copy of the func, stores a reference in the cache | 1325 | // pushes a copy of the func, stores a reference in the cache |
1322 | inter_copy_func( L2, L2_cache_i, L, i); // ... {cache} ... function | 1326 | inter_copy_func( L2, L2_cache_i, L, i, upName_); // ... {cache} ... function |
1323 | } | 1327 | } |
1324 | else // found function in the cache | 1328 | else // found function in the cache |
1325 | { | 1329 | { |
@@ -1363,16 +1367,19 @@ static int discover_object_name_recur( lua_State* L, int shortest_, int depth_) | |||
1363 | lua_pushinteger( L, 1); // o "r" {c} {fqn} ... {?} {?} 1 | 1367 | lua_pushinteger( L, 1); // o "r" {c} {fqn} ... {?} {?} 1 |
1364 | lua_rawset( L, cache); // o "r" {c} {fqn} ... {?} | 1368 | lua_rawset( L, cache); // o "r" {c} {fqn} ... {?} |
1365 | // scan table contents | 1369 | // scan table contents |
1370 | STACK_CHECK( L); | ||
1366 | lua_pushnil( L); // o "r" {c} {fqn} ... {?} nil | 1371 | lua_pushnil( L); // o "r" {c} {fqn} ... {?} nil |
1367 | while( lua_next( L, -2)) // o "r" {c} {fqn} ... {?} k v | 1372 | while( lua_next( L, -2)) // o "r" {c} {fqn} ... {?} k v |
1368 | { | 1373 | { |
1369 | //char const *const key = lua_tostring( L, -2); // only for debugging (BEWARE, IT MAY CHANGE THE VALUE IF IT IS CONVERTIBLE, AND WRECK THE LOOP ITERATION PROCESS!) | 1374 | //char const *const strKey = (lua_type( L, -2) == LUA_TSTRING) ? lua_tostring( L, -2) : NULL; // only for debugging |
1375 | //lua_Number const numKey = (lua_type( L, -2) == LUA_TNUMBER) ? lua_tonumber( L, -2) : -6666; // only for debugging | ||
1370 | // append key name to fqn stack | 1376 | // append key name to fqn stack |
1371 | ++ depth_; | 1377 | ++ depth_; |
1372 | lua_pushvalue( L, -2); // o "r" {c} {fqn} ... {?} k v k | 1378 | lua_pushvalue( L, -2); // o "r" {c} {fqn} ... {?} k v k |
1373 | lua_rawseti( L, fqn, depth_); // o "r" {c} {fqn} ... {?} k v | 1379 | lua_rawseti( L, fqn, depth_); // o "r" {c} {fqn} ... {?} k v |
1374 | if( lua_rawequal( L, -1, what)) // is it what we are looking for? | 1380 | if( lua_rawequal( L, -1, what)) // is it what we are looking for? |
1375 | { | 1381 | { |
1382 | STACK_MID( L, 2); | ||
1376 | // update shortest name | 1383 | // update shortest name |
1377 | if( depth_ < shortest_) | 1384 | if( depth_ < shortest_) |
1378 | { | 1385 | { |
@@ -1382,32 +1389,74 @@ static int discover_object_name_recur( lua_State* L, int shortest_, int depth_) | |||
1382 | } | 1389 | } |
1383 | // no need to search further at this level | 1390 | // no need to search further at this level |
1384 | lua_pop( L, 2); // o "r" {c} {fqn} ... {?} | 1391 | lua_pop( L, 2); // o "r" {c} {fqn} ... {?} |
1392 | STACK_MID( L, 0); | ||
1385 | break; | 1393 | break; |
1386 | } | 1394 | } |
1387 | else if( lua_istable( L, -1)) | 1395 | else if( lua_istable( L, -1)) // o "r" {c} {fqn} ... {?} k {} |
1388 | { | 1396 | { |
1397 | STACK_MID( L, 2); | ||
1389 | shortest_ = discover_object_name_recur( L, shortest_, depth_); | 1398 | shortest_ = discover_object_name_recur( L, shortest_, depth_); |
1390 | // search in the table's metatable too | 1399 | // search in the table's metatable too |
1391 | if( lua_getmetatable( L, -1)) | 1400 | if( lua_getmetatable( L, -1)) // o "r" {c} {fqn} ... {?} k {} {mt} |
1392 | { | 1401 | { |
1393 | if( lua_istable( L, -1)) | 1402 | if( lua_istable( L, -1)) |
1394 | { | 1403 | { |
1404 | ++ depth_; | ||
1405 | lua_pushliteral( L, "__metatable"); // o "r" {c} {fqn} ... {?} k {} {mt} "__metatable" | ||
1406 | lua_rawseti( L, fqn, depth_); // o "r" {c} {fqn} ... {?} k {} {mt} | ||
1395 | shortest_ = discover_object_name_recur( L, shortest_, depth_); | 1407 | shortest_ = discover_object_name_recur( L, shortest_, depth_); |
1408 | lua_pushnil( L); // o "r" {c} {fqn} ... {?} k {} {mt} nil | ||
1409 | lua_rawseti( L, fqn, depth_); // o "r" {c} {fqn} ... {?} k {} {mt} | ||
1410 | -- depth_; | ||
1396 | } | 1411 | } |
1397 | lua_pop( L, 1); | 1412 | lua_pop( L, 1); // o "r" {c} {fqn} ... {?} k {} |
1413 | STACK_MID( L, 2); | ||
1398 | } | 1414 | } |
1399 | } | 1415 | } |
1400 | else if( lua_isuserdata( L, -1)) | 1416 | else if( lua_isthread( L, -1)) // o "r" {c} {fqn} ... {?} k T |
1401 | { | 1417 | { |
1418 | // search in the object's uservalue if it is a table | ||
1419 | lua_getuservalue( L, -1); // o "r" {c} {fqn} ... {?} k T {u} | ||
1420 | if( lua_istable( L, -1)) | ||
1421 | { | ||
1422 | shortest_ = discover_object_name_recur( L, shortest_, depth_); | ||
1423 | } | ||
1424 | lua_pop( L, 1); // o "r" {c} {fqn} ... {?} k T | ||
1425 | STACK_MID( L, 2); | ||
1426 | } | ||
1427 | else if( lua_isuserdata( L, -1)) // o "r" {c} {fqn} ... {?} k U | ||
1428 | { | ||
1429 | STACK_MID( L, 2); | ||
1402 | // search in the object's metatable (some modules are built that way) | 1430 | // search in the object's metatable (some modules are built that way) |
1403 | if( lua_getmetatable( L, -1)) | 1431 | if( lua_getmetatable( L, -1)) // o "r" {c} {fqn} ... {?} k U {mt} |
1404 | { | 1432 | { |
1405 | if( lua_istable( L, -1)) | 1433 | if( lua_istable( L, -1)) |
1406 | { | 1434 | { |
1435 | ++ depth_; | ||
1436 | lua_pushliteral( L, "__metatable"); // o "r" {c} {fqn} ... {?} k U {mt} "__metatable" | ||
1437 | lua_rawseti( L, fqn, depth_); // o "r" {c} {fqn} ... {?} k U {mt} | ||
1407 | shortest_ = discover_object_name_recur( L, shortest_, depth_); | 1438 | shortest_ = discover_object_name_recur( L, shortest_, depth_); |
1439 | lua_pushnil( L); // o "r" {c} {fqn} ... {?} k U {mt} nil | ||
1440 | lua_rawseti( L, fqn, depth_); // o "r" {c} {fqn} ... {?} k U {mt} | ||
1441 | -- depth_; | ||
1408 | } | 1442 | } |
1409 | lua_pop( L, 1); | 1443 | lua_pop( L, 1); // o "r" {c} {fqn} ... {?} k U |
1444 | STACK_MID( L, 2); | ||
1445 | } | ||
1446 | // search in the object's uservalue if it is a table | ||
1447 | lua_getuservalue( L, -1); // o "r" {c} {fqn} ... {?} k U {u} | ||
1448 | if( lua_istable( L, -1)) | ||
1449 | { | ||
1450 | ++ depth_; | ||
1451 | lua_pushliteral( L, "uservalue"); // o "r" {c} {fqn} ... {?} k v {u} "uservalue" | ||
1452 | lua_rawseti( L, fqn, depth_); // o "r" {c} {fqn} ... {?} k v {u} | ||
1453 | shortest_ = discover_object_name_recur( L, shortest_, depth_); | ||
1454 | lua_pushnil( L); // o "r" {c} {fqn} ... {?} k v {u} nil | ||
1455 | lua_rawseti( L, fqn, depth_); // o "r" {c} {fqn} ... {?} k v {u} | ||
1456 | -- depth_; | ||
1410 | } | 1457 | } |
1458 | lua_pop( L, 1); // o "r" {c} {fqn} ... {?} k U | ||
1459 | STACK_MID( L, 2); | ||
1411 | } | 1460 | } |
1412 | // make ready for next iteration | 1461 | // make ready for next iteration |
1413 | lua_pop( L, 1); // o "r" {c} {fqn} ... {?} k | 1462 | lua_pop( L, 1); // o "r" {c} {fqn} ... {?} k |
@@ -1416,6 +1465,7 @@ static int discover_object_name_recur( lua_State* L, int shortest_, int depth_) | |||
1416 | lua_rawseti( L, fqn, depth_); // o "r" {c} {fqn} ... {?} k | 1465 | lua_rawseti( L, fqn, depth_); // o "r" {c} {fqn} ... {?} k |
1417 | -- depth_; | 1466 | -- depth_; |
1418 | } // o "r" {c} {fqn} ... {?} | 1467 | } // o "r" {c} {fqn} ... {?} |
1468 | STACK_END( L, 0); | ||
1419 | // remove the visited table from the cache, in case a shorter path to the searched object exists | 1469 | // remove the visited table from the cache, in case a shorter path to the searched object exists |
1420 | lua_pushvalue( L, -1); // o "r" {c} {fqn} ... {?} {?} | 1470 | lua_pushvalue( L, -1); // o "r" {c} {fqn} ... {?} {?} |
1421 | lua_pushnil( L); // o "r" {c} {fqn} ... {?} {?} nil | 1471 | lua_pushnil( L); // o "r" {c} {fqn} ... {?} {?} nil |
@@ -1442,6 +1492,7 @@ int luaG_nameof( lua_State* L) | |||
1442 | lua_insert( L, -2); // "type" o | 1492 | lua_insert( L, -2); // "type" o |
1443 | return 2; | 1493 | return 2; |
1444 | } | 1494 | } |
1495 | |||
1445 | STACK_GROW( L, 4); | 1496 | STACK_GROW( L, 4); |
1446 | // this slot will contain the shortest name we found when we are done | 1497 | // this slot will contain the shortest name we found when we are done |
1447 | lua_pushnil( L); // o nil | 1498 | lua_pushnil( L); // o nil |
@@ -1461,7 +1512,7 @@ int luaG_nameof( lua_State* L) | |||
1461 | /* | 1512 | /* |
1462 | * Push a looked-up native/LuaJIT function. | 1513 | * Push a looked-up native/LuaJIT function. |
1463 | */ | 1514 | */ |
1464 | static void lookup_native_func( lua_State* L2, lua_State* L, uint_t i) | 1515 | static void lookup_native_func( lua_State* L2, lua_State* L, uint_t i, char const* upName_) |
1465 | { | 1516 | { |
1466 | char const* fqn; // L // L2 | 1517 | char const* fqn; // L // L2 |
1467 | size_t len; | 1518 | size_t len; |
@@ -1478,14 +1529,28 @@ static void lookup_native_func( lua_State* L2, lua_State* L, uint_t i) | |||
1478 | lua_pop( L, 2); // ... f ... | 1529 | lua_pop( L, 2); // ... f ... |
1479 | if( !fqn) | 1530 | if( !fqn) |
1480 | { | 1531 | { |
1481 | char const* from; | 1532 | char const *from, *typewhat, *what, *gotchaA, *gotchaB; |
1482 | // try to discover the name of the function we want to send | 1533 | // try to discover the name of the function we want to send |
1483 | lua_pushcfunction( L, luaG_nameof); // ... f ...luaG_nameof | 1534 | lua_getglobal( L, "decoda_name"); // ... f ... decoda_name |
1484 | lua_pushvalue( L, i); // ... f ... luaG_nameof f | ||
1485 | lua_call( L, 1, 2); // ... f ... "type" "name" | ||
1486 | lua_getglobal( L, "decoda_name"); // ... f ... "type" "name" decoda_name | ||
1487 | from = lua_tostring( L, -1); | 1535 | from = lua_tostring( L, -1); |
1488 | (void) luaL_error( L, "%s '%s' not found in %s origin transfer database.", lua_tostring( L, -3), lua_tostring( L, -2), from ? from : "main"); | 1536 | lua_pushcfunction( L, luaG_nameof); // ... f ... decoda_name luaG_nameof |
1537 | lua_pushvalue( L, i); // ... f ... decoda_name luaG_nameof f | ||
1538 | lua_call( L, 1, 2); // ... f ... decoda_name "type" "name"|nil | ||
1539 | typewhat = (lua_type( L, -2) == LUA_TSTRING) ? lua_tostring( L, -2) : luaL_typename( L, -2); | ||
1540 | // second return value can be nil if the function was not found | ||
1541 | // probable reason: the function was removed from the source Lua state before Lanes was required. | ||
1542 | if( lua_isnil( L, -1)) | ||
1543 | { | ||
1544 | gotchaA = " referenced by"; | ||
1545 | gotchaB = "\n(did you remove it from the source Lua state before requiring Lanes?)"; | ||
1546 | what = upName_; | ||
1547 | } | ||
1548 | else | ||
1549 | { | ||
1550 | gotchaB = ""; | ||
1551 | what = (lua_type( L, -1) == LUA_TSTRING) ? lua_tostring( L, -1) : luaL_typename( L, -1); | ||
1552 | } | ||
1553 | (void) luaL_error( L, "%s%s '%s' not found in %s origin transfer database.%s", typewhat, gotchaA, what, from ? from : "main", gotchaB); | ||
1489 | return; | 1554 | return; |
1490 | } | 1555 | } |
1491 | STACK_END( L, 0); | 1556 | STACK_END( L, 0); |
@@ -1516,9 +1581,9 @@ static void lookup_native_func( lua_State* L2, lua_State* L, uint_t i) | |||
1516 | enum e_vt { | 1581 | enum e_vt { |
1517 | VT_NORMAL, VT_KEY, VT_METATABLE | 1582 | VT_NORMAL, VT_KEY, VT_METATABLE |
1518 | }; | 1583 | }; |
1519 | static bool_t inter_copy_one_( lua_State *L2, uint_t L2_cache_i, lua_State *L, uint_t i, enum e_vt value_type ); | 1584 | static bool_t inter_copy_one_( lua_State* L2, uint_t L2_cache_i, lua_State* L, uint_t i, enum e_vt value_type, char const* upName_); |
1520 | 1585 | ||
1521 | static void inter_copy_func( lua_State* L2, uint_t L2_cache_i, lua_State* L, uint_t i) | 1586 | static void inter_copy_func( lua_State* L2, uint_t L2_cache_i, lua_State* L, uint_t i, char const* upName_) |
1522 | { | 1587 | { |
1523 | FuncSubType funcSubType; | 1588 | FuncSubType funcSubType; |
1524 | /*lua_CFunction cfunc =*/ luaG_tocfunction( L, i, &funcSubType); // NULL for LuaJIT-fast && bytecode functions | 1589 | /*lua_CFunction cfunc =*/ luaG_tocfunction( L, i, &funcSubType); // NULL for LuaJIT-fast && bytecode functions |
@@ -1612,14 +1677,14 @@ static void inter_copy_func( lua_State* L2, uint_t L2_cache_i, lua_State* L, uin | |||
1612 | * instead, the function shall have LUA_RIDX_GLOBALS taken in the destination state! | 1677 | * instead, the function shall have LUA_RIDX_GLOBALS taken in the destination state! |
1613 | */ | 1678 | */ |
1614 | { | 1679 | { |
1615 | DEBUGSPEW_CODE( char const* upname); | 1680 | char const* upname; |
1616 | #if LUA_VERSION_NUM == 502 | 1681 | #if LUA_VERSION_NUM == 502 |
1617 | // With Lua 5.2, each Lua function gets its environment as one of its upvalues (named LUA_ENV, aka "_ENV" by default) | 1682 | // With Lua 5.2, each Lua function gets its environment as one of its upvalues (named LUA_ENV, aka "_ENV" by default) |
1618 | // Generally this is LUA_RIDX_GLOBALS, which we don't want to copy from the source to the destination state... | 1683 | // Generally this is LUA_RIDX_GLOBALS, which we don't want to copy from the source to the destination state... |
1619 | // -> if we encounter an upvalue equal to the global table in the source, bind it to the destination's global table | 1684 | // -> if we encounter an upvalue equal to the global table in the source, bind it to the destination's global table |
1620 | lua_pushglobaltable( L); // ... _G | 1685 | lua_pushglobaltable( L); // ... _G |
1621 | #endif // LUA_VERSION_NUM | 1686 | #endif // LUA_VERSION_NUM |
1622 | for( n = 0; (DEBUGSPEW_CODE( upname =) lua_getupvalue( L, i, 1 + n)) != NULL; ++ n) | 1687 | for( n = 0; (upname = lua_getupvalue( L, i, 1 + n)) != NULL; ++ n) |
1623 | { // ... _G up[n] | 1688 | { // ... _G up[n] |
1624 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "UPNAME[%d]: %s\n" INDENT_END, n, upname)); | 1689 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "UPNAME[%d]: %s\n" INDENT_END, n, upname)); |
1625 | #if LUA_VERSION_NUM == 502 | 1690 | #if LUA_VERSION_NUM == 502 |
@@ -1630,8 +1695,10 @@ static void inter_copy_func( lua_State* L2, uint_t L2_cache_i, lua_State* L, uin | |||
1630 | else | 1695 | else |
1631 | #endif // LUA_VERSION_NUM | 1696 | #endif // LUA_VERSION_NUM |
1632 | { | 1697 | { |
1633 | if( !inter_copy_one_( L2, L2_cache_i, L, lua_gettop( L), VT_NORMAL)) // ... {cache} ... function <upvalues> | 1698 | if( !inter_copy_one_( L2, L2_cache_i, L, lua_gettop( L), VT_NORMAL, upname)) // ... {cache} ... function <upvalues> |
1699 | { | ||
1634 | luaL_error( L, "Cannot copy upvalue type '%s'", luaL_typename( L, -1)); | 1700 | luaL_error( L, "Cannot copy upvalue type '%s'", luaL_typename( L, -1)); |
1701 | } | ||
1635 | } | 1702 | } |
1636 | lua_pop( L, 1); // ... _G | 1703 | lua_pop( L, 1); // ... _G |
1637 | } | 1704 | } |
@@ -1664,7 +1731,7 @@ static void inter_copy_func( lua_State* L2, uint_t L2_cache_i, lua_State* L, uin | |||
1664 | { | 1731 | { |
1665 | lua_pop( L2, 1); // ... {cache} ... | 1732 | lua_pop( L2, 1); // ... {cache} ... |
1666 | // No need to transfer upvalues for C/JIT functions since they weren't actually copied, only looked up | 1733 | // No need to transfer upvalues for C/JIT functions since they weren't actually copied, only looked up |
1667 | lookup_native_func( L2, L, i); // ... {cache} ... function | 1734 | lookup_native_func( L2, L, i, upName_); // ... {cache} ... function |
1668 | } | 1735 | } |
1669 | STACK_END( L, 0); | 1736 | STACK_END( L, 0); |
1670 | } | 1737 | } |
@@ -1679,7 +1746,7 @@ static void inter_copy_func( lua_State* L2, uint_t L2_cache_i, lua_State* L, uin | |||
1679 | * | 1746 | * |
1680 | * Returns TRUE if value was pushed, FALSE if its type is non-supported. | 1747 | * Returns TRUE if value was pushed, FALSE if its type is non-supported. |
1681 | */ | 1748 | */ |
1682 | static bool_t inter_copy_one_( lua_State* L2, uint_t L2_cache_i, lua_State* L, uint_t i, enum e_vt vt) | 1749 | static bool_t inter_copy_one_( lua_State* L2, uint_t L2_cache_i, lua_State* L, uint_t i, enum e_vt vt, char const* upName_) |
1683 | { | 1750 | { |
1684 | bool_t ret = TRUE; | 1751 | bool_t ret = TRUE; |
1685 | 1752 | ||
@@ -1762,25 +1829,9 @@ static bool_t inter_copy_one_( lua_State* L2, uint_t L2_cache_i, lua_State* L, u | |||
1762 | break; | 1829 | break; |
1763 | } | 1830 | } |
1764 | { | 1831 | { |
1765 | /* | 1832 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "FUNCTION\n" INDENT_END)); |
1766 | * Passing C functions is risky; if they refer to LUA_ENVIRONINDEX | ||
1767 | * and/or LUA_REGISTRYINDEX they might work unintended (not work) | ||
1768 | * at the target. | ||
1769 | * | ||
1770 | * On the other hand, NOT copying them causes many self tests not | ||
1771 | * to work (timer, hangtest, ...) | ||
1772 | * | ||
1773 | * The trouble is, we cannot KNOW if the function at hand is safe | ||
1774 | * or not. We cannot study it's behaviour. We could trust the user, | ||
1775 | * but they might not even know they're sending lua_CFunction over | ||
1776 | * (as upvalues etc.). | ||
1777 | */ | ||
1778 | #if 0 | ||
1779 | if( lua_iscfunction( L, i)) | ||
1780 | luaL_error( L, "Copying lua_CFunction between Lua states is risky, and currently disabled." ); | ||
1781 | #endif | ||
1782 | STACK_CHECK( L2); | 1833 | STACK_CHECK( L2); |
1783 | push_cached_func( L2, L2_cache_i, L, i); | 1834 | push_cached_func( L2, L2_cache_i, L, i, upName_); |
1784 | STACK_END( L2, 1); | 1835 | STACK_END( L2, 1); |
1785 | } | 1836 | } |
1786 | break; | 1837 | break; |
@@ -1822,13 +1873,28 @@ static bool_t inter_copy_one_( lua_State* L2, uint_t L2_cache_i, lua_State* L, u | |||
1822 | 1873 | ||
1823 | /* Only basic key types are copied over; others ignored | 1874 | /* Only basic key types are copied over; others ignored |
1824 | */ | 1875 | */ |
1825 | if( inter_copy_one_( L2, 0 /*key*/, L, key_i, VT_KEY)) | 1876 | if( inter_copy_one_( L2, 0 /*key*/, L, key_i, VT_KEY, upName_)) |
1826 | { | 1877 | { |
1878 | char* valPath = (char*) upName_; | ||
1879 | if( GVerboseErrors) | ||
1880 | { | ||
1881 | // for debug purposes, let's try to build a useful name | ||
1882 | if( lua_type( L, key_i) == LUA_TSTRING) | ||
1883 | { | ||
1884 | valPath = (char*) alloca( strlen( upName_) + strlen( lua_tostring( L, key_i)) + 2); | ||
1885 | sprintf( valPath, "%s.%s", upName_, lua_tostring( L, key_i)); | ||
1886 | } | ||
1887 | else if( lua_type( L, key_i) == LUA_TNUMBER) | ||
1888 | { | ||
1889 | valPath = (char*) alloca( strlen( upName_) + 32 + 3); | ||
1890 | sprintf( valPath, "%s[" LUA_NUMBER_FMT "]", upName_, lua_tonumber( L, key_i)); | ||
1891 | } | ||
1892 | } | ||
1827 | /* | 1893 | /* |
1828 | * Contents of metatables are copied with cache checking; | 1894 | * Contents of metatables are copied with cache checking; |
1829 | * important to detect loops. | 1895 | * important to detect loops. |
1830 | */ | 1896 | */ |
1831 | if( inter_copy_one_( L2, L2_cache_i, L, val_i, VT_NORMAL)) | 1897 | if( inter_copy_one_( L2, L2_cache_i, L, val_i, VT_NORMAL, valPath)) |
1832 | { | 1898 | { |
1833 | ASSERT_L( lua_istable(L2,-3)); | 1899 | ASSERT_L( lua_istable(L2,-3)); |
1834 | lua_rawset( L2, -3); // add to table (pops key & val) | 1900 | lua_rawset( L2, -3); // add to table (pops key & val) |
@@ -1870,7 +1936,7 @@ static bool_t inter_copy_one_( lua_State* L2, uint_t L2_cache_i, lua_State* L, u | |||
1870 | lua_pop( L2, 1); | 1936 | lua_pop( L2, 1); |
1871 | STACK_MID( L2, 2); | 1937 | STACK_MID( L2, 2); |
1872 | ASSERT_L( lua_istable(L,-1)); | 1938 | ASSERT_L( lua_istable(L,-1)); |
1873 | if( inter_copy_one_( L2, L2_cache_i /*for function cacheing*/, L, lua_gettop(L) /*[-1]*/, VT_METATABLE)) | 1939 | if( inter_copy_one_( L2, L2_cache_i /*for function cacheing*/, L, lua_gettop(L) /*[-1]*/, VT_METATABLE, upName_)) |
1874 | { | 1940 | { |
1875 | // | 1941 | // |
1876 | // L2 ([-3]: copied table) | 1942 | // L2 ([-3]: copied table) |
@@ -1942,7 +2008,9 @@ int luaG_inter_copy( lua_State* L, lua_State* L2, uint_t n) | |||
1942 | { | 2008 | { |
1943 | uint_t top_L = lua_gettop( L); | 2009 | uint_t top_L = lua_gettop( L); |
1944 | uint_t top_L2 = lua_gettop( L2); | 2010 | uint_t top_L2 = lua_gettop( L2); |
1945 | uint_t i; | 2011 | uint_t i, j; |
2012 | char tmpBuf[16]; | ||
2013 | char* pBuf = GVerboseErrors ? tmpBuf : "?"; | ||
1946 | bool_t copyok = TRUE; | 2014 | bool_t copyok = TRUE; |
1947 | 2015 | ||
1948 | if( n > top_L) | 2016 | if( n > top_L) |
@@ -1960,9 +2028,13 @@ int luaG_inter_copy( lua_State* L, lua_State* L2, uint_t n) | |||
1960 | */ | 2028 | */ |
1961 | lua_newtable( L2); | 2029 | lua_newtable( L2); |
1962 | 2030 | ||
1963 | for( i = top_L - n + 1; i <= top_L; ++ i) | 2031 | for( i = top_L - n + 1, j = 1; i <= top_L; ++ i, ++ j) |
1964 | { | 2032 | { |
1965 | copyok = inter_copy_one_( L2, top_L2 + 1, L, i, VT_NORMAL); | 2033 | if( GVerboseErrors) |
2034 | { | ||
2035 | sprintf( tmpBuf, "arg_%d", j); | ||
2036 | } | ||
2037 | copyok = inter_copy_one_( L2, top_L2 + 1, L, i, VT_NORMAL, pBuf); | ||
1966 | if( !copyok) | 2038 | if( !copyok) |
1967 | { | 2039 | { |
1968 | break; | 2040 | break; |