Skip to content

Commit

Permalink
Fix debugname on class constructors and methods
Browse files Browse the repository at this point in the history
  • Loading branch information
kunitoki committed Mar 3, 2024
1 parent 9ab762e commit e26283a
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 25 deletions.
2 changes: 1 addition & 1 deletion Source/LuaBridge/detail/CFunctions.h
Original file line number Diff line number Diff line change
Expand Up @@ -925,7 +925,7 @@ int invoke_const_member_function(lua_State* L)
template <class T>
int invoke_member_cfunction(lua_State* L)
{
using F = int (T::*)(lua_State * L);
using F = int (T::*)(lua_State* L);

LUABRIDGE_ASSERT(isfulluserdata(L, lua_upvalueindex(1)));

Expand Down
4 changes: 2 additions & 2 deletions Source/LuaBridge/detail/LuaHelpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ inline void* lua_newuserdata_x(lua_State* L, size_t sz)
return lua_newuserdata(L, sz);
}

inline void lua_pushcfunction_x(lua_State *L, lua_CFunction fn, const char* debugname = "")
inline void lua_pushcfunction_x(lua_State *L, lua_CFunction fn, const char* debugname)
{
unused(debugname);

Expand Down Expand Up @@ -505,7 +505,7 @@ void* lua_newuserdata_aligned(lua_State* L, Args&&... args)
void* pointer = lua_newuserdata_x<T>(L, maximum_space_needed_to_align<T>());

lua_newtable(L);
lua_pushcfunction_x(L, &lua_deleteuserdata_aligned<T>);
lua_pushcfunction_x(L, &lua_deleteuserdata_aligned<T>, "");
rawsetfield(L, -2, "__gc");
lua_setmetatable(L, -2);
#endif
Expand Down
6 changes: 4 additions & 2 deletions Source/LuaBridge/detail/LuaRef.h
Original file line number Diff line number Diff line change
Expand Up @@ -999,20 +999,22 @@ class LuaRef : public LuaRefBase<LuaRef, LuaRef>
* @brief Create a new function on the top of a Lua stack and return a reference to it.
*
* @param L A Lua state.
* @param func The c++ function to map to lua.
* @param debugname Optional debug name (used only by Luau).
*
* @returns A reference to the newly created function.
*
* @see luabridge::newFunction()
*/
template <class F>
static LuaRef newFunction(lua_State* L, F&& func)
static LuaRef newFunction(lua_State* L, F&& func, const char* debugname = "")
{
#if LUABRIDGE_SAFE_STACK_CHECKS
if (! lua_checkstack(L, 1))
return { L };
#endif

detail::push_function(L, std::forward<F>(func), "");
detail::push_function(L, std::forward<F>(func), debugname);
return LuaRef(L, FromStack());
}

Expand Down
42 changes: 22 additions & 20 deletions Source/LuaBridge/detail/Namespace.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,8 +150,9 @@ class Namespace : public detail::Registrar
class ClassBase : public detail::Registrar
{
public:
explicit ClassBase(Namespace parent)
explicit ClassBase(const char* name, Namespace parent)
: Registrar(std::move(parent))
, className(name == nullptr ? "" : name)
{
}

Expand Down Expand Up @@ -274,6 +275,9 @@ class Namespace : public detail::Registrar
LUABRIDGE_ASSERT(lua_istable(L, -2));
LUABRIDGE_ASSERT(lua_istable(L, -1));
}

//=========================================================================================
const char* className = "";
};

