diff --git a/docs/source/codecvt.rst b/docs/source/codecvt.rst index ff901ede..750f6936 100644 --- a/docs/source/codecvt.rst +++ b/docs/source/codecvt.rst @@ -3,6 +3,6 @@ std::(w/u16/u32)string support because this is surprisingly hard using standard C++ ---------------------------------------------------- -Individuals using Visual Studio 2015, or on Windows with the VC++ and MinGW compilers (possibly Clang++ on Windows as well) have ```` headers, and thusly Sol will attempt to include it. Individuals on GC 4.9.x, Clang 3.5.x, Clang 3.6.x do not seem to have ```` shipped with the standard library that comes with installation of these compilers. If you want ``std::wstring``, ``std::u16string``, ``std::u32string`` automatic handling then you need to make sure you have those headers and then define ``SOL_CODECVT_SUPPORT``. +Individuals using Visual Studio 2015, or on Windows with the VC++ and MinGW compilers (possibly Clang++ on Windows as well) have ```` headers, and thusly Sol will attempt to include it. Individuals on GC 4.9.x, Clang 3.5.x, Clang 3.6.x do not seem to have ```` shipped with the standard library that comes with installation of these compilers. If you want ``std::wstring``, ``std::u16string``, ``std::u32string`` automatic handling then you need to make sure you have those headers and then define ``SOL_CODECVT_SUPPORT`` on unsupported compilers. ThePhD did not want this to have to be a thing, but slow implementations and such force their hand. When GCC 7.x comes out, ThePhD will consider removing the effect of defining this macro and leaving support in at all times. diff --git a/docs/source/errors.rst b/docs/source/errors.rst index f017daad..896fa3b7 100644 --- a/docs/source/errors.rst +++ b/docs/source/errors.rst @@ -10,9 +10,10 @@ Catch and CRASH! By default, Sol will add a ``default_at_panic`` handler. If exceptions are not turned off, this handler will throw to allow the user a chance to recover. However, in almost all cases, when Lua calls ``lua_atpanic`` and hits this function, it means that something *irreversibly wrong* occured in your code or the Lua code and the VM is in an unpredictable or dead state. Catching an error thrown from the default handler and then proceeding as if things are cleaned up or okay is NOT the best idea. Unexpected bugs in optimized and release mode builds can result, among other serious issues. - It is preferred if you catch an error that you log what happened, terminate the Lua VM as soon as possible, and then crash if your application cannot handle spinning up a new Lua state. Catching can be done, but you should understand the risks of what you're doing when you do it. +Lua is a C API first and foremost: exceptions bubbling out of it is essentially last-ditch, terminal behavior that the VM does not expect. You can see an example of handling a panic on the exceptions page :ref:`here`. + Destructors and Safety ---------------------- @@ -25,6 +26,11 @@ Protected Functions and Access By default, :doc:`sol::function` assumes the code ran just fine and there are no problems. :ref:`sol::state(_view)::script(_file)` also assumes that code ran just fine. Use :doc:`sol::protected_function` to have function access where you can check if things worked out. Use :doc:`sol::optional` to get a value safely from Lua. Use :ref:`sol::state(_view)::do_string/do_file/load/load_file` to safely load and get results from a script. The defaults are provided to be simple and fast with thrown exceptions to violently crash the VM in case things go wrong. +Protected Functions Are Not Catch All +------------------------------------- + +Sometimes, some scripts load poorly. Even if you protect the function call, the actual file loading or file execution will be bad, in which case :doc:`sol::protected_function` will not save you. Make sure you register your own panic handler so you can catch errors, or follow the advice of the catch + crash behavior above. + Raw Functions ------------- diff --git a/docs/source/exceptions.rst b/docs/source/exceptions.rst index 13be8b9a..ee36a962 100644 --- a/docs/source/exceptions.rst +++ b/docs/source/exceptions.rst @@ -11,23 +11,27 @@ To make this not be the case, you can set a panic function directly with ``lua_a .. code-block:: cpp :caption: regular panic function + :name: typical-panic-function #include #include - int my_panic_function( lua_State* L ) { - // error message is at the top of the stack - const char* message = lua_tostring(L, -1); - // message can be null, so don't crash - // us with nullptr-constructed-string if it is - std::string err = message ? message : "An unexpected error occurred and forced the lua state to call atpanic"; - // Weee - std::cerr << err << std::endl; + inline void my_panic(sol::optional maybe_msg) { + std::cerr << "Lua is in a panic state and will now abort() the application" << std::endl; + if (maybe_msg) { + const std::string& msg = maybe_msg.value(); + std::cerr << "\terror message: " << msg << std::endl; + } // When this function exits, Lua will exhibit default behavior and abort() } int main () { - sol::state lua(my_panic_function); + sol::state lua(sol::c_call); + // or, if you already have a lua_State* L + // lua_atpanic( L, sol::c_call, &my_panic> ); + // or, with state/state_view: + // sol::state_view lua(L); + // lua.set_panic( sol::c_call, &my_panic_call> ); } diff --git a/docs/source/performance.rst b/docs/source/performance.rst index 534ab7e5..4115e01f 100644 --- a/docs/source/performance.rst +++ b/docs/source/performance.rst @@ -9,6 +9,7 @@ As shown by the :doc:`benchmarks`, Sol is very performant with its a * If you have a bound function call / bound member function that you are going to call in a very tight, performance-heavy loop, considering using :doc:`sol::c_call` * Be wary of passing by value / reference, and what it means by reading :ref:`this note`. * It is currently undocumented that usertypes will "inherit" member function / member variables from bound classes, mostly because the semantics are unclear and it is not the most performant (although it is flexible: you can register base classes after / whenever you want in relation to the derived class, provided that derived class has its bases listed). Specifying all member functions / member variables for the usertype constructor / ``new_usertype`` function call and not relying on base lookup will boost performance of member lookup +* Use the :doc:`sol::stack_{}` versions of functions in order to achieve maximum performance benefits when doing things like calling a function from Lua and knowing that certain arguments of certain Lua types will be on the stack. This can save you a very small fraction of performance to not copy to the register (but is also more dangerous and usually not terribly worth it). * Specifying base classes can make getting the usertype out of Sol a bit slower since we have to check and cast; if you know the exact type wherever you're retrieving it, considering not specifying the bases, retrieving the exact type from Sol, and then casting to a base type yourself * Member variables can sometimes cost an extra lookup to occur within the Lua system (as mentioned :doc:`bottom of the usertype page`); until we find out a safe way around this, member variables will always incur that extra lookup cost diff --git a/sol/compatibility/version.hpp b/sol/compatibility/version.hpp index 5ddc23d9..cf23c712 100644 --- a/sol/compatibility/version.hpp +++ b/sol/compatibility/version.hpp @@ -24,7 +24,7 @@ #include -#if defined(_WIN32) || defined(_MSC_VER) || defined(__MINGW32__) +#if defined(_WIN32) || defined(_MSC_VER) #ifndef SOL_CODECVT_SUPPORT #define SOL_CODECVT_SUPPORT 1 #endif // sol codecvt support @@ -33,7 +33,7 @@ #ifndef SOL_CODECVT_SUPPORT #define SOL_CODECVT_SUPPORT 1 #endif // codecvt support -#endif // g++ 5.x.x +#endif // g++ 5.x.x (MinGW too) #else // Clang sucks and doesn't really utilize codecvt support, // not without checking the library versions explicitly (and we're not gonna do that, so fuck you)