Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 24 additions & 24 deletions .github/workflows/build_macos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,15 +51,15 @@ jobs:
- name: Build Lua ${{ matrix.lua.version }} (C++17)
working-directory: ${{runner.workspace}}/build17
run: |
cmake --build . --config $BUILD_TYPE --parallel $(nproc) --target \
cmake --build . --config $BUILD_TYPE --parallel $(sysctl -n hw.ncpu) --target \
LuaBridgeTests${{ matrix.lua.suffix }} \
LuaBridgeTests${{ matrix.lua.suffix }}LuaC \
LuaBridgeTests${{ matrix.lua.suffix }}Noexcept \
LuaBridgeTests${{ matrix.lua.suffix }}LuaCNoexcept

- name: Test Lua ${{ matrix.lua.version }} (C++17)
working-directory: ${{runner.workspace}}/build17
run: ctest --parallel $(nproc) -R "LuaBridgeTests${{ matrix.lua.suffix }}" --output-on-failure
run: ctest --parallel $(sysctl -n hw.ncpu) -R "LuaBridgeTests${{ matrix.lua.suffix }}" --output-on-failure

- name: Configure C++20
working-directory: ${{runner.workspace}}/build20
Expand All @@ -68,15 +68,15 @@ jobs:
- name: Build Lua ${{ matrix.lua.version }} (C++20)
working-directory: ${{runner.workspace}}/build20
run: |
cmake --build . --config $BUILD_TYPE --parallel $(nproc) --target \
cmake --build . --config $BUILD_TYPE --parallel $(sysctl -n hw.ncpu) --target \
LuaBridgeTests${{ matrix.lua.suffix }} \
LuaBridgeTests${{ matrix.lua.suffix }}LuaC \
LuaBridgeTests${{ matrix.lua.suffix }}Noexcept \
LuaBridgeTests${{ matrix.lua.suffix }}LuaCNoexcept

- name: Test Lua ${{ matrix.lua.version }} (C++20)
working-directory: ${{runner.workspace}}/build20
run: ctest --parallel $(nproc) -R "LuaBridgeTests${{ matrix.lua.suffix }}" --output-on-failure
run: ctest --parallel $(sysctl -n hw.ncpu) -R "LuaBridgeTests${{ matrix.lua.suffix }}" --output-on-failure

- name: Configure C++23
working-directory: ${{runner.workspace}}/build23
Expand All @@ -85,15 +85,15 @@ jobs:
- name: Build Lua ${{ matrix.lua.version }} (C++23)
working-directory: ${{runner.workspace}}/build23
run: |
cmake --build . --config $BUILD_TYPE --parallel $(nproc) --target \
cmake --build . --config $BUILD_TYPE --parallel $(sysctl -n hw.ncpu) --target \
LuaBridgeTests${{ matrix.lua.suffix }} \
LuaBridgeTests${{ matrix.lua.suffix }}LuaC \
LuaBridgeTests${{ matrix.lua.suffix }}Noexcept \
LuaBridgeTests${{ matrix.lua.suffix }}LuaCNoexcept

- name: Test Lua ${{ matrix.lua.version }} (C++23)
working-directory: ${{runner.workspace}}/build23
run: ctest --parallel $(nproc) -R "LuaBridgeTests${{ matrix.lua.suffix }}" --output-on-failure
run: ctest --parallel $(sysctl -n hw.ncpu) -R "LuaBridgeTests${{ matrix.lua.suffix }}" --output-on-failure

luajit:
runs-on: macos-latest
Expand All @@ -116,13 +116,13 @@ jobs:
- name: Build LuaJIT (C++17)
working-directory: ${{runner.workspace}}/build17
run: |
cmake --build . --config $BUILD_TYPE --parallel $(nproc) --target \
cmake --build . --config $BUILD_TYPE --parallel $(sysctl -n hw.ncpu) --target \
LuaBridgeTestsLuaJIT \
LuaBridgeTestsLuaJITNoexcept

- name: Test LuaJIT (C++17)
working-directory: ${{runner.workspace}}/build17
run: ctest --parallel $(nproc) -R "LuaBridgeTestsLuaJIT" --output-on-failure
run: ctest --parallel $(sysctl -n hw.ncpu) -R "LuaBridgeTestsLuaJIT" --output-on-failure

