diff options
Diffstat (limited to 'src/deep.c')
-rw-r--r-- | src/deep.c | 76 |
1 files changed, 38 insertions, 38 deletions
@@ -97,8 +97,8 @@ static void get_deep_lookup( lua_State* L) | |||
97 | REGISTRY_GET( L, DEEP_LOOKUP_KEY); // a {} | 97 | REGISTRY_GET( L, DEEP_LOOKUP_KEY); // a {} |
98 | if( !lua_isnil( L, -1)) | 98 | if( !lua_isnil( L, -1)) |
99 | { | 99 | { |
100 | lua_insert( L, -2); // {} a | 100 | lua_insert( L, -2); // {} a |
101 | lua_rawget( L, -2); // {} b | 101 | lua_rawget( L, -2); // {} b |
102 | } | 102 | } |
103 | lua_remove( L, -2); // a|b | 103 | lua_remove( L, -2); // a|b |
104 | STACK_END( L, 1); | 104 | STACK_END( L, 1); |
@@ -173,7 +173,7 @@ static int deep_userdata_gc( lua_State* L) | |||
173 | if( v == 0) | 173 | if( v == 0) |
174 | { | 174 | { |
175 | // retrieve wrapped __gc | 175 | // retrieve wrapped __gc |
176 | lua_pushvalue( L, lua_upvalueindex( 1)); // self __gc? | 176 | lua_pushvalue( L, lua_upvalueindex( 1)); // self __gc? |
177 | if( !lua_isnil( L, -1)) | 177 | if( !lua_isnil( L, -1)) |
178 | { | 178 | { |
179 | lua_insert( L, -2); // __gc self | 179 | lua_insert( L, -2); // __gc self |
@@ -213,12 +213,12 @@ char const* push_deep_proxy( Universe* U, lua_State* L, DeepPrelude* prelude, in | |||
213 | lua_rawget( L, -2); // DPC proxy | 213 | lua_rawget( L, -2); // DPC proxy |
214 | if ( !lua_isnil( L, -1)) | 214 | if ( !lua_isnil( L, -1)) |
215 | { | 215 | { |
216 | lua_remove( L, -2); // proxy | 216 | lua_remove( L, -2); // proxy |
217 | return NULL; | 217 | return NULL; |
218 | } | 218 | } |
219 | else | 219 | else |
220 | { | 220 | { |
221 | lua_pop( L, 1); // DPC | 221 | lua_pop( L, 1); // DPC |
222 | } | 222 | } |
223 | 223 | ||
224 | // can work without a universe if creating a deep userdata from some external C module when Lanes isn't loaded | 224 | // can work without a universe if creating a deep userdata from some external C module when Lanes isn't loaded |
@@ -231,7 +231,7 @@ char const* push_deep_proxy( Universe* U, lua_State* L, DeepPrelude* prelude, in | |||
231 | STACK_CHECK( L, 0); | 231 | STACK_CHECK( L, 0); |
232 | 232 | ||
233 | // a new full userdata, fitted with the specified number of uservalue slots (always 1 for Lua < 5.4) | 233 | // a new full userdata, fitted with the specified number of uservalue slots (always 1 for Lua < 5.4) |
234 | proxy = lua_newuserdatauv( L, sizeof(DeepPrelude*), nuv_); // DPC proxy | 234 | proxy = (DeepPrelude**) lua_newuserdatauv( L, sizeof(DeepPrelude*), nuv_); // DPC proxy |
235 | ASSERT_L( proxy); | 235 | ASSERT_L( proxy); |
236 | *proxy = prelude; | 236 | *proxy = prelude; |
237 | 237 | ||
@@ -242,101 +242,101 @@ char const* push_deep_proxy( Universe* U, lua_State* L, DeepPrelude* prelude, in | |||
242 | if( lua_isnil( L, -1)) // // No metatable yet. | 242 | if( lua_isnil( L, -1)) // // No metatable yet. |
243 | { | 243 | { |
244 | char const* modname; | 244 | char const* modname; |
245 | int oldtop = lua_gettop( L); // DPC proxy nil | 245 | int oldtop = lua_gettop( L); // DPC proxy nil |
246 | lua_pop( L, 1); // DPC proxy | 246 | lua_pop( L, 1); // DPC proxy |
247 | // 1 - make one and register it | 247 | // 1 - make one and register it |
248 | if( mode_ != eLM_ToKeeper) | 248 | if( mode_ != eLM_ToKeeper) |
249 | { | 249 | { |
250 | (void) prelude->idfunc( L, eDO_metatable); // DPC proxy metatable | 250 | (void) prelude->idfunc( L, eDO_metatable); // DPC proxy metatable |
251 | if( lua_gettop( L) - oldtop != 0 || !lua_istable( L, -1)) | 251 | if( lua_gettop( L) - oldtop != 0 || !lua_istable( L, -1)) |
252 | { | 252 | { |
253 | lua_settop( L, oldtop); // DPC proxy X | 253 | lua_settop( L, oldtop); // DPC proxy X |
254 | lua_pop( L, 3); // | 254 | lua_pop( L, 3); // |
255 | return "Bad idfunc(eOP_metatable): unexpected pushed value"; | 255 | return "Bad idfunc(eOP_metatable): unexpected pushed value"; |
256 | } | 256 | } |
257 | // if the metatable contains a __gc, we will call it from our own | 257 | // if the metatable contains a __gc, we will call it from our own |
258 | lua_getfield( L, -1, "__gc"); // DPC proxy metatable __gc | 258 | lua_getfield( L, -1, "__gc"); // DPC proxy metatable __gc |
259 | } | 259 | } |
260 | else | 260 | else |
261 | { | 261 | { |
262 | // keepers need a minimal metatable that only contains our own __gc | 262 | // keepers need a minimal metatable that only contains our own __gc |
263 | lua_newtable( L); // DPC proxy metatable | 263 | lua_newtable( L); // DPC proxy metatable |
264 | lua_pushnil( L); // DPC proxy metatable nil | 264 | lua_pushnil( L); // DPC proxy metatable nil |
265 | } | 265 | } |
266 | if( lua_isnil( L, -1)) | 266 | if( lua_isnil( L, -1)) |
267 | { | 267 | { |
268 | // Add our own '__gc' method | 268 | // Add our own '__gc' method |
269 | lua_pop( L, 1); // DPC proxy metatable | 269 | lua_pop( L, 1); // DPC proxy metatable |
270 | lua_pushcfunction( L, deep_userdata_gc); // DPC proxy metatable deep_userdata_gc | 270 | lua_pushcfunction( L, deep_userdata_gc); // DPC proxy metatable deep_userdata_gc |
271 | } | 271 | } |
272 | else | 272 | else |
273 | { | 273 | { |
274 | // Add our own '__gc' method wrapping the original | 274 | // Add our own '__gc' method wrapping the original |
275 | lua_pushcclosure( L, deep_userdata_gc, 1); // DPC proxy metatable deep_userdata_gc | 275 | lua_pushcclosure( L, deep_userdata_gc, 1); // DPC proxy metatable deep_userdata_gc |
276 | } | 276 | } |
277 | lua_setfield( L, -2, "__gc"); // DPC proxy metatable | 277 | lua_setfield( L, -2, "__gc"); // DPC proxy metatable |
278 | 278 | ||
279 | // Memorize for later rounds | 279 | // Memorize for later rounds |
280 | lua_pushvalue( L, -1); // DPC proxy metatable metatable | 280 | lua_pushvalue( L, -1); // DPC proxy metatable metatable |
281 | lua_pushlightuserdata( L, (void*)(ptrdiff_t)(prelude->idfunc)); // DPC proxy metatable metatable idfunc | 281 | lua_pushlightuserdata( L, (void*)(ptrdiff_t)(prelude->idfunc)); // DPC proxy metatable metatable idfunc |
282 | set_deep_lookup( L); // DPC proxy metatable | 282 | set_deep_lookup( L); // DPC proxy metatable |
283 | 283 | ||
284 | // 2 - cause the target state to require the module that exported the idfunc | 284 | // 2 - cause the target state to require the module that exported the idfunc |
285 | // this is needed because we must make sure the shared library is still loaded as long as we hold a pointer on the idfunc | 285 | // this is needed because we must make sure the shared library is still loaded as long as we hold a pointer on the idfunc |
286 | { | 286 | { |
287 | int oldtop_module = lua_gettop( L); | 287 | int oldtop_module = lua_gettop( L); |
288 | modname = (char const*) prelude->idfunc( L, eDO_module); // DPC proxy metatable | 288 | modname = (char const*) prelude->idfunc( L, eDO_module); // DPC proxy metatable |
289 | // make sure the function pushed nothing on the stack! | 289 | // make sure the function pushed nothing on the stack! |
290 | if( lua_gettop( L) - oldtop_module != 0) | 290 | if( lua_gettop( L) - oldtop_module != 0) |
291 | { | 291 | { |
292 | lua_pop( L, 3); // | 292 | lua_pop( L, 3); // |
293 | return "Bad idfunc(eOP_module): should not push anything"; | 293 | return "Bad idfunc(eOP_module): should not push anything"; |
294 | } | 294 | } |
295 | } | 295 | } |
296 | if( NULL != modname) // we actually got a module name | 296 | if( NULL != modname) // we actually got a module name |
297 | { | 297 | { |
298 | // L.registry._LOADED exists without having registered the 'package' library. | 298 | // L.registry._LOADED exists without having registered the 'package' library. |
299 | lua_getglobal( L, "require"); // DPC proxy metatable require() | 299 | lua_getglobal( L, "require"); // DPC proxy metatable require() |
300 | // check that the module is already loaded (or being loaded, we are happy either way) | 300 | // check that the module is already loaded (or being loaded, we are happy either way) |
301 | if( lua_isfunction( L, -1)) | 301 | if( lua_isfunction( L, -1)) |
302 | { | 302 | { |
303 | lua_pushstring( L, modname); // DPC proxy metatable require() "module" | 303 | lua_pushstring( L, modname); // DPC proxy metatable require() "module" |
304 | lua_getfield( L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE); // DPC proxy metatable require() "module" _R._LOADED | 304 | lua_getfield( L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE); // DPC proxy metatable require() "module" _R._LOADED |
305 | if( lua_istable( L, -1)) | 305 | if( lua_istable( L, -1)) |
306 | { | 306 | { |
307 | bool_t alreadyloaded; | 307 | bool_t alreadyloaded; |
308 | lua_pushvalue( L, -2); // DPC proxy metatable require() "module" _R._LOADED "module" | 308 | lua_pushvalue( L, -2); // DPC proxy metatable require() "module" _R._LOADED "module" |
309 | lua_rawget( L, -2); // DPC proxy metatable require() "module" _R._LOADED module | 309 | lua_rawget( L, -2); // DPC proxy metatable require() "module" _R._LOADED module |
310 | alreadyloaded = lua_toboolean( L, -1); | 310 | alreadyloaded = lua_toboolean( L, -1); |
311 | if( !alreadyloaded) // not loaded | 311 | if( !alreadyloaded) // not loaded |
312 | { | 312 | { |
313 | int require_result; | 313 | int require_result; |
314 | lua_pop( L, 2); // DPC proxy metatable require() "module" | 314 | lua_pop( L, 2); // DPC proxy metatable require() "module" |
315 | // require "modname" | 315 | // require "modname" |
316 | require_result = lua_pcall( L, 1, 0, 0); // DPC proxy metatable error? | 316 | require_result = lua_pcall( L, 1, 0, 0); // DPC proxy metatable error? |
317 | if( require_result != LUA_OK) | 317 | if( require_result != LUA_OK) |
318 | { | 318 | { |
319 | // failed, return the error message | 319 | // failed, return the error message |
320 | lua_pushfstring( L, "error while requiring '%s' identified by idfunc(eOP_module): ", modname); | 320 | lua_pushfstring( L, "error while requiring '%s' identified by idfunc(eOP_module): ", modname); |
321 | lua_insert( L, -2); // DPC proxy metatable prefix error | 321 | lua_insert( L, -2); // DPC proxy metatable prefix error |
322 | lua_concat( L, 2); // DPC proxy metatable error | 322 | lua_concat( L, 2); // DPC proxy metatable error |
323 | return lua_tostring( L, -1); | 323 | return lua_tostring( L, -1); |
324 | } | 324 | } |
325 | } | 325 | } |
326 | else // already loaded, we are happy | 326 | else // already loaded, we are happy |
327 | { | 327 | { |
328 | lua_pop( L, 4); // DPC proxy metatable | 328 | lua_pop( L, 4); // DPC proxy metatable |
329 | } | 329 | } |
330 | } | 330 | } |
331 | else // no L.registry._LOADED; can this ever happen? | 331 | else // no L.registry._LOADED; can this ever happen? |
332 | { | 332 | { |
333 | lua_pop( L, 6); // | 333 | lua_pop( L, 6); // |
334 | return "unexpected error while requiring a module identified by idfunc(eOP_module)"; | 334 | return "unexpected error while requiring a module identified by idfunc(eOP_module)"; |
335 | } | 335 | } |
336 | } | 336 | } |
337 | else // a module name, but no require() function :-( | 337 | else // a module name, but no require() function :-( |
338 | { | 338 | { |
339 | lua_pop( L, 4); // | 339 | lua_pop( L, 4); // |
340 | return "lanes receiving deep userdata should register the 'package' library"; | 340 | return "lanes receiving deep userdata should register the 'package' library"; |
341 | } | 341 | } |
342 | } | 342 | } |
@@ -386,7 +386,7 @@ int luaG_newdeepuserdata( lua_State* L, luaG_IdFunction idfunc, int nuv_) | |||
386 | STACK_CHECK( L, 0); | 386 | STACK_CHECK( L, 0); |
387 | { | 387 | { |
388 | int const oldtop = lua_gettop( L); | 388 | int const oldtop = lua_gettop( L); |
389 | DeepPrelude* prelude = idfunc( L, eDO_new); | 389 | DeepPrelude* prelude = (DeepPrelude*) idfunc( L, eDO_new); |
390 | if( prelude == NULL) | 390 | if( prelude == NULL) |
391 | { | 391 | { |
392 | return luaL_error( L, "idfunc(eDO_new) failed to create deep userdata (out of memory)"); | 392 | return luaL_error( L, "idfunc(eDO_new) failed to create deep userdata (out of memory)"); |
@@ -473,7 +473,7 @@ bool_t copydeep( Universe* U, lua_State* L2, uint_t L2_cache_i, lua_State* L, ui | |||
473 | lua_pop( L, 1); // ... u [uv]* | 473 | lua_pop( L, 1); // ... u [uv]* |
474 | STACK_MID( L, nuv); | 474 | STACK_MID( L, nuv); |
475 | 475 | ||
476 | errmsg = push_deep_proxy( U, L2, *(DeepPrelude**) lua_touserdata( L, i), nuv, mode_); // u | 476 | errmsg = push_deep_proxy( U, L2, *(DeepPrelude**) lua_touserdata( L, i), nuv, mode_); // u |
477 | 477 | ||
478 | // transfer all uservalues of the source in the destination | 478 | // transfer all uservalues of the source in the destination |
479 | { | 479 | { |
@@ -481,7 +481,7 @@ bool_t copydeep( Universe* U, lua_State* L2, uint_t L2_cache_i, lua_State* L, ui | |||
481 | while( nuv) | 481 | while( nuv) |
482 | { | 482 | { |
483 | inter_copy_one( U, L2, L2_cache_i, L, lua_absindex( L, -1), VT_NORMAL, mode_, upName_); // u uv | 483 | inter_copy_one( U, L2, L2_cache_i, L, lua_absindex( L, -1), VT_NORMAL, mode_, upName_); // u uv |
484 | lua_pop( L, 1); // ... u [uv]* | 484 | lua_pop( L, 1); // ... u [uv]* |
485 | // this pops the value from the stack | 485 | // this pops the value from the stack |
486 | lua_setiuservalue( L2, clone_i, nuv); // u | 486 | lua_setiuservalue( L2, clone_i, nuv); // u |
487 | -- nuv; | 487 | -- nuv; |