diff options
Diffstat (limited to 'src/deep.c')
-rw-r--r-- | src/deep.c | 70 |
1 files changed, 9 insertions, 61 deletions
@@ -49,59 +49,6 @@ THE SOFTWARE. | |||
49 | 49 | ||
50 | /*-- Metatable copying --*/ | 50 | /*-- Metatable copying --*/ |
51 | 51 | ||
52 | /* | ||
53 | * 'reg[ REG_MT_KNOWN ]'= { | ||
54 | * [ table ]= id_uint, | ||
55 | * ... | ||
56 | * [ id_uint ]= table, | ||
57 | * ... | ||
58 | * } | ||
59 | */ | ||
60 | |||
61 | /* | ||
62 | * Does what the original 'push_registry_subtable' function did, but adds an optional mode argument to it | ||
63 | */ | ||
64 | static void push_registry_subtable_mode( lua_State* L, UniqueKey key_, const char* mode_) | ||
65 | { | ||
66 | STACK_GROW( L, 3); | ||
67 | STACK_CHECK( L, 0); | ||
68 | |||
69 | REGISTRY_GET( L, key_); // {}|nil | ||
70 | STACK_MID( L, 1); | ||
71 | |||
72 | if( lua_isnil( L, -1)) | ||
73 | { | ||
74 | lua_pop( L, 1); // | ||
75 | lua_newtable( L); // {} | ||
76 | // _R[key_] = {} | ||
77 | REGISTRY_SET( L, key_, lua_pushvalue( L, -2)); // {} | ||
78 | STACK_MID( L, 1); | ||
79 | |||
80 | // Set its metatable if requested | ||
81 | if( mode_) | ||
82 | { | ||
83 | lua_newtable( L); // {} mt | ||
84 | lua_pushliteral( L, "__mode"); // {} mt "__mode" | ||
85 | lua_pushstring( L, mode_); // {} mt "__mode" mode | ||
86 | lua_rawset( L, -3); // {} mt | ||
87 | lua_setmetatable( L, -2); // {} | ||
88 | } | ||
89 | } | ||
90 | STACK_END( L, 1); | ||
91 | ASSERT_L( lua_istable( L, -1)); | ||
92 | } | ||
93 | |||
94 | |||
95 | /* | ||
96 | * Push a registry subtable (keyed by unique 'key_') onto the stack. | ||
97 | * If the subtable does not exist, it is created and chained. | ||
98 | */ | ||
99 | void push_registry_subtable( lua_State* L, UniqueKey key_) | ||
100 | { | ||
101 | push_registry_subtable_mode( L, key_, NULL); | ||
102 | } | ||
103 | |||
104 | |||
105 | /*---=== Deep userdata ===---*/ | 52 | /*---=== Deep userdata ===---*/ |
106 | 53 | ||
107 | /* | 54 | /* |
@@ -503,10 +450,10 @@ void* luaG_todeep( lua_State* L, luaG_IdFunction idfunc, int index) | |||
503 | * the id function of the copied value, or NULL for non-deep userdata | 450 | * the id function of the copied value, or NULL for non-deep userdata |
504 | * (not copied) | 451 | * (not copied) |
505 | */ | 452 | */ |
506 | bool_t copydeep( Universe* U, lua_State* L, lua_State* L2, int index, LookupMode mode_) | 453 | bool_t copydeep( Universe* U, lua_State* L2, uint_t L2_cache_i, lua_State* L, uint_t i, LookupMode mode_, char const* upName_) |
507 | { | 454 | { |
508 | char const* errmsg; | 455 | char const* errmsg; |
509 | luaG_IdFunction idfunc = get_idfunc( L, index, mode_); | 456 | luaG_IdFunction idfunc = get_idfunc( L, i, mode_); |
510 | int nuv = 0; | 457 | int nuv = 0; |
511 | 458 | ||
512 | if( idfunc == NULL) | 459 | if( idfunc == NULL) |
@@ -518,24 +465,25 @@ bool_t copydeep( Universe* U, lua_State* L, lua_State* L2, int index, LookupMode | |||
518 | STACK_CHECK( L2, 0); | 465 | STACK_CHECK( L2, 0); |
519 | 466 | ||
520 | // extract all uservalues of the source | 467 | // extract all uservalues of the source |
521 | while( lua_getiuservalue( L, index, nuv + 1) != LUA_TNONE) // ... u [uv]+ nil | 468 | while( lua_getiuservalue( L, i, nuv + 1) != LUA_TNONE) // ... u [uv]* nil |
522 | { | 469 | { |
523 | ++ nuv; | 470 | ++ nuv; |
524 | } | 471 | } |
525 | // last call returned TNONE and pushed nil, that we don't need | 472 | // last call returned TNONE and pushed nil, that we don't need |
526 | lua_pop( L, 1); // ... u [uv]+ | 473 | lua_pop( L, 1); // ... u [uv]* |
527 | STACK_MID( L, nuv); | 474 | STACK_MID( L, nuv); |
528 | 475 | ||
529 | errmsg = push_deep_proxy( U, L2, *(DeepPrelude**) lua_touserdata( L, index), nuv, mode_); // u | 476 | errmsg = push_deep_proxy( U, L2, *(DeepPrelude**) lua_touserdata( L, i), nuv, mode_); // u |
530 | 477 | ||
531 | // transfer all uservalues of the source in the destination | 478 | // transfer all uservalues of the source in the destination |
532 | { | 479 | { |
533 | int const clone_i = lua_gettop( L2); | 480 | int const clone_i = lua_gettop( L2); |
534 | luaG_inter_move( U, L, L2, nuv, mode_); // ... u // u [uv]+ | 481 | while( nuv) |
535 | while( nuv > 0) | ||
536 | { | 482 | { |
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]* | ||
537 | // this pops the value from the stack | 485 | // this pops the value from the stack |
538 | lua_setiuservalue( L2, clone_i, nuv); // ... u // u | 486 | lua_setiuservalue( L2, clone_i, nuv); // u |
539 | -- nuv; | 487 | -- nuv; |
540 | } | 488 | } |
541 | } | 489 | } |