//=============================================================================================
Expand All @@ -300,7 +304,7 @@ class Namespace : public detail::Registrar
* @param options Class options.
*/
Class(const char* name, Namespace parent, Options options)
: ClassBase(std::move(parent))
: ClassBase(name, std::move(parent))
{
LUABRIDGE_ASSERT(name != nullptr);
LUABRIDGE_ASSERT(lua_istable(L, -1)); // Stack: namespace table (ns)
Expand Down Expand Up @@ -375,7 +379,7 @@ class Namespace : public detail::Registrar
* @param staticKey Key where the class is stored.
*/
Class(const char* name, Namespace parent, const void* const staticKey, Options options)
: ClassBase(std::move(parent))
: ClassBase(name, std::move(parent))
{
LUABRIDGE_ASSERT(name != nullptr);
LUABRIDGE_ASSERT(lua_istable(L, -1)); // Stack: namespace table (ns)
Expand Down Expand Up @@ -1078,7 +1082,7 @@ class Namespace : public detail::Registrar
{
([&]
{
lua_pushcclosure_x(L, &detail::constructor_placement_proxy<T, detail::function_arguments_t<Functions>>, "", 0); // TODO
lua_pushcclosure_x(L, &detail::constructor_placement_proxy<T, detail::function_arguments_t<Functions>>, className, 0);

} (), ...);
}
Expand All @@ -1096,14 +1100,14 @@ class Namespace : public detail::Registrar
lua_pushinteger(L, static_cast<int>(detail::function_arity_excluding_v<Functions, lua_State*>));
lua_settable(L, -3);
lua_pushinteger(L, 2);
lua_pushcclosure_x(L, &detail::constructor_placement_proxy<T, detail::function_arguments_t<Functions>>, "", 0); // TODO
lua_pushcclosure_x(L, &detail::constructor_placement_proxy<T, detail::function_arguments_t<Functions>>, className, 0);
lua_settable(L, -3);
lua_rawseti(L, -2, idx);
++idx;

} (), ...);

lua_pushcclosure_x(L, &detail::try_overload_functions<true>, "", 1); // TODO
lua_pushcclosure_x(L, &detail::try_overload_functions<true>, className, 1);
}

rawsetfield(L, -2, "__call");
Expand Down Expand Up @@ -1136,7 +1140,7 @@ class Namespace : public detail::Registrar
using F = detail::constructor_forwarder<T, Functions>;

lua_newuserdata_aligned<F>(L, F(std::move(functions))); // Stack: co, cl, st, upvalue
lua_pushcclosure_x(L, &detail::invoke_proxy_constructor<F>, "", 1); // Stack: co, cl, st, function // TODO
lua_pushcclosure_x(L, &detail::invoke_proxy_constructor<F>, className, 1); // Stack: co, cl, st, function

} (), ...);
}
Expand All @@ -1160,14 +1164,14 @@ class Namespace : public detail::Registrar
lua_settable(L, -3);
lua_pushinteger(L, 2);
lua_newuserdata_aligned<F>(L, F(std::move(functions)));
lua_pushcclosure_x(L, &detail::invoke_proxy_constructor<F>, "", 1); // TODO
lua_pushcclosure_x(L, &detail::invoke_proxy_constructor<F>, className, 1);
lua_settable(L, -3);
lua_rawseti(L, -2, idx);
++idx;

} (), ...);

lua_pushcclosure_x(L, &detail::try_overload_functions<true>, "", 1); // TODO
lua_pushcclosure_x(L, &detail::try_overload_functions<true>, className, 1);
}

rawsetfield(L, -2, "__call"); // Stack: co, cl, st
Expand All @@ -1189,7 +1193,7 @@ class Namespace : public detail::Registrar
{
([&]
{
lua_pushcclosure_x(L, &detail::constructor_container_proxy<C, detail::function_arguments_t<Functions>>, "", 0); // TODO
lua_pushcclosure_x(L, &detail::constructor_container_proxy<C, detail::function_arguments_t<Functions>>, className, 0);

} (), ...);
}
Expand All @@ -1207,14 +1211,14 @@ class Namespace : public detail::Registrar
lua_pushinteger(L, static_cast<int>(detail::function_arity_excluding_v<Functions, lua_State*>));
lua_settable(L, -3);
lua_pushinteger(L, 2);
lua_pushcclosure_x(L, &detail::constructor_container_proxy<C, detail::function_arguments_t<Functions>>, "", 0); // TODO
lua_pushcclosure_x(L, &detail::constructor_container_proxy<C, detail::function_arguments_t<Functions>>, className, 0);
lua_settable(L, -3);
lua_rawseti(L, -2, idx);
++idx;

} (), ...);

lua_pushcclosure_x(L, &detail::try_overload_functions<true>, "", 1); // TODO
lua_pushcclosure_x(L, &detail::try_overload_functions<true>, className, 1);
}

rawsetfield(L, -2, "__call");
Expand Down Expand Up @@ -1243,7 +1247,7 @@ class Namespace : public detail::Registrar
using F = detail::container_forwarder<C, Functions>;