- name: Configure C++20
working-directory: ${{runner.workspace}}/build20
Expand All @@ -131,13 +131,13 @@ jobs:
- name: Build LuaJIT (C++20)
working-directory: ${{runner.workspace}}/build20
run: |
cmake --build . --config $BUILD_TYPE --parallel $(nproc) --target \
cmake --build . --config $BUILD_TYPE --parallel $(sysctl -n hw.ncpu) --target \
LuaBridgeTestsLuaJIT \
LuaBridgeTestsLuaJITNoexcept

- name: Test LuaJIT (C++20)
working-directory: ${{runner.workspace}}/build20
run: ctest --parallel $(nproc) -R "LuaBridgeTestsLuaJIT" --output-on-failure
run: ctest --parallel $(sysctl -n hw.ncpu) -R "LuaBridgeTestsLuaJIT" --output-on-failure

- name: Configure C++23
working-directory: ${{runner.workspace}}/build23
Expand All @@ -146,13 +146,13 @@ jobs:
- name: Build LuaJIT (C++23)
working-directory: ${{runner.workspace}}/build23
run: |
cmake --build . --config $BUILD_TYPE --parallel $(nproc) --target \
cmake --build . --config $BUILD_TYPE --parallel $(sysctl -n hw.ncpu) --target \
LuaBridgeTestsLuaJIT \
LuaBridgeTestsLuaJITNoexcept

- name: Test LuaJIT (C++23)
working-directory: ${{runner.workspace}}/build23
run: ctest --parallel $(nproc) -R "LuaBridgeTestsLuaJIT" --output-on-failure
run: ctest --parallel $(sysctl -n hw.ncpu) -R "LuaBridgeTestsLuaJIT" --output-on-failure

luau:
runs-on: macos-latest
Expand All @@ -174,35 +174,35 @@ jobs:

- name: Build Luau (C++17)
working-directory: ${{runner.workspace}}/build17
run: cmake --build . --config $BUILD_TYPE --parallel $(nproc) --target LuaBridgeTestsLuau
run: cmake --build . --config $BUILD_TYPE --parallel $(sysctl -n hw.ncpu) --target LuaBridgeTestsLuau

- name: Test Luau (C++17)
working-directory: ${{runner.workspace}}/build17
run: ctest --parallel $(nproc) -R "LuaBridgeTestsLuau" --output-on-failure
run: ctest --parallel $(sysctl -n hw.ncpu) -R "LuaBridgeTestsLuau" --output-on-failure

- name: Configure C++20
working-directory: ${{runner.workspace}}/build20
run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_CXX_STANDARD=20 -G Ninja

- name: Build Luau (C++20)
working-directory: ${{runner.workspace}}/build20
run: cmake --build . --config $BUILD_TYPE --parallel $(nproc) --target LuaBridgeTestsLuau
run: cmake --build . --config $BUILD_TYPE --parallel $(sysctl -n hw.ncpu) --target LuaBridgeTestsLuau

- name: Test Luau (C++20)
working-directory: ${{runner.workspace}}/build20
run: ctest --parallel $(nproc) -R "LuaBridgeTestsLuau" --output-on-failure
run: ctest --parallel $(sysctl -n hw.ncpu) -R "LuaBridgeTestsLuau" --output-on-failure

- name: Configure C++23
working-directory: ${{runner.workspace}}/build23
run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_CXX_STANDARD=23 -G Ninja

- name: Build Luau (C++23)
working-directory: ${{runner.workspace}}/build23
run: cmake --build . --config $BUILD_TYPE --parallel $(nproc) --target LuaBridgeTestsLuau
run: cmake --build . --config $BUILD_TYPE --parallel $(sysctl -n hw.ncpu) --target LuaBridgeTestsLuau

- name: Test Luau (C++23)
working-directory: ${{runner.workspace}}/build23
run: ctest --parallel $(nproc) -R "LuaBridgeTestsLuau" --output-on-failure
run: ctest --parallel $(sysctl -n hw.ncpu) -R "LuaBridgeTestsLuau" --output-on-failure

ravi:
runs-on: macos-latest
Expand All @@ -224,32 +224,32 @@ jobs:

- name: Build Ravi (C++17)
working-directory: ${{runner.workspace}}/build17
run: cmake --build . --config $BUILD_TYPE --parallel $(nproc) --target LuaBridgeTestsRavi
run: cmake --build . --config $BUILD_TYPE --parallel $(sysctl -n hw.ncpu) --target LuaBridgeTestsRavi

