diff options
Diffstat (limited to '')
-rw-r--r-- | docs/index.html | 2 | ||||
-rw-r--r-- | src/universe.cpp | 20 |
2 files changed, 6 insertions, 16 deletions
diff --git a/docs/index.html b/docs/index.html index ca91273..6e2b4ed 100644 --- a/docs/index.html +++ b/docs/index.html | |||
@@ -358,6 +358,7 @@ | |||
358 | <td> | 358 | <td> |
359 | If provided, will be called in every created Lua state right after initializing the base libraries, with a single string argument, either <tt>"lane"</tt> or <tt>"keeper"</tt>.<br /> | 359 | If provided, will be called in every created Lua state right after initializing the base libraries, with a single string argument, either <tt>"lane"</tt> or <tt>"keeper"</tt>.<br /> |
360 | If it is a C function, a C closure will be reconstructed in the created state from the C pointer. Lanes will raise an error if the function has upvalues.<br /> | 360 | If it is a C function, a C closure will be reconstructed in the created state from the C pointer. Lanes will raise an error if the function has upvalues.<br /> |
361 | If it is a Lua function, it will be transfered normally before the call.<br /> | ||
361 | Keeper states will call it as well, but only if it is a C function (<a href="#keepers">Keeper states</a> are not able to execute any user Lua code).<br /> | 362 | Keeper states will call it as well, but only if it is a C function (<a href="#keepers">Keeper states</a> are not able to execute any user Lua code).<br /> |
362 | Typical usage is twofold: | 363 | Typical usage is twofold: |
363 | <ul> | 364 | <ul> |
@@ -365,7 +366,6 @@ | |||
365 | <li>Load some additional C functions in the global space (of course only a C function will be able to do this).</li> | 366 | <li>Load some additional C functions in the global space (of course only a C function will be able to do this).</li> |
366 | </ul> | 367 | </ul> |
367 | That way, all changes in the state can be properly taken into account when building the function lookup database. Default is <tt>nil</tt>.<br /> | 368 | That way, all changes in the state can be properly taken into account when building the function lookup database. Default is <tt>nil</tt>.<br /> |
368 | If <tt>on_state_create()</tt> is a Lua function, it will be transfered normally before the call.<br /> | ||
369 | </td> | 369 | </td> |
370 | </tr> | 370 | </tr> |
371 | 371 | ||
diff --git a/src/universe.cpp b/src/universe.cpp index 08fdf40..0dc5646 100644 --- a/src/universe.cpp +++ b/src/universe.cpp | |||
@@ -303,24 +303,14 @@ void Universe::initializeOnStateCreate(lua_State* const L_) | |||
303 | STACK_CHECK_START_REL(L_, 0); // L_: settings | 303 | STACK_CHECK_START_REL(L_, 0); // L_: settings |
304 | if (luaG_getfield(L_, -1, kOnStateCreate) != LuaType::NIL) { // L_: settings on_state_create|nil | 304 | if (luaG_getfield(L_, -1, kOnStateCreate) != LuaType::NIL) { // L_: settings on_state_create|nil |
305 | LUA_ASSERT(L_, luaG_type(L_, -1) == LuaType::FUNCTION); // ensured by lanes.lua parameter validation | 305 | LUA_ASSERT(L_, luaG_type(L_, -1) == LuaType::FUNCTION); // ensured by lanes.lua parameter validation |
306 | // make sure the function doesn't have upvalues other than _G | ||
307 | int _uvi{ 1 }; | ||
308 | for ( | ||
309 | char const* _upname{ lua_getupvalue(L_, -1, _uvi) }; | ||
310 | _upname; | ||
311 | _upname = lua_getupvalue(L_, -1, ++_uvi) // L_: settings on_state_create upvalue | ||
312 | ) { | ||
313 | // starting with Lua 5.2, functions have _ENV as their first upvalue. This is ok, it is mapped correctly | ||
314 | luaG_pushglobaltable(L_); // L_: settings on_state_create upvalue _G | ||
315 | if (!lua_rawequal(L_, -1, -2)) { | ||
316 | raise_luaL_error(L_, "%s with upvalues are forbidden", kOnStateCreate.data()); | ||
317 | } | ||
318 | lua_pop(L_, 2); // L_: settings on_state_create | ||
319 | } | ||
320 | STACK_CHECK(L_, 1); // make sure no garbage remains on the stack after upvalue check // L_: settings on_state_create | ||
321 | // store C function pointer in an internal variable | 306 | // store C function pointer in an internal variable |
322 | lua_CFunction const _func{ lua_tocfunction(L_, -1) }; // L_: settings on_state_create | 307 | lua_CFunction const _func{ lua_tocfunction(L_, -1) }; // L_: settings on_state_create |
323 | if (_func) { | 308 | if (_func) { |
309 | // make sure the function doesn't have upvalues | ||
310 | char const* _upname{ lua_getupvalue(L_, -1, 1) }; // L_: settings on_state_create upval? | ||
311 | if (_upname != nullptr) { // should be "" for C functions with upvalues if any | ||
312 | raise_luaL_error(L_, "%s shouldn't have upvalues", kOnStateCreate.data()); | ||
313 | } | ||
324 | onStateCreateFunc.emplace<lua_CFunction>(_func); | 314 | onStateCreateFunc.emplace<lua_CFunction>(_func); |
325 | // remove this C function from the config table so that it doesn't cause problems | 315 | // remove this C function from the config table so that it doesn't cause problems |
326 | // when we transfer the config table in newly created Lua states | 316 | // when we transfer the config table in newly created Lua states |