diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7e6efb00d..c6f09606a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -107,7 +107,7 @@ jobs: - uses: actions/checkout@v3 - name: Install Dependencies - run: C:\vcpkg\vcpkg install freetype[core] sdl2[core,vulkan] lua[core] + run: C:\vcpkg\vcpkg install freetype[core] sdl2[core,vulkan] lua[core] luajit - name: Create Build Environment run: cmake -E make_directory ${{github.workspace}}/Build @@ -118,10 +118,21 @@ jobs: cmake $env:GITHUB_WORKSPACE -A x64 -DBUILD_SHARED_LIBS=ON -DCMAKE_BUILD_TYPE=$env:BUILD_TYPE -DBUILD_LUA_BINDINGS=ON -DBUILD_SAMPLES=ON -DWARNINGS_AS_ERRORS=ON -DCMAKE_TOOLCHAIN_FILE="C:/vcpkg/scripts/buildsystems/vcpkg.cmake" ${{ matrix.cmake_options }} + + - name: Configure luajit CMake + working-directory: ${{github.workspace}}/BuildLuajit + run: >- + cmake $env:GITHUB_WORKSPACE -A x64 -DBUILD_SHARED_LIBS=ON -DCMAKE_BUILD_TYPE=$env:BUILD_TYPE -DBUILD_LUA_BINDINGS=ON -DBUILD_SAMPLES=ON -DWARNINGS_AS_ERRORS=ON -DBUILD_USE_LUAJITBUILD_LUA_BINDINGS_FOR_LUAJIT=ON + -DCMAKE_TOOLCHAIN_FILE="C:/vcpkg/scripts/buildsystems/vcpkg.cmake" + ${{ matrix.cmake_options }} - name: Build working-directory: ${{github.workspace}}/Build run: cmake --build . --config $env:BUILD_TYPE + + - name: BuildLuajit + working-directory: ${{github.workspace}}/BuildLuajit + run: cmake --build . --config $env:BUILD_TYPE Emscripten: diff --git a/CMake/FindLuaJIT.cmake b/CMake/FindLuaJIT.cmake new file mode 100644 index 000000000..199518773 --- /dev/null +++ b/CMake/FindLuaJIT.cmake @@ -0,0 +1,16 @@ +# Try to find the lua library +# LUAJIT_FOUND - system has lua +# LUAJIT_INCLUDE_DIR - the lua include directory +# LUAJIT_LIBRARY - the lua library + +FIND_PATH(LUAJIT_INCLUDE_DIR NAMES luajit.h PATH_SUFFIXES luajit luajit-2.0 luajit-2.1) +SET(_LUAJIT_STATIC_LIBS libluajit-5.1.a libluajit.a liblua51.a) +SET(_LUAJIT_SHARED_LIBS luajit-5.1 luajit lua51) +IF(USE_STATIC_LIBS) + FIND_LIBRARY(LUAJIT_LIBRARY NAMES ${_LUAJIT_STATIC_LIBS} ${_LUAJIT_SHARED_LIBS}) +ELSE() + FIND_LIBRARY(LUAJIT_LIBRARY NAMES ${_LUAJIT_SHARED_LIBS} ${_LUAJIT_STATIC_LIBS}) +ENDIF() +INCLUDE(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(LuaJIT DEFAULT_MSG LUAJIT_LIBRARY LUAJIT_INCLUDE_DIR) +MARK_AS_ADVANCED(LUAJIT_LIBRARY LUAJIT_INCLUDE_DIR) diff --git a/CMakeLists.txt b/CMakeLists.txt index c442fc889..0cecd7ea4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -157,6 +157,10 @@ endif(NOT IOS) option(BUILD_LUA_BINDINGS "Build Lua bindings" OFF) +if (BUILD_LUA_BINDINGS) + option(BUILD_LUA_BINDINGS_FOR_LUAJIT "Build Lua bindings using luajit" OFF) +endif() + if(APPLE) option(BUILD_FRAMEWORK "Build Framework bundle for OSX" OFF) endif() @@ -356,9 +360,15 @@ endif() # Lua if(BUILD_LUA_BINDINGS) - find_package(Lua REQUIRED) - list(APPEND LUA_BINDINGS_INCLUDE_DIRS ${LUA_INCLUDE_DIR}) - list(APPEND LUA_BINDINGS_LINK_LIBS ${LUA_LIBRARIES}) + if(BUILD_USE_LUAJIT) + find_package(LuaJIT REQUIRED) + list(APPEND LUA_BINDINGS_INCLUDE_DIRS ${LUAJIT_INCLUDE_DIR}) + list(APPEND LUA_BINDINGS_LINK_LIBS ${LUAJIT_LIBRARY}) + else() + find_package(Lua REQUIRED) + list(APPEND LUA_BINDINGS_INCLUDE_DIRS ${LUA_INCLUDE_DIR}) + list(APPEND LUA_BINDINGS_LINK_LIBS ${LUA_LIBRARIES}) + endif() endif() # rlottie diff --git a/Include/RmlUi/Lua/Utilities.h b/Include/RmlUi/Lua/Utilities.h index cbecc920f..808f1ec43 100644 --- a/Include/RmlUi/Lua/Utilities.h +++ b/Include/RmlUi/Lua/Utilities.h @@ -39,6 +39,22 @@ namespace Rml { namespace Lua { +#if LUA_VERSION_NUM < 502 +#define lua_setuservalue(L, i) \ + (luaL_checktype((L), -1, LUA_TTABLE), lua_setfenv((L), (i))) + +inline int lua_absindex(lua_State* L, int idx) +{ + if (idx > LUA_REGISTRYINDEX && idx < 0) + return lua_gettop(L) + idx + 1; + else + return idx; +} + +void lua_len (lua_State *L, int i); +lua_Integer luaL_len(lua_State *L, int i); +#endif + /** casts the variant to its specific type before pushing it to the stack @relates LuaType */ void RMLUILUA_API PushVariant(lua_State* L, const Variant* var); diff --git a/Source/Lua/Utilities.cpp b/Source/Lua/Utilities.cpp index d3f8d9073..1c56bce7b 100644 --- a/Source/Lua/Utilities.cpp +++ b/Source/Lua/Utilities.cpp @@ -32,6 +32,39 @@ namespace Rml { namespace Lua { +#if LUA_VERSION_NUM < 502 +void lua_len (lua_State *L, int i) { + switch (lua_type(L, i)) { + case LUA_TSTRING: + lua_pushnumber(L, (lua_Number)lua_objlen(L, i)); + break; + case LUA_TTABLE: + if (!luaL_callmeta(L, i, "__len")) + lua_pushnumber(L, (lua_Number)lua_objlen(L, i)); + break; + case LUA_TUSERDATA: + if (luaL_callmeta(L, i, "__len")) + break; + /* FALLTHROUGH */ + default: + luaL_error(L, "attempt to get length of a %s value", + lua_typename(L, lua_type(L, i))); + } +} + +lua_Integer luaL_len(lua_State *L, int i) { + lua_Integer res = 0; + int isnum = 0; + luaL_checkstack(L, 1, "not enough stack slots"); + lua_len(L, i); + res = lua_tointegerx(L, -1, &isnum); + lua_pop(L, 1); + if (!isnum) + luaL_error(L, "object length is not an integer"); + return res; +} +#endif + void PushVariant(lua_State* L, const Variant* var) { if (!var)