aboutsummaryrefslogtreecommitdiff
path: root/src/tools.c
diff options
context:
space:
mode:
authorBenoit Germain <b n t DOT g e r m a i n AT g m a i l DOT c o m>2018-10-29 13:39:49 +0100
committerBenoit Germain <b n t DOT g e r m a i n AT g m a i l DOT c o m>2018-10-29 13:39:49 +0100
commitea9e8a3af1c2357c454ef18c8136c14a22b8675a (patch)
tree0b089ae8b94d7901db8c86051fb001bf5936bc54 /src/tools.c
parente2908369e92b14e661b16401b6389d6d4a026278 (diff)
parentdebc6b3403077fc5bd1d144d779806fdd22ab55e (diff)
downloadlanes-ea9e8a3af1c2357c454ef18c8136c14a22b8675a.tar.gz
lanes-ea9e8a3af1c2357c454ef18c8136c14a22b8675a.tar.bz2
lanes-ea9e8a3af1c2357c454ef18c8136c14a22b8675a.zip
Merge changes
Diffstat (limited to 'src/tools.c')
-rw-r--r--src/tools.c153
1 files changed, 86 insertions, 67 deletions
diff --git a/src/tools.c b/src/tools.c
index 13e714d..051e3cc 100644
--- a/src/tools.c
+++ b/src/tools.c
@@ -31,22 +31,22 @@ THE SOFTWARE.
31=============================================================================== 31===============================================================================
32*/ 32*/
33 33
34#include "compat.h"
35#include "universe.h"
36#include "tools.h"
37#include "keeper.h"
38#include "lanes.h"
39
40#include <stdio.h> 34#include <stdio.h>
41#include <string.h> 35#include <string.h>
42#include <ctype.h> 36#include <ctype.h>
43#include <stdlib.h> 37#include <stdlib.h>
44#if !defined(__APPLE__) 38#if !defined(__APPLE__)
45#include <malloc.h> 39#include <malloc.h>
46#endif 40#endif // __APPLE__
41
42#include "tools.h"
43#include "compat.h"
44#include "universe.h"
45#include "keeper.h"
46#include "lanes.h"
47 47
48// functions implemented in deep.c 48// functions implemented in deep.c
49extern luaG_IdFunction copydeep( struct s_Universe* U, lua_State* L, lua_State* L2, int index, enum eLookupMode mode_); 49extern luaG_IdFunction copydeep( Universe* U, lua_State* L, lua_State* L2, int index, LookupMode mode_);
50extern void push_registry_subtable( lua_State* L, void* key_); 50extern void push_registry_subtable( lua_State* L, void* key_);
51 51
52char const* const CONFIG_REGKEY = "ee932492-a654-4506-9da8-f16540bdb5d4"; 52char const* const CONFIG_REGKEY = "ee932492-a654-4506-9da8-f16540bdb5d4";
@@ -105,7 +105,7 @@ void luaG_dump( lua_State* L)
105 fprintf( stderr, "\n"); 105 fprintf( stderr, "\n");
106} 106}
107 107
108void initialize_on_state_create( struct s_Universe* U, lua_State* L) 108void initialize_on_state_create( Universe* U, lua_State* L)
109{ 109{
110 STACK_CHECK( L); 110 STACK_CHECK( L);
111 lua_getfield( L, -1, "on_state_create"); // settings on_state_create|nil 111 lua_getfield( L, -1, "on_state_create"); // settings on_state_create|nil
@@ -139,7 +139,7 @@ void initialize_on_state_create( struct s_Universe* U, lua_State* L)
139// ################################################################################################ 139// ################################################################################################
140 140
141// just like lua_xmove, args are (from, to) 141// just like lua_xmove, args are (from, to)
142void luaG_copy_one_time_settings( struct s_Universe* U, lua_State* L, lua_State* L2) 142void luaG_copy_one_time_settings( Universe* U, lua_State* L, lua_State* L2)
143{ 143{
144 STACK_GROW( L, 1); 144 STACK_GROW( L, 1);
145 // copy settings from from source to destination registry 145 // copy settings from from source to destination registry
@@ -198,7 +198,7 @@ static const luaL_Reg libs[] =
198 { NULL, NULL } 198 { NULL, NULL }
199}; 199};
200 200
201static void open1lib( struct s_Universe* U, lua_State* L, char const* name_, size_t len_, lua_State* from_) 201static void open1lib( Universe* U, lua_State* L, char const* name_, size_t len_, lua_State* from_)
202{ 202{
203 int i; 203 int i;
204 for( i = 0; libs[i].name; ++ i) 204 for( i = 0; libs[i].name; ++ i)
@@ -341,7 +341,7 @@ static void update_lookup_entry( lua_State* L, int _ctx_base, int _depth)
341 size_t prevNameLength, newNameLength; 341 size_t prevNameLength, newNameLength;
342 char const* prevName; 342 char const* prevName;
343 DEBUGSPEW_CODE( char const *newName); 343 DEBUGSPEW_CODE( char const *newName);
344 DEBUGSPEW_CODE( struct s_Universe* U = universe_get( L)); 344 DEBUGSPEW_CODE( Universe* U = universe_get( L));
345 345
346 STACK_CHECK( L); 346 STACK_CHECK( L);
347 // first, raise an error if the function is already known 347 // first, raise an error if the function is already known
@@ -412,7 +412,7 @@ static void populate_func_lookup_table_recur( lua_State* L, int _ctx_base, int _
412 int const cache = _ctx_base + 2; 412 int const cache = _ctx_base + 2;
413 // we need to remember subtables to process them after functions encountered at the current depth (breadth-first search) 413 // we need to remember subtables to process them after functions encountered at the current depth (breadth-first search)
414 int const breadth_first_cache = lua_gettop( L) + 1; 414 int const breadth_first_cache = lua_gettop( L) + 1;
415 DEBUGSPEW_CODE( struct s_Universe* U = universe_get( L)); 415 DEBUGSPEW_CODE( Universe* U = universe_get( L));
416 416
417 STACK_GROW( L, 6); 417 STACK_GROW( L, 6);
418 // slot _i contains a table where we search for functions (or a full userdata with a metatable) 418 // slot _i contains a table where we search for functions (or a full userdata with a metatable)
@@ -530,7 +530,7 @@ void populate_func_lookup_table( lua_State* L, int _i, char const* name_)
530 int const ctx_base = lua_gettop( L) + 1; 530 int const ctx_base = lua_gettop( L) + 1;
531 int const in_base = lua_absindex( L, _i); 531 int const in_base = lua_absindex( L, _i);
532 int start_depth = 0; 532 int start_depth = 0;
533 DEBUGSPEW_CODE( struct s_Universe* U = universe_get( L)); 533 DEBUGSPEW_CODE( Universe* U = universe_get( L));
534 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "%p: populate_func_lookup_table('%s')\n" INDENT_END, L, name_ ? name_ : "NULL")); 534 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "%p: populate_func_lookup_table('%s')\n" INDENT_END, L, name_ ? name_ : "NULL"));
535 DEBUGSPEW_CODE( ++ U->debugspew_indent_depth); 535 DEBUGSPEW_CODE( ++ U->debugspew_indent_depth);
536 STACK_GROW( L, 3); 536 STACK_GROW( L, 3);
@@ -585,7 +585,7 @@ void populate_func_lookup_table( lua_State* L, int _i, char const* name_)
585 DEBUGSPEW_CODE( -- U->debugspew_indent_depth); 585 DEBUGSPEW_CODE( -- U->debugspew_indent_depth);
586} 586}
587 587
588void call_on_state_create( struct s_Universe* U, lua_State* L, lua_State* from_, enum eLookupMode mode_) 588void call_on_state_create( Universe* U, lua_State* L, lua_State* from_, LookupMode mode_)
589{ 589{
590 if( U->on_state_create_func != NULL) 590 if( U->on_state_create_func != NULL)
591 { 591 {
@@ -630,7 +630,7 @@ void call_on_state_create( struct s_Universe* U, lua_State* L, lua_State* from_,
630 * *NOT* called for keeper states! 630 * *NOT* called for keeper states!
631 * 631 *
632 */ 632 */
633lua_State* luaG_newstate( struct s_Universe* U, lua_State* from_, char const* libs_) 633lua_State* luaG_newstate( Universe* U, lua_State* from_, char const* libs_)
634{ 634{
635 // re-use alloc function from the originating state 635 // re-use alloc function from the originating state
636#if PROPAGATE_ALLOCF 636#if PROPAGATE_ALLOCF
@@ -761,7 +761,7 @@ lua_State* luaG_newstate( struct s_Universe* U, lua_State* from_, char const* li
761/* 761/*
762* Get a unique ID for metatable at [i]. 762* Get a unique ID for metatable at [i].
763*/ 763*/
764static uint_t get_mt_id( struct s_Universe* U, lua_State* L, int i) 764static uint_t get_mt_id( Universe* U, lua_State* L, int i)
765{ 765{
766 uint_t id; 766 uint_t id;
767 767
@@ -828,9 +828,9 @@ static int table_lookup_sentinel( lua_State* L)
828/* 828/*
829 * retrieve the name of a function/table in the lookup database 829 * retrieve the name of a function/table in the lookup database
830 */ 830 */
831static char const* find_lookup_name( lua_State* L, uint_t i, enum eLookupMode mode_, char const* upName_, size_t* len_) 831static char const* find_lookup_name( lua_State* L, uint_t i, LookupMode mode_, char const* upName_, size_t* len_)
832{ 832{
833 DEBUGSPEW_CODE( struct s_Universe* const U = universe_get( L)); 833 DEBUGSPEW_CODE( Universe* const U = universe_get( L));
834 char const* fqn; 834 char const* fqn;
835 ASSERT_L( lua_isfunction( L, i) || lua_istable( L, i)); // ... v ... 835 ASSERT_L( lua_isfunction( L, i) || lua_istable( L, i)); // ... v ...
836 STACK_CHECK( L); 836 STACK_CHECK( L);
@@ -899,7 +899,7 @@ static char const* find_lookup_name( lua_State* L, uint_t i, enum eLookupMode mo
899/* 899/*
900 * Push a looked-up table, or nothing if we found nothing 900 * Push a looked-up table, or nothing if we found nothing
901 */ 901 */
902static bool_t lookup_table( lua_State* L2, lua_State* L, uint_t i, enum eLookupMode mode_, char const* upName_) 902static bool_t lookup_table( lua_State* L2, lua_State* L, uint_t i, LookupMode mode_, char const* upName_)
903{ 903{
904 // get the name of the table we want to send 904 // get the name of the table we want to send
905 size_t len; 905 size_t len;
@@ -1195,7 +1195,7 @@ int luaG_nameof( lua_State* L)
1195/* 1195/*
1196 * Push a looked-up native/LuaJIT function. 1196 * Push a looked-up native/LuaJIT function.
1197 */ 1197 */
1198static void lookup_native_func( lua_State* L2, lua_State* L, uint_t i, enum eLookupMode mode_, char const* upName_) 1198static void lookup_native_func( lua_State* L2, lua_State* L, uint_t i, LookupMode mode_, char const* upName_)
1199{ 1199{
1200 // get the name of the function we want to send 1200 // get the name of the function we want to send
1201 size_t len; 1201 size_t len;
@@ -1276,9 +1276,9 @@ enum e_vt
1276 VT_KEY, 1276 VT_KEY,
1277 VT_METATABLE 1277 VT_METATABLE
1278}; 1278};
1279static bool_t inter_copy_one_( struct s_Universe* U, lua_State* L2, uint_t L2_cache_i, lua_State* L, uint_t i, enum e_vt value_type, enum eLookupMode mode_, char const* upName_); 1279static bool_t inter_copy_one_( Universe* U, lua_State* L2, uint_t L2_cache_i, lua_State* L, uint_t i, enum e_vt value_type, LookupMode mode_, char const* upName_);
1280 1280
1281static void inter_copy_func( struct s_Universe* U, lua_State* L2, uint_t L2_cache_i, lua_State* L, uint_t i, enum eLookupMode mode_, char const* upName_) 1281static void inter_copy_func( Universe* U, lua_State* L2, uint_t L2_cache_i, lua_State* L, uint_t i, LookupMode mode_, char const* upName_)
1282{ 1282{
1283 int n, needToPush; 1283 int n, needToPush;
1284 luaL_Buffer b; 1284 luaL_Buffer b;
@@ -1427,7 +1427,7 @@ static void inter_copy_func( struct s_Universe* U, lua_State* L2, uint_t L2_cach
1427 * 1427 *
1428 * Always pushes a function to 'L2'. 1428 * Always pushes a function to 'L2'.
1429 */ 1429 */
1430static void push_cached_func( struct s_Universe* U, lua_State* L2, uint_t L2_cache_i, lua_State* L, uint_t i, enum eLookupMode mode_, char const* upName_) 1430static void push_cached_func( Universe* U, lua_State* L2, uint_t L2_cache_i, lua_State* L, uint_t i, LookupMode mode_, char const* upName_)
1431{ 1431{
1432 FuncSubType funcSubType; 1432 FuncSubType funcSubType;
1433 /*lua_CFunction cfunc =*/ luaG_tocfunction( L, i, &funcSubType); // NULL for LuaJIT-fast && bytecode functions 1433 /*lua_CFunction cfunc =*/ luaG_tocfunction( L, i, &funcSubType); // NULL for LuaJIT-fast && bytecode functions
@@ -1480,7 +1480,7 @@ static void push_cached_func( struct s_Universe* U, lua_State* L2, uint_t L2_cac
1480 } 1480 }
1481} 1481}
1482 1482
1483static bool_t push_cached_metatable( struct s_Universe* U, lua_State* L2, uint_t L2_cache_i, lua_State* L, uint_t i, enum eLookupMode mode_, char const* upName_) 1483static bool_t push_cached_metatable( Universe* U, lua_State* L2, uint_t L2_cache_i, lua_State* L, uint_t i, enum eLookupMode mode_, char const* upName_)
1484{ 1484{
1485 if( lua_getmetatable( L, i)) // ... mt 1485 if( lua_getmetatable( L, i)) // ... mt
1486 { 1486 {
@@ -1526,6 +1526,58 @@ static bool_t push_cached_metatable( struct s_Universe* U, lua_State* L2, uint_t
1526 return FALSE; 1526 return FALSE;
1527} 1527}
1528 1528
1529static void inter_copy_keyvaluepair( Universe* U, lua_State* L2, uint_t L2_cache_i, lua_State* L, enum e_vt vt, LookupMode mode_, char const* upName_)
1530{
1531 uint_t val_i = lua_gettop( L);
1532 uint_t key_i = val_i - 1;
1533
1534 // Only basic key types are copied over; others ignored
1535 if( inter_copy_one_( U, L2, 0 /*key*/, L, key_i, VT_KEY, mode_, upName_))
1536 {
1537 char* valPath = (char*) upName_;
1538 if( U->verboseErrors)
1539 {
1540 // for debug purposes, let's try to build a useful name
1541 if( lua_type( L, key_i) == LUA_TSTRING)
1542 {
1543 char const* key = lua_tostring( L, key_i);
1544 size_t const keyRawLen = lua_rawlen( L, key_i);
1545 size_t const bufLen = strlen( upName_) + keyRawLen + 2;
1546 valPath = (char*) alloca( bufLen);
1547 sprintf( valPath, "%s.%*s", upName_, (int) keyRawLen, key);
1548 key = NULL;
1549 }
1550#if defined LUA_LNUM || LUA_VERSION_NUM >= 503
1551 else if( lua_isinteger( L, key_i))
1552 {
1553 lua_Integer key = lua_tointeger( L, key_i);
1554 valPath = (char*) alloca( strlen( upName_) + 32 + 3);
1555 sprintf( valPath, "%s[" LUA_INTEGER_FMT "]", upName_, key);
1556 }
1557#endif // defined LUA_LNUM || LUA_VERSION_NUM >= 503
1558 else if( lua_type( L, key_i) == LUA_TNUMBER)
1559 {
1560 lua_Number key = lua_tonumber( L, key_i);
1561 valPath = (char*) alloca( strlen( upName_) + 32 + 3);
1562 sprintf( valPath, "%s[" LUA_NUMBER_FMT "]", upName_, key);
1563 }
1564 }
1565 /*
1566 * Contents of metatables are copied with cache checking;
1567 * important to detect loops.
1568 */
1569 if( inter_copy_one_( U, L2, L2_cache_i, L, val_i, VT_NORMAL, mode_, valPath))
1570 {
1571 ASSERT_L( lua_istable( L2, -3));
1572 lua_rawset( L2, -3); // add to table (pops key & val)
1573 }
1574 else
1575 {
1576 luaL_error( L, "Unable to copy over type '%s' (in %s)", luaL_typename( L, val_i), (vt == VT_NORMAL) ? "table" : "metatable");
1577 }
1578 }
1579}
1580
1529/* 1581/*
1530* Copies a value from 'L' state (at index 'i') to 'L2' state. Does not remove 1582* Copies a value from 'L' state (at index 'i') to 'L2' state. Does not remove
1531* the original value. 1583* the original value.
@@ -1536,7 +1588,7 @@ static bool_t push_cached_metatable( struct s_Universe* U, lua_State* L2, uint_t
1536* 1588*
1537* Returns TRUE if value was pushed, FALSE if its type is non-supported. 1589* Returns TRUE if value was pushed, FALSE if its type is non-supported.
1538*/ 1590*/
1539static bool_t inter_copy_one_( struct s_Universe* U, lua_State* L2, uint_t L2_cache_i, lua_State* L, uint_t i, enum e_vt vt, enum eLookupMode mode_, char const* upName_) 1591static bool_t inter_copy_one_( Universe* U, lua_State* L2, uint_t L2_cache_i, lua_State* L, uint_t i, enum e_vt vt, LookupMode mode_, char const* upName_)
1540{ 1592{
1541 bool_t ret = TRUE; 1593 bool_t ret = TRUE;
1542 bool_t ignore = FALSE; 1594 bool_t ignore = FALSE;
@@ -1575,7 +1627,7 @@ static bool_t inter_copy_one_( struct s_Universe* U, lua_State* L2, uint_t L2_ca
1575 break; 1627 break;
1576 } 1628 }
1577 else 1629 else
1578#endif 1630#endif // defined LUA_LNUM || LUA_VERSION_NUM >= 503
1579 { 1631 {
1580 lua_Number v = lua_tonumber( L, i); 1632 lua_Number v = lua_tonumber( L, i);
1581 DEBUGSPEW_CODE( if( vt == VT_KEY) fprintf( stderr, INDENT_BEGIN "KEY: " LUA_NUMBER_FMT "\n" INDENT_END, v)); 1633 DEBUGSPEW_CODE( if( vt == VT_KEY) fprintf( stderr, INDENT_BEGIN "KEY: " LUA_NUMBER_FMT "\n" INDENT_END, v));
@@ -1735,41 +1787,8 @@ static bool_t inter_copy_one_( struct s_Universe* U, lua_State* L2, uint_t L2_ca
1735 lua_pushnil( L); // start iteration 1787 lua_pushnil( L); // start iteration
1736 while( lua_next( L, i)) 1788 while( lua_next( L, i))
1737 { 1789 {
1738 uint_t val_i = lua_gettop( L); 1790 // need a function to prevent overflowing the stack with verboseErrors-induced alloca()
1739 uint_t key_i = val_i - 1; 1791 inter_copy_keyvaluepair( U, L2, L2_cache_i, L, vt, mode_, upName_);
1740
1741 // Only basic key types are copied over; others ignored
1742 if( inter_copy_one_( U, L2, 0 /*key*/, L, key_i, VT_KEY, mode_, upName_))
1743 {
1744 char* valPath = (char*) upName_;
1745 if( U->verboseErrors)
1746 {
1747 // for debug purposes, let's try to build a useful name
1748 if( lua_type( L, key_i) == LUA_TSTRING)
1749 {
1750 valPath = (char*) alloca( strlen( upName_) + strlen( lua_tostring( L, key_i)) + 2);
1751 sprintf( valPath, "%s.%s", upName_, lua_tostring( L, key_i));
1752 }
1753 else if( lua_type( L, key_i) == LUA_TNUMBER)
1754 {
1755 valPath = (char*) alloca( strlen( upName_) + 32 + 3);
1756 sprintf( valPath, "%s[" LUA_NUMBER_FMT "]", upName_, lua_tonumber( L, key_i));
1757 }
1758 }
1759 /*
1760 * Contents of metatables are copied with cache checking;
1761 * important to detect loops.
1762 */
1763 if( inter_copy_one_( U, L2, L2_cache_i, L, val_i, VT_NORMAL, mode_, valPath))
1764 {
1765 ASSERT_L( lua_istable( L2, -3));
1766 lua_rawset( L2, -3); // add to table (pops key & val)
1767 }
1768 else
1769 {
1770 (void) luaL_error( L, "Unable to copy over type '%s' (in %s)", luaL_typename( L, val_i), (vt == VT_NORMAL) ? "table" : "metatable");
1771 }
1772 }
1773 lua_pop( L, 1); // pop value (next round) 1792 lua_pop( L, 1); // pop value (next round)
1774 } 1793 }
1775 STACK_MID( L, 0); 1794 STACK_MID( L, 0);
@@ -1805,7 +1824,7 @@ static bool_t inter_copy_one_( struct s_Universe* U, lua_State* L2, uint_t L2_ca
1805* 1824*
1806* Note: Parameters are in this order ('L' = from first) to be same as 'lua_xmove'. 1825* Note: Parameters are in this order ('L' = from first) to be same as 'lua_xmove'.
1807*/ 1826*/
1808int luaG_inter_copy( struct s_Universe* U, lua_State* L, lua_State* L2, uint_t n, enum eLookupMode mode_) 1827int luaG_inter_copy( Universe* U, lua_State* L, lua_State* L2, uint_t n, LookupMode mode_)
1809{ 1828{
1810 uint_t top_L = lua_gettop( L); 1829 uint_t top_L = lua_gettop( L);
1811 uint_t top_L2 = lua_gettop( L2); 1830 uint_t top_L2 = lua_gettop( L2);
@@ -1863,14 +1882,14 @@ int luaG_inter_copy( struct s_Universe* U, lua_State* L, lua_State* L2, uint_t n
1863} 1882}
1864 1883
1865 1884
1866int luaG_inter_move( struct s_Universe* U, lua_State* L, lua_State* L2, uint_t n, enum eLookupMode mode_) 1885int luaG_inter_move( Universe* U, lua_State* L, lua_State* L2, uint_t n, LookupMode mode_)
1867{ 1886{
1868 int ret = luaG_inter_copy( U, L, L2, n, mode_); 1887 int ret = luaG_inter_copy( U, L, L2, n, mode_);
1869 lua_pop( L, (int) n); 1888 lua_pop( L, (int) n);
1870 return ret; 1889 return ret;
1871} 1890}
1872 1891
1873int luaG_inter_copy_package( struct s_Universe* U, lua_State* L, lua_State* L2, int package_idx_, enum eLookupMode mode_) 1892int luaG_inter_copy_package( Universe* U, lua_State* L, lua_State* L2, int package_idx_, LookupMode mode_)
1874{ 1893{
1875 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "luaG_inter_copy_package()\n" INDENT_END)); 1894 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "luaG_inter_copy_package()\n" INDENT_END));
1876 DEBUGSPEW_CODE( ++ U->debugspew_indent_depth); 1895 DEBUGSPEW_CODE( ++ U->debugspew_indent_depth);
@@ -1937,7 +1956,7 @@ int luaG_new_require( lua_State* L)
1937{ 1956{
1938 int rc, i; 1957 int rc, i;
1939 int args = lua_gettop( L); 1958 int args = lua_gettop( L);
1940 struct s_Universe* U = universe_get( L); 1959 Universe* U = universe_get( L);
1941 //char const* modname = luaL_checkstring( L, 1); 1960 //char const* modname = luaL_checkstring( L, 1);
1942 1961
1943 STACK_GROW( L, args + 1); 1962 STACK_GROW( L, args + 1);
@@ -1970,7 +1989,7 @@ int luaG_new_require( lua_State* L)
1970/* 1989/*
1971* Serialize calls to 'require', if it exists 1990* Serialize calls to 'require', if it exists
1972*/ 1991*/
1973void serialize_require( struct s_Universe* U, lua_State* L) 1992void serialize_require( Universe* U, lua_State* L)
1974{ 1993{
1975 STACK_GROW( L, 1); 1994 STACK_GROW( L, 1);
1976 STACK_CHECK( L); 1995 STACK_CHECK( L);