- name: Test Ravi (C++17)
working-directory: ${{runner.workspace}}/build17
run: ctest --parallel $(nproc) -R "LuaBridgeTestsRavi" --output-on-failure
run: ctest --parallel $(sysctl -n hw.ncpu) -R "LuaBridgeTestsRavi" --output-on-failure

- name: Configure C++20
working-directory: ${{runner.workspace}}/build20
run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_CXX_STANDARD=20 -G Ninja

- name: Build Ravi (C++20)
working-directory: ${{runner.workspace}}/build20
run: cmake --build . --config $BUILD_TYPE --parallel $(nproc) --target LuaBridgeTestsRavi
run: cmake --build . --config $BUILD_TYPE --parallel $(sysctl -n hw.ncpu) --target LuaBridgeTestsRavi

- name: Test Ravi (C++20)
working-directory: ${{runner.workspace}}/build20
run: ctest --parallel $(nproc) -R "LuaBridgeTestsRavi" --output-on-failure
run: ctest --parallel $(sysctl -n hw.ncpu) -R "LuaBridgeTestsRavi" --output-on-failure

- name: Configure C++23
working-directory: ${{runner.workspace}}/build23
run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_CXX_STANDARD=23 -G Ninja

- name: Build Ravi (C++23)
working-directory: ${{runner.workspace}}/build23
run: cmake --build . --config $BUILD_TYPE --parallel $(nproc) --target LuaBridgeTestsRavi
run: cmake --build . --config $BUILD_TYPE --parallel $(sysctl -n hw.ncpu) --target LuaBridgeTestsRavi

- name: Test Ravi (C++23)
working-directory: ${{runner.workspace}}/build23
run: ctest --parallel $(nproc) -R "LuaBridgeTestsRavi" --output-on-failure
run: ctest --parallel $(sysctl -n hw.ncpu) -R "LuaBridgeTestsRavi" --output-on-failure
4 changes: 4 additions & 0 deletions Source/LuaBridge/detail/LuaHelpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,8 @@ inline void lua_pushcclosure_x(lua_State* L, lua_CFunction fn, const char* debug
[[noreturn]] inline void lua_error_x(lua_State* L)
{
lua_error(L);

detail::unreachable();
}

inline int lua_getstack_x(lua_State* L, int level, lua_Debug* ar)
Expand Down Expand Up @@ -184,6 +186,8 @@ inline void lua_pushcclosure_x(lua_State* L, lua_CFunction fn, const char* debug
[[noreturn]] inline void lua_error_x(lua_State* L)
{
lua_error(L);

detail::unreachable();
}

inline int lua_getstack_x(lua_State* L, int level, lua_Debug* ar)
Expand Down
20 changes: 19 additions & 1 deletion Source/LuaBridge/detail/LuaRef.h
Original file line number Diff line number Diff line change
Expand Up @@ -1836,11 +1836,29 @@ class LuaRef : public LuaRefBase<LuaRef, LuaRef>
const void* getPointer() const
{
#if LUABRIDGE_SAFE_STACK_CHECKS
if (! lua_checkstack(m_L, 1))
if (! lua_checkstack(m_L, 3))
return nullptr;
#endif

lua_rawgeti(m_L, LUA_REGISTRYINDEX, m_ref);

if (lua_isuserdata(m_L, -1) && lua_getmetatable(m_L, -1))
{
const void* key = static_cast<const void*>(detail::getTypeKey());
lua_pushlightuserdata(m_L, const_cast<void*>(key));
lua_rawget(m_L, -2);
const bool isLuaBridgeType = lua_isstring(m_L, -1);
lua_pop(m_L, 2);

if (isLuaBridgeType)
{
const auto* ud = static_cast<detail::Userdata*>(lua_touserdata(m_L, -1));
const void* ptr = ud->getPointer();
lua_pop(m_L, 1);
return ptr;
}
}

const void* ptr = lua_topointer(m_L, -1);
lua_pop(m_L, 1);

Expand Down
7 changes: 4 additions & 3 deletions Source/LuaBridge/detail/Userdata.h
Original file line number Diff line number Diff line change
Expand Up @@ -363,17 +363,18 @@ class Userdata
|| isInstance(L, index, detail::getConstRegistryKey<T>());
}

protected:
Userdata() = default;

/**
* @brief Get an untyped pointer to the contained class.
*/
public:
void* getPointer() const noexcept
{
return m_p;
}

protected:
Userdata() = default;

void* m_p = nullptr; // subclasses must set this
};

Expand Down
132 changes: 132 additions & 0 deletions Tests/Source/LuaRefTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2184,3 +2184,135 @@ TEST_F(LuaRefTests, PreservesLuaTableMutations)
ASSERT_TRUE(secondResult);
EXPECT_EQ(200, *secondResult);
}

