Browse Source

LuaPlugin: LuaJit support (#387)

* LuaPlugin: LuaJit support

* Try to fix Github actions for luajit

---------

Co-authored-by: Michael Ragazzon <[email protected]>
mrianura 2 years ago
parent
commit
d411bf30ff
5 changed files with 80 additions and 5 deletions
  1. 2 2
      .github/workflows/build.yml
  2. 16 0
      CMake/FindLuaJIT.cmake
  3. 13 3
      CMakeLists.txt
  4. 16 0
      Include/RmlUi/Lua/Utilities.h
  5. 33 0
      Source/Lua/Utilities.cpp

+ 2 - 2
.github/workflows/build.yml

@@ -101,13 +101,13 @@ jobs:
         include:
           - cmake_options: -DSAMPLES_BACKEND=auto -DENABLE_PRECOMPILED_HEADERS=OFF
           - cmake_options: -DSAMPLES_BACKEND=Win32_VK -DRMLUI_VK_DEBUG=ON
-          - cmake_options: -DSAMPLES_BACKEND=SDL_VK
+          - cmake_options: -DSAMPLES_BACKEND=SDL_VK -DBUILD_LUA_BINDINGS_FOR_LUAJIT=ON
     
     steps:
     - 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

+ 16 - 0
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)

+ 13 - 3
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_LUA_BINDINGS_FOR_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

+ 16 - 0
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);

+ 33 - 0
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)