aboutsummaryrefslogtreecommitdiff
path: root/src/state.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/state.cpp')
-rw-r--r--src/state.cpp76
1 files changed, 39 insertions, 37 deletions
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*/
94void serialize_require( DEBUGSPEW_PARAM_COMMA( Universe* U) lua_State* L) 94void 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
197static void copy_one_time_settings( Universe* U, lua_State* L, lua_State* L2) 197static 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
219void initialize_on_state_create( Universe* U, lua_State* L) 219void 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
250lua_State* create_state( Universe* U, lua_State* from_) 250lua_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}