TEST_F(LuaRefTests, GetPointerDefaultConstructed)
{
luabridge::LuaRef ref(L);
EXPECT_EQ(nullptr, ref.getPointer());
}

TEST_F(LuaRefTests, GetPointerNil)
{
runLua("result = nil");
EXPECT_EQ(nullptr, result().getPointer());

luabridge::LuaRef nilRef(L, luabridge::LuaNil());
EXPECT_EQ(nullptr, nilRef.getPointer());
}

TEST_F(LuaRefTests, GetPointerBoolean)
{
runLua("result = true");
EXPECT_EQ(nullptr, result().getPointer());

runLua("result = false");
EXPECT_EQ(nullptr, result().getPointer());
}

TEST_F(LuaRefTests, GetPointerNumber)
{
runLua("result = 42");
EXPECT_EQ(nullptr, result().getPointer());

runLua("result = 3.14");
EXPECT_EQ(nullptr, result().getPointer());
}

TEST_F(LuaRefTests, GetPointerString)
{
runLua("result = 'hello'");

#if LUA_VERSION_NUM >= 504 || LUABRIDGE_ON_LUAU || LUABRIDGE_ON_LUAJIT
// Lua 5.4+, Luau, and LuaJIT return a pointer for strings via lua_topointer
EXPECT_NE(nullptr, result().getPointer());
#else
EXPECT_EQ(nullptr, result().getPointer());
#endif
}

TEST_F(LuaRefTests, GetPointerTable)
{
runLua("result = {}");
EXPECT_NE(nullptr, result().getPointer());
}

TEST_F(LuaRefTests, GetPointerTableIdentity)
{
runLua("result = {}");
const void* p1 = result().getPointer();
const void* p2 = result().getPointer();
EXPECT_NE(nullptr, p1);
EXPECT_EQ(p1, p2);
}

TEST_F(LuaRefTests, GetPointerDistinctTables)
{
runLua("t1 = {}; t2 = {}");
auto t1 = luabridge::getGlobal(L, "t1");
auto t2 = luabridge::getGlobal(L, "t2");

const void* p1 = t1.getPointer();
const void* p2 = t2.getPointer();
EXPECT_NE(nullptr, p1);
EXPECT_NE(nullptr, p2);
EXPECT_NE(p1, p2);
}

TEST_F(LuaRefTests, GetPointerFunction)
{
runLua("result = function() end");
EXPECT_NE(nullptr, result().getPointer());
}

TEST_F(LuaRefTests, GetPointerLightUserdata)
{
int dummy = 0;
lua_pushlightuserdata(L, &dummy);
auto ref = luabridge::LuaRef::fromStack(L);
EXPECT_EQ(&dummy, ref.getPointer());
}

TEST_F(LuaRefTests, GetPointerLightUserdataNull)
{
lua_pushlightuserdata(L, nullptr);
auto ref = luabridge::LuaRef::fromStack(L);
EXPECT_EQ(nullptr, ref.getPointer());
}

TEST_F(LuaRefTests, GetPointerUserdata)
{
void* p = lua_newuserdata(L, 100);
auto ref = luabridge::LuaRef::fromStack(L);
EXPECT_NE(nullptr, ref.getPointer());
EXPECT_EQ(p, ref.getPointer());
}

TEST_F(LuaRefTests, GetPointerRegisteredClass)
{
luabridge::getGlobalNamespace(L).beginClass<Class>("Class").endClass();

Class obj;
auto ref = luabridge::LuaRef(L, &obj);
EXPECT_EQ(&obj, ref.getPointer());
}

TEST_F(LuaRefTests, GetPointerThread)
{
lua_State* threadL = lua_newthread(L);
lua_pushthread(threadL);
auto ref = luabridge::LuaRef::fromStack(L);
EXPECT_NE(nullptr, ref.getPointer());
EXPECT_EQ(threadL, ref.getPointer());
}

#if LUABRIDGE_SAFE_STACK_CHECKS
TEST_F(LuaRefTests, GetPointerStackOverflow)
{
runLua("result = {}");
auto ref = result();
exhaustStackSpace();
const void* p = ref.getPointer();
lua_settop(L, 0);
EXPECT_EQ(nullptr, p);
}
#endif
Loading