lua_newuserdata_aligned<F>(L, F(std::move(functions))); // Stack: co, cl, st, upvalue
lua_pushcclosure_x(L, &detail::invoke_proxy_constructor<F>, "", 1); // Stack: co, cl, st, function // TODO
lua_pushcclosure_x(L, &detail::invoke_proxy_constructor<F>, className, 1); // Stack: co, cl, st, function

} (), ...);
}
Expand All @@ -1267,14 +1271,14 @@ class Namespace : public detail::Registrar
lua_settable(L, -3);
lua_pushinteger(L, 2);
lua_newuserdata_aligned<F>(L, F(std::move(functions)));
lua_pushcclosure_x(L, &detail::invoke_proxy_constructor<F>, "", 1); // TODO
lua_pushcclosure_x(L, &detail::invoke_proxy_constructor<F>, className, 1);
lua_settable(L, -3);
lua_rawseti(L, -2, idx);
++idx;

} (), ...);

lua_pushcclosure_x(L, &detail::try_overload_functions<true>, "", 1); // TODO
lua_pushcclosure_x(L, &detail::try_overload_functions<true>, className, 1);
}

rawsetfield(L, -2, "__call"); // Stack: co, cl, st
Expand All @@ -1299,7 +1303,7 @@ class Namespace : public detail::Registrar
using F = detail::factory_forwarder<T, Allocator, Deallocator>;

lua_newuserdata_aligned<F>(L, F(std::move(allocator), std::move(deallocator))); // Stack: co, cl, st, upvalue
lua_pushcclosure_x(L, &detail::invoke_proxy_constructor<F>, "", 1); // Stack: co, cl, st, function // TODO
lua_pushcclosure_x(L, &detail::invoke_proxy_constructor<F>, className, 1); // Stack: co, cl, st, function
rawsetfield(L, -2, "__call"); // Stack: co, cl, st

return *this;
Expand Down Expand Up @@ -1684,14 +1688,12 @@ class Namespace : public detail::Registrar
{
using U = std::underlying_type_t<T>;

auto result = Stack<U>::push(L, static_cast<U>(value));
if (! result)
if (auto result = Stack<U>::push(L, static_cast<U>(value)); ! result)
luaL_error(L, "%s", result.message().c_str());
}
else
{
auto result = Stack<T>::push(L, value);
if (! result)
if (auto result = Stack<T>::push(L, value); ! result)
luaL_error(L, "%s", result.message().c_str());
}

Expand Down
62 changes: 62 additions & 0 deletions Tests/Source/ClassTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3265,3 +3265,65 @@ TEST_F(ClassTests, BugWithFactoryConstructor)

SUCCEED();
}

namespace {

struct ClassWithMethod
{
ClassWithMethod(int)
{
}

ClassWithMethod(lua_State* L)
{
luaL_argerror(L, 1, "test message");
}

int methodWithError(lua_State* L)
{
luaL_argerror(L, 2, "test message");
return 0;
}
};

} // namespace

TEST_F(ClassTests, BugWithLuauNotPrintingClassConstructorNameInErrors)
{
luabridge::getGlobalNamespace(L)
.beginNamespace("foo")
.beginClass<ClassWithMethod>("ClassWithMethod")
.addConstructor<void (*)(lua_State*)>()
.addFunction("methodWithError", &ClassWithMethod::methodWithError)
.endClass()
.endNamespace();

auto [result, error] = runLuaCaptureError(R"(
local bar = foo.ClassWithMethod()
result = bar
)");

EXPECT_FALSE(result);
EXPECT_TRUE(error.find("ClassWithMethod") != std::string::npos);
}

TEST_F(ClassTests, BugWithLuauNotPrintingClassMethodNameInErrors)
{
luabridge::getGlobalNamespace(L)
.beginNamespace("foo")
.beginClass<ClassWithMethod>("ClassWithMethod")
.addConstructor<void (*)(lua_State*)>()
.addFunction("methodWithError", &ClassWithMethod::methodWithError)
.endClass()
.endNamespace();

ClassWithMethod x(1);
luabridge::setGlobal(L, x, "xyz");

auto [result, error] = runLuaCaptureError(R"(
result = xyz:methodWithError()
)");

EXPECT_FALSE(result);
EXPECT_TRUE(error.find("methodWithError") != std::string::npos);
}

0 comments on commit e26283a

Please sign in to comment.