aboutsummaryrefslogtreecommitdiff
path: root/src/tools.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools.c')
-rw-r--r--src/tools.c91
1 files changed, 74 insertions, 17 deletions
diff --git a/src/tools.c b/src/tools.c
index 8885dea..4a0aec6 100644
--- a/src/tools.c
+++ b/src/tools.c
@@ -120,7 +120,7 @@ static void* protected_lua_Alloc( void *ud, void *ptr, size_t osize, size_t nsiz
120static int luaG_provide_protected_allocator( lua_State* L) 120static int luaG_provide_protected_allocator( lua_State* L)
121{ 121{
122 Universe* U = universe_get( L); 122 Universe* U = universe_get( L);
123 AllocatorDefinition* def = lua_newuserdata( L, sizeof(AllocatorDefinition)); 123 AllocatorDefinition* def = lua_newuserdatauv( L, sizeof(AllocatorDefinition), 0);
124 def->allocF = protected_lua_Alloc; 124 def->allocF = protected_lua_Alloc;
125 def->allocUD = &U->protected_allocator; 125 def->allocUD = &U->protected_allocator;
126 return 1; 126 return 1;
@@ -356,7 +356,7 @@ FuncSubType luaG_getfuncsubtype( lua_State *L, int _i)
356 // the provided writer fails with code 666 356 // the provided writer fails with code 666
357 // therefore, anytime we get 666, this means that lua_dump() attempted a dump 357 // therefore, anytime we get 666, this means that lua_dump() attempted a dump
358 // all other cases mean this is either a C or LuaJIT-fast function 358 // all other cases mean this is either a C or LuaJIT-fast function
359 dumpres = lua503_dump( L, dummy_writer, NULL, 0); 359 dumpres = lua504_dump( L, dummy_writer, NULL, 0);
360 lua_pop( L, mustpush); 360 lua_pop( L, mustpush);
361 if( dumpres == 666) 361 if( dumpres == 666)
362 { 362 {
@@ -1223,19 +1223,27 @@ static int discover_object_name_recur( lua_State* L, int shortest_, int depth_)
1223 lua_pop( L, 1); // o "r" {c} {fqn} ... {?} k U 1223 lua_pop( L, 1); // o "r" {c} {fqn} ... {?} k U
1224 } 1224 }
1225 STACK_MID( L, 2); 1225 STACK_MID( L, 2);
1226 // search in the object's uservalue if it is a table 1226 // search in the object's uservalues
1227 lua_getuservalue( L, -1); // o "r" {c} {fqn} ... {?} k U {u}
1228 if( lua_istable( L, -1))
1229 { 1227 {
1230 ++ depth_; 1228 int uvi = 1;
1231 lua_pushliteral( L, "uservalue"); // o "r" {c} {fqn} ... {?} k v {u} "uservalue" 1229 while( lua_getiuservalue( L, -1, uvi) != LUA_TNONE) // o "r" {c} {fqn} ... {?} k U {u}
1232 lua_rawseti( L, fqn, depth_); // o "r" {c} {fqn} ... {?} k v {u} 1230 {
1233 shortest_ = discover_object_name_recur( L, shortest_, depth_); 1231 if( lua_istable( L, -1)) // if it is a table, look inside
1234 lua_pushnil( L); // o "r" {c} {fqn} ... {?} k v {u} nil 1232 {
1235 lua_rawseti( L, fqn, depth_); // o "r" {c} {fqn} ... {?} k v {u} 1233 ++ depth_;
1236 -- depth_; 1234 lua_pushliteral( L, "uservalue"); // o "r" {c} {fqn} ... {?} k v {u} "uservalue"
1235 lua_rawseti( L, fqn, depth_); // o "r" {c} {fqn} ... {?} k v {u}
1236 shortest_ = discover_object_name_recur( L, shortest_, depth_);
1237 lua_pushnil( L); // o "r" {c} {fqn} ... {?} k v {u} nil
1238 lua_rawseti( L, fqn, depth_); // o "r" {c} {fqn} ... {?} k v {u}
1239 -- depth_;
1240 }
1241 lua_pop( L, 1); // o "r" {c} {fqn} ... {?} k U
1242 ++ uvi;
1243 }
1244 // when lua_getiuservalue() returned LUA_TNONE, it pushed a nil. pop it now
1245 lua_pop( L, 1); // o "r" {c} {fqn} ... {?} k U
1237 } 1246 }
1238 lua_pop( L, 1); // o "r" {c} {fqn} ... {?} k U
1239 STACK_MID( L, 2); 1247 STACK_MID( L, 2);
1240 break; 1248 break;
1241 } 1249 }
@@ -1436,7 +1444,7 @@ static void inter_copy_func( Universe* U, lua_State* L2, uint_t L2_cache_i, lua_
1436 // "value returned is the error code returned by the last call 1444 // "value returned is the error code returned by the last call
1437 // to the writer" (and we only return 0) 1445 // to the writer" (and we only return 0)
1438 // not sure this could ever fail but for memory shortage reasons 1446 // not sure this could ever fail but for memory shortage reasons
1439 if( lua503_dump( L, buf_writer, &b, 0) != 0) 1447 if( lua504_dump( L, buf_writer, &b, 0) != 0)
1440 { 1448 {
1441 luaL_error( L, "internal error: function dump failed."); 1449 luaL_error( L, "internal error: function dump failed.");
1442 } 1450 }
@@ -1846,7 +1854,32 @@ static bool_t inter_copy_one_( Universe* U, lua_State* L2, uint_t L2_cache_i, lu
1846 STACK_MID( L, 3); 1854 STACK_MID( L, 3);
1847 userdata_size = (size_t) lua_tointeger( L, -1); // ... mt __lanesclone size 1855 userdata_size = (size_t) lua_tointeger( L, -1); // ... mt __lanesclone size
1848 lua_pop( L, 1); // ... mt __lanesclone 1856 lua_pop( L, 1); // ... mt __lanesclone
1849 clone = lua_newuserdata( L2, userdata_size); // ... u 1857 // we need to copy over the uservalues of the userdata as well
1858 lua_pushnil( L2); // ... nil
1859 {
1860 int const clone_i = lua_gettop( L2);
1861 int uvi = 0;
1862 while( lua_getiuservalue( L, i, uvi + 1) != LUA_TNONE) // ... mt __lanesclone uv
1863 {
1864 luaG_inter_move( U, L, L2, 1, mode_); // ... mt __lanesclone // ... nil [uv]+
1865 ++ uvi;
1866 }
1867 // when lua_getiuservalue() returned LUA_TNONE, it pushed a nil. pop it now
1868 lua_pop( L, 1); // ... mt __lanesclone
1869 // create the clone userdata with the required number of uservalue slots
1870 clone = lua_newuserdatauv( L2, userdata_size, uvi); // ... nil [uv]+ u
1871 lua_replace( L2, clone_i); // ... u [uv]+
1872 // assign uservalues
1873 while( uvi > 0)
1874 {
1875 // this pops the value from the stack
1876 lua_setiuservalue( L2, clone_i, uvi); // ... u [uv]+
1877 -- uvi;
1878 }
1879 // when we are done, all uservalues are popped from the stack
1880 STACK_MID( L2, 1); // ... u
1881 }
1882 STACK_MID( L, 2); // ... mt __lanesclone
1850 // call cloning function in source state to perform the actual memory cloning 1883 // call cloning function in source state to perform the actual memory cloning
1851 lua_pushlightuserdata( L, clone); // ... mt __lanesclone clone 1884 lua_pushlightuserdata( L, clone); // ... mt __lanesclone clone
1852 lua_pushlightuserdata( L, source); // ... mt __lanesclone source 1885 lua_pushlightuserdata( L, source); // ... mt __lanesclone source
@@ -1920,13 +1953,37 @@ static bool_t inter_copy_one_( Universe* U, lua_State* L2, uint_t L2_cache_i, lu
1920 source = lua_touserdata( L, -1); 1953 source = lua_touserdata( L, -1);
1921 lookup_table( L2, L, i, mode_, upName_); // ... u // ... mt 1954 lookup_table( L2, L, i, mode_, upName_); // ... u // ... mt
1922 // __lanesclone should always exist because we woudln't be restoring data from a userdata_clone_sentinel closure to begin with 1955 // __lanesclone should always exist because we woudln't be restoring data from a userdata_clone_sentinel closure to begin with
1923 lua_getfield( L2, -1, "__lanesclone"); // // ... mt __lanesclone 1956 lua_getfield( L2, -1, "__lanesclone"); // ... mt __lanesclone
1924 lua_pushvalue( L2, -1); // ... mt __lanesclone __lanesclone 1957 lua_pushvalue( L2, -1); // ... mt __lanesclone __lanesclone
1925 // call the cloning function with 0 arguments, should return the number of bytes to allocate for the clone 1958 // call the cloning function with 0 arguments, should return the number of bytes to allocate for the clone
1926 lua_call( L2, 0, 1); // ... mt __lanesclone size 1959 lua_call( L2, 0, 1); // ... mt __lanesclone size
1927 userdata_size = (size_t) lua_tointeger( L2, -1); // ... mt __lanesclone size 1960 userdata_size = (size_t) lua_tointeger( L2, -1); // ... mt __lanesclone size
1928 lua_pop( L2, 1); // ... mt __lanesclone 1961 lua_pop( L2, 1); // ... mt __lanesclone
1929 clone = lua_newuserdata( L2, userdata_size); // ... mt __lanesclone u 1962 lua_pushnil( L2); // ... mt __lanesclone nil
1963 {
1964 int const clone_i = lua_gettop( L2);
1965 int uvi = 0;
1966 while( lua_getiuservalue( L, i, uvi + 1) != LUA_TNONE) // ... u uv
1967 {
1968 luaG_inter_move( U, L, L2, 1, mode_); // ... u // ... mt __lanesclone nil [uv]+
1969 ++ uvi;
1970 }
1971 // when lua_getiuservalue() returned LUA_TNONE, it pushed a nil. pop it now
1972 lua_pop( L, 1); // ... u
1973 // create the clone userdata with the required number of uservalue slots
1974 clone = lua_newuserdatauv( L2, userdata_size, uvi); // ... mt __lanesclone nil [uv]+ u
1975 lua_replace( L2, clone_i); // ... mt __lanesclone u [uv]+
1976 // assign uservalues
1977 while( uvi > 0)
1978 {
1979 // this pops the value from the stack
1980 lua_setiuservalue( L2, clone_i, uvi); // ... mt __lanesclone u [uv]+
1981 -- uvi;
1982 }
1983 // when we are done, all uservalues are popped from the stack
1984 STACK_MID( L2, 3); // ... mt __lanesclone u
1985 }
1986 STACK_MID( L, 1); // u
1930 lua_insert( L2, -3); // ... u mt __lanesclone 1987 lua_insert( L2, -3); // ... u mt __lanesclone
1931 lua_pushlightuserdata( L2, clone); // ... u mt __lanesclone clone 1988 lua_pushlightuserdata( L2, clone); // ... u mt __lanesclone clone
1932 lua_pushlightuserdata( L2, source); // ... u mt __lanesclone clone source 1989 lua_pushlightuserdata( L2, source); // ... u mt __lanesclone clone source