diff options
Diffstat (limited to 'src/state.cpp')
-rw-r--r-- | src/state.cpp | 107 |
1 files changed, 59 insertions, 48 deletions
diff --git a/src/state.cpp b/src/state.cpp index a3dfbcd..f894978 100644 --- a/src/state.cpp +++ b/src/state.cpp | |||
@@ -34,6 +34,7 @@ THE SOFTWARE. | |||
34 | #include "state.h" | 34 | #include "state.h" |
35 | 35 | ||
36 | #include "lanes.h" | 36 | #include "lanes.h" |
37 | #include "lanes_private.h" | ||
37 | #include "tools.h" | 38 | #include "tools.h" |
38 | #include "universe.h" | 39 | #include "universe.h" |
39 | 40 | ||
@@ -111,68 +112,71 @@ void serialize_require(DEBUGSPEW_PARAM_COMMA(Universe* U_) lua_State* L_) | |||
111 | [[nodiscard]] static int require_lanes_core(lua_State* L_) | 112 | [[nodiscard]] static int require_lanes_core(lua_State* L_) |
112 | { | 113 | { |
113 | // leaves a copy of 'lanes.core' module table on the stack | 114 | // leaves a copy of 'lanes.core' module table on the stack |
114 | luaL_requiref(L_, "lanes.core", luaopen_lanes_core, 0); | 115 | luaL_requiref(L_, kLanesCoreLibName, luaopen_lanes_core, 0); |
115 | return 1; | 116 | return 1; |
116 | } | 117 | } |
117 | 118 | ||
118 | // ################################################################################################# | 119 | // ################################################################################################# |
119 | 120 | ||
120 | static luaL_Reg const libs[] = { | 121 | namespace global |
121 | { LUA_LOADLIBNAME, luaopen_package }, | 122 | { |
122 | { LUA_TABLIBNAME, luaopen_table }, | 123 | static luaL_Reg const sLibs[] = { |
123 | { LUA_STRLIBNAME, luaopen_string }, | 124 | { "base", nullptr }, // ignore "base" (already acquired it) |
124 | { LUA_MATHLIBNAME, luaopen_math }, | 125 | #if LUA_VERSION_NUM >= 502 |
126 | #ifdef luaopen_bit32 | ||
127 | { LUA_BITLIBNAME, luaopen_bit32 }, | ||
128 | #endif | ||
129 | { LUA_COLIBNAME, luaopen_coroutine }, // Lua 5.2: coroutine is no longer a part of base! | ||
130 | #else // LUA_VERSION_NUM | ||
131 | { LUA_COLIBNAME, nullptr }, // Lua 5.1: part of base package | ||
132 | #endif // LUA_VERSION_NUM | ||
133 | { LUA_DBLIBNAME, luaopen_debug }, | ||
125 | #ifndef PLATFORM_XBOX // no os/io libs on xbox | 134 | #ifndef PLATFORM_XBOX // no os/io libs on xbox |
126 | { LUA_OSLIBNAME, luaopen_os }, | 135 | { LUA_IOLIBNAME, luaopen_io }, |
127 | { LUA_IOLIBNAME, luaopen_io }, | 136 | { LUA_OSLIBNAME, luaopen_os }, |
128 | #endif // PLATFORM_XBOX | 137 | #endif // PLATFORM_XBOX |
138 | { LUA_LOADLIBNAME, luaopen_package }, | ||
139 | { LUA_MATHLIBNAME, luaopen_math }, | ||
140 | { LUA_STRLIBNAME, luaopen_string }, | ||
141 | { LUA_TABLIBNAME, luaopen_table }, | ||
129 | #if LUA_VERSION_NUM >= 503 | 142 | #if LUA_VERSION_NUM >= 503 |
130 | { LUA_UTF8LIBNAME, luaopen_utf8 }, | 143 | { LUA_UTF8LIBNAME, luaopen_utf8 }, |
131 | #endif | 144 | #endif |
132 | #if LUA_VERSION_NUM >= 502 | ||
133 | #ifdef luaopen_bit32 | ||
134 | { LUA_BITLIBNAME, luaopen_bit32 }, | ||
135 | #endif | ||
136 | { LUA_COLIBNAME, luaopen_coroutine }, // Lua 5.2: coroutine is no longer a part of base! | ||
137 | #else // LUA_VERSION_NUM | ||
138 | { LUA_COLIBNAME, nullptr }, // Lua 5.1: part of base package | ||
139 | #endif // LUA_VERSION_NUM | ||
140 | { LUA_DBLIBNAME, luaopen_debug }, | ||
141 | #if LUAJIT_FLAVOR() != 0 // building against LuaJIT headers, add some LuaJIT-specific libs | 145 | #if LUAJIT_FLAVOR() != 0 // building against LuaJIT headers, add some LuaJIT-specific libs |
142 | // #pragma message( "supporting JIT base libs") | 146 | { LUA_BITLIBNAME, luaopen_bit }, |
143 | { LUA_BITLIBNAME, luaopen_bit }, | 147 | { LUA_FFILIBNAME, luaopen_ffi }, |
144 | { LUA_JITLIBNAME, luaopen_jit }, | 148 | { LUA_JITLIBNAME, luaopen_jit }, |
145 | { LUA_FFILIBNAME, luaopen_ffi }, | ||
146 | #endif // LUAJIT_FLAVOR() | 149 | #endif // LUAJIT_FLAVOR() |
147 | 150 | ||
148 | { LUA_DBLIBNAME, luaopen_debug }, | 151 | { kLanesCoreLibName, require_lanes_core }, // So that we can open it like any base library (possible since we have access to the init function) |
149 | { "lanes.core", require_lanes_core }, // So that we can open it like any base library (possible since we have access to the init function) | 152 | // |
150 | // | 153 | { nullptr, nullptr } |
151 | { "base", nullptr }, // ignore "base" (already acquired it) | 154 | }; |
152 | { nullptr, nullptr } | 155 | |
153 | }; | 156 | } // namespace global |
154 | 157 | ||
155 | // ################################################################################################# | 158 | // ################################################################################################# |
156 | 159 | ||
157 | static void open1lib(DEBUGSPEW_PARAM_COMMA(Universe* U_) lua_State* L_, char const* name_, size_t len_) | 160 | static void open1lib(DEBUGSPEW_PARAM_COMMA(Universe* U_) lua_State* L_, char const* name_, size_t len_) |
158 | { | 161 | { |
159 | for (int i{ 0 }; libs[i].name; ++i) { | 162 | for (int i{ 0 }; global::sLibs[i].name; ++i) { |
160 | if (strncmp(name_, libs[i].name, len_) == 0) { | 163 | if (strncmp(name_, global::sLibs[i].name, len_) == 0) { |
161 | lua_CFunction libfunc = libs[i].func; | 164 | lua_CFunction const libfunc{ global::sLibs[i].func }; |
162 | name_ = libs[i].name; // note that the provided name_ doesn't necessarily ends with '\0', hence len_ | 165 | if (!libfunc) { |
163 | if (libfunc != nullptr) { | 166 | continue; |
164 | bool const isLanesCore{ libfunc == require_lanes_core }; // don't want to create a global for "lanes.core" | 167 | } |
165 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "opening %.*s library\n" INDENT_END(U_), (int) len_, name_)); | 168 | name_ = global::sLibs[i].name; // note that the provided name_ doesn't necessarily ends with '\0', hence len_ |
166 | STACK_CHECK_START_REL(L_, 0); | 169 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "opening %.*s library\n" INDENT_END(U_), (int) len_, name_)); |
167 | // open the library as if through require(), and create a global as well if necessary (the library table is left on the stack) | 170 | STACK_CHECK_START_REL(L_, 0); |
168 | luaL_requiref(L_, name_, libfunc, !isLanesCore); | 171 | // open the library as if through require(), and create a global as well if necessary (the library table is left on the stack) |
169 | // lanes.core doesn't declare a global, so scan it here and now | 172 | bool const isLanesCore{ libfunc == require_lanes_core }; // don't want to create a global for "lanes.core" |
170 | if (isLanesCore == true) { | 173 | luaL_requiref(L_, name_, libfunc, !isLanesCore); // L_: {lib} |
171 | populate_func_lookup_table(L_, -1, name_); | 174 | // lanes.core doesn't declare a global, so scan it here and now |
172 | } | 175 | if (isLanesCore) { |
173 | lua_pop(L_, 1); | 176 | populate_func_lookup_table(L_, -1, name_); |
174 | STACK_CHECK(L_, 0); | ||
175 | } | 177 | } |
178 | lua_pop(L_, 1); // L_: | ||
179 | STACK_CHECK(L_, 0); | ||
176 | break; | 180 | break; |
177 | } | 181 | } |
178 | } | 182 | } |
@@ -180,6 +184,14 @@ static void open1lib(DEBUGSPEW_PARAM_COMMA(Universe* U_) lua_State* L_, char con | |||
180 | 184 | ||
181 | // ################################################################################################# | 185 | // ################################################################################################# |
182 | 186 | ||
187 | template<size_t N> | ||
188 | static inline void open1lib(DEBUGSPEW_PARAM_COMMA(Universe* U_) lua_State* L_, char const (&name_)[N]) | ||
189 | { | ||
190 | open1lib(DEBUGSPEW_PARAM_COMMA(U_) L_, name_, N - 1); | ||
191 | } | ||
192 | |||
193 | // ################################################################################################# | ||
194 | |||
183 | // just like lua_xmove, args are (from, to) | 195 | // just like lua_xmove, args are (from, to) |
184 | static void copy_one_time_settings(Universe* U_, SourceState L1_, DestState L2_) | 196 | static void copy_one_time_settings(Universe* U_, SourceState L1_, DestState L2_) |
185 | { | 197 | { |
@@ -195,7 +207,7 @@ static void copy_one_time_settings(Universe* U_, SourceState L1_, DestState L2_) | |||
195 | // copy settings from from source to destination registry | 207 | // copy settings from from source to destination registry |
196 | InterCopyContext c{ U_, L2_, L1_, {}, {}, {}, {}, {} }; | 208 | InterCopyContext c{ U_, L2_, L1_, {}, {}, {}, {}, {} }; |
197 | if (c.inter_move(1) != InterCopyResult::Success) { // L1_: L2_: config | 209 | if (c.inter_move(1) != InterCopyResult::Success) { // L1_: L2_: config |
198 | raise_luaL_error(L1_, "failed to copy settings when loading lanes.core"); | 210 | raise_luaL_error(L1_, "failed to copy settings when loading " kLanesCoreLibName); |
199 | } | 211 | } |
200 | // set L2:_R[kConfigRegKey] = settings | 212 | // set L2:_R[kConfigRegKey] = settings |
201 | kConfigRegKey.setValue(L2_, [](lua_State* L_) { lua_insert(L_, -2); }); // L1_: L2_: config | 213 | kConfigRegKey.setValue(L2_, [](lua_State* L_) { lua_insert(L_, -2); }); // L1_: L2_: config |
@@ -334,11 +346,10 @@ lua_State* luaG_newstate(Universe* U_, SourceState from_, char const* libs_) | |||
334 | // copy settings (for example because it may contain a Lua on_state_create function) | 346 | // copy settings (for example because it may contain a Lua on_state_create function) |
335 | copy_one_time_settings(U_, from_, L); | 347 | copy_one_time_settings(U_, from_, L); |
336 | 348 | ||
337 | // 'lua.c' stops GC during initialization so perhaps its a good idea. :) | 349 | // 'lua.c' stops GC during initialization so perhaps it is a good idea. :) |
338 | lua_gc(L, LUA_GCSTOP, 0); | 350 | lua_gc(L, LUA_GCSTOP, 0); |
339 | 351 | ||
340 | // Anything causes 'base' to be taken in | 352 | // Anything causes 'base' to be taken in |
341 | // | ||
342 | if (libs_ != nullptr) { | 353 | if (libs_ != nullptr) { |
343 | // special "*" case (mainly to help with LuaJIT compatibility) | 354 | // special "*" case (mainly to help with LuaJIT compatibility) |
344 | // as we are called from luaopen_lanes_core() already, and that would deadlock | 355 | // as we are called from luaopen_lanes_core() already, and that would deadlock |
@@ -346,7 +357,7 @@ lua_State* luaG_newstate(Universe* U_, SourceState from_, char const* libs_) | |||
346 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "opening ALL standard libraries\n" INDENT_END(U_))); | 357 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "opening ALL standard libraries\n" INDENT_END(U_))); |
347 | luaL_openlibs(L); | 358 | luaL_openlibs(L); |
348 | // don't forget lanes.core for regular lane states | 359 | // don't forget lanes.core for regular lane states |
349 | open1lib(DEBUGSPEW_PARAM_COMMA(U_) L, "lanes.core", 10); | 360 | open1lib(DEBUGSPEW_PARAM_COMMA(U_) L, kLanesCoreLibName); |
350 | libs_ = nullptr; // done with libs | 361 | libs_ = nullptr; // done with libs |
351 | } else { | 362 | } else { |
352 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "opening base library\n" INDENT_END(U_))); | 363 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "opening base library\n" INDENT_END(U_))); |