diff --git a/docs/source/exceptions.rst b/docs/source/exceptions.rst index 87dbd91b..2eddbbfb 100644 --- a/docs/source/exceptions.rst +++ b/docs/source/exceptions.rst @@ -59,7 +59,7 @@ You can ``#define SOL_EXCEPTIONS_SAFE_PROPAGATION`` before including Sol or defi This will prevent sol from catching ``(...)`` errors in platforms and compilers that have full C++ exception interoperability. This means that Lua errors can be caught with ``catch (...)`` in the C++ end of your code after it goes through Lua, and exceptions can pass through the Lua API and Stack safely. -Currently, the only known platform to do this is the listed "Full" `platforms for LuaJIT`_ and Lua compiled as C++. This define is turned on automatically for compiling Lua as C++. +Currently, the only known platform to do this is the listed "Full" `platforms for LuaJIT`_ and Lua compiled as C++. This define is turned on automatically for compiling Lua as C++ and ``SOL_USING_CXX_LUA`` (or ``SOL_USING_CXX_LUA_JIT``) is defined. .. warning:: diff --git a/docs/source/functions.rst b/docs/source/functions.rst index 1986bf0d..ec4a60fd 100644 --- a/docs/source/functions.rst +++ b/docs/source/functions.rst @@ -88,16 +88,21 @@ Please read the :doc:`error page` and :doc:`exception page` functions and argument passing ------------------------------ -.. note:: - - All arguments are forwarded. Unlike :doc:`get/set/operator[] on sol::state` or :doc:`sol::table`, value semantics are not used here. It is forwarding reference semantics, which do not copy/move unless it is specifically done by the receiving functions / specifically done by the user. - +All arguments are forwarded. Unlike :doc:`get/set/operator[] on sol::state` or :doc:`sol::table`, value semantics are not used here. It is forwarding reference semantics, which do not copy/move unless it is specifically done by the receiving functions / specifically done by the user. .. note:: This also means that you should pass and receive arguments in certain ways to maximize efficiency. For example, ``sol::table``, ``sol::object``, ``sol::userdata`` and friends are cheap to copy, and should simply by taken as values. This includes primitive types like ``int`` and ``double``. However, C++ types -- if you do not want copies -- should be taken as ``const type&`` or ``type&``, to save on copies if it's important. Note that taking references from Lua also means you can modify the data inside of Lua directly, so be careful. Lua by default deals with things mostly by reference (save for primitive types). - Please avoid taking special unique_usertype arguments, by either reference or value. In many cases, by-value does not work (e.g., with ``std::unique_ptr``) because many types are move-only and Lua has no concept of "move" semantics. By-reference is dangerous because sol2 will hand you a reference to the original data: but, any pointers stored in Lua can be invalidated if you call ``.reset()`` or similar on the core pointer. Please take a pointer (``T*``) if you anticipate ``nil``/``nullptr`` being passed to your function, or a reference (``const T&`` or ``T&``) if you do not. + +When you bind a function to Lua, please take any pointer arguments as ``T*``, unless you specifically know you are going to match the exact type of the unique/shared pointer and the class it wraps. sol2 cannot support "implicit wrapped pointer casting", such as taking a ``std::shared_ptr`` when the function is passed a ``std::shared_ptr``. Sometimes it may work because the compiler might be able to line up your classes in such a way that raw casts work, but this is undefined behavior through and through and sol2 has no mechanisms by which it can make this safe and not blow up in the user's face. + +.. note:: + + Please avoid taking special unique_usertype arguments, by either reference or value. In many cases, by-value does not work (e.g., with ``std::unique_ptr``) because many types are move-only and Lua has no concept of "move" semantics. By-reference is dangerous because sol2 will hand you a reference to the original data: but, any pointers stored in Lua can be invalidated if you call ``.reset()`` or similar on the core pointer. Please take a pointer (``T*``) if you anticipate ``nil``/``nullptr`` being passed to your function, or a reference (``const T&`` or ``T&``) if you do not. As a side note, if you write a small wrapping class that holds a base pointer type, and interact using the wrapper, then when you get the wrapper as an argument in a C++-function bound to Lua you can cast the internal object freely. It is simply a direct cast as an argument to a function that is the problem. + + +.. note:: You can get even more speed out of ``sol::object`` style of types by taking a ``sol::stack_object`` (or ``sol::stack_...``, where ``...`` is ``userdata``, ``reference``, ``table``, etc.). These reference a stack position directly rather than cheaply/safely the internal Lua reference to make sure it can't be swept out from under you. Note that if you manipulate the stack out from under these objects, they may misbehave, so please do not blow up your Lua stack when working with these types. diff --git a/docs/source/safety.rst b/docs/source/safety.rst index fcfd6179..ebffbc57 100644 --- a/docs/source/safety.rst +++ b/docs/source/safety.rst @@ -58,12 +58,19 @@ Note that you can obtain safety with regards to functions you bind by using the ``SOL_USING_CXX_LUA`` triggers the following changes: * Lua includes are no longer wrapped in ``extern "C" {}`` blocks + * Turns on ``SOL_EXCEPTIONS_SAFE_PROPAGATION`` automatically for you * Only use this if you know you've built your LuaJIT with the C++-specific invocations of your compiler (Lua by default builds as C code and is not distributed as a C++ library, but a C one with C symbols) ``SOL_USING_CXX_LUA_JIT`` triggers the following changes: * LuaJIT includes are no longer wrapped in ``extern "C" {}`` blocks + * Turns on ``SOL_EXCEPTIONS_SAFE_PROPAGATION`` automatically for you * Only use this if you know you've built your LuaJIT with the C++-specific invocations of your compiler (LuaJIT by default builds as C code) +``SOL_EXCEPTIONS_SAFE_PROPAGATION`` triggers the following changes: + * try/catch will not be used around C-function trampolines when going from Lua to C++ + * try/catch will not be used in ``safe_``/``protected_function`` internals + * Should only be used in accordance with compiling vanilla PUC-RIO Lua as C++, using :ref:`LuaJIT under the proper conditions`, or in accordance with your Lua distribution's documentation + Tests are compiled with this on to ensure everything is going as expected. Remember that if you want these features, you must explicitly turn them on all of them to be sure you are getting them. memory