aboutsummaryrefslogtreecommitdiff
path: root/src/tools.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools.c')
-rw-r--r--src/tools.c129
1 files changed, 66 insertions, 63 deletions
diff --git a/src/tools.c b/src/tools.c
index 8e886b5..6f71dd8 100644
--- a/src/tools.c
+++ b/src/tools.c
@@ -199,7 +199,7 @@ static const luaL_Reg libs[] =
199 { NULL, NULL } 199 { NULL, NULL }
200}; 200};
201 201
202static void open1lib( Universe* U, lua_State* L, char const* name_, size_t len_, lua_State* from_) 202static void open1lib( DEBUGSPEW_PARAM_COMMA( Universe* U) lua_State* L, char const* name_, size_t len_)
203{ 203{
204 int i; 204 int i;
205 for( i = 0; libs[i].name; ++ i) 205 for( i = 0; libs[i].name; ++ i)
@@ -679,7 +679,7 @@ lua_State* luaG_newstate( Universe* U, lua_State* from_, char const* libs_)
679 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "opening ALL standard libraries\n" INDENT_END)); 679 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "opening ALL standard libraries\n" INDENT_END));
680 luaL_openlibs( L); 680 luaL_openlibs( L);
681 // don't forget lanes.core for regular lane states 681 // don't forget lanes.core for regular lane states
682 open1lib( U, L, "lanes.core", 10, from_); 682 open1lib( DEBUGSPEW_PARAM_COMMA( U) L, "lanes.core", 10);
683 libs_ = NULL; // done with libs 683 libs_ = NULL; // done with libs
684 } 684 }
685 else 685 else
@@ -713,12 +713,12 @@ lua_State* luaG_newstate( Universe* U, lua_State* from_, char const* libs_)
713 while( isalnum( p[len]) || p[len] == '.') 713 while( isalnum( p[len]) || p[len] == '.')
714 ++ len; 714 ++ len;
715 // open library 715 // open library
716 open1lib( U, L, p, len, from_); 716 open1lib( DEBUGSPEW_PARAM_COMMA( U) L, p, len);
717 } 717 }
718 } 718 }
719 lua_gc( L, LUA_GCRESTART, 0); 719 lua_gc( L, LUA_GCRESTART, 0);
720 720
721 serialize_require( U, L); 721 serialize_require( DEBUGSPEW_PARAM_COMMA( U) L);
722 722
723 // call this after the base libraries are loaded and GC is restarted 723 // call this after the base libraries are loaded and GC is restarted
724 // will raise an error in from_ in case of problem 724 // will raise an error in from_ in case of problem
@@ -1353,7 +1353,7 @@ static void inter_copy_func( Universe* U, lua_State* L2, uint_t L2_cache_i, lua_
1353 // "Otherwise, it pushes an error message" 1353 // "Otherwise, it pushes an error message"
1354 // 1354 //
1355 STACK_GROW( L, 1); 1355 STACK_GROW( L, 1);
1356 luaL_error( L, "%s", lua_tostring( L2, -1)); 1356 luaL_error( L, "%s: %s", upName_, lua_tostring( L2, -1));
1357 } 1357 }
1358 // remove the dumped string 1358 // remove the dumped string
1359 lua_pop( L, 1); // ... 1359 lua_pop( L, 1); // ...
@@ -1567,6 +1567,12 @@ static void inter_copy_keyvaluepair( Universe* U, lua_State* L2, uint_t L2_cache
1567 valPath = (char*) alloca( strlen( upName_) + 32 + 3); 1567 valPath = (char*) alloca( strlen( upName_) + 32 + 3);
1568 sprintf( valPath, "%s[" LUA_NUMBER_FMT "]", upName_, key); 1568 sprintf( valPath, "%s[" LUA_NUMBER_FMT "]", upName_, key);
1569 } 1569 }
1570 else if( lua_type( L, key_i) == LUA_TLIGHTUSERDATA)
1571 {
1572 void* key = lua_touserdata( L, key_i);
1573 valPath = (char*) alloca( strlen( upName_) + 16 + 5);
1574 sprintf( valPath, "%s[U:%p]", upName_, key);
1575 }
1570 } 1576 }
1571 /* 1577 /*
1572 * Contents of metatables are copied with cache checking; 1578 * Contents of metatables are copied with cache checking;
@@ -1597,7 +1603,6 @@ static void inter_copy_keyvaluepair( Universe* U, lua_State* L2, uint_t L2_cache
1597static 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_) 1603static 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_)
1598{ 1604{
1599 bool_t ret = TRUE; 1605 bool_t ret = TRUE;
1600 bool_t ignore = FALSE;
1601 int val_type = lua_type( L, i); 1606 int val_type = lua_type( L, i);
1602 STACK_GROW( L2, 1); 1607 STACK_GROW( L2, 1);
1603 STACK_CHECK( L); // L // L2 1608 STACK_CHECK( L); // L // L2
@@ -1671,71 +1676,69 @@ static bool_t inter_copy_one_( Universe* U, lua_State* L2, uint_t L2_cache_i, lu
1671 } 1676 }
1672 STACK_MID( L, 0); 1677 STACK_MID( L, 0);
1673 1678
1674 if( lua_getmetatable( L, i)) // ... mt? 1679 if( lua_getmetatable( L, i)) // ... mt?
1680 {
1681 lua_getfield( L, -1, "__lanesclone"); // ... mt __lanesclone?
1682 if( lua_isnil( L, -1))
1675 { 1683 {
1676 lua_getfield( L, -1, "__lanesclone"); // ... mt __lanesclone? 1684 lua_pop( L, 2); // ...
1677 if( lua_isnil( L, -1)) 1685 }
1678 { 1686 else
1679 lua_pop( L, 2); // ... 1687 {
1680 } 1688 size_t userdata_size = 0;
1681 else 1689 void* const source = lua_touserdata( L, i);
1690 void* clone = NULL;
1691 lua_pushvalue( L, -1); // ... mt __lanesclone __lanesclone
1692 // call the cloning function with 0 arguments, should return the number of bytes to allocate for the clone
1693 lua_call( L, 0, 1); // ... mt __lanesclone size
1694 STACK_MID( L, 3);
1695 userdata_size = (size_t) lua_tointeger( L, -1); // ... mt __lanesclone size
1696 lua_pop( L, 1); // ... mt __lanesclone
1697 clone = lua_newuserdata( L2, userdata_size); // ... u
1698 // call cloning function in source state to perform the actual memory cloning
1699 lua_pushlightuserdata( L, clone); // ... mt __lanesclone clone
1700 lua_pushlightuserdata( L, source); // ... mt __lanesclone source
1701 lua_call( L, 2, 0); // ... mt
1702 STACK_MID( L, 1);
1703 // copy the metatable in the target state
1704 if( inter_copy_one_( U, L2, L2_cache_i, L, lua_absindex( L, -1), VT_NORMAL, mode_, upName_)) // ... u mt?
1682 { 1705 {
1683 FuncSubType fst; 1706 lua_pop( L, 1); // ...
1684 lua_CFunction cloneFunc = luaG_tocfunction( L, -1, &fst); 1707 STACK_MID( L, 0);
1685 size_t userdata_size = 0; 1708 // when writing to a keeper state, we have here a sentinel function with the metatable's fqn as upvalue
1686 void* const source = lua_touserdata( L, i); 1709 if( eLM_ToKeeper == mode_) // ... u sentinel
1687 void* clone = NULL;
1688 lua_pushvalue( L, -1); // ... mt __lanesclone __lanesclone
1689 // call the cloning function with 0 arguments, should return the number of bytes to allocate for the clone
1690 lua_call( L, 0, 1); // ... mt __lanesclone size
1691 STACK_MID( L, 3);
1692 userdata_size = (size_t) lua_tointeger( L, -1); // ... mt __lanesclone size
1693 lua_pop( L, 1); // ... mt __lanesclone
1694 clone = lua_newuserdata( L2, userdata_size); // ... u
1695 // call cloning function in source state to perform the actual memory cloning
1696 lua_pushlightuserdata( L, clone); // ... mt __lanesclone clone
1697 lua_pushlightuserdata( L, source); // ... mt __lanesclone source
1698 lua_call( L, 2, 0); // ... mt
1699 STACK_MID( L, 1);
1700 // copy the metatable in the target state
1701 if( inter_copy_one_( U, L2, L2_cache_i, L, lua_absindex( L, -1), VT_NORMAL, mode_, upName_)) // ... u mt?
1702 { 1710 {
1703 lua_pop( L, 1); // ... 1711 ASSERT_L( lua_tocfunction( L2, -1) == table_lookup_sentinel);
1704 STACK_MID( L, 0); 1712 // we want to create a new closure with a 'clone sentinel' function, where the upvalues are the userdata and the metatable fqn
1705 // when writing to a keeper state, we have here a sentinel function with the metatable's fqn as upvalue 1713 lua_getupvalue( L2, -1, 1); // ... u sentinel fqn
1706 if( eLM_ToKeeper == mode_) // ... u sentinel 1714 lua_remove( L2, -2); // ... u fqn
1707 { 1715 lua_insert( L2, -2); // ... fqn u
1708 ASSERT_L( lua_tocfunction( L2, -1) == table_lookup_sentinel); 1716 lua_pushcclosure( L2, userdata_clone_sentinel, 2); // ... userdata_clone_sentinel
1709 // we want to create a new closure with a 'clone sentinel' function, where the upvalues are the userdata and the metatable fqn
1710 lua_getupvalue( L2, -1, 1); // ... u sentinel fqn
1711 lua_remove( L2, -2); // ... u fqn
1712 lua_insert( L2, -2); // ... fqn u
1713 lua_pushcclosure( L2, userdata_clone_sentinel, 2); // ... userdata_clone_sentinel
1714 }
1715 else // from keeper or direct, we have the userdata and the metatable
1716 {
1717 ASSERT_L( lua_istable( L2, -1));
1718 lua_setmetatable( L2, -2); // ... u
1719 }
1720 } 1717 }
1721 else 1718 else // from keeper or direct, we have the userdata and the metatable
1722 { 1719 {
1723 (void) luaL_error( L, "Error copying a metatable"); 1720 ASSERT_L( lua_istable( L2, -1));
1721 lua_setmetatable( L2, -2); // ... u
1724 } 1722 }
1725 } 1723 }
1726 break; 1724 else
1725 {
1726 (void) luaL_error( L, "Error copying a metatable");
1727 }
1727 } 1728 }
1729 break;
1730 }
1728 1731
1729 // Not a deep or clonable full userdata 1732 // Not a deep or clonable full userdata
1730 if( U->demoteFullUserdata) // attempt demotion to light userdata 1733 if( U->demoteFullUserdata) // attempt demotion to light userdata
1731 { 1734 {
1732 void* lud = lua_touserdata( L, i); 1735 void* lud = lua_touserdata( L, i);
1733 lua_pushlightuserdata( L2, lud); 1736 lua_pushlightuserdata( L2, lud);
1734 } 1737 }
1735 else // raise an error 1738 else // raise an error
1736 { 1739 {
1737 (void) luaL_error( L, "can't copy non-deep full userdata across lanes"); 1740 (void) luaL_error( L, "can't copy non-deep full userdata across lanes");
1738 } 1741 }
1739 break; 1742 break;
1740 1743
1741 case LUA_TNIL: 1744 case LUA_TNIL:
@@ -2035,7 +2038,7 @@ int luaG_new_require( lua_State* L)
2035/* 2038/*
2036* Serialize calls to 'require', if it exists 2039* Serialize calls to 'require', if it exists
2037*/ 2040*/
2038void serialize_require( Universe* U, lua_State* L) 2041void serialize_require( DEBUGSPEW_PARAM_COMMA( Universe* U) lua_State* L)
2039{ 2042{
2040 STACK_GROW( L, 1); 2043 STACK_GROW( L, 1);
2041 STACK_CHECK( L); 2044 STACK_CHECK( L);