aboutsummaryrefslogtreecommitdiff
path: root/src/deep.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/deep.c')
-rw-r--r--src/deep.c43
1 files changed, 37 insertions, 6 deletions
diff --git a/src/deep.c b/src/deep.c
index fadb895..fd2ae73 100644
--- a/src/deep.c
+++ b/src/deep.c
@@ -256,7 +256,7 @@ static int deep_userdata_gc( lua_State* L)
256 * used in this Lua state (metatable, registring it). Otherwise, increments the 256 * used in this Lua state (metatable, registring it). Otherwise, increments the
257 * reference count. 257 * reference count.
258 */ 258 */
259char const* push_deep_proxy( Universe* U, lua_State* L, DeepPrelude* prelude, LookupMode mode_) 259char const* push_deep_proxy( Universe* U, lua_State* L, DeepPrelude* prelude, int nuv_, LookupMode mode_)
260{ 260{
261 DeepPrelude** proxy; 261 DeepPrelude** proxy;
262 262
@@ -283,7 +283,8 @@ char const* push_deep_proxy( Universe* U, lua_State* L, DeepPrelude* prelude, Lo
283 STACK_GROW( L, 7); 283 STACK_GROW( L, 7);
284 STACK_CHECK( L, 0); 284 STACK_CHECK( L, 0);
285 285
286 proxy = lua_newuserdatauv( L, sizeof(DeepPrelude*), 0); // DPC proxy 286 // a new full userdata, fitted with the specified number of uservalue slots (always 1 for Lua < 5.4)
287 proxy = lua_newuserdatauv( L, sizeof(DeepPrelude*), nuv_); // DPC proxy
287 ASSERT_L( proxy); 288 ASSERT_L( proxy);
288 *proxy = prelude; 289 *proxy = prelude;
289 290
@@ -414,7 +415,7 @@ char const* push_deep_proxy( Universe* U, lua_State* L, DeepPrelude* prelude, Lo
414* proxy_ud= deep_userdata( idfunc [, ...] ) 415* proxy_ud= deep_userdata( idfunc [, ...] )
415* 416*
416* Creates a deep userdata entry of the type defined by 'idfunc'. 417* Creates a deep userdata entry of the type defined by 'idfunc'.
417* Other parameters are passed on to the 'idfunc' "new" invocation. 418* Parameters found on the stack are left as is passed on to the 'idfunc' "new" invocation.
418* 419*
419* 'idfunc' must fulfill the following features: 420* 'idfunc' must fulfill the following features:
420* 421*
@@ -430,7 +431,7 @@ char const* push_deep_proxy( Universe* U, lua_State* L, DeepPrelude* prelude, Lo
430* 431*
431* Returns: 'proxy' userdata for accessing the deep data via 'luaG_todeep()' 432* Returns: 'proxy' userdata for accessing the deep data via 'luaG_todeep()'
432*/ 433*/
433int luaG_newdeepuserdata( lua_State* L, luaG_IdFunction idfunc) 434int luaG_newdeepuserdata( lua_State* L, luaG_IdFunction idfunc, int nuv_)
434{ 435{
435 char const* errmsg; 436 char const* errmsg;
436 437
@@ -460,7 +461,7 @@ int luaG_newdeepuserdata( lua_State* L, luaG_IdFunction idfunc)
460 idfunc( L, eDO_delete); 461 idfunc( L, eDO_delete);
461 return luaL_error( L, "Bad idfunc(eDO_new): should not push anything on the stack"); 462 return luaL_error( L, "Bad idfunc(eDO_new): should not push anything on the stack");
462 } 463 }
463 errmsg = push_deep_proxy( universe_get( L), L, prelude, eLM_LaneBody); // proxy 464 errmsg = push_deep_proxy( universe_get( L), L, prelude, nuv_, eLM_LaneBody); // proxy
464 if( errmsg != NULL) 465 if( errmsg != NULL)
465 { 466 {
466 return luaL_error( L, errmsg); 467 return luaL_error( L, errmsg);
@@ -506,12 +507,42 @@ bool_t copydeep( Universe* U, lua_State* L, lua_State* L2, int index, LookupMode
506{ 507{
507 char const* errmsg; 508 char const* errmsg;
508 luaG_IdFunction idfunc = get_idfunc( L, index, mode_); 509 luaG_IdFunction idfunc = get_idfunc( L, index, mode_);
510 int nuv = 0;
511
509 if( idfunc == NULL) 512 if( idfunc == NULL)
510 { 513 {
511 return FALSE; // not a deep userdata 514 return FALSE; // not a deep userdata
512 } 515 }
513 516
514 errmsg = push_deep_proxy( U, L2, *(DeepPrelude**) lua_touserdata( L, index), mode_); 517 STACK_CHECK( L, 0);
518 STACK_CHECK( L2, 0);
519
520 // extract all uservalues of the source
521 while( lua_getiuservalue( L, index, nuv + 1) != LUA_TNONE) // ... u [uv]+ nil
522 {
523 ++ nuv;
524 }
525 // last call returned TNONE and pushed nil, that we don't need
526 lua_pop( L, 1); // ... u [uv]+
527 STACK_MID( L, nuv);
528
529 errmsg = push_deep_proxy( U, L2, *(DeepPrelude**) lua_touserdata( L, index), nuv, mode_); // u
530
531 // transfer all uservalues of the source in the destination
532 {
533 int const clone_i = lua_gettop( L2);
534 luaG_inter_move( U, L, L2, nuv, mode_); // ... u // u [uv]+
535 while( nuv > 0)
536 {
537 // this pops the value from the stack
538 lua_setiuservalue( L2, clone_i, nuv); // ... u // u
539 -- nuv;
540 }
541 }
542
543 STACK_END( L2, 1);
544 STACK_END( L, 0);
545
515 if( errmsg != NULL) 546 if( errmsg != NULL)
516 { 547 {
517 // raise the error in the proper state (not the keeper) 548 // raise the error in the proper state (not the keeper)