aboutsummaryrefslogtreecommitdiff
path: root/src/state.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/state.cpp')
-rw-r--r--src/state.cpp107
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
120static luaL_Reg const libs[] = { 121namespace 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
157static void open1lib(DEBUGSPEW_PARAM_COMMA(Universe* U_) lua_State* L_, char const* name_, size_t len_) 160static 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
187template<size_t N>
188static 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)
184static void copy_one_time_settings(Universe* U_, SourceState L1_, DestState L2_) 196static 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_)));