diff options
| author | Benoit Germain <benoit.germain@ubisoft.com> | 2024-03-25 10:43:25 +0100 |
|---|---|---|
| committer | Benoit Germain <benoit.germain@ubisoft.com> | 2024-03-25 10:43:25 +0100 |
| commit | 0c060e6e4b9f99dc887b5dfebdae76fcde9524f1 (patch) | |
| tree | 2ba9a1923e3e983375e33aa5f41d9fbc21451832 /src | |
| parent | dad1d5fbf7c7a30caea00694de608c6036789aa5 (diff) | |
| download | lanes-0c060e6e4b9f99dc887b5dfebdae76fcde9524f1.tar.gz lanes-0c060e6e4b9f99dc887b5dfebdae76fcde9524f1.tar.bz2 lanes-0c060e6e4b9f99dc887b5dfebdae76fcde9524f1.zip | |
C++ migration: revamped stack checking macros
Diffstat (limited to 'src')
| -rw-r--r-- | src/deep.cpp | 41 | ||||
| -rw-r--r-- | src/keeper.cpp | 46 | ||||
| -rw-r--r-- | src/lanes.cpp | 107 | ||||
| -rw-r--r-- | src/lanes_private.h | 7 | ||||
| -rw-r--r-- | src/linda.cpp | 16 | ||||
| -rw-r--r-- | src/macros_and_utils.h | 116 | ||||
| -rw-r--r-- | src/state.cpp | 76 | ||||
| -rw-r--r-- | src/tools.cpp | 252 | ||||
| -rw-r--r-- | src/universe.cpp | 18 |
9 files changed, 359 insertions, 320 deletions
diff --git a/src/deep.cpp b/src/deep.cpp index 1aab6ed..cd5a844 100644 --- a/src/deep.cpp +++ b/src/deep.cpp | |||
| @@ -74,16 +74,16 @@ static constexpr UniqueKey DEEP_PROXY_CACHE_KEY{ 0x05773d6fc26be106ull }; | |||
| 74 | static void set_deep_lookup( lua_State* L) | 74 | static void set_deep_lookup( lua_State* L) |
| 75 | { | 75 | { |
| 76 | STACK_GROW( L, 3); | 76 | STACK_GROW( L, 3); |
| 77 | STACK_CHECK( L, 2); // a b | 77 | STACK_CHECK_START_REL(L, 2); // a b |
| 78 | push_registry_subtable( L, DEEP_LOOKUP_KEY); // a b {} | 78 | push_registry_subtable( L, DEEP_LOOKUP_KEY); // a b {} |
| 79 | STACK_MID( L, 3); | 79 | STACK_CHECK( L, 3); |
| 80 | lua_insert( L, -3); // {} a b | 80 | lua_insert( L, -3); // {} a b |
| 81 | lua_pushvalue( L, -1); // {} a b b | 81 | lua_pushvalue( L, -1); // {} a b b |
| 82 | lua_pushvalue( L,-3); // {} a b b a | 82 | lua_pushvalue( L,-3); // {} a b b a |
| 83 | lua_rawset( L, -5); // {} a b | 83 | lua_rawset( L, -5); // {} a b |
| 84 | lua_rawset( L, -3); // {} | 84 | lua_rawset( L, -3); // {} |
| 85 | lua_pop( L, 1); // | 85 | lua_pop( L, 1); // |
| 86 | STACK_END( L, 0); | 86 | STACK_CHECK( L, 0); |
| 87 | } | 87 | } |
| 88 | 88 | ||
| 89 | /* | 89 | /* |
| @@ -93,7 +93,7 @@ static void set_deep_lookup( lua_State* L) | |||
| 93 | static void get_deep_lookup( lua_State* L) | 93 | static void get_deep_lookup( lua_State* L) |
| 94 | { | 94 | { |
| 95 | STACK_GROW( L, 1); | 95 | STACK_GROW( L, 1); |
| 96 | STACK_CHECK( L, 1); // a | 96 | STACK_CHECK_START_REL(L, 1); // a |
| 97 | DEEP_LOOKUP_KEY.query_registry(L); // a {} | 97 | DEEP_LOOKUP_KEY.query_registry(L); // a {} |
| 98 | if( !lua_isnil( L, -1)) | 98 | if( !lua_isnil( L, -1)) |
| 99 | { | 99 | { |
| @@ -101,7 +101,7 @@ static void get_deep_lookup( lua_State* L) | |||
| 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_CHECK( L, 1); |
| 105 | } | 105 | } |
| 106 | 106 | ||
| 107 | /* | 107 | /* |
| @@ -122,9 +122,8 @@ static inline luaG_IdFunction* get_idfunc( lua_State* L, int index, LookupMode m | |||
| 122 | // essentially we are making sure that the metatable of the object we want to copy is stored in our metatable/idfunc database | 122 | // essentially we are making sure that the metatable of the object we want to copy is stored in our metatable/idfunc database |
| 123 | // it is the only way to ensure that the userdata is indeed a deep userdata! | 123 | // it is the only way to ensure that the userdata is indeed a deep userdata! |
| 124 | // of course, we could just trust the caller, but we won't | 124 | // of course, we could just trust the caller, but we won't |
| 125 | luaG_IdFunction* ret; | ||
| 126 | STACK_GROW( L, 1); | 125 | STACK_GROW( L, 1); |
| 127 | STACK_CHECK( L, 0); | 126 | STACK_CHECK_START_REL(L, 0); |
| 128 | 127 | ||
| 129 | if( !lua_getmetatable( L, index)) // deep ... metatable? | 128 | if( !lua_getmetatable( L, index)) // deep ... metatable? |
| 130 | { | 129 | { |
| @@ -134,9 +133,9 @@ static inline luaG_IdFunction* get_idfunc( lua_State* L, int index, LookupMode m | |||
| 134 | // replace metatable with the idfunc pointer, if it is actually a deep userdata | 133 | // replace metatable with the idfunc pointer, if it is actually a deep userdata |
| 135 | get_deep_lookup( L); // deep ... idfunc|nil | 134 | get_deep_lookup( L); // deep ... idfunc|nil |
| 136 | 135 | ||
| 137 | ret = (luaG_IdFunction*) lua_touserdata( L, -1); // nullptr if not a userdata | 136 | luaG_IdFunction* const ret{ static_cast<luaG_IdFunction*>(lua_touserdata(L, -1)) }; // nullptr if not a userdata |
| 138 | lua_pop( L, 1); | 137 | lua_pop( L, 1); |
| 139 | STACK_END( L, 0); | 138 | STACK_CHECK( L, 0); |
| 140 | return ret; | 139 | return ret; |
| 141 | } | 140 | } |
| 142 | } | 141 | } |
| @@ -228,7 +227,7 @@ char const* push_deep_proxy( Universe* U, lua_State* L, DeepPrelude* prelude, in | |||
| 228 | if( U) MUTEX_UNLOCK( &U->deep_lock); | 227 | if( U) MUTEX_UNLOCK( &U->deep_lock); |
| 229 | 228 | ||
| 230 | STACK_GROW( L, 7); | 229 | STACK_GROW( L, 7); |
| 231 | STACK_CHECK( L, 0); | 230 | STACK_CHECK_START_REL(L, 0); |
| 232 | 231 | ||
| 233 | // a new full userdata, fitted with the specified number of uservalue slots (always 1 for Lua < 5.4) | 232 | // a new full userdata, fitted with the specified number of uservalue slots (always 1 for Lua < 5.4) |
| 234 | proxy = (DeepPrelude**) lua_newuserdatauv( L, sizeof(DeepPrelude*), nuv_); // DPC proxy | 233 | proxy = (DeepPrelude**) lua_newuserdatauv( L, sizeof(DeepPrelude*), nuv_); // DPC proxy |
| @@ -340,7 +339,7 @@ char const* push_deep_proxy( Universe* U, lua_State* L, DeepPrelude* prelude, in | |||
| 340 | } | 339 | } |
| 341 | } | 340 | } |
| 342 | } | 341 | } |
| 343 | STACK_MID( L, 2); // DPC proxy metatable | 342 | STACK_CHECK( L, 2); // DPC proxy metatable |
| 344 | ASSERT_L( lua_isuserdata( L, -2)); | 343 | ASSERT_L( lua_isuserdata( L, -2)); |
| 345 | ASSERT_L( lua_istable( L, -1)); | 344 | ASSERT_L( lua_istable( L, -1)); |
| 346 | lua_setmetatable( L, -2); // DPC proxy | 345 | lua_setmetatable( L, -2); // DPC proxy |
| @@ -351,7 +350,7 @@ char const* push_deep_proxy( Universe* U, lua_State* L, DeepPrelude* prelude, in | |||
| 351 | lua_rawset( L, -4); // DPC proxy | 350 | lua_rawset( L, -4); // DPC proxy |
| 352 | lua_remove( L, -2); // proxy | 351 | lua_remove( L, -2); // proxy |
| 353 | ASSERT_L( lua_isuserdata( L, -1)); | 352 | ASSERT_L( lua_isuserdata( L, -1)); |
| 354 | STACK_END( L, 0); | 353 | STACK_CHECK( L, 0); |
| 355 | return nullptr; | 354 | return nullptr; |
| 356 | } | 355 | } |
| 357 | 356 | ||
| @@ -382,7 +381,7 @@ int luaG_newdeepuserdata( lua_State* L, luaG_IdFunction* idfunc, int nuv_) | |||
| 382 | char const* errmsg; | 381 | char const* errmsg; |
| 383 | 382 | ||
| 384 | STACK_GROW( L, 1); | 383 | STACK_GROW( L, 1); |
| 385 | STACK_CHECK( L, 0); | 384 | STACK_CHECK_START_REL(L, 0); |
| 386 | { | 385 | { |
| 387 | int const oldtop = lua_gettop( L); | 386 | int const oldtop = lua_gettop( L); |
| 388 | DeepPrelude* prelude = (DeepPrelude*) idfunc( L, eDO_new); | 387 | DeepPrelude* prelude = (DeepPrelude*) idfunc( L, eDO_new); |
| @@ -413,7 +412,7 @@ int luaG_newdeepuserdata( lua_State* L, luaG_IdFunction* idfunc, int nuv_) | |||
| 413 | return luaL_error( L, errmsg); | 412 | return luaL_error( L, errmsg); |
| 414 | } | 413 | } |
| 415 | } | 414 | } |
| 416 | STACK_END( L, 1); | 415 | STACK_CHECK( L, 1); |
| 417 | return 1; | 416 | return 1; |
| 418 | } | 417 | } |
| 419 | 418 | ||
| @@ -428,7 +427,7 @@ void* luaG_todeep( lua_State* L, luaG_IdFunction* idfunc, int index) | |||
| 428 | { | 427 | { |
| 429 | DeepPrelude** proxy; | 428 | DeepPrelude** proxy; |
| 430 | 429 | ||
| 431 | STACK_CHECK( L, 0); | 430 | STACK_CHECK_START_REL(L, 0); |
| 432 | // ensure it is actually a deep userdata | 431 | // ensure it is actually a deep userdata |
| 433 | if( get_idfunc( L, index, eLM_LaneBody) != idfunc) | 432 | if( get_idfunc( L, index, eLM_LaneBody) != idfunc) |
| 434 | { | 433 | { |
| @@ -436,7 +435,7 @@ void* luaG_todeep( lua_State* L, luaG_IdFunction* idfunc, int index) | |||
| 436 | } | 435 | } |
| 437 | 436 | ||
| 438 | proxy = (DeepPrelude**) lua_touserdata( L, index); | 437 | proxy = (DeepPrelude**) lua_touserdata( L, index); |
| 439 | STACK_END( L, 0); | 438 | STACK_CHECK( L, 0); |
| 440 | 439 | ||
| 441 | return *proxy; | 440 | return *proxy; |
| 442 | } | 441 | } |
| @@ -460,8 +459,8 @@ bool copydeep(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, int i, L | |||
| 460 | return false; // not a deep userdata | 459 | return false; // not a deep userdata |
| 461 | } | 460 | } |
| 462 | 461 | ||
| 463 | STACK_CHECK( L, 0); | 462 | STACK_CHECK_START_REL(L, 0); |
| 464 | STACK_CHECK( L2, 0); | 463 | STACK_CHECK_START_REL(L2, 0); |
| 465 | 464 | ||
| 466 | // extract all uservalues of the source | 465 | // extract all uservalues of the source |
| 467 | while( lua_getiuservalue( L, i, nuv + 1) != LUA_TNONE) // ... u [uv]* nil | 466 | while( lua_getiuservalue( L, i, nuv + 1) != LUA_TNONE) // ... u [uv]* nil |
| @@ -470,7 +469,7 @@ bool copydeep(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, int i, L | |||
| 470 | } | 469 | } |
| 471 | // last call returned TNONE and pushed nil, that we don't need | 470 | // last call returned TNONE and pushed nil, that we don't need |
| 472 | lua_pop( L, 1); // ... u [uv]* | 471 | lua_pop( L, 1); // ... u [uv]* |
| 473 | STACK_MID( L, nuv); | 472 | STACK_CHECK( L, nuv); |
| 474 | 473 | ||
| 475 | errmsg = push_deep_proxy( U, L2, *(DeepPrelude**) lua_touserdata( L, i), nuv, mode_); // u | 474 | errmsg = push_deep_proxy( U, L2, *(DeepPrelude**) lua_touserdata( L, i), nuv, mode_); // u |
| 476 | 475 | ||
| @@ -487,8 +486,8 @@ bool copydeep(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, int i, L | |||
| 487 | } | 486 | } |
| 488 | } | 487 | } |
| 489 | 488 | ||
| 490 | STACK_END( L2, 1); | 489 | STACK_CHECK( L2, 1); |
| 491 | STACK_END( L, 0); | 490 | STACK_CHECK( L, 0); |
| 492 | 491 | ||
| 493 | if (errmsg != nullptr) | 492 | if (errmsg != nullptr) |
| 494 | { | 493 | { |
diff --git a/src/keeper.cpp b/src/keeper.cpp index 0cb1a94..19f6ae1 100644 --- a/src/keeper.cpp +++ b/src/keeper.cpp | |||
| @@ -170,12 +170,12 @@ static constexpr UniqueKey FIFOS_KEY{ 0xdce50bbc351cd465ull }; | |||
| 170 | static void push_table(lua_State* L, int idx_) | 170 | static void push_table(lua_State* L, int idx_) |
| 171 | { | 171 | { |
| 172 | STACK_GROW(L, 4); | 172 | STACK_GROW(L, 4); |
| 173 | STACK_CHECK(L, 0); | 173 | STACK_CHECK_START_REL(L, 0); |
| 174 | idx_ = lua_absindex(L, idx_); | 174 | idx_ = lua_absindex(L, idx_); |
| 175 | FIFOS_KEY.query_registry(L); // ud fifos | 175 | FIFOS_KEY.query_registry(L); // ud fifos |
| 176 | lua_pushvalue(L, idx_); // ud fifos ud | 176 | lua_pushvalue(L, idx_); // ud fifos ud |
| 177 | lua_rawget(L, -2); // ud fifos fifos[ud] | 177 | lua_rawget(L, -2); // ud fifos fifos[ud] |
| 178 | STACK_MID(L, 2); | 178 | STACK_CHECK(L, 2); |
| 179 | if (lua_isnil(L, -1)) | 179 | if (lua_isnil(L, -1)) |
| 180 | { | 180 | { |
| 181 | lua_pop(L, 1); // ud fifos | 181 | lua_pop(L, 1); // ud fifos |
| @@ -186,7 +186,7 @@ static void push_table(lua_State* L, int idx_) | |||
| 186 | lua_rawset(L, -4); // ud fifos fifos[ud] | 186 | lua_rawset(L, -4); // ud fifos fifos[ud] |
| 187 | } | 187 | } |
| 188 | lua_remove(L, -2); // ud fifos[ud] | 188 | lua_remove(L, -2); // ud fifos[ud] |
| 189 | STACK_END(L, 1); | 189 | STACK_CHECK(L, 1); |
| 190 | } | 190 | } |
| 191 | 191 | ||
| 192 | // ################################################################################################## | 192 | // ################################################################################################## |
| @@ -197,7 +197,7 @@ int keeper_push_linda_storage(Universe* U, lua_State* L, void* ptr_, ptrdiff_t m | |||
| 197 | lua_State* const KL = K ? K->L : nullptr; | 197 | lua_State* const KL = K ? K->L : nullptr; |
| 198 | if( KL == nullptr) return 0; | 198 | if( KL == nullptr) return 0; |
| 199 | STACK_GROW(KL, 4); | 199 | STACK_GROW(KL, 4); |
| 200 | STACK_CHECK(KL, 0); | 200 | STACK_CHECK_START_REL(KL, 0); |
| 201 | FIFOS_KEY.query_registry(KL); // fifos | 201 | FIFOS_KEY.query_registry(KL); // fifos |
| 202 | lua_pushlightuserdata(KL, ptr_); // fifos ud | 202 | lua_pushlightuserdata(KL, ptr_); // fifos ud |
| 203 | lua_rawget(KL, -2); // fifos storage | 203 | lua_rawget(KL, -2); // fifos storage |
| @@ -205,38 +205,38 @@ int keeper_push_linda_storage(Universe* U, lua_State* L, void* ptr_, ptrdiff_t m | |||
| 205 | if( !lua_istable(KL, -1)) | 205 | if( !lua_istable(KL, -1)) |
| 206 | { | 206 | { |
| 207 | lua_pop(KL, 1); // | 207 | lua_pop(KL, 1); // |
| 208 | STACK_MID(KL, 0); | 208 | STACK_CHECK(KL, 0); |
| 209 | return 0; | 209 | return 0; |
| 210 | } | 210 | } |
| 211 | // move data from keeper to destination state KEEPER MAIN | 211 | // move data from keeper to destination state KEEPER MAIN |
| 212 | lua_pushnil(KL); // storage nil | 212 | lua_pushnil(KL); // storage nil |
| 213 | STACK_GROW(L, 5); | 213 | STACK_GROW(L, 5); |
| 214 | STACK_CHECK(L, 0); | 214 | STACK_CHECK_START_REL(L, 0); |
| 215 | lua_newtable(L); // out | 215 | lua_newtable(L); // out |
| 216 | while( lua_next(KL, -2)) // storage key fifo | 216 | while( lua_next(KL, -2)) // storage key fifo |
| 217 | { | 217 | { |
| 218 | keeper_fifo* fifo = prepare_fifo_access(KL, -1); // storage key fifo | 218 | keeper_fifo* fifo = prepare_fifo_access(KL, -1); // storage key fifo |
| 219 | lua_pushvalue(KL, -2); // storage key fifo key | 219 | lua_pushvalue(KL, -2); // storage key fifo key |
| 220 | luaG_inter_move(U, KL, L, 1, eLM_FromKeeper); // storage key fifo // out key | 220 | luaG_inter_move(U, KL, L, 1, eLM_FromKeeper); // storage key fifo // out key |
| 221 | STACK_MID(L, 2); | 221 | STACK_CHECK(L, 2); |
| 222 | lua_newtable(L); // out key keyout | 222 | lua_newtable(L); // out key keyout |
| 223 | luaG_inter_move(U, KL, L, 1, eLM_FromKeeper); // storage key // out key keyout fifo | 223 | luaG_inter_move(U, KL, L, 1, eLM_FromKeeper); // storage key // out key keyout fifo |
| 224 | lua_pushinteger(L, fifo->first); // out key keyout fifo first | 224 | lua_pushinteger(L, fifo->first); // out key keyout fifo first |
| 225 | STACK_MID(L, 5); | 225 | STACK_CHECK(L, 5); |
| 226 | lua_setfield(L, -3, "first"); // out key keyout fifo | 226 | lua_setfield(L, -3, "first"); // out key keyout fifo |
| 227 | lua_pushinteger(L, fifo->count); // out key keyout fifo count | 227 | lua_pushinteger(L, fifo->count); // out key keyout fifo count |
| 228 | STACK_MID(L, 5); | 228 | STACK_CHECK(L, 5); |
| 229 | lua_setfield(L, -3, "count"); // out key keyout fifo | 229 | lua_setfield(L, -3, "count"); // out key keyout fifo |
| 230 | lua_pushinteger(L, fifo->limit); // out key keyout fifo limit | 230 | lua_pushinteger(L, fifo->limit); // out key keyout fifo limit |
| 231 | STACK_MID(L, 5); | 231 | STACK_CHECK(L, 5); |
| 232 | lua_setfield(L, -3, "limit"); // out key keyout fifo | 232 | lua_setfield(L, -3, "limit"); // out key keyout fifo |
| 233 | lua_setfield(L, -2, "fifo"); // out key keyout | 233 | lua_setfield(L, -2, "fifo"); // out key keyout |
| 234 | lua_rawset(L, -3); // out | 234 | lua_rawset(L, -3); // out |
| 235 | STACK_MID(L, 1); | 235 | STACK_CHECK(L, 1); |
| 236 | } | 236 | } |
| 237 | STACK_END(L, 1); | 237 | STACK_CHECK(L, 1); |
| 238 | lua_pop(KL, 1); // | 238 | lua_pop(KL, 1); // |
| 239 | STACK_END(KL, 0); | 239 | STACK_CHECK(KL, 0); |
| 240 | return 1; | 240 | return 1; |
| 241 | } | 241 | } |
| 242 | 242 | ||
| @@ -246,13 +246,13 @@ int keeper_push_linda_storage(Universe* U, lua_State* L, void* ptr_, ptrdiff_t m | |||
| 246 | int keepercall_clear(lua_State* L) | 246 | int keepercall_clear(lua_State* L) |
| 247 | { | 247 | { |
| 248 | STACK_GROW(L, 3); | 248 | STACK_GROW(L, 3); |
| 249 | STACK_CHECK(L, 0); | 249 | STACK_CHECK_START_REL(L, 0); |
| 250 | FIFOS_KEY.query_registry(L); // ud fifos | 250 | FIFOS_KEY.query_registry(L); // ud fifos |
| 251 | lua_pushvalue(L, 1); // ud fifos ud | 251 | lua_pushvalue(L, 1); // ud fifos ud |
| 252 | lua_pushnil(L); // ud fifos ud nil | 252 | lua_pushnil(L); // ud fifos ud nil |
| 253 | lua_rawset(L, -3); // ud fifos | 253 | lua_rawset(L, -3); // ud fifos |
| 254 | lua_pop(L, 1); // ud | 254 | lua_pop(L, 1); // ud |
| 255 | STACK_END(L, 0); | 255 | STACK_CHECK(L, 0); |
| 256 | return 0; | 256 | return 0; |
| 257 | } | 257 | } |
| 258 | 258 | ||
| @@ -637,7 +637,7 @@ void close_keepers(Universe* U) | |||
| 637 | */ | 637 | */ |
| 638 | void init_keepers(Universe* U, lua_State* L) | 638 | void init_keepers(Universe* U, lua_State* L) |
| 639 | { | 639 | { |
| 640 | STACK_CHECK(L, 0); // L K | 640 | STACK_CHECK_START_REL(L, 0); // L K |
| 641 | lua_getfield(L, 1, "nb_keepers"); // nb_keepers | 641 | lua_getfield(L, 1, "nb_keepers"); // nb_keepers |
| 642 | int nb_keepers{ static_cast<int>(lua_tointeger(L, -1)) }; | 642 | int nb_keepers{ static_cast<int>(lua_tointeger(L, -1)) }; |
| 643 | lua_pop(L, 1); // | 643 | lua_pop(L, 1); // |
| @@ -677,19 +677,19 @@ void init_keepers(Universe* U, lua_State* L) | |||
| 677 | // therefore, we need a recursive mutex. | 677 | // therefore, we need a recursive mutex. |
| 678 | MUTEX_RECURSIVE_INIT(&U->keepers->keeper_array[i].keeper_cs); | 678 | MUTEX_RECURSIVE_INIT(&U->keepers->keeper_array[i].keeper_cs); |
| 679 | 679 | ||
| 680 | STACK_CHECK(K, 0); | 680 | STACK_CHECK_START_ABS(K, 0); |
| 681 | 681 | ||
| 682 | // copy the universe pointer in the keeper itself | 682 | // copy the universe pointer in the keeper itself |
| 683 | universe_store(K, U); | 683 | universe_store(K, U); |
| 684 | STACK_MID(K, 0); | 684 | STACK_CHECK(K, 0); |
| 685 | 685 | ||
| 686 | // make sure 'package' is initialized in keeper states, so that we have require() | 686 | // make sure 'package' is initialized in keeper states, so that we have require() |
| 687 | // this because this is needed when transferring deep userdata object | 687 | // this because this is needed when transferring deep userdata object |
| 688 | luaL_requiref(K, "package", luaopen_package, 1); // package | 688 | luaL_requiref(K, "package", luaopen_package, 1); // package |
| 689 | lua_pop(K, 1); // | 689 | lua_pop(K, 1); // |
| 690 | STACK_MID(K, 0); | 690 | STACK_CHECK(K, 0); |
| 691 | serialize_require(DEBUGSPEW_PARAM_COMMA(U) K); | 691 | serialize_require(DEBUGSPEW_PARAM_COMMA(U) K); |
| 692 | STACK_MID(K, 0); | 692 | STACK_CHECK(K, 0); |
| 693 | 693 | ||
| 694 | // copy package.path and package.cpath from the source state | 694 | // copy package.path and package.cpath from the source state |
| 695 | lua_getglobal(L, "package"); // "..." keepersUD package | 695 | lua_getglobal(L, "package"); // "..." keepersUD package |
| @@ -705,7 +705,7 @@ void init_keepers(Universe* U, lua_State* L) | |||
| 705 | } | 705 | } |
| 706 | } | 706 | } |
| 707 | lua_pop(L, 1); // | 707 | lua_pop(L, 1); // |
| 708 | STACK_MID(L, 0); | 708 | STACK_CHECK(L, 0); |
| 709 | 709 | ||
| 710 | // attempt to call on_state_create(), if we have one and it is a C function | 710 | // attempt to call on_state_create(), if we have one and it is a C function |
| 711 | // (only support a C function because we can't transfer executable Lua code in keepers) | 711 | // (only support a C function because we can't transfer executable Lua code in keepers) |
| @@ -717,9 +717,9 @@ void init_keepers(Universe* U, lua_State* L) | |||
| 717 | lua_setglobal(K, "decoda_name"); // | 717 | lua_setglobal(K, "decoda_name"); // |
| 718 | // create the fifos table in the keeper state | 718 | // create the fifos table in the keeper state |
| 719 | FIFOS_KEY.set_registry(K, [](lua_State* L) { lua_newtable(L); }); | 719 | FIFOS_KEY.set_registry(K, [](lua_State* L) { lua_newtable(L); }); |
| 720 | STACK_END(K, 0); | 720 | STACK_CHECK(K, 0); |
| 721 | } | 721 | } |
| 722 | STACK_END(L, 0); | 722 | STACK_CHECK(L, 0); |
| 723 | } | 723 | } |
| 724 | 724 | ||
| 725 | // ################################################################################################## | 725 | // ################################################################################################## |
diff --git a/src/lanes.cpp b/src/lanes.cpp index 38dd92c..6123766 100644 --- a/src/lanes.cpp +++ b/src/lanes.cpp | |||
| @@ -113,7 +113,7 @@ THE SOFTWARE. | |||
| 113 | // intern the debug name in the specified lua state so that the pointer remains valid when the lane's state is closed | 113 | // intern the debug name in the specified lua state so that the pointer remains valid when the lane's state is closed |
| 114 | static void securize_debug_threadname( lua_State* L, Lane* s) | 114 | static void securize_debug_threadname( lua_State* L, Lane* s) |
| 115 | { | 115 | { |
| 116 | STACK_CHECK( L, 0); | 116 | STACK_CHECK_START_REL(L, 0); |
| 117 | STACK_GROW( L, 3); | 117 | STACK_GROW( L, 3); |
| 118 | lua_getiuservalue( L, 1, 1); | 118 | lua_getiuservalue( L, 1, 1); |
| 119 | lua_newtable( L); | 119 | lua_newtable( L); |
| @@ -122,7 +122,7 @@ static void securize_debug_threadname( lua_State* L, Lane* s) | |||
| 122 | s->debug_name = lua_tostring( L, -1); | 122 | s->debug_name = lua_tostring( L, -1); |
| 123 | lua_rawset( L, -3); | 123 | lua_rawset( L, -3); |
| 124 | lua_pop( L, 1); | 124 | lua_pop( L, 1); |
| 125 | STACK_END( L, 0); | 125 | STACK_CHECK( L, 0); |
| 126 | } | 126 | } |
| 127 | 127 | ||
| 128 | #if ERROR_FULL_STACK | 128 | #if ERROR_FULL_STACK |
| @@ -155,12 +155,13 @@ struct s_Linda; | |||
| 155 | static bool push_registry_table( lua_State* L, UniqueKey key, bool create) | 155 | static bool push_registry_table( lua_State* L, UniqueKey key, bool create) |
| 156 | { | 156 | { |
| 157 | STACK_GROW( L, 3); | 157 | STACK_GROW( L, 3); |
| 158 | STACK_CHECK( L, 0); | 158 | STACK_CHECK_START_REL(L, 0); |
| 159 | 159 | ||
| 160 | key.query_registry(L); // ? | 160 | key.query_registry(L); // ? |
| 161 | if( lua_isnil( L, -1)) // nil? | 161 | if( lua_isnil( L, -1)) // nil? |
| 162 | { | 162 | { |
| 163 | lua_pop( L, 1); // | 163 | lua_pop( L, 1); // |
| 164 | STACK_CHECK(L, 0); | ||
| 164 | 165 | ||
| 165 | if( !create) | 166 | if( !create) |
| 166 | { | 167 | { |
| @@ -170,7 +171,7 @@ static bool push_registry_table( lua_State* L, UniqueKey key, bool create) | |||
| 170 | lua_newtable( L); // t | 171 | lua_newtable( L); // t |
| 171 | key.set_registry(L, [](lua_State* L) { lua_pushvalue(L, -2); }); | 172 | key.set_registry(L, [](lua_State* L) { lua_pushvalue(L, -2); }); |
| 172 | } | 173 | } |
| 173 | STACK_END( L, 1); | 174 | STACK_CHECK( L, 1); |
| 174 | return true; // table pushed | 175 | return true; // table pushed |
| 175 | } | 176 | } |
| 176 | 177 | ||
| @@ -675,11 +676,8 @@ done: | |||
| 675 | 676 | ||
| 676 | static int lane_error( lua_State* L) | 677 | static int lane_error( lua_State* L) |
| 677 | { | 678 | { |
| 678 | lua_Debug ar; | ||
| 679 | int n; | ||
| 680 | |||
| 681 | // error message (any type) | 679 | // error message (any type) |
| 682 | STACK_CHECK_ABS( L, 1); // some_error | 680 | STACK_CHECK_START_ABS(L, 1); // some_error |
| 683 | 681 | ||
| 684 | // Don't do stack survey for cancelled lanes. | 682 | // Don't do stack survey for cancelled lanes. |
| 685 | // | 683 | // |
| @@ -692,6 +690,7 @@ static int lane_error( lua_State* L) | |||
| 692 | EXTENDED_STACKTRACE_REGKEY.query_registry(L); // some_error basic|extended | 690 | EXTENDED_STACKTRACE_REGKEY.query_registry(L); // some_error basic|extended |
| 693 | bool const extended{ lua_toboolean(L, -1) ? true : false}; | 691 | bool const extended{ lua_toboolean(L, -1) ? true : false}; |
| 694 | lua_pop( L, 1); // some_error | 692 | lua_pop( L, 1); // some_error |
| 693 | STACK_CHECK(L, 1); | ||
| 695 | 694 | ||
| 696 | // Place stack trace at 'registry[STACKTRACE_REGKEY]' for the 'lua_pcall()' | 695 | // Place stack trace at 'registry[STACKTRACE_REGKEY]' for the 'lua_pcall()' |
| 697 | // caller to fetch. This bypasses the Lua 5.1 limitation of only one | 696 | // caller to fetch. This bypasses the Lua 5.1 limitation of only one |
| @@ -709,7 +708,8 @@ static int lane_error( lua_State* L) | |||
| 709 | // and we don't get '.currentline' for that. It's okay - just keep level | 708 | // and we don't get '.currentline' for that. It's okay - just keep level |
| 710 | // and table index growing separate. --AKa 22-Jan-2009 | 709 | // and table index growing separate. --AKa 22-Jan-2009 |
| 711 | // | 710 | // |
| 712 | for( n = 1; lua_getstack( L, n, &ar); ++ n) | 711 | lua_Debug ar; |
| 712 | for (int n = 1; lua_getstack(L, n, &ar); ++n) | ||
| 713 | { | 713 | { |
| 714 | lua_getinfo( L, extended ? "Sln" : "Sl", &ar); | 714 | lua_getinfo( L, extended ? "Sln" : "Sl", &ar); |
| 715 | if( extended) | 715 | if( extended) |
| @@ -745,8 +745,8 @@ static int lane_error( lua_State* L) | |||
| 745 | // store the stack trace table in the registry | 745 | // store the stack trace table in the registry |
| 746 | STACKTRACE_REGKEY.set_registry(L, [](lua_State* L) { lua_insert(L, -2); }); // some_error | 746 | STACKTRACE_REGKEY.set_registry(L, [](lua_State* L) { lua_insert(L, -2); }); // some_error |
| 747 | 747 | ||
| 748 | STACK_END( L, 1); | 748 | STACK_CHECK(L, 1); |
| 749 | return 1; // the untouched error value | 749 | return 1; // the untouched error value |
| 750 | } | 750 | } |
| 751 | #endif // ERROR_FULL_STACK | 751 | #endif // ERROR_FULL_STACK |
| 752 | 752 | ||
| @@ -761,12 +761,12 @@ static void push_stack_trace( lua_State* L, int rc_, int stk_base_) | |||
| 761 | case LUA_ERRRUN: // cancellation or a runtime error | 761 | case LUA_ERRRUN: // cancellation or a runtime error |
| 762 | #if ERROR_FULL_STACK // when ERROR_FULL_STACK, we installed a handler | 762 | #if ERROR_FULL_STACK // when ERROR_FULL_STACK, we installed a handler |
| 763 | { | 763 | { |
| 764 | STACK_CHECK( L, 0); | 764 | STACK_CHECK_START_REL(L, 0); |
| 765 | // fetch the call stack table from the registry where the handler stored it | 765 | // fetch the call stack table from the registry where the handler stored it |
| 766 | STACK_GROW( L, 1); | 766 | STACK_GROW( L, 1); |
| 767 | // yields nil if no stack was generated (in case of cancellation for example) | 767 | // yields nil if no stack was generated (in case of cancellation for example) |
| 768 | STACKTRACE_REGKEY.query_registry(L); // err trace|nil | 768 | STACKTRACE_REGKEY.query_registry(L); // err trace|nil |
| 769 | STACK_END( L, 1); | 769 | STACK_CHECK( L, 1); |
| 770 | 770 | ||
| 771 | // For cancellation the error message is CANCEL_ERROR, and a stack trace isn't placed | 771 | // For cancellation the error message is CANCEL_ERROR, and a stack trace isn't placed |
| 772 | // For other errors, the message can be whatever was thrown, and we should have a stack trace table | 772 | // For other errors, the message can be whatever was thrown, and we should have a stack trace table |
| @@ -793,16 +793,16 @@ LUAG_FUNC( set_debug_threadname) | |||
| 793 | Lane* s = (Lane*) lua_touserdata( L, lua_upvalueindex( 1)); | 793 | Lane* s = (Lane*) lua_touserdata( L, lua_upvalueindex( 1)); |
| 794 | luaL_checktype( L, -1, LUA_TSTRING); // "name" | 794 | luaL_checktype( L, -1, LUA_TSTRING); // "name" |
| 795 | lua_settop( L, 1); | 795 | lua_settop( L, 1); |
| 796 | STACK_CHECK_ABS( L, 1); | 796 | STACK_CHECK_START_ABS( L, 1); |
| 797 | // store a hidden reference in the registry to make sure the string is kept around even if a lane decides to manually change the "decoda_name" global... | 797 | // store a hidden reference in the registry to make sure the string is kept around even if a lane decides to manually change the "decoda_name" global... |
| 798 | hidden_regkey.set_registry(L, [](lua_State* L) { lua_pushvalue(L, -2); }); | 798 | hidden_regkey.set_registry(L, [](lua_State* L) { lua_pushvalue(L, -2); }); |
| 799 | STACK_MID( L, 1); | 799 | STACK_CHECK( L, 1); |
| 800 | s->debug_name = lua_tostring( L, -1); | 800 | s->debug_name = lua_tostring( L, -1); |
| 801 | // keep a direct pointer on the string | 801 | // keep a direct pointer on the string |
| 802 | THREAD_SETNAME( s->debug_name); | 802 | THREAD_SETNAME( s->debug_name); |
| 803 | // to see VM name in Decoda debugger Virtual Machine window | 803 | // to see VM name in Decoda debugger Virtual Machine window |
| 804 | lua_setglobal( L, "decoda_name"); // | 804 | lua_setglobal( L, "decoda_name"); // |
| 805 | STACK_END( L, 0); | 805 | STACK_CHECK( L, 0); |
| 806 | return 0; | 806 | return 0; |
| 807 | } | 807 | } |
| 808 | 808 | ||
| @@ -990,7 +990,7 @@ LUAG_FUNC( require) | |||
| 990 | char const* name = lua_tostring( L, 1); | 990 | char const* name = lua_tostring( L, 1); |
| 991 | int const nargs = lua_gettop( L); | 991 | int const nargs = lua_gettop( L); |
| 992 | DEBUGSPEW_CODE( Universe* U = universe_get( L)); | 992 | DEBUGSPEW_CODE( Universe* U = universe_get( L)); |
| 993 | STACK_CHECK( L, 0); | 993 | STACK_CHECK_START_REL(L, 0); |
| 994 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "lanes.require %s BEGIN\n" INDENT_END, name)); | 994 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "lanes.require %s BEGIN\n" INDENT_END, name)); |
| 995 | DEBUGSPEW_CODE( ++ U->debugspew_indent_depth); | 995 | DEBUGSPEW_CODE( ++ U->debugspew_indent_depth); |
| 996 | lua_pushvalue( L, lua_upvalueindex(1)); // "name" require | 996 | lua_pushvalue( L, lua_upvalueindex(1)); // "name" require |
| @@ -999,7 +999,7 @@ LUAG_FUNC( require) | |||
| 999 | populate_func_lookup_table( L, -1, name); | 999 | populate_func_lookup_table( L, -1, name); |
| 1000 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "lanes.require %s END\n" INDENT_END, name)); | 1000 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "lanes.require %s END\n" INDENT_END, name)); |
| 1001 | DEBUGSPEW_CODE( -- U->debugspew_indent_depth); | 1001 | DEBUGSPEW_CODE( -- U->debugspew_indent_depth); |
| 1002 | STACK_END( L, 0); | 1002 | STACK_CHECK( L, 0); |
| 1003 | return 1; | 1003 | return 1; |
| 1004 | } | 1004 | } |
| 1005 | 1005 | ||
| @@ -1015,13 +1015,13 @@ LUAG_FUNC( register) | |||
| 1015 | lua_settop( L, 2); | 1015 | lua_settop( L, 2); |
| 1016 | luaL_argcheck( L, (mod_type == LUA_TTABLE) || (mod_type == LUA_TFUNCTION), 2, "unexpected module type"); | 1016 | luaL_argcheck( L, (mod_type == LUA_TTABLE) || (mod_type == LUA_TFUNCTION), 2, "unexpected module type"); |
| 1017 | DEBUGSPEW_CODE( Universe* U = universe_get( L)); | 1017 | DEBUGSPEW_CODE( Universe* U = universe_get( L)); |
| 1018 | STACK_CHECK( L, 0); // "name" mod_table | 1018 | STACK_CHECK_START_REL(L, 0); // "name" mod_table |
| 1019 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "lanes.register %s BEGIN\n" INDENT_END, name)); | 1019 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "lanes.register %s BEGIN\n" INDENT_END, name)); |
| 1020 | DEBUGSPEW_CODE( ++ U->debugspew_indent_depth); | 1020 | DEBUGSPEW_CODE( ++ U->debugspew_indent_depth); |
| 1021 | populate_func_lookup_table( L, -1, name); | 1021 | populate_func_lookup_table( L, -1, name); |
| 1022 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "lanes.register %s END\n" INDENT_END, name)); | 1022 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "lanes.register %s END\n" INDENT_END, name)); |
| 1023 | DEBUGSPEW_CODE( -- U->debugspew_indent_depth); | 1023 | DEBUGSPEW_CODE( -- U->debugspew_indent_depth); |
| 1024 | STACK_END( L, 0); | 1024 | STACK_CHECK( L, 0); |
| 1025 | return 0; | 1025 | return 0; |
| 1026 | } | 1026 | } |
| 1027 | 1027 | ||
| @@ -1075,10 +1075,10 @@ LUAG_FUNC( lane_new) | |||
| 1075 | L2 = luaG_newstate( U, L, libs_str); // L // L2 | 1075 | L2 = luaG_newstate( U, L, libs_str); // L // L2 |
| 1076 | 1076 | ||
| 1077 | STACK_GROW( L2, nargs + 3); // | 1077 | STACK_GROW( L2, nargs + 3); // |
| 1078 | STACK_CHECK( L2, 0); | 1078 | STACK_CHECK_START_REL(L2, 0); |
| 1079 | 1079 | ||
| 1080 | STACK_GROW( L, 3); // func libs priority globals package required gc_cb [... args ...] | 1080 | STACK_GROW( L, 3); // func libs priority globals package required gc_cb [... args ...] |
| 1081 | STACK_CHECK( L, 0); | 1081 | STACK_CHECK_START_REL(L, 0); |
| 1082 | 1082 | ||
| 1083 | // give a default "Lua" name to the thread to see VM name in Decoda debugger | 1083 | // give a default "Lua" name to the thread to see VM name in Decoda debugger |
| 1084 | lua_pushfstring( L2, "Lane #%p", L2); // "..." | 1084 | lua_pushfstring( L2, "Lane #%p", L2); // "..." |
| @@ -1146,8 +1146,8 @@ LUAG_FUNC( lane_new) | |||
| 1146 | } // func libs priority globals package required gc_cb [... args ...] | 1146 | } // func libs priority globals package required gc_cb [... args ...] |
| 1147 | DEBUGSPEW_CODE( -- U->debugspew_indent_depth); | 1147 | DEBUGSPEW_CODE( -- U->debugspew_indent_depth); |
| 1148 | } | 1148 | } |
| 1149 | STACK_MID( L, 0); | 1149 | STACK_CHECK( L, 0); |
| 1150 | STACK_MID( L2, 0); // | 1150 | STACK_CHECK( L2, 0); // |
| 1151 | 1151 | ||
| 1152 | // Appending the specified globals to the global environment | 1152 | // Appending the specified globals to the global environment |
| 1153 | // *after* stdlibs have been loaded and modules required, in case we transfer references to native functions they exposed... | 1153 | // *after* stdlibs have been loaded and modules required, in case we transfer references to native functions they exposed... |
| @@ -1175,8 +1175,8 @@ LUAG_FUNC( lane_new) | |||
| 1175 | 1175 | ||
| 1176 | DEBUGSPEW_CODE( -- U->debugspew_indent_depth); | 1176 | DEBUGSPEW_CODE( -- U->debugspew_indent_depth); |
| 1177 | } | 1177 | } |
| 1178 | STACK_MID( L, 0); | 1178 | STACK_CHECK( L, 0); |
| 1179 | STACK_MID( L2, 0); | 1179 | STACK_CHECK( L2, 0); |
| 1180 | 1180 | ||
| 1181 | // Lane main function | 1181 | // Lane main function |
| 1182 | if( lua_type( L, 1) == LUA_TFUNCTION) | 1182 | if( lua_type( L, 1) == LUA_TFUNCTION) |
| @@ -1200,8 +1200,8 @@ LUAG_FUNC( lane_new) | |||
| 1200 | return luaL_error( L, "error when parsing lane function code"); | 1200 | return luaL_error( L, "error when parsing lane function code"); |
| 1201 | } | 1201 | } |
| 1202 | } | 1202 | } |
| 1203 | STACK_MID( L, 0); | 1203 | STACK_CHECK( L, 0); |
| 1204 | STACK_MID( L2, 1); | 1204 | STACK_CHECK( L2, 1); |
| 1205 | ASSERT_L( lua_isfunction( L2, 1)); | 1205 | ASSERT_L( lua_isfunction( L2, 1)); |
| 1206 | 1206 | ||
| 1207 | // revive arguments | 1207 | // revive arguments |
| @@ -1217,10 +1217,10 @@ LUAG_FUNC( lane_new) | |||
| 1217 | return luaL_error( L, "tried to copy unsupported types"); | 1217 | return luaL_error( L, "tried to copy unsupported types"); |
| 1218 | } | 1218 | } |
| 1219 | } | 1219 | } |
| 1220 | STACK_END( L, -nargs); | 1220 | STACK_CHECK( L, -nargs); |
| 1221 | ASSERT_L( lua_gettop( L) == FIXED_ARGS); | 1221 | ASSERT_L( lua_gettop( L) == FIXED_ARGS); |
| 1222 | STACK_CHECK( L, 0); | 1222 | STACK_CHECK_RESET_REL(L, 0); |
| 1223 | STACK_MID( L2, 1 + nargs); | 1223 | STACK_CHECK( L2, 1 + nargs); |
| 1224 | 1224 | ||
| 1225 | // 's' is allocated from heap, not Lua, since its life span may surpass the handle's (if free running thread) | 1225 | // 's' is allocated from heap, not Lua, since its life span may surpass the handle's (if free running thread) |
| 1226 | // | 1226 | // |
| @@ -1260,7 +1260,7 @@ LUAG_FUNC( lane_new) | |||
| 1260 | // | 1260 | // |
| 1261 | lua_pushvalue( L, lua_upvalueindex( 1)); // func libs priority globals package required gc_cb lane mt | 1261 | lua_pushvalue( L, lua_upvalueindex( 1)); // func libs priority globals package required gc_cb lane mt |
| 1262 | lua_setmetatable( L, -2); // func libs priority globals package required gc_cb lane | 1262 | lua_setmetatable( L, -2); // func libs priority globals package required gc_cb lane |
| 1263 | STACK_MID( L, 1); | 1263 | STACK_CHECK( L, 1); |
| 1264 | 1264 | ||
| 1265 | // Create uservalue for the userdata | 1265 | // Create uservalue for the userdata |
| 1266 | // (this is where lane body return values will be stored when the handle is indexed by a numeric key) | 1266 | // (this is where lane body return values will be stored when the handle is indexed by a numeric key) |
| @@ -1279,8 +1279,8 @@ LUAG_FUNC( lane_new) | |||
| 1279 | // Store 's' in the lane's registry, for 'cancel_test()' (we do cancel tests at pending send/receive). | 1279 | // Store 's' in the lane's registry, for 'cancel_test()' (we do cancel tests at pending send/receive). |
| 1280 | CANCEL_TEST_KEY.set_registry(L2, [s](lua_State* L) { lua_pushlightuserdata(L, s); }); // func [... args ...] | 1280 | CANCEL_TEST_KEY.set_registry(L2, [s](lua_State* L) { lua_pushlightuserdata(L, s); }); // func [... args ...] |
| 1281 | 1281 | ||
| 1282 | STACK_END( L, 1); | 1282 | STACK_CHECK( L, 1); |
| 1283 | STACK_END( L2, 1 + nargs); | 1283 | STACK_CHECK( L2, 1 + nargs); |
| 1284 | 1284 | ||
| 1285 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "lane_new: launching thread\n" INDENT_END)); | 1285 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "lane_new: launching thread\n" INDENT_END)); |
| 1286 | THREAD_CREATE( &s->thread, lane_main, s, priority); | 1286 | THREAD_CREATE( &s->thread, lane_main, s, priority); |
| @@ -1436,7 +1436,7 @@ LUAG_FUNC( thread_join) | |||
| 1436 | return 2; | 1436 | return 2; |
| 1437 | } | 1437 | } |
| 1438 | 1438 | ||
| 1439 | STACK_CHECK( L, 0); | 1439 | STACK_CHECK_START_REL(L, 0); |
| 1440 | // Thread is DONE/ERROR_ST/CANCELLED; all ours now | 1440 | // Thread is DONE/ERROR_ST/CANCELLED; all ours now |
| 1441 | 1441 | ||
| 1442 | if (s->mstatus == ThreadStatus::Killed) // OS thread was killed if thread_cancel was forced | 1442 | if (s->mstatus == ThreadStatus::Killed) // OS thread was killed if thread_cancel was forced |
| @@ -1492,7 +1492,7 @@ LUAG_FUNC( thread_join) | |||
| 1492 | lua_close( L2); | 1492 | lua_close( L2); |
| 1493 | } | 1493 | } |
| 1494 | s->L = 0; | 1494 | s->L = 0; |
| 1495 | STACK_END( L, ret); | 1495 | STACK_CHECK( L, ret); |
| 1496 | return ret; | 1496 | return ret; |
| 1497 | } | 1497 | } |
| 1498 | 1498 | ||
| @@ -1723,7 +1723,7 @@ LUAG_FUNC( wakeup_conv ) | |||
| 1723 | // .yday (day of the year) | 1723 | // .yday (day of the year) |
| 1724 | // .isdst (daylight saving on/off) | 1724 | // .isdst (daylight saving on/off) |
| 1725 | 1725 | ||
| 1726 | STACK_CHECK( L, 0); | 1726 | STACK_CHECK_START_REL(L, 0); |
| 1727 | lua_getfield( L, 1, "year" ); year= (int)lua_tointeger(L,-1); lua_pop(L,1); | 1727 | lua_getfield( L, 1, "year" ); year= (int)lua_tointeger(L,-1); lua_pop(L,1); |
| 1728 | lua_getfield( L, 1, "month" ); month= (int)lua_tointeger(L,-1); lua_pop(L,1); | 1728 | lua_getfield( L, 1, "month" ); month= (int)lua_tointeger(L,-1); lua_pop(L,1); |
| 1729 | lua_getfield( L, 1, "day" ); day= (int)lua_tointeger(L,-1); lua_pop(L,1); | 1729 | lua_getfield( L, 1, "day" ); day= (int)lua_tointeger(L,-1); lua_pop(L,1); |
| @@ -1737,7 +1737,7 @@ LUAG_FUNC( wakeup_conv ) | |||
| 1737 | lua_getfield( L, 1, "isdst" ); | 1737 | lua_getfield( L, 1, "isdst" ); |
| 1738 | isdst= lua_isboolean(L,-1) ? lua_toboolean(L,-1) : -1; | 1738 | isdst= lua_isboolean(L,-1) ? lua_toboolean(L,-1) : -1; |
| 1739 | lua_pop(L,1); | 1739 | lua_pop(L,1); |
| 1740 | STACK_END( L, 0); | 1740 | STACK_CHECK( L, 0); |
| 1741 | 1741 | ||
| 1742 | t.tm_year= year-1900; | 1742 | t.tm_year= year-1900; |
| 1743 | t.tm_mon= month-1; // 0..11 | 1743 | t.tm_mon= month-1; // 0..11 |
| @@ -1863,7 +1863,7 @@ LUAG_FUNC( configure) | |||
| 1863 | #endif // THREADAPI == THREADAPI_PTHREAD | 1863 | #endif // THREADAPI == THREADAPI_PTHREAD |
| 1864 | 1864 | ||
| 1865 | STACK_GROW( L, 4); | 1865 | STACK_GROW( L, 4); |
| 1866 | STACK_CHECK_ABS( L, 1); // settings | 1866 | STACK_CHECK_START_ABS( L, 1); // settings |
| 1867 | 1867 | ||
| 1868 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "%p: lanes.configure() BEGIN\n" INDENT_END, L)); | 1868 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "%p: lanes.configure() BEGIN\n" INDENT_END, L)); |
| 1869 | DEBUGSPEW_CODE( if( U) ++ U->debugspew_indent_depth); | 1869 | DEBUGSPEW_CODE( if( U) ++ U->debugspew_indent_depth); |
| @@ -1900,13 +1900,13 @@ LUAG_FUNC( configure) | |||
| 1900 | initialize_allocator_function( U, L); | 1900 | initialize_allocator_function( U, L); |
| 1901 | initialize_on_state_create( U, L); | 1901 | initialize_on_state_create( U, L); |
| 1902 | init_keepers( U, L); | 1902 | init_keepers( U, L); |
| 1903 | STACK_MID( L, 1); | 1903 | STACK_CHECK( L, 1); |
| 1904 | 1904 | ||
| 1905 | // Initialize 'timer_deep'; a common Linda object shared by all states | 1905 | // Initialize 'timer_deep'; a common Linda object shared by all states |
| 1906 | lua_pushcfunction( L, LG_linda); // settings lanes.linda | 1906 | lua_pushcfunction( L, LG_linda); // settings lanes.linda |
| 1907 | lua_pushliteral( L, "lanes-timer"); // settings lanes.linda "lanes-timer" | 1907 | lua_pushliteral( L, "lanes-timer"); // settings lanes.linda "lanes-timer" |
| 1908 | lua_call( L, 1, 1); // settings linda | 1908 | lua_call( L, 1, 1); // settings linda |
| 1909 | STACK_MID( L, 2); | 1909 | STACK_CHECK( L, 2); |
| 1910 | 1910 | ||
| 1911 | // Proxy userdata contents is only a 'DEEP_PRELUDE*' pointer | 1911 | // Proxy userdata contents is only a 'DEEP_PRELUDE*' pointer |
| 1912 | U->timer_deep = *(DeepPrelude**) lua_touserdata( L, -1); | 1912 | U->timer_deep = *(DeepPrelude**) lua_touserdata( L, -1); |
| @@ -1914,7 +1914,7 @@ LUAG_FUNC( configure) | |||
| 1914 | ++ U->timer_deep->refcount; | 1914 | ++ U->timer_deep->refcount; |
| 1915 | lua_pop( L, 1); // settings | 1915 | lua_pop( L, 1); // settings |
| 1916 | } | 1916 | } |
| 1917 | STACK_MID( L, 1); | 1917 | STACK_CHECK( L, 1); |
| 1918 | 1918 | ||
| 1919 | // Serialize calls to 'require' from now on, also in the primary state | 1919 | // Serialize calls to 'require' from now on, also in the primary state |
| 1920 | serialize_require( DEBUGSPEW_PARAM_COMMA( U) L); | 1920 | serialize_require( DEBUGSPEW_PARAM_COMMA( U) L); |
| @@ -1934,7 +1934,7 @@ LUAG_FUNC( configure) | |||
| 1934 | lua_setfield( L, -2, "threads"); // settings M | 1934 | lua_setfield( L, -2, "threads"); // settings M |
| 1935 | } | 1935 | } |
| 1936 | #endif // HAVE_LANE_TRACKING() | 1936 | #endif // HAVE_LANE_TRACKING() |
| 1937 | STACK_MID( L, 2); | 1937 | STACK_CHECK( L, 2); |
| 1938 | 1938 | ||
| 1939 | { | 1939 | { |
| 1940 | char const* errmsg; | 1940 | char const* errmsg; |
| @@ -1945,7 +1945,7 @@ LUAG_FUNC( configure) | |||
| 1945 | } | 1945 | } |
| 1946 | lua_setfield( L, -2, "timer_gateway"); // settings M | 1946 | lua_setfield( L, -2, "timer_gateway"); // settings M |
| 1947 | } | 1947 | } |
| 1948 | STACK_MID( L, 2); | 1948 | STACK_CHECK( L, 2); |
| 1949 | 1949 | ||
| 1950 | // prepare the metatable for threads | 1950 | // prepare the metatable for threads |
| 1951 | // contains keys: { __gc, __index, cached_error, cached_tostring, cancel, join, get_debug_threadname } | 1951 | // contains keys: { __gc, __index, cached_error, cached_tostring, cancel, join, get_debug_threadname } |
| @@ -1992,16 +1992,16 @@ LUAG_FUNC( configure) | |||
| 1992 | CANCEL_ERROR.push(L); // settings M CANCEL_ERROR | 1992 | CANCEL_ERROR.push(L); // settings M CANCEL_ERROR |
| 1993 | lua_setfield( L, -2, "cancel_error"); // settings M | 1993 | lua_setfield( L, -2, "cancel_error"); // settings M |
| 1994 | 1994 | ||
| 1995 | STACK_MID( L, 2); // reference stack contains only the function argument 'settings' | 1995 | STACK_CHECK( L, 2); // reference stack contains only the function argument 'settings' |
| 1996 | // we'll need this every time we transfer some C function from/to this state | 1996 | // we'll need this every time we transfer some C function from/to this state |
| 1997 | LOOKUP_REGKEY.set_registry(L, [](lua_State* L) { lua_newtable(L); }); // settings M | 1997 | LOOKUP_REGKEY.set_registry(L, [](lua_State* L) { lua_newtable(L); }); // settings M |
| 1998 | STACK_MID( L, 2); | 1998 | STACK_CHECK( L, 2); |
| 1999 | 1999 | ||
| 2000 | // register all native functions found in that module in the transferable functions database | 2000 | // register all native functions found in that module in the transferable functions database |
| 2001 | // we process it before _G because we don't want to find the module when scanning _G (this would generate longer names) | 2001 | // we process it before _G because we don't want to find the module when scanning _G (this would generate longer names) |
| 2002 | // for example in package.loaded["lanes.core"].* | 2002 | // for example in package.loaded["lanes.core"].* |
| 2003 | populate_func_lookup_table( L, -1, name); | 2003 | populate_func_lookup_table( L, -1, name); |
| 2004 | STACK_MID( L, 2); | 2004 | STACK_CHECK( L, 2); |
| 2005 | 2005 | ||
| 2006 | // record all existing C/JIT-fast functions | 2006 | // record all existing C/JIT-fast functions |
| 2007 | // Lua 5.2 no longer has LUA_GLOBALSINDEX: we must push globals table on the stack | 2007 | // Lua 5.2 no longer has LUA_GLOBALSINDEX: we must push globals table on the stack |
| @@ -2018,7 +2018,7 @@ LUAG_FUNC( configure) | |||
| 2018 | 2018 | ||
| 2019 | // set _R[CONFIG_REGKEY] = settings | 2019 | // set _R[CONFIG_REGKEY] = settings |
| 2020 | CONFIG_REGKEY.set_registry(L, [](lua_State* L) { lua_pushvalue(L, -2); }); | 2020 | CONFIG_REGKEY.set_registry(L, [](lua_State* L) { lua_pushvalue(L, -2); }); |
| 2021 | STACK_END( L, 1); | 2021 | STACK_CHECK( L, 1); |
| 2022 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "%p: lanes.configure() END\n" INDENT_END, L)); | 2022 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "%p: lanes.configure() END\n" INDENT_END, L)); |
| 2023 | DEBUGSPEW_CODE( -- U->debugspew_indent_depth); | 2023 | DEBUGSPEW_CODE( -- U->debugspew_indent_depth); |
| 2024 | // Return the settings table | 2024 | // Return the settings table |
| @@ -2085,7 +2085,7 @@ LANES_API int luaopen_lanes_core( lua_State* L) | |||
| 2085 | #endif // defined PLATFORM_WIN32 && !defined NDEBUG | 2085 | #endif // defined PLATFORM_WIN32 && !defined NDEBUG |
| 2086 | 2086 | ||
| 2087 | STACK_GROW( L, 4); | 2087 | STACK_GROW( L, 4); |
| 2088 | STACK_CHECK( L, 0); | 2088 | STACK_CHECK_START_REL(L, 0); |
| 2089 | 2089 | ||
| 2090 | // Prevent PUC-Lua/LuaJIT mismatch. Hopefully this works for MoonJIT too | 2090 | // Prevent PUC-Lua/LuaJIT mismatch. Hopefully this works for MoonJIT too |
| 2091 | lua_getglobal( L, "jit"); // {jit?} | 2091 | lua_getglobal( L, "jit"); // {jit?} |
| @@ -2097,6 +2097,7 @@ LANES_API int luaopen_lanes_core( lua_State* L) | |||
| 2097 | return luaL_error( L, "Lanes is built for LuaJIT, don't run from PUC-Lua"); | 2097 | return luaL_error( L, "Lanes is built for LuaJIT, don't run from PUC-Lua"); |
| 2098 | #endif | 2098 | #endif |
| 2099 | lua_pop( L, 1); // | 2099 | lua_pop( L, 1); // |
| 2100 | STACK_CHECK(L, 0); | ||
| 2100 | 2101 | ||
| 2101 | // Create main module interface table | 2102 | // Create main module interface table |
| 2102 | // we only have 1 closure, which must be called to configure Lanes | 2103 | // we only have 1 closure, which must be called to configure Lanes |
| @@ -2118,7 +2119,7 @@ LANES_API int luaopen_lanes_core( lua_State* L) | |||
| 2118 | lua_setfield( L, -2, "configure"); // M | 2119 | lua_setfield( L, -2, "configure"); // M |
| 2119 | } | 2120 | } |
| 2120 | 2121 | ||
| 2121 | STACK_END( L, 1); | 2122 | STACK_CHECK( L, 1); |
| 2122 | return 1; | 2123 | return 1; |
| 2123 | } | 2124 | } |
| 2124 | 2125 | ||
| @@ -2135,12 +2136,12 @@ static int default_luaopen_lanes( lua_State* L) | |||
| 2135 | // call this instead of luaopen_lanes_core() when embedding Lua and Lanes in a custom application | 2136 | // call this instead of luaopen_lanes_core() when embedding Lua and Lanes in a custom application |
| 2136 | LANES_API void luaopen_lanes_embedded( lua_State* L, lua_CFunction _luaopen_lanes) | 2137 | LANES_API void luaopen_lanes_embedded( lua_State* L, lua_CFunction _luaopen_lanes) |
| 2137 | { | 2138 | { |
| 2138 | STACK_CHECK( L, 0); | 2139 | STACK_CHECK_START_REL(L, 0); |
| 2139 | // pre-require lanes.core so that when lanes.lua calls require "lanes.core" it finds it is already loaded | 2140 | // pre-require lanes.core so that when lanes.lua calls require "lanes.core" it finds it is already loaded |
| 2140 | luaL_requiref( L, "lanes.core", luaopen_lanes_core, 0); // ... lanes.core | 2141 | luaL_requiref( L, "lanes.core", luaopen_lanes_core, 0); // ... lanes.core |
| 2141 | lua_pop( L, 1); // ... | 2142 | lua_pop( L, 1); // ... |
| 2142 | STACK_MID( L, 0); | 2143 | STACK_CHECK( L, 0); |
| 2143 | // call user-provided function that runs the chunk "lanes.lua" from wherever they stored it | 2144 | // call user-provided function that runs the chunk "lanes.lua" from wherever they stored it |
| 2144 | luaL_requiref( L, "lanes", _luaopen_lanes ? _luaopen_lanes : default_luaopen_lanes, 0); // ... lanes | 2145 | luaL_requiref( L, "lanes", _luaopen_lanes ? _luaopen_lanes : default_luaopen_lanes, 0); // ... lanes |
| 2145 | STACK_END( L, 1); | 2146 | STACK_CHECK( L, 1); |
| 2146 | } | 2147 | } |
diff --git a/src/lanes_private.h b/src/lanes_private.h index 2fbbae9..b8d26d3 100644 --- a/src/lanes_private.h +++ b/src/lanes_private.h | |||
| @@ -80,13 +80,12 @@ struct Lane | |||
| 80 | 80 | ||
| 81 | static inline Lane* get_lane_from_registry( lua_State* L) | 81 | static inline Lane* get_lane_from_registry( lua_State* L) |
| 82 | { | 82 | { |
| 83 | Lane* s; | ||
| 84 | STACK_GROW( L, 1); | 83 | STACK_GROW( L, 1); |
| 85 | STACK_CHECK( L, 0); | 84 | STACK_CHECK_START_REL(L, 0); |
| 86 | CANCEL_TEST_KEY.query_registry(L); | 85 | CANCEL_TEST_KEY.query_registry(L); |
| 87 | s = (Lane*) lua_touserdata( L, -1); // lightuserdata (true 's_lane' pointer) / nil | 86 | Lane* const s = static_cast<Lane*>(lua_touserdata(L, -1)); // lightuserdata (true 's_lane' pointer) / nil |
| 88 | lua_pop( L, 1); | 87 | lua_pop( L, 1); |
| 89 | STACK_END( L, 0); | 88 | STACK_CHECK( L, 0); |
| 90 | return s; | 89 | return s; |
| 91 | } | 90 | } |
| 92 | 91 | ||
diff --git a/src/linda.cpp b/src/linda.cpp index ff3d543..a6025ce 100644 --- a/src/linda.cpp +++ b/src/linda.cpp | |||
| @@ -88,7 +88,7 @@ LUAG_FUNC( linda_protected_call) | |||
| 88 | 88 | ||
| 89 | // acquire the keeper | 89 | // acquire the keeper |
| 90 | Keeper* K = keeper_acquire( linda->U->keepers, LINDA_KEEPER_HASHSEED(linda)); | 90 | Keeper* K = keeper_acquire( linda->U->keepers, LINDA_KEEPER_HASHSEED(linda)); |
| 91 | lua_State* KL = K ? K->L : nullptr; // need to do this for 'STACK_CHECK' | 91 | lua_State* KL = K ? K->L : nullptr; |
| 92 | if( KL == nullptr) return 0; | 92 | if( KL == nullptr) return 0; |
| 93 | 93 | ||
| 94 | // retrieve the actual function to be called and move it before the arguments | 94 | // retrieve the actual function to be called and move it before the arguments |
| @@ -168,10 +168,10 @@ LUAG_FUNC( linda_send) | |||
| 168 | 168 | ||
| 169 | { | 169 | { |
| 170 | Lane* const s = get_lane_from_registry( L); | 170 | Lane* const s = get_lane_from_registry( L); |
| 171 | Keeper* K = which_keeper( linda->U->keepers, LINDA_KEEPER_HASHSEED( linda)); | 171 | Keeper* const K = which_keeper( linda->U->keepers, LINDA_KEEPER_HASHSEED( linda)); |
| 172 | lua_State* KL = K ? K->L : nullptr; // need to do this for 'STACK_CHECK' | 172 | lua_State* KL = K ? K->L : nullptr; |
| 173 | if( KL == nullptr) return 0; | 173 | if( KL == nullptr) return 0; |
| 174 | STACK_CHECK( KL, 0); | 174 | STACK_CHECK_START_REL(KL, 0); |
| 175 | for(bool try_again{ true };;) | 175 | for(bool try_again{ true };;) |
| 176 | { | 176 | { |
| 177 | if( s != nullptr) | 177 | if( s != nullptr) |
| @@ -186,7 +186,7 @@ LUAG_FUNC( linda_send) | |||
| 186 | break; | 186 | break; |
| 187 | } | 187 | } |
| 188 | 188 | ||
| 189 | STACK_MID( KL, 0); | 189 | STACK_CHECK( KL, 0); |
| 190 | pushed = keeper_call( linda->U, KL, KEEPER_API( send), L, linda, key_i); | 190 | pushed = keeper_call( linda->U, KL, KEEPER_API( send), L, linda, key_i); |
| 191 | if( pushed < 0) | 191 | if( pushed < 0) |
| 192 | { | 192 | { |
| @@ -231,7 +231,7 @@ LUAG_FUNC( linda_send) | |||
| 231 | } | 231 | } |
| 232 | } | 232 | } |
| 233 | } | 233 | } |
| 234 | STACK_END( KL, 0); | 234 | STACK_CHECK( KL, 0); |
| 235 | } | 235 | } |
| 236 | 236 | ||
| 237 | if( pushed < 0) | 237 | if( pushed < 0) |
| @@ -839,7 +839,7 @@ static void* linda_id( lua_State* L, DeepOp op_) | |||
| 839 | case eDO_metatable: | 839 | case eDO_metatable: |
| 840 | { | 840 | { |
| 841 | 841 | ||
| 842 | STACK_CHECK( L, 0); | 842 | STACK_CHECK_START_REL(L, 0); |
| 843 | lua_newtable( L); | 843 | lua_newtable( L); |
| 844 | // metatable is its own index | 844 | // metatable is its own index |
| 845 | lua_pushvalue( L, -1); | 845 | lua_pushvalue( L, -1); |
| @@ -904,7 +904,7 @@ static void* linda_id( lua_State* L, DeepOp op_) | |||
| 904 | NIL_SENTINEL.push(L); | 904 | NIL_SENTINEL.push(L); |
| 905 | lua_setfield( L, -2, "null"); | 905 | lua_setfield( L, -2, "null"); |
| 906 | 906 | ||
| 907 | STACK_END( L, 1); | 907 | STACK_CHECK( L, 1); |
| 908 | return nullptr; | 908 | return nullptr; |
| 909 | } | 909 | } |
| 910 | 910 | ||
diff --git a/src/macros_and_utils.h b/src/macros_and_utils.h index 9982693..c549d72 100644 --- a/src/macros_and_utils.h +++ b/src/macros_and_utils.h | |||
| @@ -10,6 +10,8 @@ extern "C" { | |||
| 10 | } | 10 | } |
| 11 | #endif // __cplusplus | 11 | #endif // __cplusplus |
| 12 | 12 | ||
| 13 | #include <cassert> | ||
| 14 | |||
| 13 | #define USE_DEBUG_SPEW() 0 | 15 | #define USE_DEBUG_SPEW() 0 |
| 14 | #if USE_DEBUG_SPEW() | 16 | #if USE_DEBUG_SPEW() |
| 15 | extern char const* debugspew_indent; | 17 | extern char const* debugspew_indent; |
| @@ -27,53 +29,89 @@ extern char const* debugspew_indent; | |||
| 27 | #ifdef NDEBUG | 29 | #ifdef NDEBUG |
| 28 | 30 | ||
| 29 | #define _ASSERT_L(lua,c) //nothing | 31 | #define _ASSERT_L(lua,c) //nothing |
| 30 | #define STACK_CHECK(L,o) //nothing | ||
| 31 | #define STACK_CHECK_ABS(L,o) //nothing | ||
| 32 | #define STACK_MID(L,c) //nothing | ||
| 33 | #define STACK_END(L,c) //nothing | ||
| 34 | #define STACK_DUMP(L) //nothing | 32 | #define STACK_DUMP(L) //nothing |
| 35 | 33 | ||
| 34 | #define STACK_CHECK_START_REL(L, offset_) | ||
| 35 | #define STACK_CHECK_START_ABS(L, offset_) | ||
| 36 | #define STACK_CHECK_RESET_REL(L, offset_) | ||
| 37 | #define STACK_CHECK_RESET_ABS(L, offset_) | ||
| 38 | #define STACK_CHECK(L, offset_) | ||
| 39 | |||
| 36 | #else // NDEBUG | 40 | #else // NDEBUG |
| 37 | 41 | ||
| 38 | #define _ASSERT_L( L, cond_) if( (cond_) == 0) { (void) luaL_error( L, "ASSERT failed: %s:%d '%s'", __FILE__, __LINE__, #cond_);} | 42 | #define _ASSERT_L( L, cond_) if( (cond_) == 0) { (void) luaL_error( L, "ASSERT failed: %s:%d '%s'", __FILE__, __LINE__, #cond_);} |
| 43 | #define STACK_DUMP( L) luaG_dump( L) | ||
| 44 | |||
| 45 | class StackChecker | ||
| 46 | { | ||
| 47 | private: | ||
| 48 | lua_State* const m_L; | ||
| 49 | int m_oldtop; | ||
| 50 | |||
| 51 | public: | ||
| 52 | struct Relative | ||
| 53 | { | ||
| 54 | int const m_offset; | ||
| 55 | |||
| 56 | operator int() const { return m_offset; } | ||
| 57 | }; | ||
| 58 | |||
| 59 | struct Absolute | ||
| 60 | { | ||
| 61 | int const m_offset; | ||
| 39 | 62 | ||
| 40 | #define STACK_CHECK( L, offset_) \ | 63 | operator int() const { return m_offset; } |
| 41 | { \ | 64 | }; |
| 42 | int const L##_delta = offset_; \ | 65 | |
| 43 | if( (L##_delta < 0) || (lua_gettop( L) < L##_delta)) \ | 66 | StackChecker(lua_State* const L_, Relative offset_, char const* file_, size_t const line_) |
| 44 | { \ | 67 | : m_L{ L_ } |
| 45 | assert( false); \ | 68 | , m_oldtop{ lua_gettop(L_) - offset_ } |
| 46 | (void) luaL_error( L, "STACK INIT ASSERT failed (%d not %d): %s:%d", lua_gettop( L), L##_delta, __FILE__, __LINE__); \ | 69 | { |
| 47 | } \ | 70 | if ((offset_ < 0) || (m_oldtop < 0)) |
| 48 | int const L##_oldtop = lua_gettop( L) - L##_delta | 71 | { |
| 49 | 72 | assert(false); | |
| 50 | #define STACK_CHECK_ABS( L, offset_) \ | 73 | (void) luaL_error(m_L, "STACK INIT ASSERT failed (%d not %d): %s:%d", lua_gettop(m_L), offset_, file_, line_); |
| 51 | { \ | 74 | } |
| 52 | int const L##_pos = offset_; \ | ||
| 53 | if( lua_gettop( L) < L##_pos) \ | ||
| 54 | { \ | ||
| 55 | assert( false); \ | ||
| 56 | (void) luaL_error( L, "STACK INIT ASSERT failed (%d not %d): %s:%d", lua_gettop( L), L##_pos, __FILE__, __LINE__); \ | ||
| 57 | } \ | ||
| 58 | int const L##_oldtop = 0 | ||
| 59 | |||
| 60 | #define STACK_MID( L, change) \ | ||
| 61 | do if( change != LUA_MULTRET) \ | ||
| 62 | { \ | ||
| 63 | int stack_check_a = lua_gettop( L) - L##_oldtop; \ | ||
| 64 | int stack_check_b = (change); \ | ||
| 65 | if( stack_check_a != stack_check_b) \ | ||
| 66 | { \ | ||
| 67 | assert( false); \ | ||
| 68 | luaL_error( L, "STACK ASSERT failed (%d not %d): %s:%d", stack_check_a, stack_check_b, __FILE__, __LINE__); \ | ||
| 69 | } \ | ||
| 70 | } while( 0) | ||
| 71 | |||
| 72 | #define STACK_END( L, change) \ | ||
| 73 | STACK_MID( L, change); \ | ||
| 74 | } | 75 | } |
| 75 | 76 | ||
| 76 | #define STACK_DUMP( L) luaG_dump( L) | 77 | StackChecker(lua_State* const L_, Absolute pos_, char const* file_, size_t const line_) |
| 78 | : m_L{ L_ } | ||
| 79 | , m_oldtop{ 0 } | ||
| 80 | { | ||
| 81 | if (lua_gettop(m_L) != pos_) | ||
| 82 | { | ||
| 83 | assert(false); | ||
| 84 | (void) luaL_error(m_L, "STACK INIT ASSERT failed (%d not %d): %s:%d", lua_gettop(m_L), pos_, file_, line_); | ||
| 85 | } | ||
| 86 | } | ||
| 87 | |||
| 88 | StackChecker& operator=(StackChecker const& rhs_) | ||
| 89 | { | ||
| 90 | assert(m_L == rhs_.m_L); | ||
| 91 | m_oldtop = rhs_.m_oldtop; | ||
| 92 | return *this; | ||
| 93 | } | ||
| 94 | |||
| 95 | // verify if the distance between the current top and the initial one is what we expect | ||
| 96 | void check(int expected_, char const* file_, size_t const line_) | ||
| 97 | { | ||
| 98 | if (expected_ != LUA_MULTRET) | ||
| 99 | { | ||
| 100 | int const actual{ lua_gettop(m_L) - m_oldtop }; | ||
| 101 | if (actual != expected_) | ||
| 102 | { | ||
| 103 | assert(false); | ||
| 104 | luaL_error(m_L, "STACK ASSERT failed (%d not %d): %s:%d", actual, expected_, file_, line_); | ||
| 105 | } | ||
| 106 | } | ||
| 107 | } | ||
| 108 | }; | ||
| 109 | |||
| 110 | #define STACK_CHECK_START_REL(L, offset_) StackChecker stackChecker_##L(L, StackChecker::Relative{ offset_ }, __FILE__, __LINE__) | ||
| 111 | #define STACK_CHECK_START_ABS(L, offset_) StackChecker stackChecker_##L(L, StackChecker::Absolute{ offset_ }, __FILE__, __LINE__) | ||
| 112 | #define STACK_CHECK_RESET_REL(L, offset_) stackChecker_##L = StackChecker{L, StackChecker::Relative{ offset_ }, __FILE__, __LINE__} | ||
| 113 | #define STACK_CHECK_RESET_ABS(L, offset_) stackChecker_##L = StackChecker{L, StackChecker::Absolute{ offset_ }, __FILE__, __LINE__} | ||
| 114 | #define STACK_CHECK(L, offset_) stackChecker_##L.check(offset_, __FILE__, __LINE__) | ||
| 77 | 115 | ||
| 78 | #endif // NDEBUG | 116 | #endif // NDEBUG |
| 79 | 117 | ||
diff --git a/src/state.cpp b/src/state.cpp index f53d180..aa6b38a 100644 --- a/src/state.cpp +++ b/src/state.cpp | |||
| @@ -91,28 +91,28 @@ static int luaG_new_require( lua_State* L) | |||
| 91 | /* | 91 | /* |
| 92 | * Serialize calls to 'require', if it exists | 92 | * Serialize calls to 'require', if it exists |
| 93 | */ | 93 | */ |
| 94 | void serialize_require( DEBUGSPEW_PARAM_COMMA( Universe* U) lua_State* L) | 94 | void serialize_require(DEBUGSPEW_PARAM_COMMA( Universe* U) lua_State* L) |
| 95 | { | 95 | { |
| 96 | STACK_GROW( L, 1); | 96 | STACK_GROW(L, 1); |
| 97 | STACK_CHECK( L, 0); | 97 | STACK_CHECK_START_REL(L, 0); |
| 98 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "serializing require()\n" INDENT_END)); | 98 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "serializing require()\n" INDENT_END)); |
| 99 | 99 | ||
| 100 | // Check 'require' is there and not already wrapped; if not, do nothing | 100 | // Check 'require' is there and not already wrapped; if not, do nothing |
| 101 | // | 101 | // |
| 102 | lua_getglobal( L, "require"); | 102 | lua_getglobal(L, "require"); |
| 103 | if( lua_isfunction( L, -1) && lua_tocfunction( L, -1) != luaG_new_require) | 103 | if (lua_isfunction(L, -1) && lua_tocfunction(L, -1) != luaG_new_require) |
| 104 | { | 104 | { |
| 105 | // [-1]: original 'require' function | 105 | // [-1]: original 'require' function |
| 106 | lua_pushcclosure( L, luaG_new_require, 1 /*upvalues*/); | 106 | lua_pushcclosure(L, luaG_new_require, 1 /*upvalues*/); |
| 107 | lua_setglobal( L, "require"); | 107 | lua_setglobal(L, "require"); |
| 108 | } | 108 | } |
| 109 | else | 109 | else |
| 110 | { | 110 | { |
| 111 | // [-1]: nil | 111 | // [-1]: nil |
| 112 | lua_pop( L, 1); | 112 | lua_pop(L, 1); |
| 113 | } | 113 | } |
| 114 | 114 | ||
| 115 | STACK_END( L, 0); | 115 | STACK_CHECK(L, 0); |
| 116 | } | 116 | } |
| 117 | 117 | ||
| 118 | // ################################################################################################ | 118 | // ################################################################################################ |
| @@ -176,7 +176,7 @@ static void open1lib( DEBUGSPEW_PARAM_COMMA( Universe* U) lua_State* L, char con | |||
| 176 | { | 176 | { |
| 177 | bool const isLanesCore{ libfunc == require_lanes_core }; // don't want to create a global for "lanes.core" | 177 | bool const isLanesCore{ libfunc == require_lanes_core }; // don't want to create a global for "lanes.core" |
| 178 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "opening %.*s library\n" INDENT_END, (int) len_, name_)); | 178 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "opening %.*s library\n" INDENT_END, (int) len_, name_)); |
| 179 | STACK_CHECK( L, 0); | 179 | STACK_CHECK_START_REL(L, 0); |
| 180 | // open the library as if through require(), and create a global as well if necessary (the library table is left on the stack) | 180 | // open the library as if through require(), and create a global as well if necessary (the library table is left on the stack) |
| 181 | luaL_requiref( L, name_, libfunc, !isLanesCore); | 181 | luaL_requiref( L, name_, libfunc, !isLanesCore); |
| 182 | // lanes.core doesn't declare a global, so scan it here and now | 182 | // lanes.core doesn't declare a global, so scan it here and now |
| @@ -185,7 +185,7 @@ static void open1lib( DEBUGSPEW_PARAM_COMMA( Universe* U) lua_State* L, char con | |||
| 185 | populate_func_lookup_table( L, -1, name_); | 185 | populate_func_lookup_table( L, -1, name_); |
| 186 | } | 186 | } |
| 187 | lua_pop( L, 1); | 187 | lua_pop( L, 1); |
| 188 | STACK_END( L, 0); | 188 | STACK_CHECK( L, 0); |
| 189 | } | 189 | } |
| 190 | break; | 190 | break; |
| 191 | } | 191 | } |
| @@ -197,8 +197,8 @@ static void open1lib( DEBUGSPEW_PARAM_COMMA( Universe* U) lua_State* L, char con | |||
| 197 | static void copy_one_time_settings( Universe* U, lua_State* L, lua_State* L2) | 197 | static void copy_one_time_settings( Universe* U, lua_State* L, lua_State* L2) |
| 198 | { | 198 | { |
| 199 | STACK_GROW( L, 2); | 199 | STACK_GROW( L, 2); |
| 200 | STACK_CHECK( L, 0); | 200 | STACK_CHECK_START_REL(L, 0); |
| 201 | STACK_CHECK( L2, 0); | 201 | STACK_CHECK_START_REL(L2, 0); |
| 202 | 202 | ||
| 203 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "copy_one_time_settings()\n" INDENT_END)); | 203 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "copy_one_time_settings()\n" INDENT_END)); |
| 204 | DEBUGSPEW_CODE( ++ U->debugspew_indent_depth); | 204 | DEBUGSPEW_CODE( ++ U->debugspew_indent_depth); |
| @@ -211,31 +211,31 @@ static void copy_one_time_settings( Universe* U, lua_State* L, lua_State* L2) | |||
| 211 | } | 211 | } |
| 212 | // set L2:_R[CONFIG_REGKEY] = settings | 212 | // set L2:_R[CONFIG_REGKEY] = settings |
| 213 | CONFIG_REGKEY.set_registry(L2, [](lua_State* L) { lua_insert(L, -2); }); // config | 213 | CONFIG_REGKEY.set_registry(L2, [](lua_State* L) { lua_insert(L, -2); }); // config |
| 214 | STACK_END( L2, 0); | 214 | STACK_CHECK( L2, 0); |
| 215 | STACK_END( L, 0); | 215 | STACK_CHECK( L, 0); |
| 216 | DEBUGSPEW_CODE( -- U->debugspew_indent_depth); | 216 | DEBUGSPEW_CODE( -- U->debugspew_indent_depth); |
| 217 | } | 217 | } |
| 218 | 218 | ||
| 219 | void initialize_on_state_create( Universe* U, lua_State* L) | 219 | void initialize_on_state_create( Universe* U, lua_State* L) |
| 220 | { | 220 | { |
| 221 | STACK_CHECK( L, 0); | 221 | STACK_CHECK_START_REL(L, 1); // settings |
| 222 | lua_getfield( L, -1, "on_state_create"); // settings on_state_create|nil | 222 | lua_getfield(L, -1, "on_state_create"); // settings on_state_create|nil |
| 223 | if( !lua_isnil( L, -1)) | 223 | if( !lua_isnil(L, -1)) |
| 224 | { | 224 | { |
| 225 | // store C function pointer in an internal variable | 225 | // store C function pointer in an internal variable |
| 226 | U->on_state_create_func = lua_tocfunction( L, -1); // settings on_state_create | 226 | U->on_state_create_func = lua_tocfunction(L, -1); // settings on_state_create |
| 227 | if (U->on_state_create_func != nullptr) | 227 | if (U->on_state_create_func != nullptr) |
| 228 | { | 228 | { |
| 229 | // make sure the function doesn't have upvalues | 229 | // make sure the function doesn't have upvalues |
| 230 | char const* upname = lua_getupvalue( L, -1, 1); // settings on_state_create upval? | 230 | char const* upname = lua_getupvalue(L, -1, 1); // settings on_state_create upval? |
| 231 | if (upname != nullptr) // should be "" for C functions with upvalues if any | 231 | if (upname != nullptr) // should be "" for C functions with upvalues if any |
| 232 | { | 232 | { |
| 233 | (void) luaL_error( L, "on_state_create shouldn't have upvalues"); | 233 | (void) luaL_error(L, "on_state_create shouldn't have upvalues"); |
| 234 | } | 234 | } |
| 235 | // remove this C function from the config table so that it doesn't cause problems | 235 | // remove this C function from the config table so that it doesn't cause problems |
| 236 | // when we transfer the config table in newly created Lua states | 236 | // when we transfer the config table in newly created Lua states |
| 237 | lua_pushnil( L); // settings on_state_create nil | 237 | lua_pushnil(L); // settings on_state_create nil |
| 238 | lua_setfield( L, -3, "on_state_create"); // settings on_state_create | 238 | lua_setfield(L, -3, "on_state_create"); // settings on_state_create |
| 239 | } | 239 | } |
| 240 | else | 240 | else |
| 241 | { | 241 | { |
| @@ -243,8 +243,8 @@ void initialize_on_state_create( Universe* U, lua_State* L) | |||
| 243 | U->on_state_create_func = (lua_CFunction) initialize_on_state_create; | 243 | U->on_state_create_func = (lua_CFunction) initialize_on_state_create; |
| 244 | } | 244 | } |
| 245 | } | 245 | } |
| 246 | lua_pop( L, 1); // settings | 246 | lua_pop(L, 1); // settings |
| 247 | STACK_END( L, 0); | 247 | STACK_CHECK(L, 1); |
| 248 | } | 248 | } |
| 249 | 249 | ||
| 250 | lua_State* create_state( Universe* U, lua_State* from_) | 250 | lua_State* create_state( Universe* U, lua_State* from_) |
| @@ -282,7 +282,7 @@ void call_on_state_create( Universe* U, lua_State* L, lua_State* from_, LookupMo | |||
| 282 | { | 282 | { |
| 283 | if (U->on_state_create_func != nullptr) | 283 | if (U->on_state_create_func != nullptr) |
| 284 | { | 284 | { |
| 285 | STACK_CHECK( L, 0); | 285 | STACK_CHECK_START_REL(L, 0); |
| 286 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "calling on_state_create()\n" INDENT_END)); | 286 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "calling on_state_create()\n" INDENT_END)); |
| 287 | if( U->on_state_create_func != (lua_CFunction) initialize_on_state_create) | 287 | if( U->on_state_create_func != (lua_CFunction) initialize_on_state_create) |
| 288 | { | 288 | { |
| @@ -295,20 +295,21 @@ void call_on_state_create( Universe* U, lua_State* L, lua_State* from_, LookupMo | |||
| 295 | { | 295 | { |
| 296 | // if attempting to call in a keeper state, do nothing because the function doesn't exist there | 296 | // if attempting to call in a keeper state, do nothing because the function doesn't exist there |
| 297 | // this doesn't count as an error though | 297 | // this doesn't count as an error though |
| 298 | STACK_CHECK(L, 0); | ||
| 298 | return; | 299 | return; |
| 299 | } | 300 | } |
| 300 | CONFIG_REGKEY.query_registry(L); // {} | 301 | CONFIG_REGKEY.query_registry(L); // {} |
| 301 | STACK_MID( L, 1); | 302 | STACK_CHECK( L, 1); |
| 302 | lua_getfield( L, -1, "on_state_create"); // {} on_state_create() | 303 | lua_getfield( L, -1, "on_state_create"); // {} on_state_create() |
| 303 | lua_remove( L, -2); // on_state_create() | 304 | lua_remove( L, -2); // on_state_create() |
| 304 | } | 305 | } |
| 305 | STACK_MID( L, 1); | 306 | STACK_CHECK( L, 1); |
| 306 | // capture error and raise it in caller state | 307 | // capture error and raise it in caller state |
| 307 | if( lua_pcall( L, 0, 0, 0) != LUA_OK) | 308 | if( lua_pcall( L, 0, 0, 0) != LUA_OK) |
| 308 | { | 309 | { |
| 309 | luaL_error( from_, "on_state_create failed: \"%s\"", lua_isstring( L, -1) ? lua_tostring( L, -1) : lua_typename( L, lua_type( L, -1))); | 310 | luaL_error( from_, "on_state_create failed: \"%s\"", lua_isstring( L, -1) ? lua_tostring( L, -1) : lua_typename( L, lua_type( L, -1))); |
| 310 | } | 311 | } |
| 311 | STACK_END( L, 0); | 312 | STACK_CHECK( L, 0); |
| 312 | } | 313 | } |
| 313 | } | 314 | } |
| 314 | 315 | ||
| @@ -330,16 +331,16 @@ lua_State* luaG_newstate( Universe* U, lua_State* from_, char const* libs_) | |||
| 330 | lua_State* L = create_state( U, from_); | 331 | lua_State* L = create_state( U, from_); |
| 331 | 332 | ||
| 332 | STACK_GROW( L, 2); | 333 | STACK_GROW( L, 2); |
| 333 | STACK_CHECK_ABS( L, 0); | 334 | STACK_CHECK_START_ABS(L, 0); |
| 334 | 335 | ||
| 335 | // copy the universe as a light userdata (only the master state holds the full userdata) | 336 | // copy the universe as a light userdata (only the master state holds the full userdata) |
| 336 | // that way, if Lanes is required in this new state, we'll know we are part of this universe | 337 | // that way, if Lanes is required in this new state, we'll know we are part of this universe |
| 337 | universe_store( L, U); | 338 | universe_store( L, U); |
| 338 | STACK_MID( L, 0); | 339 | STACK_CHECK(L, 0); |
| 339 | 340 | ||
| 340 | // we'll need this every time we transfer some C function from/to this state | 341 | // we'll need this every time we transfer some C function from/to this state |
| 341 | LOOKUP_REGKEY.set_registry(L, [](lua_State* L) { lua_newtable(L); }); | 342 | LOOKUP_REGKEY.set_registry(L, [](lua_State* L) { lua_newtable(L); }); |
| 342 | STACK_MID( L, 0); | 343 | STACK_CHECK(L, 0); |
| 343 | 344 | ||
| 344 | // neither libs (not even 'base') nor special init func: we are done | 345 | // neither libs (not even 'base') nor special init func: we are done |
| 345 | if (libs_ == nullptr && U->on_state_create_func == nullptr) | 346 | if (libs_ == nullptr && U->on_state_create_func == nullptr) |
| @@ -386,7 +387,7 @@ lua_State* luaG_newstate( Universe* U, lua_State* from_, char const* libs_) | |||
| 386 | #endif // LUA_VERSION_NUM | 387 | #endif // LUA_VERSION_NUM |
| 387 | } | 388 | } |
| 388 | } | 389 | } |
| 389 | STACK_END( L, 0); | 390 | STACK_CHECK(L, 0); |
| 390 | 391 | ||
| 391 | // scan all libraries, open them one by one | 392 | // scan all libraries, open them one by one |
| 392 | if( libs_) | 393 | if( libs_) |
| @@ -414,9 +415,10 @@ lua_State* luaG_newstate( Universe* U, lua_State* from_, char const* libs_) | |||
| 414 | // will raise an error in from_ in case of problem | 415 | // will raise an error in from_ in case of problem |
| 415 | call_on_state_create( U, L, from_, eLM_LaneBody); | 416 | call_on_state_create( U, L, from_, eLM_LaneBody); |
| 416 | 417 | ||
| 417 | STACK_CHECK( L, 0); | 418 | STACK_CHECK(L, 0); |
| 418 | // after all this, register everything we find in our name<->function database | 419 | // after all this, register everything we find in our name<->function database |
| 419 | lua_pushglobaltable( L); // Lua 5.2 no longer has LUA_GLOBALSINDEX: we must push globals table on the stack | 420 | lua_pushglobaltable( L); // Lua 5.2 no longer has LUA_GLOBALSINDEX: we must push globals table on the stack |
| 421 | STACK_CHECK(L, 1); | ||
| 420 | populate_func_lookup_table(L, -1, nullptr); | 422 | populate_func_lookup_table(L, -1, nullptr); |
| 421 | 423 | ||
| 422 | #if 0 && USE_DEBUG_SPEW() | 424 | #if 0 && USE_DEBUG_SPEW() |
| @@ -436,7 +438,7 @@ lua_State* luaG_newstate( Universe* U, lua_State* from_, char const* libs_) | |||
| 436 | #endif // USE_DEBUG_SPEW() | 438 | #endif // USE_DEBUG_SPEW() |
| 437 | 439 | ||
| 438 | lua_pop( L, 1); | 440 | lua_pop( L, 1); |
| 439 | STACK_END( L, 0); | 441 | STACK_CHECK(L, 0); |
| 440 | DEBUGSPEW_CODE( -- U->debugspew_indent_depth); | 442 | DEBUGSPEW_CODE(--U->debugspew_indent_depth); |
| 441 | return L; | 443 | return L; |
| 442 | } | 444 | } |
diff --git a/src/tools.cpp b/src/tools.cpp index 5196e7e..1e38144 100644 --- a/src/tools.cpp +++ b/src/tools.cpp | |||
| @@ -62,10 +62,10 @@ DEBUGSPEW_CODE( char const* debugspew_indent = "----+----!----+----!----+----!-- | |||
| 62 | void push_registry_subtable_mode( lua_State* L, UniqueKey key_, const char* mode_) | 62 | void push_registry_subtable_mode( lua_State* L, UniqueKey key_, const char* mode_) |
| 63 | { | 63 | { |
| 64 | STACK_GROW(L, 3); | 64 | STACK_GROW(L, 3); |
| 65 | STACK_CHECK(L, 0); | 65 | STACK_CHECK_START_REL(L, 0); |
| 66 | 66 | ||
| 67 | key_.query_registry(L); // {}|nil | 67 | key_.query_registry(L); // {}|nil |
| 68 | STACK_MID(L, 1); | 68 | STACK_CHECK(L, 1); |
| 69 | 69 | ||
| 70 | if (lua_isnil(L, -1)) | 70 | if (lua_isnil(L, -1)) |
| 71 | { | 71 | { |
| @@ -73,7 +73,7 @@ void push_registry_subtable_mode( lua_State* L, UniqueKey key_, const char* mode | |||
| 73 | lua_newtable(L); // {} | 73 | lua_newtable(L); // {} |
| 74 | // _R[key_] = {} | 74 | // _R[key_] = {} |
| 75 | key_.set_registry(L, [](lua_State* L) { lua_pushvalue(L, -2); }); // {} | 75 | key_.set_registry(L, [](lua_State* L) { lua_pushvalue(L, -2); }); // {} |
| 76 | STACK_MID(L, 1); | 76 | STACK_CHECK(L, 1); |
| 77 | 77 | ||
| 78 | // Set its metatable if requested | 78 | // Set its metatable if requested |
| 79 | if (mode_) | 79 | if (mode_) |
| @@ -85,7 +85,7 @@ void push_registry_subtable_mode( lua_State* L, UniqueKey key_, const char* mode | |||
| 85 | lua_setmetatable(L, -2); // {} | 85 | lua_setmetatable(L, -2); // {} |
| 86 | } | 86 | } |
| 87 | } | 87 | } |
| 88 | STACK_END(L, 1); | 88 | STACK_CHECK(L, 1); |
| 89 | ASSERT_L(lua_istable(L, -1)); | 89 | ASSERT_L(lua_istable(L, -1)); |
| 90 | } | 90 | } |
| 91 | 91 | ||
| @@ -125,7 +125,7 @@ void luaG_dump( lua_State* L) | |||
| 125 | // Note: this requires 'tostring()' to be defined. If it is NOT, | 125 | // Note: this requires 'tostring()' to be defined. If it is NOT, |
| 126 | // enable it for more debugging. | 126 | // enable it for more debugging. |
| 127 | // | 127 | // |
| 128 | STACK_CHECK( L, 0); | 128 | STACK_CHECK_START_REL(L, 0); |
| 129 | STACK_GROW( L, 2); | 129 | STACK_GROW( L, 2); |
| 130 | 130 | ||
| 131 | lua_getglobal( L, "tostring"); | 131 | lua_getglobal( L, "tostring"); |
| @@ -146,7 +146,7 @@ void luaG_dump( lua_State* L) | |||
| 146 | fprintf( stderr, "%s", lua_tostring( L, -1)); | 146 | fprintf( stderr, "%s", lua_tostring( L, -1)); |
| 147 | } | 147 | } |
| 148 | lua_pop( L, 1); | 148 | lua_pop( L, 1); |
| 149 | STACK_END( L, 0); | 149 | STACK_CHECK( L, 0); |
| 150 | fprintf( stderr, "\n"); | 150 | fprintf( stderr, "\n"); |
| 151 | } | 151 | } |
| 152 | fprintf( stderr, "\n"); | 152 | fprintf( stderr, "\n"); |
| @@ -193,7 +193,7 @@ static int luaG_provide_protected_allocator( lua_State* L) | |||
| 193 | // Do I need to disable this when compiling for LuaJIT to prevent issues? | 193 | // Do I need to disable this when compiling for LuaJIT to prevent issues? |
| 194 | void initialize_allocator_function( Universe* U, lua_State* L) | 194 | void initialize_allocator_function( Universe* U, lua_State* L) |
| 195 | { | 195 | { |
| 196 | STACK_CHECK( L, 0); | 196 | STACK_CHECK_START_REL(L, 1); // settings |
| 197 | lua_getfield( L, -1, "allocator"); // settings allocator|nil|"protected" | 197 | lua_getfield( L, -1, "allocator"); // settings allocator|nil|"protected" |
| 198 | if( !lua_isnil( L, -1)) | 198 | if( !lua_isnil( L, -1)) |
| 199 | { | 199 | { |
| @@ -232,7 +232,7 @@ void initialize_allocator_function( Universe* U, lua_State* L) | |||
| 232 | U->protected_allocator.definition.allocF = lua_getallocf( L, &U->protected_allocator.definition.allocUD); | 232 | U->protected_allocator.definition.allocF = lua_getallocf( L, &U->protected_allocator.definition.allocUD); |
| 233 | } | 233 | } |
| 234 | lua_pop( L, 1); // settings | 234 | lua_pop( L, 1); // settings |
| 235 | STACK_MID(L, 0); | 235 | STACK_CHECK(L, 1); |
| 236 | 236 | ||
| 237 | lua_getfield( L, -1, "internal_allocator"); // settings "libc"|"allocator" | 237 | lua_getfield( L, -1, "internal_allocator"); // settings "libc"|"allocator" |
| 238 | { | 238 | { |
| @@ -248,7 +248,7 @@ void initialize_allocator_function( Universe* U, lua_State* L) | |||
| 248 | } | 248 | } |
| 249 | } | 249 | } |
| 250 | lua_pop( L, 1); // settings | 250 | lua_pop( L, 1); // settings |
| 251 | STACK_END( L, 0); | 251 | STACK_CHECK( L, 1); |
| 252 | } | 252 | } |
| 253 | 253 | ||
| 254 | void cleanup_allocator_function( Universe* U, lua_State* L) | 254 | void cleanup_allocator_function( Universe* U, lua_State* L) |
| @@ -335,7 +335,7 @@ static char const* luaG_pushFQN( lua_State* L, int t, int last, size_t* length) | |||
| 335 | { | 335 | { |
| 336 | int i = 1; | 336 | int i = 1; |
| 337 | luaL_Buffer b; | 337 | luaL_Buffer b; |
| 338 | STACK_CHECK( L, 0); | 338 | STACK_CHECK_START_REL(L, 0); |
| 339 | // Lua 5.4 pushes &b as light userdata on the stack. be aware of it... | 339 | // Lua 5.4 pushes &b as light userdata on the stack. be aware of it... |
| 340 | luaL_buffinit( L, &b); // ... {} ... &b? | 340 | luaL_buffinit( L, &b); // ... {} ... &b? |
| 341 | for( ; i < last; ++ i) | 341 | for( ; i < last; ++ i) |
| @@ -351,7 +351,7 @@ static char const* luaG_pushFQN( lua_State* L, int t, int last, size_t* length) | |||
| 351 | } | 351 | } |
| 352 | // &b is popped at that point (-> replaced by the result) | 352 | // &b is popped at that point (-> replaced by the result) |
| 353 | luaL_pushresult( &b); // ... {} ... "<result>" | 353 | luaL_pushresult( &b); // ... {} ... "<result>" |
| 354 | STACK_END( L, 1); | 354 | STACK_CHECK( L, 1); |
| 355 | return lua_tolstring( L, -1, length); | 355 | return lua_tolstring( L, -1, length); |
| 356 | } | 356 | } |
| 357 | 357 | ||
| @@ -376,7 +376,7 @@ static void update_lookup_entry( DEBUGSPEW_PARAM_COMMA( Universe* U) lua_State* | |||
| 376 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "update_lookup_entry()\n" INDENT_END)); | 376 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "update_lookup_entry()\n" INDENT_END)); |
| 377 | DEBUGSPEW_CODE( ++ U->debugspew_indent_depth); | 377 | DEBUGSPEW_CODE( ++ U->debugspew_indent_depth); |
| 378 | 378 | ||
| 379 | STACK_CHECK( L, 0); | 379 | STACK_CHECK_START_REL(L, 0); |
| 380 | // first, raise an error if the function is already known | 380 | // first, raise an error if the function is already known |
| 381 | lua_pushvalue( L, -1); // ... {bfc} k o o | 381 | lua_pushvalue( L, -1); // ... {bfc} k o o |
| 382 | lua_rawget( L, dest); // ... {bfc} k o name? | 382 | lua_rawget( L, dest); // ... {bfc} k o name? |
| @@ -433,7 +433,7 @@ static void update_lookup_entry( DEBUGSPEW_PARAM_COMMA( Universe* U) lua_State* | |||
| 433 | lua_rawseti( L, fqn, _depth); // ... {bfc} k | 433 | lua_rawseti( L, fqn, _depth); // ... {bfc} k |
| 434 | } | 434 | } |
| 435 | -- _depth; | 435 | -- _depth; |
| 436 | STACK_END( L, -1); | 436 | STACK_CHECK( L, -1); |
| 437 | DEBUGSPEW_CODE( -- U->debugspew_indent_depth); | 437 | DEBUGSPEW_CODE( -- U->debugspew_indent_depth); |
| 438 | } | 438 | } |
| 439 | 439 | ||
| @@ -451,13 +451,13 @@ static void populate_func_lookup_table_recur( DEBUGSPEW_PARAM_COMMA( Universe* U | |||
| 451 | 451 | ||
| 452 | STACK_GROW( L, 6); | 452 | STACK_GROW( L, 6); |
| 453 | // slot _i contains a table where we search for functions (or a full userdata with a metatable) | 453 | // slot _i contains a table where we search for functions (or a full userdata with a metatable) |
| 454 | STACK_CHECK( L, 0); // ... {_i} | 454 | STACK_CHECK_START_REL(L, 0); // ... {_i} |
| 455 | 455 | ||
| 456 | // if object is a userdata, replace it by its metatable | 456 | // if object is a userdata, replace it by its metatable |
| 457 | if( lua_type( L, _i) == LUA_TUSERDATA) | 457 | if( lua_type( L, _i) == LUA_TUSERDATA) |
| 458 | { | 458 | { |
| 459 | lua_getmetatable( L, _i); // ... {_i} mt | 459 | lua_getmetatable( L, _i); // ... {_i} mt |
| 460 | lua_replace( L, _i); // ... {_i} | 460 | lua_replace( L, _i); // ... {_i} |
| 461 | } | 461 | } |
| 462 | 462 | ||
| 463 | // if table is already visited, we are done | 463 | // if table is already visited, we are done |
| @@ -465,7 +465,7 @@ static void populate_func_lookup_table_recur( DEBUGSPEW_PARAM_COMMA( Universe* U | |||
| 465 | lua_rawget( L, cache); // ... {_i} nil|n | 465 | lua_rawget( L, cache); // ... {_i} nil|n |
| 466 | visit_count = lua_tointeger( L, -1); // 0 if nil, else n | 466 | visit_count = lua_tointeger( L, -1); // 0 if nil, else n |
| 467 | lua_pop( L, 1); // ... {_i} | 467 | lua_pop( L, 1); // ... {_i} |
| 468 | STACK_MID( L, 0); | 468 | STACK_CHECK( L, 0); |
| 469 | if( visit_count > 0) | 469 | if( visit_count > 0) |
| 470 | { | 470 | { |
| 471 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "already visited\n" INDENT_END)); | 471 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "already visited\n" INDENT_END)); |
| @@ -477,7 +477,7 @@ static void populate_func_lookup_table_recur( DEBUGSPEW_PARAM_COMMA( Universe* U | |||
| 477 | lua_pushvalue( L, _i); // ... {_i} {} | 477 | lua_pushvalue( L, _i); // ... {_i} {} |
| 478 | lua_pushinteger( L, visit_count + 1); // ... {_i} {} 1 | 478 | lua_pushinteger( L, visit_count + 1); // ... {_i} {} 1 |
| 479 | lua_rawset( L, cache); // ... {_i} | 479 | lua_rawset( L, cache); // ... {_i} |
| 480 | STACK_MID( L, 0); | 480 | STACK_CHECK( L, 0); |
| 481 | 481 | ||
| 482 | // this table is at breadth_first_cache index | 482 | // this table is at breadth_first_cache index |
| 483 | lua_newtable( L); // ... {_i} {bfc} | 483 | lua_newtable( L); // ... {_i} {bfc} |
| @@ -515,7 +515,7 @@ static void populate_func_lookup_table_recur( DEBUGSPEW_PARAM_COMMA( Universe* U | |||
| 515 | { | 515 | { |
| 516 | lua_pop( L, 1); // ... {_i} {bfc} k | 516 | lua_pop( L, 1); // ... {_i} {bfc} k |
| 517 | } | 517 | } |
| 518 | STACK_MID( L, 2); | 518 | STACK_CHECK( L, 2); |
| 519 | } | 519 | } |
| 520 | // now process the tables we encountered at that depth | 520 | // now process the tables we encountered at that depth |
| 521 | ++ _depth; | 521 | ++ _depth; |
| @@ -546,7 +546,7 @@ static void populate_func_lookup_table_recur( DEBUGSPEW_PARAM_COMMA( Universe* U | |||
| 546 | lua_rawseti( L, fqn, _depth); // ... {_i} {bfc} k {} | 546 | lua_rawseti( L, fqn, _depth); // ... {_i} {bfc} k {} |
| 547 | populate_func_lookup_table_recur( DEBUGSPEW_PARAM_COMMA( U) L, _ctx_base, lua_gettop( L), _depth); | 547 | populate_func_lookup_table_recur( DEBUGSPEW_PARAM_COMMA( U) L, _ctx_base, lua_gettop( L), _depth); |
| 548 | lua_pop( L, 1); // ... {_i} {bfc} k | 548 | lua_pop( L, 1); // ... {_i} {bfc} k |
| 549 | STACK_MID( L, 2); | 549 | STACK_CHECK( L, 2); |
| 550 | DEBUGSPEW_CODE( -- U->debugspew_indent_depth); | 550 | DEBUGSPEW_CODE( -- U->debugspew_indent_depth); |
| 551 | } | 551 | } |
| 552 | // remove table name from fqn stack | 552 | // remove table name from fqn stack |
| @@ -555,7 +555,7 @@ static void populate_func_lookup_table_recur( DEBUGSPEW_PARAM_COMMA( Universe* U | |||
| 555 | -- _depth; | 555 | -- _depth; |
| 556 | // we are done with our cache | 556 | // we are done with our cache |
| 557 | lua_pop( L, 1); // ... {_i} | 557 | lua_pop( L, 1); // ... {_i} |
| 558 | STACK_END( L, 0); | 558 | STACK_CHECK( L, 0); |
| 559 | // we are done // ... {_i} {bfc} | 559 | // we are done // ... {_i} {bfc} |
| 560 | DEBUGSPEW_CODE( -- U->debugspew_indent_depth); | 560 | DEBUGSPEW_CODE( -- U->debugspew_indent_depth); |
| 561 | } | 561 | } |
| @@ -572,9 +572,9 @@ void populate_func_lookup_table( lua_State* L, int _i, char const* name_) | |||
| 572 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "%p: populate_func_lookup_table('%s')\n" INDENT_END, L, name_ ? name_ : "nullptr")); | 572 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "%p: populate_func_lookup_table('%s')\n" INDENT_END, L, name_ ? name_ : "nullptr")); |
| 573 | DEBUGSPEW_CODE( ++ U->debugspew_indent_depth); | 573 | DEBUGSPEW_CODE( ++ U->debugspew_indent_depth); |
| 574 | STACK_GROW( L, 3); | 574 | STACK_GROW( L, 3); |
| 575 | STACK_CHECK( L, 0); | 575 | STACK_CHECK_START_REL(L, 0); |
| 576 | LOOKUP_REGKEY.query_registry(L); // {} | 576 | LOOKUP_REGKEY.query_registry(L); // {} |
| 577 | STACK_MID( L, 1); | 577 | STACK_CHECK( L, 1); |
| 578 | ASSERT_L( lua_istable( L, -1)); | 578 | ASSERT_L( lua_istable( L, -1)); |
| 579 | if( lua_type( L, in_base) == LUA_TFUNCTION) // for example when a module is a simple function | 579 | if( lua_type( L, in_base) == LUA_TFUNCTION) // for example when a module is a simple function |
| 580 | { | 580 | { |
| @@ -592,7 +592,7 @@ void populate_func_lookup_table( lua_State* L, int _i, char const* name_) | |||
| 592 | lua_newtable( L); // {} {fqn} | 592 | lua_newtable( L); // {} {fqn} |
| 593 | if( name_) | 593 | if( name_) |
| 594 | { | 594 | { |
| 595 | STACK_MID( L, 2); | 595 | STACK_CHECK( L, 2); |
| 596 | lua_pushstring( L, name_); // {} {fqn} "name" | 596 | lua_pushstring( L, name_); // {} {fqn} "name" |
| 597 | // generate a name, and if we already had one name, keep whichever is the shorter | 597 | // generate a name, and if we already had one name, keep whichever is the shorter |
| 598 | lua_pushvalue( L, in_base); // {} {fqn} "name" t | 598 | lua_pushvalue( L, in_base); // {} {fqn} "name" t |
| @@ -600,7 +600,7 @@ void populate_func_lookup_table( lua_State* L, int _i, char const* name_) | |||
| 600 | // don't forget to store the name at the bottom of the fqn stack | 600 | // don't forget to store the name at the bottom of the fqn stack |
| 601 | ++ start_depth; | 601 | ++ start_depth; |
| 602 | lua_rawseti( L, -2, start_depth); // {} {fqn} | 602 | lua_rawseti( L, -2, start_depth); // {} {fqn} |
| 603 | STACK_MID( L, 2); | 603 | STACK_CHECK( L, 2); |
| 604 | } | 604 | } |
| 605 | // retrieve the cache, create it if we haven't done it yet | 605 | // retrieve the cache, create it if we haven't done it yet |
| 606 | LOOKUPCACHE_REGKEY.query_registry(L); // {} {fqn} {cache}? | 606 | LOOKUPCACHE_REGKEY.query_registry(L); // {} {fqn} {cache}? |
| @@ -609,7 +609,7 @@ void populate_func_lookup_table( lua_State* L, int _i, char const* name_) | |||
| 609 | lua_pop( L, 1); // {} {fqn} | 609 | lua_pop( L, 1); // {} {fqn} |
| 610 | lua_newtable( L); // {} {fqn} {cache} | 610 | lua_newtable( L); // {} {fqn} {cache} |
| 611 | LOOKUPCACHE_REGKEY.set_registry(L, [](lua_State* L) { lua_pushvalue(L, -2); }); | 611 | LOOKUPCACHE_REGKEY.set_registry(L, [](lua_State* L) { lua_pushvalue(L, -2); }); |
| 612 | STACK_MID( L, 3); | 612 | STACK_CHECK( L, 3); |
| 613 | } | 613 | } |
| 614 | // process everything we find in that table, filling in lookup data for all functions and tables we see there | 614 | // process everything we find in that table, filling in lookup data for all functions and tables we see there |
| 615 | populate_func_lookup_table_recur( DEBUGSPEW_PARAM_COMMA( U) L, ctx_base, in_base, start_depth); | 615 | populate_func_lookup_table_recur( DEBUGSPEW_PARAM_COMMA( U) L, ctx_base, in_base, start_depth); |
| @@ -620,7 +620,7 @@ void populate_func_lookup_table( lua_State* L, int _i, char const* name_) | |||
| 620 | lua_pop( L, 1); // | 620 | lua_pop( L, 1); // |
| 621 | (void) luaL_error( L, "unsupported module type %s", lua_typename( L, lua_type( L, in_base))); | 621 | (void) luaL_error( L, "unsupported module type %s", lua_typename( L, lua_type( L, in_base))); |
| 622 | } | 622 | } |
| 623 | STACK_END( L, 0); | 623 | STACK_CHECK( L, 0); |
| 624 | DEBUGSPEW_CODE( -- U->debugspew_indent_depth); | 624 | DEBUGSPEW_CODE( -- U->debugspew_indent_depth); |
| 625 | } | 625 | } |
| 626 | 626 | ||
| @@ -640,14 +640,14 @@ static lua_Integer get_mt_id( Universe* U, lua_State* L, int i) | |||
| 640 | 640 | ||
| 641 | STACK_GROW( L, 3); | 641 | STACK_GROW( L, 3); |
| 642 | 642 | ||
| 643 | STACK_CHECK( L, 0); | 643 | STACK_CHECK_START_REL(L, 0); |
| 644 | push_registry_subtable( L, REG_MTID); // ... _R[REG_MTID] | 644 | push_registry_subtable( L, REG_MTID); // ... _R[REG_MTID] |
| 645 | lua_pushvalue( L, i); // ... _R[REG_MTID] {mt} | 645 | lua_pushvalue( L, i); // ... _R[REG_MTID] {mt} |
| 646 | lua_rawget( L, -2); // ... _R[REG_MTID] mtk? | 646 | lua_rawget( L, -2); // ... _R[REG_MTID] mtk? |
| 647 | 647 | ||
| 648 | id = lua_tointeger( L, -1); // 0 for nil | 648 | id = lua_tointeger( L, -1); // 0 for nil |
| 649 | lua_pop( L, 1); // ... _R[REG_MTID] | 649 | lua_pop( L, 1); // ... _R[REG_MTID] |
| 650 | STACK_MID( L, 1); | 650 | STACK_CHECK( L, 1); |
| 651 | 651 | ||
| 652 | if( id == 0) | 652 | if( id == 0) |
| 653 | { | 653 | { |
| @@ -667,7 +667,7 @@ static lua_Integer get_mt_id( Universe* U, lua_State* L, int i) | |||
| 667 | } | 667 | } |
| 668 | lua_pop( L, 1); // ... | 668 | lua_pop( L, 1); // ... |
| 669 | 669 | ||
| 670 | STACK_END( L, 0); | 670 | STACK_CHECK( L, 0); |
| 671 | 671 | ||
| 672 | return id; | 672 | return id; |
| 673 | } | 673 | } |
| @@ -699,7 +699,7 @@ static char const* find_lookup_name(lua_State* L, int i, LookupMode mode_, char | |||
| 699 | DEBUGSPEW_CODE( Universe* const U = universe_get( L)); | 699 | DEBUGSPEW_CODE( Universe* const U = universe_get( L)); |
| 700 | char const* fqn; | 700 | char const* fqn; |
| 701 | ASSERT_L( lua_isfunction( L, i) || lua_istable( L, i)); // ... v ... | 701 | ASSERT_L( lua_isfunction( L, i) || lua_istable( L, i)); // ... v ... |
| 702 | STACK_CHECK( L, 0); | 702 | STACK_CHECK_START_REL(L, 0); |
| 703 | STACK_GROW( L, 3); // up to 3 slots are necessary on error | 703 | STACK_GROW( L, 3); // up to 3 slots are necessary on error |
| 704 | if( mode_ == eLM_FromKeeper) | 704 | if( mode_ == eLM_FromKeeper) |
| 705 | { | 705 | { |
| @@ -720,7 +720,7 @@ static char const* find_lookup_name(lua_State* L, int i, LookupMode mode_, char | |||
| 720 | { | 720 | { |
| 721 | // fetch the name from the source state's lookup table | 721 | // fetch the name from the source state's lookup table |
| 722 | LOOKUP_REGKEY.query_registry(L); // ... v ... {} | 722 | LOOKUP_REGKEY.query_registry(L); // ... v ... {} |
| 723 | STACK_MID( L, 1); | 723 | STACK_CHECK( L, 1); |
| 724 | ASSERT_L( lua_istable( L, -1)); | 724 | ASSERT_L( lua_istable( L, -1)); |
| 725 | lua_pushvalue( L, i); // ... v ... {} v | 725 | lua_pushvalue( L, i); // ... v ... {} v |
| 726 | lua_rawget( L, -2); // ... v ... {} "f.q.n" | 726 | lua_rawget( L, -2); // ... v ... {} "f.q.n" |
| @@ -729,7 +729,7 @@ static char const* find_lookup_name(lua_State* L, int i, LookupMode mode_, char | |||
| 729 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "function [C] %s \n" INDENT_END, fqn)); | 729 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "function [C] %s \n" INDENT_END, fqn)); |
| 730 | // popping doesn't invalidate the pointer since this is an interned string gotten from the lookup database | 730 | // popping doesn't invalidate the pointer since this is an interned string gotten from the lookup database |
| 731 | lua_pop( L, (mode_ == eLM_FromKeeper) ? 1 : 2); // ... v ... | 731 | lua_pop( L, (mode_ == eLM_FromKeeper) ? 1 : 2); // ... v ... |
| 732 | STACK_MID( L, 0); | 732 | STACK_CHECK( L, 0); |
| 733 | if (nullptr == fqn && !lua_istable(L, i)) // raise an error if we try to send an unknown function (but not for tables) | 733 | if (nullptr == fqn && !lua_istable(L, i)) // raise an error if we try to send an unknown function (but not for tables) |
| 734 | { | 734 | { |
| 735 | char const *from, *typewhat, *what, *gotchaA, *gotchaB; | 735 | char const *from, *typewhat, *what, *gotchaA, *gotchaB; |
| @@ -758,7 +758,7 @@ static char const* find_lookup_name(lua_State* L, int i, LookupMode mode_, char | |||
| 758 | *len_ = 0; | 758 | *len_ = 0; |
| 759 | return nullptr; | 759 | return nullptr; |
| 760 | } | 760 | } |
| 761 | STACK_END( L, 0); | 761 | STACK_CHECK( L, 0); |
| 762 | return fqn; | 762 | return fqn; |
| 763 | } | 763 | } |
| 764 | 764 | ||
| @@ -776,7 +776,7 @@ static bool lookup_table(lua_State* L2, lua_State* L, int i, LookupMode mode_, c | |||
| 776 | return false; | 776 | return false; |
| 777 | } | 777 | } |
| 778 | // push the equivalent table in the destination's stack, retrieved from the lookup table | 778 | // push the equivalent table in the destination's stack, retrieved from the lookup table |
| 779 | STACK_CHECK( L2, 0); // L // L2 | 779 | STACK_CHECK_START_REL(L2, 0); // L // L2 |
| 780 | STACK_GROW( L2, 3); // up to 3 slots are necessary on error | 780 | STACK_GROW( L2, 3); // up to 3 slots are necessary on error |
| 781 | switch( mode_) | 781 | switch( mode_) |
| 782 | { | 782 | { |
| @@ -793,7 +793,7 @@ static bool lookup_table(lua_State* L2, lua_State* L, int i, LookupMode mode_, c | |||
| 793 | case eLM_LaneBody: | 793 | case eLM_LaneBody: |
| 794 | case eLM_FromKeeper: | 794 | case eLM_FromKeeper: |
| 795 | LOOKUP_REGKEY.query_registry(L2); // {} | 795 | LOOKUP_REGKEY.query_registry(L2); // {} |
| 796 | STACK_MID( L2, 1); | 796 | STACK_CHECK( L2, 1); |
| 797 | ASSERT_L( lua_istable( L2, -1)); | 797 | ASSERT_L( lua_istable( L2, -1)); |
| 798 | lua_pushlstring( L2, fqn, len); // {} "f.q.n" | 798 | lua_pushlstring( L2, fqn, len); // {} "f.q.n" |
| 799 | lua_rawget( L2, -2); // {} t | 799 | lua_rawget( L2, -2); // {} t |
| @@ -802,7 +802,7 @@ static bool lookup_table(lua_State* L2, lua_State* L, int i, LookupMode mode_, c | |||
| 802 | if( lua_isnil( L2, -1) && mode_ == eLM_LaneBody) | 802 | if( lua_isnil( L2, -1) && mode_ == eLM_LaneBody) |
| 803 | { | 803 | { |
| 804 | lua_pop( L2, 2); // | 804 | lua_pop( L2, 2); // |
| 805 | STACK_MID( L2, 0); | 805 | STACK_CHECK( L2, 0); |
| 806 | return false; | 806 | return false; |
| 807 | } | 807 | } |
| 808 | else if( !lua_istable( L2, -1)) | 808 | else if( !lua_istable( L2, -1)) |
| @@ -827,7 +827,7 @@ static bool lookup_table(lua_State* L2, lua_State* L, int i, LookupMode mode_, c | |||
| 827 | lua_remove( L2, -2); // t | 827 | lua_remove( L2, -2); // t |
| 828 | break; | 828 | break; |
| 829 | } | 829 | } |
| 830 | STACK_END( L2, 1); | 830 | STACK_CHECK( L2, 1); |
| 831 | return true; | 831 | return true; |
| 832 | } | 832 | } |
| 833 | 833 | ||
| @@ -849,7 +849,7 @@ static bool push_cached_table(lua_State* L2, int L2_cache_i, lua_State* L, int i | |||
| 849 | 849 | ||
| 850 | ASSERT_L( L2_cache_i != 0); | 850 | ASSERT_L( L2_cache_i != 0); |
| 851 | STACK_GROW( L2, 3); | 851 | STACK_GROW( L2, 3); |
| 852 | STACK_CHECK( L2, 0); | 852 | STACK_CHECK_START_REL(L2, 0); |
| 853 | 853 | ||
| 854 | // We don't need to use the from state ('L') in ID since the life span | 854 | // We don't need to use the from state ('L') in ID since the life span |
| 855 | // is only for the duration of a copy (both states are locked). | 855 | // is only for the duration of a copy (both states are locked). |
| @@ -868,7 +868,7 @@ static bool push_cached_table(lua_State* L2, int L2_cache_i, lua_State* L, int i | |||
| 868 | lua_pushvalue( L2, -2); // ... {} p {} | 868 | lua_pushvalue( L2, -2); // ... {} p {} |
| 869 | lua_rawset( L2, L2_cache_i); // ... {} | 869 | lua_rawset( L2, L2_cache_i); // ... {} |
| 870 | } | 870 | } |
| 871 | STACK_END( L2, 1); | 871 | STACK_CHECK( L2, 1); |
| 872 | ASSERT_L( lua_istable( L2, -1)); | 872 | ASSERT_L( lua_istable( L2, -1)); |
| 873 | return !not_found_in_cache; | 873 | return !not_found_in_cache; |
| 874 | } | 874 | } |
| @@ -889,7 +889,7 @@ static int discover_object_name_recur( lua_State* L, int shortest_, int depth_) | |||
| 889 | return shortest_; | 889 | return shortest_; |
| 890 | } | 890 | } |
| 891 | STACK_GROW( L, 3); | 891 | STACK_GROW( L, 3); |
| 892 | STACK_CHECK( L, 0); | 892 | STACK_CHECK_START_REL(L, 0); |
| 893 | // stack top contains the table to search in | 893 | // stack top contains the table to search in |
| 894 | lua_pushvalue( L, -1); // o "r" {c} {fqn} ... {?} {?} | 894 | lua_pushvalue( L, -1); // o "r" {c} {fqn} ... {?} {?} |
| 895 | lua_rawget( L, cache); // o "r" {c} {fqn} ... {?} nil/1 | 895 | lua_rawget( L, cache); // o "r" {c} {fqn} ... {?} nil/1 |
| @@ -910,14 +910,14 @@ static int discover_object_name_recur( lua_State* L, int shortest_, int depth_) | |||
| 910 | { | 910 | { |
| 911 | //char const *const strKey = (lua_type( L, -2) == LUA_TSTRING) ? lua_tostring( L, -2) : nullptr; // only for debugging | 911 | //char const *const strKey = (lua_type( L, -2) == LUA_TSTRING) ? lua_tostring( L, -2) : nullptr; // only for debugging |
| 912 | //lua_Number const numKey = (lua_type( L, -2) == LUA_TNUMBER) ? lua_tonumber( L, -2) : -6666; // only for debugging | 912 | //lua_Number const numKey = (lua_type( L, -2) == LUA_TNUMBER) ? lua_tonumber( L, -2) : -6666; // only for debugging |
| 913 | STACK_MID( L, 2); | 913 | STACK_CHECK( L, 2); |
| 914 | // append key name to fqn stack | 914 | // append key name to fqn stack |
| 915 | ++ depth_; | 915 | ++ depth_; |
| 916 | lua_pushvalue( L, -2); // o "r" {c} {fqn} ... {?} k v k | 916 | lua_pushvalue( L, -2); // o "r" {c} {fqn} ... {?} k v k |
| 917 | lua_rawseti( L, fqn, depth_); // o "r" {c} {fqn} ... {?} k v | 917 | lua_rawseti( L, fqn, depth_); // o "r" {c} {fqn} ... {?} k v |
| 918 | if( lua_rawequal( L, -1, what)) // is it what we are looking for? | 918 | if( lua_rawequal( L, -1, what)) // is it what we are looking for? |
| 919 | { | 919 | { |
| 920 | STACK_MID( L, 2); | 920 | STACK_CHECK( L, 2); |
| 921 | // update shortest name | 921 | // update shortest name |
| 922 | if( depth_ < shortest_) | 922 | if( depth_ < shortest_) |
| 923 | { | 923 | { |
| @@ -927,7 +927,7 @@ static int discover_object_name_recur( lua_State* L, int shortest_, int depth_) | |||
| 927 | } | 927 | } |
| 928 | // no need to search further at this level | 928 | // no need to search further at this level |
| 929 | lua_pop( L, 2); // o "r" {c} {fqn} ... {?} | 929 | lua_pop( L, 2); // o "r" {c} {fqn} ... {?} |
| 930 | STACK_MID( L, 0); | 930 | STACK_CHECK( L, 0); |
| 931 | break; | 931 | break; |
| 932 | } | 932 | } |
| 933 | switch( lua_type( L, -1)) // o "r" {c} {fqn} ... {?} k v | 933 | switch( lua_type( L, -1)) // o "r" {c} {fqn} ... {?} k v |
| @@ -936,7 +936,7 @@ static int discover_object_name_recur( lua_State* L, int shortest_, int depth_) | |||
| 936 | break; | 936 | break; |
| 937 | 937 | ||
| 938 | case LUA_TTABLE: // o "r" {c} {fqn} ... {?} k {} | 938 | case LUA_TTABLE: // o "r" {c} {fqn} ... {?} k {} |
| 939 | STACK_MID( L, 2); | 939 | STACK_CHECK( L, 2); |
| 940 | shortest_ = discover_object_name_recur( L, shortest_, depth_); | 940 | shortest_ = discover_object_name_recur( L, shortest_, depth_); |
| 941 | // search in the table's metatable too | 941 | // search in the table's metatable too |
| 942 | if( lua_getmetatable( L, -1)) // o "r" {c} {fqn} ... {?} k {} {mt} | 942 | if( lua_getmetatable( L, -1)) // o "r" {c} {fqn} ... {?} k {} {mt} |
| @@ -953,7 +953,7 @@ static int discover_object_name_recur( lua_State* L, int shortest_, int depth_) | |||
| 953 | } | 953 | } |
| 954 | lua_pop( L, 1); // o "r" {c} {fqn} ... {?} k {} | 954 | lua_pop( L, 1); // o "r" {c} {fqn} ... {?} k {} |
| 955 | } | 955 | } |
| 956 | STACK_MID( L, 2); | 956 | STACK_CHECK( L, 2); |
| 957 | break; | 957 | break; |
| 958 | 958 | ||
| 959 | case LUA_TTHREAD: // o "r" {c} {fqn} ... {?} k T | 959 | case LUA_TTHREAD: // o "r" {c} {fqn} ... {?} k T |
| @@ -961,7 +961,7 @@ static int discover_object_name_recur( lua_State* L, int shortest_, int depth_) | |||
| 961 | break; | 961 | break; |
| 962 | 962 | ||
| 963 | case LUA_TUSERDATA: // o "r" {c} {fqn} ... {?} k U | 963 | case LUA_TUSERDATA: // o "r" {c} {fqn} ... {?} k U |
| 964 | STACK_MID( L, 2); | 964 | STACK_CHECK( L, 2); |
| 965 | // search in the object's metatable (some modules are built that way) | 965 | // search in the object's metatable (some modules are built that way) |
| 966 | if( lua_getmetatable( L, -1)) // o "r" {c} {fqn} ... {?} k U {mt} | 966 | if( lua_getmetatable( L, -1)) // o "r" {c} {fqn} ... {?} k U {mt} |
| 967 | { | 967 | { |
| @@ -977,7 +977,7 @@ static int discover_object_name_recur( lua_State* L, int shortest_, int depth_) | |||
| 977 | } | 977 | } |
| 978 | lua_pop( L, 1); // o "r" {c} {fqn} ... {?} k U | 978 | lua_pop( L, 1); // o "r" {c} {fqn} ... {?} k U |
| 979 | } | 979 | } |
| 980 | STACK_MID( L, 2); | 980 | STACK_CHECK( L, 2); |
| 981 | // search in the object's uservalues | 981 | // search in the object's uservalues |
| 982 | { | 982 | { |
| 983 | int uvi = 1; | 983 | int uvi = 1; |
| @@ -999,7 +999,7 @@ static int discover_object_name_recur( lua_State* L, int shortest_, int depth_) | |||
| 999 | // when lua_getiuservalue() returned LUA_TNONE, it pushed a nil. pop it now | 999 | // when lua_getiuservalue() returned LUA_TNONE, it pushed a nil. pop it now |
| 1000 | lua_pop( L, 1); // o "r" {c} {fqn} ... {?} k U | 1000 | lua_pop( L, 1); // o "r" {c} {fqn} ... {?} k U |
| 1001 | } | 1001 | } |
| 1002 | STACK_MID( L, 2); | 1002 | STACK_CHECK( L, 2); |
| 1003 | break; | 1003 | break; |
| 1004 | } | 1004 | } |
| 1005 | // make ready for next iteration | 1005 | // make ready for next iteration |
| @@ -1007,15 +1007,15 @@ static int discover_object_name_recur( lua_State* L, int shortest_, int depth_) | |||
| 1007 | // remove name from fqn stack | 1007 | // remove name from fqn stack |
| 1008 | lua_pushnil( L); // o "r" {c} {fqn} ... {?} k nil | 1008 | lua_pushnil( L); // o "r" {c} {fqn} ... {?} k nil |
| 1009 | lua_rawseti( L, fqn, depth_); // o "r" {c} {fqn} ... {?} k | 1009 | lua_rawseti( L, fqn, depth_); // o "r" {c} {fqn} ... {?} k |
| 1010 | STACK_MID( L, 1); | 1010 | STACK_CHECK( L, 1); |
| 1011 | -- depth_; | 1011 | -- depth_; |
| 1012 | } // o "r" {c} {fqn} ... {?} | 1012 | } // o "r" {c} {fqn} ... {?} |
| 1013 | STACK_MID( L, 0); | 1013 | STACK_CHECK( L, 0); |
| 1014 | // remove the visited table from the cache, in case a shorter path to the searched object exists | 1014 | // remove the visited table from the cache, in case a shorter path to the searched object exists |
| 1015 | lua_pushvalue( L, -1); // o "r" {c} {fqn} ... {?} {?} | 1015 | lua_pushvalue( L, -1); // o "r" {c} {fqn} ... {?} {?} |
| 1016 | lua_pushnil( L); // o "r" {c} {fqn} ... {?} {?} nil | 1016 | lua_pushnil( L); // o "r" {c} {fqn} ... {?} {?} nil |
| 1017 | lua_rawset( L, cache); // o "r" {c} {fqn} ... {?} | 1017 | lua_rawset( L, cache); // o "r" {c} {fqn} ... {?} |
| 1018 | STACK_END( L, 0); | 1018 | STACK_CHECK( L, 0); |
| 1019 | return shortest_; | 1019 | return shortest_; |
| 1020 | } | 1020 | } |
| 1021 | 1021 | ||
| @@ -1040,7 +1040,7 @@ int luaG_nameof( lua_State* L) | |||
| 1040 | } | 1040 | } |
| 1041 | 1041 | ||
| 1042 | STACK_GROW( L, 4); | 1042 | STACK_GROW( L, 4); |
| 1043 | STACK_CHECK( L, 0); | 1043 | STACK_CHECK_START_REL(L, 0); |
| 1044 | // this slot will contain the shortest name we found when we are done | 1044 | // this slot will contain the shortest name we found when we are done |
| 1045 | lua_pushnil( L); // o nil | 1045 | lua_pushnil( L); // o nil |
| 1046 | // push a cache that will contain all already visited tables | 1046 | // push a cache that will contain all already visited tables |
| @@ -1061,7 +1061,7 @@ int luaG_nameof( lua_State* L) | |||
| 1061 | (void) discover_object_name_recur( L, 6666, 1); | 1061 | (void) discover_object_name_recur( L, 6666, 1); |
| 1062 | } | 1062 | } |
| 1063 | lua_pop( L, 3); // o "result" | 1063 | lua_pop( L, 3); // o "result" |
| 1064 | STACK_END( L, 1); | 1064 | STACK_CHECK( L, 1); |
| 1065 | lua_pushstring( L, luaL_typename( L, 1)); // o "result" "type" | 1065 | lua_pushstring( L, luaL_typename( L, 1)); // o "result" "type" |
| 1066 | lua_replace( L, -3); // "type" "result" | 1066 | lua_replace( L, -3); // "type" "result" |
| 1067 | return 2; | 1067 | return 2; |
| @@ -1077,7 +1077,7 @@ static void lookup_native_func(lua_State* L2, lua_State* L, int i, LookupMode mo | |||
| 1077 | size_t len; | 1077 | size_t len; |
| 1078 | char const* fqn = find_lookup_name( L, i, mode_, upName_, &len); | 1078 | char const* fqn = find_lookup_name( L, i, mode_, upName_, &len); |
| 1079 | // push the equivalent function in the destination's stack, retrieved from the lookup table | 1079 | // push the equivalent function in the destination's stack, retrieved from the lookup table |
| 1080 | STACK_CHECK( L2, 0); // L // L2 | 1080 | STACK_CHECK_START_REL(L2, 0); // L // L2 |
| 1081 | STACK_GROW( L2, 3); // up to 3 slots are necessary on error | 1081 | STACK_GROW( L2, 3); // up to 3 slots are necessary on error |
| 1082 | switch( mode_) | 1082 | switch( mode_) |
| 1083 | { | 1083 | { |
| @@ -1094,7 +1094,7 @@ static void lookup_native_func(lua_State* L2, lua_State* L, int i, LookupMode mo | |||
| 1094 | case eLM_LaneBody: | 1094 | case eLM_LaneBody: |
| 1095 | case eLM_FromKeeper: | 1095 | case eLM_FromKeeper: |
| 1096 | LOOKUP_REGKEY.query_registry(L2); // {} | 1096 | LOOKUP_REGKEY.query_registry(L2); // {} |
| 1097 | STACK_MID( L2, 1); | 1097 | STACK_CHECK( L2, 1); |
| 1098 | ASSERT_L( lua_istable( L2, -1)); | 1098 | ASSERT_L( lua_istable( L2, -1)); |
| 1099 | lua_pushlstring( L2, fqn, len); // {} "f.q.n" | 1099 | lua_pushlstring( L2, fqn, len); // {} "f.q.n" |
| 1100 | lua_rawget( L2, -2); // {} f | 1100 | lua_rawget( L2, -2); // {} f |
| @@ -1139,7 +1139,7 @@ static void lookup_native_func(lua_State* L2, lua_State* L, int i, LookupMode mo | |||
| 1139 | break; | 1139 | break; |
| 1140 | */ | 1140 | */ |
| 1141 | } | 1141 | } |
| 1142 | STACK_END( L2, 1); | 1142 | STACK_CHECK( L2, 1); |
| 1143 | } | 1143 | } |
| 1144 | 1144 | ||
| 1145 | 1145 | ||
| @@ -1194,7 +1194,7 @@ static void copy_func(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, | |||
| 1194 | 1194 | ||
| 1195 | ASSERT_L( L2_cache_i != 0); // ... {cache} ... p | 1195 | ASSERT_L( L2_cache_i != 0); // ... {cache} ... p |
| 1196 | STACK_GROW( L, 2); | 1196 | STACK_GROW( L, 2); |
| 1197 | STACK_CHECK( L, 0); | 1197 | STACK_CHECK_START_REL(L, 0); |
| 1198 | 1198 | ||
| 1199 | 1199 | ||
| 1200 | // 'lua_dump()' needs the function at top of stack | 1200 | // 'lua_dump()' needs the function at top of stack |
| @@ -1270,7 +1270,7 @@ static void copy_func(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, | |||
| 1270 | // cache[p] = function | 1270 | // cache[p] = function |
| 1271 | lua_rawset( L2, L2_cache_i); // ... {cache} ... function | 1271 | lua_rawset( L2, L2_cache_i); // ... {cache} ... function |
| 1272 | } | 1272 | } |
| 1273 | STACK_MID( L, 0); | 1273 | STACK_CHECK( L, 0); |
| 1274 | 1274 | ||
| 1275 | /* push over any upvalues; references to this function will come from | 1275 | /* push over any upvalues; references to this function will come from |
| 1276 | * cache so we don't end up in eternal loop. | 1276 | * cache so we don't end up in eternal loop. |
| @@ -1311,7 +1311,7 @@ static void copy_func(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, | |||
| 1311 | } | 1311 | } |
| 1312 | // L2: function + 'n' upvalues (>=0) | 1312 | // L2: function + 'n' upvalues (>=0) |
| 1313 | 1313 | ||
| 1314 | STACK_MID( L, 0); | 1314 | STACK_CHECK( L, 0); |
| 1315 | 1315 | ||
| 1316 | // Set upvalues (originally set to 'nil' by 'lua_load') | 1316 | // Set upvalues (originally set to 'nil' by 'lua_load') |
| 1317 | { | 1317 | { |
| @@ -1329,7 +1329,7 @@ static void copy_func(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, | |||
| 1329 | // with the function at the top of the stack // ... {cache} ... function | 1329 | // with the function at the top of the stack // ... {cache} ... function |
| 1330 | } | 1330 | } |
| 1331 | } | 1331 | } |
| 1332 | STACK_END( L, 0); | 1332 | STACK_CHECK( L, 0); |
| 1333 | } | 1333 | } |
| 1334 | 1334 | ||
| 1335 | /* | 1335 | /* |
| @@ -1352,7 +1352,7 @@ static void copy_cached_func(Universe* U, lua_State* L2, int L2_cache_i, lua_Sta | |||
| 1352 | 1352 | ||
| 1353 | // L2_cache[id_str]= function | 1353 | // L2_cache[id_str]= function |
| 1354 | // | 1354 | // |
| 1355 | STACK_CHECK( L2, 0); | 1355 | STACK_CHECK_START_REL(L2, 0); |
| 1356 | 1356 | ||
| 1357 | // We don't need to use the from state ('L') in ID since the life span | 1357 | // We don't need to use the from state ('L') in ID since the life span |
| 1358 | // is only for the duration of a copy (both states are locked). | 1358 | // is only for the duration of a copy (both states are locked). |
| @@ -1380,7 +1380,7 @@ static void copy_cached_func(Universe* U, lua_State* L2, int L2_cache_i, lua_Sta | |||
| 1380 | { | 1380 | { |
| 1381 | lua_remove( L2, -2); // ... {cache} ... function | 1381 | lua_remove( L2, -2); // ... {cache} ... function |
| 1382 | } | 1382 | } |
| 1383 | STACK_END( L2, 1); | 1383 | STACK_CHECK( L2, 1); |
| 1384 | ASSERT_L( lua_isfunction( L2, -1)); | 1384 | ASSERT_L( lua_isfunction( L2, -1)); |
| 1385 | } | 1385 | } |
| 1386 | else // function is native/LuaJIT: no need to cache | 1386 | else // function is native/LuaJIT: no need to cache |
| @@ -1393,26 +1393,26 @@ static void copy_cached_func(Universe* U, lua_State* L2, int L2_cache_i, lua_Sta | |||
| 1393 | 1393 | ||
| 1394 | static bool push_cached_metatable(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, int i, LookupMode mode_, char const* upName_) | 1394 | static bool push_cached_metatable(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, int i, LookupMode mode_, char const* upName_) |
| 1395 | { | 1395 | { |
| 1396 | STACK_CHECK( L, 0); | 1396 | STACK_CHECK_START_REL(L, 0); |
| 1397 | if( lua_getmetatable( L, i)) // ... mt | 1397 | if( lua_getmetatable( L, i)) // ... mt |
| 1398 | { | 1398 | { |
| 1399 | lua_Integer const mt_id = get_mt_id( U, L, -1); // Unique id for the metatable | 1399 | lua_Integer const mt_id = get_mt_id( U, L, -1); // Unique id for the metatable |
| 1400 | 1400 | ||
| 1401 | STACK_CHECK( L2, 0); | 1401 | STACK_CHECK_START_REL(L2, 0); |
| 1402 | STACK_GROW( L2, 4); | 1402 | STACK_GROW( L2, 4); |
| 1403 | // do we already know this metatable? | 1403 | // do we already know this metatable? |
| 1404 | push_registry_subtable( L2, REG_MTID); // _R[REG_MTID] | 1404 | push_registry_subtable( L2, REG_MTID); // _R[REG_MTID] |
| 1405 | lua_pushinteger( L2, mt_id); // _R[REG_MTID] id | 1405 | lua_pushinteger( L2, mt_id); // _R[REG_MTID] id |
| 1406 | lua_rawget( L2, -2); // _R[REG_MTID] mt? | 1406 | lua_rawget( L2, -2); // _R[REG_MTID] mt? |
| 1407 | 1407 | ||
| 1408 | STACK_MID( L2, 2); | 1408 | STACK_CHECK( L2, 2); |
| 1409 | 1409 | ||
| 1410 | if( lua_isnil( L2, -1)) | 1410 | if( lua_isnil( L2, -1)) |
| 1411 | { // L2 did not know the metatable | 1411 | { // L2 did not know the metatable |
| 1412 | lua_pop( L2, 1); // _R[REG_MTID] | 1412 | lua_pop( L2, 1); // _R[REG_MTID] |
| 1413 | if( inter_copy_one( U, L2, L2_cache_i, L, lua_gettop( L), VT_METATABLE, mode_, upName_)) // _R[REG_MTID] mt | 1413 | if( inter_copy_one( U, L2, L2_cache_i, L, lua_gettop( L), VT_METATABLE, mode_, upName_)) // _R[REG_MTID] mt |
| 1414 | { | 1414 | { |
| 1415 | STACK_MID( L2, 2); | 1415 | STACK_CHECK( L2, 2); |
| 1416 | // mt_id -> metatable | 1416 | // mt_id -> metatable |
| 1417 | lua_pushinteger( L2, mt_id); // _R[REG_MTID] mt id | 1417 | lua_pushinteger( L2, mt_id); // _R[REG_MTID] mt id |
| 1418 | lua_pushvalue( L2, -2); // _R[REG_MTID] mt id mt | 1418 | lua_pushvalue( L2, -2); // _R[REG_MTID] mt id mt |
| @@ -1427,16 +1427,16 @@ static bool push_cached_metatable(Universe* U, lua_State* L2, int L2_cache_i, lu | |||
| 1427 | { | 1427 | { |
| 1428 | (void) luaL_error( L, "Error copying a metatable"); | 1428 | (void) luaL_error( L, "Error copying a metatable"); |
| 1429 | } | 1429 | } |
| 1430 | STACK_MID( L2, 2); | 1430 | STACK_CHECK( L2, 2); |
| 1431 | } | 1431 | } |
| 1432 | lua_remove( L2, -2); // mt | 1432 | lua_remove( L2, -2); // mt |
| 1433 | 1433 | ||
| 1434 | lua_pop( L, 1); // ... | 1434 | lua_pop( L, 1); // ... |
| 1435 | STACK_END( L2, 1); | 1435 | STACK_CHECK( L2, 1); |
| 1436 | STACK_MID( L, 0); | 1436 | STACK_CHECK( L, 0); |
| 1437 | return true; | 1437 | return true; |
| 1438 | } | 1438 | } |
| 1439 | STACK_END( L, 0); | 1439 | STACK_CHECK( L, 0); |
| 1440 | return false; | 1440 | return false; |
| 1441 | } | 1441 | } |
| 1442 | 1442 | ||
| @@ -1515,27 +1515,27 @@ static bool copyclone(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, | |||
| 1515 | void* const source = lua_touserdata( L, source_i_); | 1515 | void* const source = lua_touserdata( L, source_i_); |
| 1516 | source_i_ = lua_absindex( L, source_i_); | 1516 | source_i_ = lua_absindex( L, source_i_); |
| 1517 | 1517 | ||
| 1518 | STACK_CHECK( L, 0); // L (source) // L2 (destination) | 1518 | STACK_CHECK_START_REL(L, 0); // L (source) // L2 (destination) |
| 1519 | STACK_CHECK( L2, 0); | 1519 | STACK_CHECK_START_REL(L2, 0); |
| 1520 | 1520 | ||
| 1521 | // Check if the source was already cloned during this copy | 1521 | // Check if the source was already cloned during this copy |
| 1522 | lua_pushlightuserdata( L2, source); // ... source | 1522 | lua_pushlightuserdata( L2, source); // ... source |
| 1523 | lua_rawget( L2, L2_cache_i); // ... clone? | 1523 | lua_rawget( L2, L2_cache_i); // ... clone? |
| 1524 | if ( !lua_isnil( L2, -1)) | 1524 | if ( !lua_isnil( L2, -1)) |
| 1525 | { | 1525 | { |
| 1526 | STACK_MID( L2, 1); | 1526 | STACK_CHECK( L2, 1); |
| 1527 | return true; | 1527 | return true; |
| 1528 | } | 1528 | } |
| 1529 | else | 1529 | else |
| 1530 | { | 1530 | { |
| 1531 | lua_pop( L2, 1); // ... | 1531 | lua_pop( L2, 1); // ... |
| 1532 | } | 1532 | } |
| 1533 | STACK_MID( L2, 0); | 1533 | STACK_CHECK( L2, 0); |
| 1534 | 1534 | ||
| 1535 | // no metatable? -> not clonable | 1535 | // no metatable? -> not clonable |
| 1536 | if( !lua_getmetatable( L, source_i_)) // ... mt? | 1536 | if( !lua_getmetatable( L, source_i_)) // ... mt? |
| 1537 | { | 1537 | { |
| 1538 | STACK_MID( L, 0); | 1538 | STACK_CHECK( L, 0); |
| 1539 | return false; | 1539 | return false; |
| 1540 | } | 1540 | } |
| 1541 | 1541 | ||
| @@ -1544,7 +1544,7 @@ static bool copyclone(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, | |||
| 1544 | if( lua_isnil( L, -1)) | 1544 | if( lua_isnil( L, -1)) |
| 1545 | { | 1545 | { |
| 1546 | lua_pop( L, 2); // ... | 1546 | lua_pop( L, 2); // ... |
| 1547 | STACK_MID( L, 0); | 1547 | STACK_CHECK( L, 0); |
| 1548 | return false; | 1548 | return false; |
| 1549 | } | 1549 | } |
| 1550 | 1550 | ||
| @@ -1578,7 +1578,7 @@ static bool copyclone(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, | |||
| 1578 | ASSERT_L( lua_istable( L2, -1)); | 1578 | ASSERT_L( lua_istable( L2, -1)); |
| 1579 | lua_setmetatable( L2, -2); // ... u | 1579 | lua_setmetatable( L2, -2); // ... u |
| 1580 | } | 1580 | } |
| 1581 | STACK_MID( L2, 1); | 1581 | STACK_CHECK( L2, 1); |
| 1582 | } | 1582 | } |
| 1583 | else | 1583 | else |
| 1584 | { | 1584 | { |
| @@ -1597,7 +1597,7 @@ static bool copyclone(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, | |||
| 1597 | while( uvi > 0) | 1597 | while( uvi > 0) |
| 1598 | { | 1598 | { |
| 1599 | inter_copy_one( U, L2, L2_cache_i, L, lua_absindex( L, -1), VT_NORMAL, mode_, upName_); // ... u uv | 1599 | inter_copy_one( U, L2, L2_cache_i, L, lua_absindex( L, -1), VT_NORMAL, mode_, upName_); // ... u uv |
| 1600 | lua_pop( L, 1); // ... mt __lanesclone [uv]* | 1600 | lua_pop( L, 1); // ... mt __lanesclone [uv]* |
| 1601 | // this pops the value from the stack | 1601 | // this pops the value from the stack |
| 1602 | lua_setiuservalue( L2, -2, uvi); // ... u | 1602 | lua_setiuservalue( L2, -2, uvi); // ... u |
| 1603 | -- uvi; | 1603 | -- uvi; |
| @@ -1607,26 +1607,26 @@ static bool copyclone(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, | |||
| 1607 | { | 1607 | { |
| 1608 | lua_pop( L2, 1); // ... userdata_clone_sentinel | 1608 | lua_pop( L2, 1); // ... userdata_clone_sentinel |
| 1609 | } | 1609 | } |
| 1610 | STACK_MID( L2, 1); | 1610 | STACK_CHECK( L2, 1); |
| 1611 | STACK_MID( L, 2); | 1611 | STACK_CHECK( L, 2); |
| 1612 | // call cloning function in source state to perform the actual memory cloning | 1612 | // call cloning function in source state to perform the actual memory cloning |
| 1613 | lua_pushlightuserdata( L, clone); // ... mt __lanesclone clone | 1613 | lua_pushlightuserdata( L, clone); // ... mt __lanesclone clone |
| 1614 | lua_pushlightuserdata( L, source); // ... mt __lanesclone clone source | 1614 | lua_pushlightuserdata( L, source); // ... mt __lanesclone clone source |
| 1615 | lua_pushinteger( L, userdata_size); // ... mt __lanesclone clone source size | 1615 | lua_pushinteger( L, userdata_size); // ... mt __lanesclone clone source size |
| 1616 | lua_call( L, 3, 0); // ... mt | 1616 | lua_call( L, 3, 0); // ... mt |
| 1617 | STACK_MID( L, 1); | 1617 | STACK_CHECK( L, 1); |
| 1618 | } | 1618 | } |
| 1619 | 1619 | ||
| 1620 | STACK_END( L2, 1); | 1620 | STACK_CHECK( L2, 1); |
| 1621 | lua_pop( L, 1); // ... | 1621 | lua_pop( L, 1); // ... |
| 1622 | STACK_END( L, 0); | 1622 | STACK_CHECK( L, 0); |
| 1623 | return true; | 1623 | return true; |
| 1624 | } | 1624 | } |
| 1625 | 1625 | ||
| 1626 | static bool inter_copy_userdata(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, int i, enum e_vt vt, LookupMode mode_, char const* upName_) | 1626 | static bool inter_copy_userdata(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, int i, enum e_vt vt, LookupMode mode_, char const* upName_) |
| 1627 | { | 1627 | { |
| 1628 | STACK_CHECK( L, 0); | 1628 | STACK_CHECK_START_REL(L, 0); |
| 1629 | STACK_CHECK( L2, 0); | 1629 | STACK_CHECK_START_REL(L2, 0); |
| 1630 | if( vt == VT_KEY) | 1630 | if( vt == VT_KEY) |
| 1631 | { | 1631 | { |
| 1632 | return false; | 1632 | return false; |
| @@ -1635,25 +1635,25 @@ static bool inter_copy_userdata(Universe* U, lua_State* L2, int L2_cache_i, lua_ | |||
| 1635 | // try clonable userdata first | 1635 | // try clonable userdata first |
| 1636 | if( copyclone( U, L2, L2_cache_i, L, i, mode_, upName_)) | 1636 | if( copyclone( U, L2, L2_cache_i, L, i, mode_, upName_)) |
| 1637 | { | 1637 | { |
| 1638 | STACK_MID( L, 0); | 1638 | STACK_CHECK( L, 0); |
| 1639 | STACK_MID( L2, 1); | 1639 | STACK_CHECK( L2, 1); |
| 1640 | return true; | 1640 | return true; |
| 1641 | } | 1641 | } |
| 1642 | 1642 | ||
| 1643 | STACK_MID( L, 0); | 1643 | STACK_CHECK( L, 0); |
| 1644 | STACK_MID( L2, 0); | 1644 | STACK_CHECK( L2, 0); |
| 1645 | 1645 | ||
| 1646 | // Allow only deep userdata entities to be copied across | 1646 | // Allow only deep userdata entities to be copied across |
| 1647 | DEBUGSPEW_CODE( fprintf( stderr, "USERDATA\n")); | 1647 | DEBUGSPEW_CODE( fprintf( stderr, "USERDATA\n")); |
| 1648 | if( copydeep( U, L2, L2_cache_i, L, i, mode_, upName_)) | 1648 | if( copydeep( U, L2, L2_cache_i, L, i, mode_, upName_)) |
| 1649 | { | 1649 | { |
| 1650 | STACK_MID( L, 0); | 1650 | STACK_CHECK( L, 0); |
| 1651 | STACK_MID( L2, 1); | 1651 | STACK_CHECK( L2, 1); |
| 1652 | return true; | 1652 | return true; |
| 1653 | } | 1653 | } |
| 1654 | 1654 | ||
| 1655 | STACK_MID( L, 0); | 1655 | STACK_CHECK( L, 0); |
| 1656 | STACK_MID( L2, 0); | 1656 | STACK_CHECK( L2, 0); |
| 1657 | 1657 | ||
| 1658 | // Not a deep or clonable full userdata | 1658 | // Not a deep or clonable full userdata |
| 1659 | if( U->demoteFullUserdata) // attempt demotion to light userdata | 1659 | if( U->demoteFullUserdata) // attempt demotion to light userdata |
| @@ -1666,8 +1666,8 @@ static bool inter_copy_userdata(Universe* U, lua_State* L2, int L2_cache_i, lua_ | |||
| 1666 | (void) luaL_error( L, "can't copy non-deep full userdata across lanes"); | 1666 | (void) luaL_error( L, "can't copy non-deep full userdata across lanes"); |
| 1667 | } | 1667 | } |
| 1668 | 1668 | ||
| 1669 | STACK_END( L2, 1); | 1669 | STACK_CHECK( L2, 1); |
| 1670 | STACK_END( L, 0); | 1670 | STACK_CHECK( L, 0); |
| 1671 | return true; | 1671 | return true; |
| 1672 | } | 1672 | } |
| 1673 | 1673 | ||
| @@ -1678,8 +1678,8 @@ static bool inter_copy_function(Universe* U, lua_State* L2, int L2_cache_i, lua_ | |||
| 1678 | return false; | 1678 | return false; |
| 1679 | } | 1679 | } |
| 1680 | 1680 | ||
| 1681 | STACK_CHECK( L, 0); // L (source) // L2 (destination) | 1681 | STACK_CHECK_START_REL(L, 0); // L (source) // L2 (destination) |
| 1682 | STACK_CHECK( L2, 0); | 1682 | STACK_CHECK_START_REL(L2, 0); |
| 1683 | DEBUGSPEW_CODE( fprintf( stderr, "FUNCTION %s\n", upName_)); | 1683 | DEBUGSPEW_CODE( fprintf( stderr, "FUNCTION %s\n", upName_)); |
| 1684 | 1684 | ||
| 1685 | if( lua_tocfunction( L, source_i_) == userdata_clone_sentinel) // we are actually copying a clonable full userdata from a keeper | 1685 | if( lua_tocfunction( L, source_i_) == userdata_clone_sentinel) // we are actually copying a clonable full userdata from a keeper |
| @@ -1697,8 +1697,8 @@ static bool inter_copy_function(Universe* U, lua_State* L2, int L2_cache_i, lua_ | |||
| 1697 | if( !lua_isnil( L2, -1)) | 1697 | if( !lua_isnil( L2, -1)) |
| 1698 | { | 1698 | { |
| 1699 | lua_pop( L, 1); // ... | 1699 | lua_pop( L, 1); // ... |
| 1700 | STACK_MID( L, 0); | 1700 | STACK_CHECK( L, 0); |
| 1701 | STACK_MID( L2, 1); | 1701 | STACK_CHECK( L2, 1); |
| 1702 | return true; | 1702 | return true; |
| 1703 | } | 1703 | } |
| 1704 | lua_pop( L2, 1); // ... | 1704 | lua_pop( L2, 1); // ... |
| @@ -1717,7 +1717,7 @@ static bool inter_copy_function(Universe* U, lua_State* L2, int L2_cache_i, lua_ | |||
| 1717 | // when lua_getiuservalue() returned LUA_TNONE, it pushed a nil. pop it now | 1717 | // when lua_getiuservalue() returned LUA_TNONE, it pushed a nil. pop it now |
| 1718 | lua_pop( L, 1); // ... u [uv]* | 1718 | lua_pop( L, 1); // ... u [uv]* |
| 1719 | -- uvi; | 1719 | -- uvi; |
| 1720 | STACK_MID( L, uvi + 1); | 1720 | STACK_CHECK( L, uvi + 1); |
| 1721 | // create the clone userdata with the required number of uservalue slots | 1721 | // create the clone userdata with the required number of uservalue slots |
| 1722 | clone = lua_newuserdatauv( L2, userdata_size, uvi); // ... mt u | 1722 | clone = lua_newuserdatauv( L2, userdata_size, uvi); // ... mt u |
| 1723 | // add it in the cache | 1723 | // add it in the cache |
| @@ -1738,8 +1738,8 @@ static bool inter_copy_function(Universe* U, lua_State* L2, int L2_cache_i, lua_ | |||
| 1738 | } | 1738 | } |
| 1739 | // when we are done, all uservalues are popped from the stack, we can pop the source as well | 1739 | // when we are done, all uservalues are popped from the stack, we can pop the source as well |
| 1740 | lua_pop( L, 1); // ... | 1740 | lua_pop( L, 1); // ... |
| 1741 | STACK_MID( L, 0); | 1741 | STACK_CHECK( L, 0); |
| 1742 | STACK_MID( L2, 2); // ... mt u | 1742 | STACK_CHECK( L2, 2); // ... mt u |
| 1743 | } | 1743 | } |
| 1744 | // perform the custom cloning part | 1744 | // perform the custom cloning part |
| 1745 | lua_insert( L2, -2); // ... u mt | 1745 | lua_insert( L2, -2); // ... u mt |
| @@ -1759,8 +1759,8 @@ static bool inter_copy_function(Universe* U, lua_State* L2, int L2_cache_i, lua_ | |||
| 1759 | copy_cached_func( U, L2, L2_cache_i, L, source_i_, mode_, upName_); // ... f | 1759 | copy_cached_func( U, L2, L2_cache_i, L, source_i_, mode_, upName_); // ... f |
| 1760 | DEBUGSPEW_CODE( -- U->debugspew_indent_depth); | 1760 | DEBUGSPEW_CODE( -- U->debugspew_indent_depth); |
| 1761 | } | 1761 | } |
| 1762 | STACK_END( L2, 1); | 1762 | STACK_CHECK( L2, 1); |
| 1763 | STACK_END( L, 0); | 1763 | STACK_CHECK( L, 0); |
| 1764 | return true; | 1764 | return true; |
| 1765 | } | 1765 | } |
| 1766 | 1766 | ||
| @@ -1771,8 +1771,8 @@ static bool inter_copy_table(Universe* U, lua_State* L2, int L2_cache_i, lua_Sta | |||
| 1771 | return false; | 1771 | return false; |
| 1772 | } | 1772 | } |
| 1773 | 1773 | ||
| 1774 | STACK_CHECK( L, 0); | 1774 | STACK_CHECK_START_REL(L, 0); |
| 1775 | STACK_CHECK( L2, 0); | 1775 | STACK_CHECK_START_REL(L2, 0); |
| 1776 | DEBUGSPEW_CODE( fprintf( stderr, "TABLE %s\n", upName_)); | 1776 | DEBUGSPEW_CODE( fprintf( stderr, "TABLE %s\n", upName_)); |
| 1777 | 1777 | ||
| 1778 | /* | 1778 | /* |
| @@ -1811,16 +1811,16 @@ static bool inter_copy_table(Universe* U, lua_State* L2, int L2_cache_i, lua_Sta | |||
| 1811 | inter_copy_keyvaluepair( U, L2, L2_cache_i, L, vt, mode_, upName_); | 1811 | inter_copy_keyvaluepair( U, L2, L2_cache_i, L, vt, mode_, upName_); |
| 1812 | lua_pop( L, 1); // pop value (next round) | 1812 | lua_pop( L, 1); // pop value (next round) |
| 1813 | } | 1813 | } |
| 1814 | STACK_MID( L, 0); | 1814 | STACK_CHECK( L, 0); |
| 1815 | STACK_MID( L2, 1); | 1815 | STACK_CHECK( L2, 1); |
| 1816 | 1816 | ||
| 1817 | // Metatables are expected to be immutable, and copied only once. | 1817 | // Metatables are expected to be immutable, and copied only once. |
| 1818 | if( push_cached_metatable( U, L2, L2_cache_i, L, i, mode_, upName_)) // ... t mt? | 1818 | if( push_cached_metatable( U, L2, L2_cache_i, L, i, mode_, upName_)) // ... t mt? |
| 1819 | { | 1819 | { |
| 1820 | lua_setmetatable( L2, -2); // ... t | 1820 | lua_setmetatable( L2, -2); // ... t |
| 1821 | } | 1821 | } |
| 1822 | STACK_END( L2, 1); | 1822 | STACK_CHECK( L2, 1); |
| 1823 | STACK_END( L, 0); | 1823 | STACK_CHECK( L, 0); |
| 1824 | return true; | 1824 | return true; |
| 1825 | } | 1825 | } |
| 1826 | 1826 | ||
| @@ -1840,8 +1840,8 @@ bool inter_copy_one(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, in | |||
| 1840 | int val_type = lua_type( L, i); | 1840 | int val_type = lua_type( L, i); |
| 1841 | static int const pod_mask = (1 << LUA_TNIL) | (1 << LUA_TBOOLEAN) | (1 << LUA_TLIGHTUSERDATA) | (1 << LUA_TNUMBER) | (1 << LUA_TSTRING); | 1841 | static int const pod_mask = (1 << LUA_TNIL) | (1 << LUA_TBOOLEAN) | (1 << LUA_TLIGHTUSERDATA) | (1 << LUA_TNUMBER) | (1 << LUA_TSTRING); |
| 1842 | STACK_GROW( L2, 1); | 1842 | STACK_GROW( L2, 1); |
| 1843 | STACK_CHECK( L, 0); // L // L2 | 1843 | STACK_CHECK_START_REL(L, 0); // L // L2 |
| 1844 | STACK_CHECK( L2, 0); // L // L2 | 1844 | STACK_CHECK_START_REL(L2, 0); // L // L2 |
| 1845 | 1845 | ||
| 1846 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "inter_copy_one()\n" INDENT_END)); | 1846 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "inter_copy_one()\n" INDENT_END)); |
| 1847 | DEBUGSPEW_CODE( ++ U->debugspew_indent_depth); | 1847 | DEBUGSPEW_CODE( ++ U->debugspew_indent_depth); |
| @@ -1861,7 +1861,7 @@ bool inter_copy_one(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, in | |||
| 1861 | lua_pop( L, 2); // ... | 1861 | lua_pop( L, 2); // ... |
| 1862 | } | 1862 | } |
| 1863 | } | 1863 | } |
| 1864 | STACK_MID( L, 0); | 1864 | STACK_CHECK( L, 0); |
| 1865 | 1865 | ||
| 1866 | /* Lets push nil to L2 if the object should be ignored */ | 1866 | /* Lets push nil to L2 if the object should be ignored */ |
| 1867 | switch( val_type) | 1867 | switch( val_type) |
| @@ -1945,8 +1945,8 @@ bool inter_copy_one(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, in | |||
| 1945 | 1945 | ||
| 1946 | DEBUGSPEW_CODE( -- U->debugspew_indent_depth); | 1946 | DEBUGSPEW_CODE( -- U->debugspew_indent_depth); |
| 1947 | 1947 | ||
| 1948 | STACK_END( L2, ret ? 1 : 0); | 1948 | STACK_CHECK( L2, ret ? 1 : 0); |
| 1949 | STACK_END( L, 0); | 1949 | STACK_CHECK( L, 0); |
| 1950 | return ret; | 1950 | return ret; |
| 1951 | } | 1951 | } |
| 1952 | 1952 | ||
| @@ -1977,7 +1977,7 @@ int luaG_inter_copy(Universe* U, lua_State* L, lua_State* L2, int n, LookupMode | |||
| 1977 | return -1; | 1977 | return -1; |
| 1978 | } | 1978 | } |
| 1979 | 1979 | ||
| 1980 | STACK_CHECK( L2, 0); | 1980 | STACK_CHECK_START_REL(L2, 0); |
| 1981 | STACK_GROW( L2, n + 1); | 1981 | STACK_GROW( L2, n + 1); |
| 1982 | 1982 | ||
| 1983 | /* | 1983 | /* |
| @@ -1987,7 +1987,7 @@ int luaG_inter_copy(Universe* U, lua_State* L, lua_State* L2, int n, LookupMode | |||
| 1987 | */ | 1987 | */ |
| 1988 | lua_newtable( L2); // ... cache | 1988 | lua_newtable( L2); // ... cache |
| 1989 | 1989 | ||
| 1990 | STACK_CHECK( L, 0); | 1990 | STACK_CHECK_START_REL(L, 0); |
| 1991 | for( i = top_L - n + 1, j = 1; i <= top_L; ++ i, ++ j) | 1991 | for( i = top_L - n + 1, j = 1; i <= top_L; ++ i, ++ j) |
| 1992 | { | 1992 | { |
| 1993 | if( U->verboseErrors) | 1993 | if( U->verboseErrors) |
| @@ -2000,13 +2000,13 @@ int luaG_inter_copy(Universe* U, lua_State* L, lua_State* L2, int n, LookupMode | |||
| 2000 | break; | 2000 | break; |
| 2001 | } | 2001 | } |
| 2002 | } | 2002 | } |
| 2003 | STACK_END( L, 0); | 2003 | STACK_CHECK( L, 0); |
| 2004 | 2004 | ||
| 2005 | DEBUGSPEW_CODE( -- U->debugspew_indent_depth); | 2005 | DEBUGSPEW_CODE( -- U->debugspew_indent_depth); |
| 2006 | 2006 | ||
| 2007 | if( copyok) | 2007 | if( copyok) |
| 2008 | { | 2008 | { |
| 2009 | STACK_MID( L2, n + 1); | 2009 | STACK_CHECK( L2, n + 1); |
| 2010 | // Remove the cache table. Persistent caching would cause i.e. multiple | 2010 | // Remove the cache table. Persistent caching would cause i.e. multiple |
| 2011 | // messages passed in the same table to use the same table also in receiving end. | 2011 | // messages passed in the same table to use the same table also in receiving end. |
| 2012 | lua_remove( L2, top_L2 + 1); | 2012 | lua_remove( L2, top_L2 + 1); |
| @@ -2015,7 +2015,7 @@ int luaG_inter_copy(Universe* U, lua_State* L, lua_State* L2, int n, LookupMode | |||
| 2015 | 2015 | ||
| 2016 | // error -> pop everything from the target state stack | 2016 | // error -> pop everything from the target state stack |
| 2017 | lua_settop( L2, top_L2); | 2017 | lua_settop( L2, top_L2); |
| 2018 | STACK_END( L2, 0); | 2018 | STACK_CHECK( L2, 0); |
| 2019 | return -2; | 2019 | return -2; |
| 2020 | } | 2020 | } |
| 2021 | 2021 | ||
| @@ -2032,13 +2032,13 @@ int luaG_inter_copy_package( Universe* U, lua_State* L, lua_State* L2, int packa | |||
| 2032 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "luaG_inter_copy_package()\n" INDENT_END)); | 2032 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "luaG_inter_copy_package()\n" INDENT_END)); |
| 2033 | DEBUGSPEW_CODE( ++ U->debugspew_indent_depth); | 2033 | DEBUGSPEW_CODE( ++ U->debugspew_indent_depth); |
| 2034 | // package | 2034 | // package |
| 2035 | STACK_CHECK( L, 0); | 2035 | STACK_CHECK_START_REL(L, 0); |
| 2036 | STACK_CHECK( L2, 0); | 2036 | STACK_CHECK_START_REL(L2, 0); |
| 2037 | package_idx_ = lua_absindex( L, package_idx_); | 2037 | package_idx_ = lua_absindex( L, package_idx_); |
| 2038 | if( lua_type( L, package_idx_) != LUA_TTABLE) | 2038 | if( lua_type( L, package_idx_) != LUA_TTABLE) |
| 2039 | { | 2039 | { |
| 2040 | lua_pushfstring( L, "expected package as table, got %s", luaL_typename( L, package_idx_)); | 2040 | lua_pushfstring( L, "expected package as table, got %s", luaL_typename( L, package_idx_)); |
| 2041 | STACK_MID( L, 1); | 2041 | STACK_CHECK( L, 1); |
| 2042 | // raise the error when copying from lane to lane, else just leave it on the stack to be raised later | 2042 | // raise the error when copying from lane to lane, else just leave it on the stack to be raised later |
| 2043 | return ( mode_ == eLM_LaneBody) ? lua_error( L) : 1; | 2043 | return ( mode_ == eLM_LaneBody) ? lua_error( L) : 1; |
| 2044 | } | 2044 | } |
| @@ -2073,8 +2073,8 @@ int luaG_inter_copy_package( Universe* U, lua_State* L, lua_State* L2, int packa | |||
| 2073 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "'package' not loaded, nothing to do\n" INDENT_END)); | 2073 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "'package' not loaded, nothing to do\n" INDENT_END)); |
| 2074 | } | 2074 | } |
| 2075 | lua_pop( L2, 1); | 2075 | lua_pop( L2, 1); |
| 2076 | STACK_END( L2, 0); | 2076 | STACK_CHECK( L2, 0); |
| 2077 | STACK_END( L, 0); | 2077 | STACK_CHECK( L, 0); |
| 2078 | DEBUGSPEW_CODE( -- U->debugspew_indent_depth); | 2078 | DEBUGSPEW_CODE( -- U->debugspew_indent_depth); |
| 2079 | return 0; | 2079 | return 0; |
| 2080 | } | 2080 | } |
diff --git a/src/universe.cpp b/src/universe.cpp index 5d0d3b6..06c7313 100644 --- a/src/universe.cpp +++ b/src/universe.cpp | |||
| @@ -41,35 +41,35 @@ static constexpr UniqueKey UNIVERSE_REGKEY{ 0x9f877b2cf078f17full }; | |||
| 41 | 41 | ||
| 42 | // ################################################################################################ | 42 | // ################################################################################################ |
| 43 | 43 | ||
| 44 | Universe* universe_create( lua_State* L) | 44 | Universe* universe_create(lua_State* L) |
| 45 | { | 45 | { |
| 46 | Universe* U = (Universe*) lua_newuserdatauv( L, sizeof(Universe), 0); // universe | 46 | Universe* U = (Universe*) lua_newuserdatauv( L, sizeof(Universe), 0); // universe |
| 47 | memset( U, 0, sizeof( Universe)); | 47 | memset( U, 0, sizeof( Universe)); |
| 48 | STACK_CHECK( L, 1); | 48 | STACK_CHECK_START_REL(L, 1); |
| 49 | UNIVERSE_REGKEY.set_registry(L, [](lua_State* L) { lua_pushvalue(L, -2); }); // universe | 49 | UNIVERSE_REGKEY.set_registry(L, [](lua_State* L) { lua_pushvalue(L, -2); }); // universe |
| 50 | STACK_END( L, 1); | 50 | STACK_CHECK( L, 1); |
| 51 | return U; | 51 | return U; |
| 52 | } | 52 | } |
| 53 | 53 | ||
| 54 | // ################################################################################################ | 54 | // ################################################################################################ |
| 55 | 55 | ||
| 56 | void universe_store( lua_State* L, Universe* U) | 56 | void universe_store(lua_State* L, Universe* U) |
| 57 | { | 57 | { |
| 58 | STACK_CHECK( L, 0); | 58 | STACK_CHECK_START_REL(L, 0); |
| 59 | UNIVERSE_REGKEY.set_registry(L, [U](lua_State* L) { U ? lua_pushlightuserdata( L, U) : lua_pushnil( L); }); | 59 | UNIVERSE_REGKEY.set_registry(L, [U](lua_State* L) { U ? lua_pushlightuserdata( L, U) : lua_pushnil( L); }); |
| 60 | STACK_END( L, 0); | 60 | STACK_CHECK( L, 0); |
| 61 | } | 61 | } |
| 62 | 62 | ||
| 63 | // ################################################################################################ | 63 | // ################################################################################################ |
| 64 | 64 | ||
| 65 | Universe* universe_get( lua_State* L) | 65 | Universe* universe_get(lua_State* L) |
| 66 | { | 66 | { |
| 67 | Universe* universe; | 67 | Universe* universe; |
| 68 | STACK_GROW( L, 2); | 68 | STACK_GROW( L, 2); |
| 69 | STACK_CHECK( L, 0); | 69 | STACK_CHECK_START_REL(L, 0); |
| 70 | UNIVERSE_REGKEY.query_registry(L); | 70 | UNIVERSE_REGKEY.query_registry(L); |
| 71 | universe = (Universe*) lua_touserdata( L, -1); // nullptr if nil | 71 | universe = (Universe*) lua_touserdata( L, -1); // nullptr if nil |
| 72 | lua_pop( L, 1); | 72 | lua_pop( L, 1); |
| 73 | STACK_END( L, 0); | 73 | STACK_CHECK( L, 0); |
| 74 | return universe; | 74 | return universe; |
| 75 | } | 75 | } |
