aboutsummaryrefslogtreecommitdiff
path: root/src/deep.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/deep.cpp')
-rw-r--r--src/deep.cpp53
1 files changed, 30 insertions, 23 deletions
diff --git a/src/deep.cpp b/src/deep.cpp
index ac2905e..d0b8123 100644
--- a/src/deep.cpp
+++ b/src/deep.cpp
@@ -1,5 +1,5 @@
1/* 1/*
2 * DEEP.C Copyright (c) 2017, Benoit Germain 2 * DEEP.CPP Copyright (c) 2024, Benoit Germain
3 * 3 *
4 * Deep userdata support, separate in its own source file to help integration 4 * Deep userdata support, separate in its own source file to help integration
5 * without enforcing a Lanes dependency 5 * without enforcing a Lanes dependency
@@ -9,7 +9,7 @@
9=============================================================================== 9===============================================================================
10 10
11Copyright (C) 2002-10 Asko Kauppi <akauppi@gmail.com> 11Copyright (C) 2002-10 Asko Kauppi <akauppi@gmail.com>
12 2011-17 Benoit Germain <bnt.germain@gmail.com> 12 2011-24 Benoit Germain <bnt.germain@gmail.com>
13 13
14Permission is hereby granted, free of charge, to any person obtaining a copy 14Permission is hereby granted, free of charge, to any person obtaining a copy
15of this software and associated documentation files (the "Software"), to deal 15of this software and associated documentation files (the "Software"), to deal
@@ -41,13 +41,6 @@ THE SOFTWARE.
41 41
42#include <bit> 42#include <bit>
43#include <cassert> 43#include <cassert>
44#include <ctype.h>
45#include <stdio.h>
46#include <string.h>
47#include <stdlib.h>
48#if !defined(__APPLE__)
49#include <malloc.h>
50#endif
51 44
52/*-- Metatable copying --*/ 45/*-- Metatable copying --*/
53 46
@@ -73,7 +66,7 @@ static constexpr UniqueKey DEEP_PROXY_CACHE_KEY{ 0x05773d6fc26be106ull };
73* Sets up [-1]<->[-2] two-way lookups, and ensures the lookup table exists. 66* Sets up [-1]<->[-2] two-way lookups, and ensures the lookup table exists.
74* Pops the both values off the stack. 67* Pops the both values off the stack.
75*/ 68*/
76static void set_deep_lookup( lua_State* L) 69static void set_deep_lookup(lua_State* L)
77{ 70{
78 STACK_GROW( L, 3); 71 STACK_GROW( L, 3);
79 STACK_CHECK_START_REL(L, 2); // a b 72 STACK_CHECK_START_REL(L, 2); // a b
@@ -88,11 +81,13 @@ static void set_deep_lookup( lua_State* L)
88 STACK_CHECK( L, 0); 81 STACK_CHECK( L, 0);
89} 82}
90 83
84// ################################################################################################
85
91/* 86/*
92* Pops the key (metatable or idfunc) off the stack, and replaces with the 87* Pops the key (metatable or idfunc) off the stack, and replaces with the
93* deep lookup value (idfunc/metatable/nil). 88* deep lookup value (idfunc/metatable/nil).
94*/ 89*/
95static void get_deep_lookup( lua_State* L) 90static void get_deep_lookup(lua_State* L)
96{ 91{
97 STACK_GROW( L, 1); 92 STACK_GROW( L, 1);
98 STACK_CHECK_START_REL(L, 1); // a 93 STACK_CHECK_START_REL(L, 1); // a
@@ -106,11 +101,13 @@ static void get_deep_lookup( lua_State* L)
106 STACK_CHECK( L, 1); 101 STACK_CHECK( L, 1);
107} 102}
108 103
104// ################################################################################################
105
109/* 106/*
110* Return the registered ID function for 'index' (deep userdata proxy), 107* Return the registered ID function for 'index' (deep userdata proxy),
111* or nullptr if 'index' is not a deep userdata proxy. 108* or nullptr if 'index' is not a deep userdata proxy.
112*/ 109*/
113static inline luaG_IdFunction get_idfunc( lua_State* L, int index, LookupMode mode_) 110[[nodiscard]] static inline luaG_IdFunction get_idfunc(lua_State* L, int index, LookupMode mode_)
114{ 111{
115 // when looking inside a keeper, we are 100% sure the object is a deep userdata 112 // when looking inside a keeper, we are 100% sure the object is a deep userdata
116 if (mode_ == LookupMode::FromKeeper) 113 if (mode_ == LookupMode::FromKeeper)
@@ -142,8 +139,9 @@ static inline luaG_IdFunction get_idfunc( lua_State* L, int index, LookupMode mo
142 } 139 }
143} 140}
144 141
142// ################################################################################################
145 143
146void free_deep_prelude( lua_State* L, DeepPrelude* prelude_) 144void free_deep_prelude(lua_State* L, DeepPrelude* prelude_)
147{ 145{
148 ASSERT_L(prelude_->idfunc); 146 ASSERT_L(prelude_->idfunc);
149 STACK_CHECK_START_REL(L, 0); 147 STACK_CHECK_START_REL(L, 0);
@@ -154,6 +152,7 @@ void free_deep_prelude( lua_State* L, DeepPrelude* prelude_)
154 STACK_CHECK(L, 0); 152 STACK_CHECK(L, 0);
155} 153}
156 154
155// ################################################################################################
157 156
158/* 157/*
159 * void= mt.__gc( proxy_ud ) 158 * void= mt.__gc( proxy_ud )
@@ -161,7 +160,7 @@ void free_deep_prelude( lua_State* L, DeepPrelude* prelude_)
161 * End of life for a proxy object; reduce the deep reference count and clean it up if reaches 0. 160 * End of life for a proxy object; reduce the deep reference count and clean it up if reaches 0.
162 * 161 *
163 */ 162 */
164static int deep_userdata_gc( lua_State* L) 163[[nodiscard]] static int deep_userdata_gc(lua_State* L)
165{ 164{
166 DeepPrelude** const proxy{ lua_tofulluserdata<DeepPrelude*>(L, 1) }; 165 DeepPrelude** const proxy{ lua_tofulluserdata<DeepPrelude*>(L, 1) };
167 DeepPrelude* p = *proxy; 166 DeepPrelude* p = *proxy;
@@ -193,6 +192,7 @@ static int deep_userdata_gc( lua_State* L)
193 return 0; 192 return 0;
194} 193}
195 194
195// ################################################################################################
196 196
197/* 197/*
198 * Push a proxy userdata on the stack. 198 * Push a proxy userdata on the stack.
@@ -203,7 +203,7 @@ static int deep_userdata_gc( lua_State* L)
203 * used in this Lua state (metatable, registring it). Otherwise, increments the 203 * used in this Lua state (metatable, registring it). Otherwise, increments the
204 * reference count. 204 * reference count.
205 */ 205 */
206char const* push_deep_proxy(lua_State* L, DeepPrelude* prelude, int nuv_, LookupMode mode_) 206char const* push_deep_proxy(Dest L, DeepPrelude* prelude, int nuv_, LookupMode mode_)
207{ 207{
208 // Check if a proxy already exists 208 // Check if a proxy already exists
209 push_registry_subtable_mode( L, DEEP_PROXY_CACHE_KEY, "v"); // DPC 209 push_registry_subtable_mode( L, DEEP_PROXY_CACHE_KEY, "v"); // DPC
@@ -278,7 +278,7 @@ char const* push_deep_proxy(lua_State* L, DeepPrelude* prelude, int nuv_, Lookup
278 // this is needed because we must make sure the shared library is still loaded as long as we hold a pointer on the idfunc 278 // this is needed because we must make sure the shared library is still loaded as long as we hold a pointer on the idfunc
279 { 279 {
280 int oldtop_module = lua_gettop( L); 280 int oldtop_module = lua_gettop( L);
281 modname = (char const*) prelude->idfunc( L, DeepOp::Module); // DPC proxy metatable 281 modname = (char const*) prelude->idfunc( L, DeepOp::Module); // DPC proxy metatable
282 // make sure the function pushed nothing on the stack! 282 // make sure the function pushed nothing on the stack!
283 if( lua_gettop( L) - oldtop_module != 0) 283 if( lua_gettop( L) - oldtop_module != 0)
284 { 284 {
@@ -348,6 +348,8 @@ char const* push_deep_proxy(lua_State* L, DeepPrelude* prelude, int nuv_, Lookup
348 return nullptr; 348 return nullptr;
349} 349}
350 350
351// ################################################################################################
352
351/* 353/*
352* Create a deep userdata 354* Create a deep userdata
353* 355*
@@ -370,7 +372,7 @@ char const* push_deep_proxy(lua_State* L, DeepPrelude* prelude, int nuv_, Lookup
370* 372*
371* Returns: 'proxy' userdata for accessing the deep data via 'luaG_todeep()' 373* Returns: 'proxy' userdata for accessing the deep data via 'luaG_todeep()'
372*/ 374*/
373int luaG_newdeepuserdata( lua_State* L, luaG_IdFunction idfunc, int nuv_) 375int luaG_newdeepuserdata(Dest L, luaG_IdFunction idfunc, int nuv_)
374{ 376{
375 STACK_GROW( L, 1); 377 STACK_GROW( L, 1);
376 STACK_CHECK_START_REL(L, 0); 378 STACK_CHECK_START_REL(L, 0);
@@ -409,6 +411,7 @@ int luaG_newdeepuserdata( lua_State* L, luaG_IdFunction idfunc, int nuv_)
409 return 1; 411 return 1;
410} 412}
411 413
414// ################################################################################################
412 415
413/* 416/*
414* Access deep userdata through a proxy. 417* Access deep userdata through a proxy.
@@ -430,6 +433,7 @@ DeepPrelude* luaG_todeep(lua_State* L, luaG_IdFunction idfunc, int index)
430 return *proxy; 433 return *proxy;
431} 434}
432 435
436// ################################################################################################
433 437
434/* 438/*
435 * Copy deep userdata between two separate Lua states (from L to L2) 439 * Copy deep userdata between two separate Lua states (from L to L2)
@@ -438,7 +442,7 @@ DeepPrelude* luaG_todeep(lua_State* L, luaG_IdFunction idfunc, int index)
438 * the id function of the copied value, or nullptr for non-deep userdata 442 * the id function of the copied value, or nullptr for non-deep userdata
439 * (not copied) 443 * (not copied)
440 */ 444 */
441bool copydeep(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, int i, LookupMode mode_, char const* upName_) 445bool copydeep(Universe* U, Dest L2, int L2_cache_i, Source L, int i, LookupMode mode_, char const* upName_)
442{ 446{
443 luaG_IdFunction const idfunc { get_idfunc(L, i, mode_) }; 447 luaG_IdFunction const idfunc { get_idfunc(L, i, mode_) };
444 if (idfunc == nullptr) 448 if (idfunc == nullptr)
@@ -466,22 +470,25 @@ bool copydeep(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, int i, L
466 int const clone_i = lua_gettop( L2); 470 int const clone_i = lua_gettop( L2);
467 while( nuv) 471 while( nuv)
468 { 472 {
469 inter_copy_one( U, L2, L2_cache_i, L, lua_absindex( L, -1), VT::NORMAL, mode_, upName_); // u uv 473 if (!inter_copy_one(U, L2, L2_cache_i, L, lua_absindex(L, -1), VT::NORMAL, mode_, upName_)) // u uv
474 {
475 return luaL_error(L, "Cannot copy upvalue type '%s'", luaL_typename(L, -1));
476 }
470 lua_pop( L, 1); // ... u [uv]* 477 lua_pop( L, 1); // ... u [uv]*
471 // this pops the value from the stack 478 // this pops the value from the stack
472 lua_setiuservalue( L2, clone_i, nuv); // u 479 lua_setiuservalue(L2, clone_i, nuv); // u
473 -- nuv; 480 -- nuv;
474 } 481 }
475 } 482 }
476 483
477 STACK_CHECK( L2, 1); 484 STACK_CHECK(L2, 1);
478 STACK_CHECK( L, 0); 485 STACK_CHECK(L, 0);
479 486
480 if (errmsg != nullptr) 487 if (errmsg != nullptr)
481 { 488 {
482 // raise the error in the proper state (not the keeper) 489 // raise the error in the proper state (not the keeper)
483 lua_State* const errL{ (mode_ == LookupMode::FromKeeper) ? L2 : L }; 490 lua_State* const errL{ (mode_ == LookupMode::FromKeeper) ? L2 : L };
484 std::ignore = luaL_error(errL, errmsg); 491 luaL_error(errL, errmsg); // doesn't return
485 } 492 }
486 return true; 493 return true;
487} \ No newline at end of file 494} \ No newline at end of file