From c1c8920024a6a6373f311dfdee3d78bc84bc9853 Mon Sep 17 00:00:00 2001 From: Daniel Wallin Date: Wed, 15 Oct 2008 13:34:15 +0200 Subject: [PATCH] Add more API wrappers to object.hpp. This adds tocfunction(), touserdata(), getupvalue(), setupvalue(). --- doc/docs.rst | 14 ++++++++++++++ luabind/object.hpp | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ test/test_object.cpp | 42 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 107 insertions(+) diff --git a/doc/docs.rst b/doc/docs.rst index f78509e..b674659 100755 --- a/doc/docs.rst +++ b/doc/docs.rst @@ -1249,6 +1249,20 @@ This function creates a new table and returns it as an object. These functions get and set the metatable of a Lua object. +:: + + lua_CFunction tocfunction(object const& value); + template T* touserdata(object const& value) + +These extract values from the object at a lower level than ``object_cast()``. + +:: + + object getupvalue(object const& function, int index); + void setupvalue(object const& function, int index, object const& value); + +These get and set the upvalues of ``function``. + Assigning nil ------------- diff --git a/luabind/object.hpp b/luabind/object.hpp index 158855f..4b48d62 100644 --- a/luabind/object.hpp +++ b/luabind/object.hpp @@ -1251,6 +1251,57 @@ inline void setmetatable( lua_setmetatable(interpreter, -2); } +template +inline lua_CFunction tocfunction(ValueWrapper const& value) +{ + lua_State* interpreter = value_wrapper_traits::interpreter( + value + ); + + value_wrapper_traits::unwrap(interpreter, value); + detail::stack_pop pop(interpreter, 1); + return lua_tocfunction(interpreter, -1); +} + +template +inline T* touserdata(ValueWrapper const& value) +{ + lua_State* interpreter = value_wrapper_traits::interpreter( + value + ); + + value_wrapper_traits::unwrap(interpreter, value); + detail::stack_pop pop(interpreter, 1); + return static_cast(lua_touserdata(interpreter, -1)); +} + +template +inline object getupvalue(ValueWrapper const& value, int index) +{ + lua_State* interpreter = value_wrapper_traits::interpreter( + value + ); + + value_wrapper_traits::unwrap(interpreter, value); + detail::stack_pop pop(interpreter, 2); + lua_getupvalue(interpreter, -1, index); + return object(from_stack(interpreter, -1)); +} + +template +inline void setupvalue( + ValueWrapper1 const& function, int index, ValueWrapper2 const& value) +{ + lua_State* interpreter = value_wrapper_traits::interpreter( + function + ); + + value_wrapper_traits::unwrap(interpreter, function); + detail::stack_pop pop(interpreter, 1); + value_wrapper_traits::unwrap(interpreter, value); + lua_setupvalue(interpreter, -2, index); +} + } // namespace luabind #endif // LUABIND_OBJECT_050419_HPP diff --git a/test/test_object.cpp b/test/test_object.cpp index dd604fa..5063433 100644 --- a/test/test_object.cpp +++ b/test/test_object.cpp @@ -170,6 +170,46 @@ void test_metatable(lua_State* L) assert(type(getmetatable(G["index_table"])["nonexistent"]) == LUA_TNIL); } +int with_upvalues(lua_State *) +{ + return 0; +} + +void test_upvalues(lua_State* L) +{ + lua_pushnumber(L, 3); + lua_pushnumber(L, 4); + lua_pushcclosure(L, &with_upvalues, 2); + + object f(from_stack(L, -1)); + lua_pop(L, 1); + + assert(getupvalue(f, 1) == 3); + assert(getupvalue(f, 2) == 4); + + setupvalue(f, 1, object(L, 4)); + assert(getupvalue(f, 1) == 4); + assert(getupvalue(f, 2) == 4); + + setupvalue(f, 2, object(L, 5)); + assert(getupvalue(f, 1) == 4); + assert(getupvalue(f, 2) == 5); +} + +void test_explicit_conversions(lua_State* L) +{ + lua_pushcclosure(L, &with_upvalues, 0); + object f(from_stack(L, -1)); + lua_pop(L, 1); + assert(tocfunction(f) == &with_upvalues); + + int* p = static_cast(lua_newuserdata(L, sizeof(int))); + *p = 1234; + object x(from_stack(L, -1)); + lua_pop(L, 1); + assert(*touserdata(x) == 1234); +} + void test_main(lua_State* L) { using namespace luabind; @@ -348,5 +388,7 @@ void test_main(lua_State* L) test_call(L); test_metatable(L); + test_upvalues(L); + test_explicit_conversions(L); } -- 2.11.4.GIT