From 0b0a380d25afdfc0c20aa5caadaf1eb5f7086d1a Mon Sep 17 00:00:00 2001 From: Daniel Wallin Date: Wed, 11 Feb 2004 19:24:28 +0000 Subject: [PATCH] new scope system --- luabind/class.hpp | 94 +++++-- luabind/detail/class_rep.hpp | 28 +-- luabind/detail/is_indirect_const.hpp | 2 +- luabind/detail/pointee_sizeof.hpp | 6 +- luabind/function.hpp | 27 +- luabind/scope.hpp | 473 +++++++---------------------------- src/makefile | 2 + test/makefile | 2 +- test/test_scope.cpp | 4 +- 9 files changed, 198 insertions(+), 440 deletions(-) rewrite luabind/scope.hpp (86%) diff --git a/luabind/class.hpp b/luabind/class.hpp index 1f9d9dc..cd2f4e9 100644 --- a/luabind/class.hpp +++ b/luabind/class.hpp @@ -125,6 +125,7 @@ #include #include #include +#include //#include @@ -625,7 +626,7 @@ namespace luabind - +/* struct class_base: detail::scoped_object { protected: @@ -1032,20 +1033,77 @@ namespace luabind return ret; } }; +*/ + namespace detail { + struct class_registration; + + struct class_base : detail::scope + { + public: + class_base(char const* name); + struct base_desc + { + LUABIND_TYPE_INFO type; + int ptr_offset; + }; + void init( + LUABIND_TYPE_INFO type + , LUABIND_TYPE_INFO holder_type + , LUABIND_TYPE_INFO const_holder_type + , void*(*extractor)(void*) + , const void*(*const_extractor)(void*) + , void(*const_converter)(void*,void*) + , void(*holder_constructor)(void*,void*) + , void(*const_holder_constructor)(void*,void*) + , void(*destructor)(void*) + , void(*const_holder_destructor)(void*) + , int holder_size + , int holder_alignment); + + void add_getter( + const char* name + , const boost::function2& g); + + void add_setter( + const char* name + , const boost::function2& s); + + void add_base(const base_desc& b); + void add_constructor(const detail::construct_rep::overload_t& o); + void add_method(const char* name, const detail::overload_rep& o); +#ifndef LUABIND_NO_ERROR_CHECKING + void add_operator( + int op_id + , int(*func)(lua_State*) + , int(*matcher)(lua_State*) + , void(*sig)(lua_State* + , std::string&) + , int arity); +#else + void add_operator( + int op_id + , int(*func)(lua_State*) + , int(*matcher)(lua_State*) + , int arity); +#endif + const char* name() const; + void add_static_constant(const char* name, int val); + + private: + class_registration* m_registration; + }; - - - + } // namespace detail // registers a class in the lua environment template - struct class_: class_base + struct class_: detail::class_base { typedef class_ self_t; @@ -1139,7 +1197,7 @@ namespace luabind struct internal_def_s { template - static void apply(const char* name, F f, class_base* c) + static void apply(const char* name, F f, detail::class_base* c) { // std::cout << "HeldType2: " << typeid(HeldType).name() << "\n"; @@ -1160,7 +1218,7 @@ namespace luabind } template - static void apply(constructor, class_base* c) + static void apply(constructor, detail::class_base* c) { // std::cout << "HeldType2: " << typeid(HeldType).name() << "\n"; @@ -1207,14 +1265,14 @@ namespace luabind ~class_() { - if (m_L != 0) + /* if (m_L != 0) { scope::init(m_L); lua_pushvalue(m_L, LUA_GLOBALSINDEX); scope_stack::push(m_L); commit(m_L); scope_stack::pop(m_L); - } + }*/ } template @@ -1391,13 +1449,6 @@ namespace luabind return detail::enum_maker(*this); } - class_& operator[](const detail::scoped_object& x) - { - detail::scoped_object* ptr = &const_cast(x); - m_children.push_back(ptr->clone()); - return *this; - } - private: void init() @@ -1417,15 +1468,14 @@ namespace luabind , bases >::type Base; - HeldType* crap = 0; - -// boost::langbinding::register_dynamic_id(); - class_base::init(LUABIND_TYPEID(T) , detail::internal_holder_type::apply() + , detail::pointee_typeid( + get_const_holder(static_cast(0))) , detail::internal_holder_extractor::apply(detail::type()) , detail::internal_const_holder_extractor::apply(detail::type()) - , detail::const_converter::apply(luabind::get_const_holder(crap)) + , detail::const_converter::apply( + luabind::get_const_holder((HeldType*)0)) , detail::holder_constructor::apply(detail::type()) , detail::const_holder_constructor::apply(detail::type()) , detail::internal_holder_destructor::apply(detail::type()) @@ -1433,8 +1483,6 @@ namespace luabind , detail::internal_holder_size::apply() , detail::get_holder_alignment::apply()); - set_const_holder_type(luabind::get_const_holder(static_cast(0))); - generate_baseclass_list(detail::type()); } diff --git a/luabind/detail/class_rep.hpp b/luabind/detail/class_rep.hpp index 1599eee..a037533 100644 --- a/luabind/detail/class_rep.hpp +++ b/luabind/detail/class_rep.hpp @@ -47,9 +47,6 @@ namespace luabind template struct bases {}; typedef bases no_bases; - - struct class_base; - } namespace luabind { namespace detail @@ -59,6 +56,8 @@ namespace luabind { namespace detail LUABIND_API std::string stack_content_by_name(lua_State* L, int start_index); int construct_lua_class_callback(lua_State* L); + struct class_registration; + // this is class-specific information, poor man's vtable // this is allocated statically (removed by the compiler) // a pointer to this structure is stored in the lua tables' @@ -70,7 +69,7 @@ namespace luabind { namespace detail class LUABIND_API class_rep { - friend struct luabind::class_base; + friend struct class_registration; friend int super_callback(lua_State*); //TODO: avoid the lua-prefix friend int lua_class_gettable(lua_State*); @@ -243,6 +242,16 @@ namespace luabind { namespace detail m_construct_holder = base->m_construct_holder; m_construct_const_holder = base->m_construct_const_holder; } + + struct operator_callback: public overload_rep_base + { + inline void set_fun(int (*f)(lua_State*)) { func = f; } + inline int call(lua_State* L) { return func(L); } + inline void set_arity(int arity) { m_arity = arity; } + + private: + int(*func)(lua_State*); + }; private: @@ -335,17 +344,6 @@ namespace luabind { namespace detail std::map m_getters; std::map m_setters; - struct operator_callback: public overload_rep_base - { - inline void set_fun(int (*f)(lua_State*)) { func = f; } - inline int call(lua_State* L) { return func(L); } - inline void set_arity(int arity) { m_arity = arity; } - - private: - - int(*func)(lua_State*); - }; - std::vector m_operators[number_of_operators]; // the operators in lua void(*m_destructor)(void*); diff --git a/luabind/detail/is_indirect_const.hpp b/luabind/detail/is_indirect_const.hpp index 52000e1..b6c1282 100755 --- a/luabind/detail/is_indirect_const.hpp +++ b/luabind/detail/is_indirect_const.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2004 Daniel Wallin +// Copyright (c) 2004 Daniel Wallin and Arvid Norberg // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), diff --git a/luabind/detail/pointee_sizeof.hpp b/luabind/detail/pointee_sizeof.hpp index d4e2787..3875c09 100755 --- a/luabind/detail/pointee_sizeof.hpp +++ b/luabind/detail/pointee_sizeof.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2004 Daniel Wallin +// Copyright (c) 2004 Daniel Wallin and Arvid Norberg // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), @@ -34,6 +34,10 @@ namespace luabind { } // namespace detail + // returns the indirect sizeof U, as in + // sizeof(T*) = sizeof(T) + // sizeof(T&) = sizeof(T) + // sizeof(T) = sizeof(T) template struct pointee_sizeof { diff --git a/luabind/function.hpp b/luabind/function.hpp index 0e73e81..c8dc848 100644 --- a/luabind/function.hpp +++ b/luabind/function.hpp @@ -221,7 +221,7 @@ namespace luabind LUABIND_API int function_dispatcher(lua_State* L); } } - + template void function(lua_State* L, const char* name, F f, const Policies& p) { @@ -237,7 +237,7 @@ namespace luabind namespace detail { template - struct function_commiter : detail::scoped_object + struct function_commiter : detail::registration { function_commiter(const char* n, F f, const Policies& p) : m_name(n) @@ -245,12 +245,7 @@ namespace luabind , policies(p) {} - virtual detail::scoped_object* clone() - { - return new function_commiter(*this); - } - - virtual void commit(lua_State* L) + virtual void register_(lua_State* L) const { detail::free_functions::overload_rep o(fun, static_cast(0)); @@ -261,7 +256,6 @@ namespace luabind o.set_sig_fun(&detail::get_free_function_signature::apply); #endif - detail::getref(L, scope_stack::top(L)); lua_pushstring(L, m_name.c_str()); lua_gettable(L, -2); @@ -305,8 +299,6 @@ namespace luabind } rep->add_overload(o); - - lua_pop(L, 1); // pop scope } std::string m_name; @@ -316,17 +308,18 @@ namespace luabind } template - detail::function_commiter - def(const char* name, F f, const Policies& policies) + detail::scope def(const char* name, F f, const Policies& policies) { - return detail::function_commiter(name, f, policies); + return detail::scope(std::auto_ptr( + new detail::function_commiter(name, f, policies))); } template - detail::function_commiter - def(const char* name, F f) + detail::scope def(const char* name, F f) { - return detail::function_commiter(name, f, detail::null_type()); + return detail::scope(std::auto_ptr( + new detail::function_commiter( + name, f, detail::null_type()))); } } // namespace luabind diff --git a/luabind/scope.hpp b/luabind/scope.hpp dissimilarity index 86% index 74860e5..df4d827 100755 --- a/luabind/scope.hpp +++ b/luabind/scope.hpp @@ -1,380 +1,93 @@ -// Copyright (c) 2003 Daniel Wallin and Arvid Norberg - -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: - -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. - -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF -// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED -// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT -// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR -// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE -// OR OTHER DEALINGS IN THE SOFTWARE. - - -#ifndef LUABIND_SCOPE_HPP_INCLUDED -#define LUABIND_SCOPE_HPP_INCLUDED - -#include -#include -#include - -#include - -namespace luabind -{ - namespace detail - { - struct scoped_sequence; - - struct scoped_object - { - scoped_object() {} - virtual ~scoped_object() {} - - virtual void commit(lua_State*) = 0; - virtual scoped_object* clone() = 0; - - scoped_sequence operator,(const scoped_object& rhs) const; - }; - - struct scoped_sequence : scoped_object - { - scoped_sequence(scoped_object* a, scoped_object* b) - { -#ifndef NDEBUG - m_cloned = false; -#endif - this->objects.push_back(a); - this->objects.push_back(b); - } - - scoped_sequence() - { -#ifndef NDEBUG - m_cloned = false; -#endif - } - - virtual ~scoped_sequence() - { - for (std::vector - ::const_iterator i = this->objects.begin() - ; i != this->objects.end() - ; ++i) - { - scoped_object* ptr = *i; - delete ptr; - } - } - - scoped_sequence& operator,(const scoped_object& rhs) - { - objects.push_back(const_cast(rhs).clone()); - return *this; - } - - virtual scoped_object* clone() - { - scoped_sequence* copy = new scoped_sequence(); - copy->objects.swap(this->objects); - - assert(!m_cloned && "You cannot register the scoped_object twice"); -#ifndef NDEBUG - m_cloned = true; -#endif - return copy; - } - - virtual void commit(lua_State* L) - { - assert(!m_cloned && "You cannot register the scoped_object twice"); - - for (std::vector - ::const_iterator i = this->objects.begin() - ; i != this->objects.end() - ; ++i) - { - scoped_object* ptr = *i; - ptr->commit(L); - } -#ifndef NDEBUG - m_cloned = false; -#endif - - } - - private: -#ifndef NDEBUG - bool m_cloned; -#endif - mutable std::vector objects; - - }; - - inline scoped_sequence scoped_object::operator,(const scoped_object& rhs) const - { - return scoped_sequence(const_cast(this)->clone(), const_cast(rhs).clone()); - } - - } - - struct scope_stack - { - std::stack scopes; - - static int gc(lua_State* L) - { - scope_stack* scopes = static_cast( - lua_touserdata(L, -1) - ); - - assert(scopes->scopes.size() == 0); - - scopes->~scope_stack(); - - return 0; - } - - static int top(lua_State* L) - { - lua_pushstring(L, "__luabind_scope_stack"); - lua_gettable(L, LUA_REGISTRYINDEX); - - scope_stack* scopes = static_cast( - lua_touserdata(L, -1) - ); - - lua_pop(L, 1); - - return scopes->scopes.top(); - } - - static void push(lua_State* L) - { - lua_pushstring(L, "__luabind_scope_stack"); - lua_gettable(L, LUA_REGISTRYINDEX); - - scope_stack* scopes = static_cast( - lua_touserdata(L, -1) - ); - - lua_pop(L, 1); - - scopes->scopes.push(detail::ref(L)); - } - - static void pop(lua_State* L) - { - lua_pushstring(L, "__luabind_scope_stack"); - lua_gettable(L, LUA_REGISTRYINDEX); - - scope_stack* scopes = static_cast( - lua_touserdata(L, -1) - ); - - lua_pop(L, 1); - - int n = scopes->scopes.top(); - scopes->scopes.pop(); - detail::unref(L, n); - } - }; - - class scope : public detail::scoped_object - { - public: - - static void init(lua_State* L) - { - lua_pushstring(L, "__luabind_scope_stack"); - lua_gettable(L, LUA_REGISTRYINDEX); - - scope_stack* scopes = static_cast( - lua_touserdata(L, -1) - ); - - lua_pop(L, 1); - - if (scopes == 0) - { - scopes = static_cast( - lua_newuserdata(L, sizeof(scope_stack)) - ); - - lua_pushstring(L, "__luabind_scope_stack"); - lua_pushvalue(L, -2); - lua_settable(L, LUA_REGISTRYINDEX); - - new (scopes) scope_stack(); - - lua_newtable(L); - lua_pushstring(L, "__gc"); - lua_pushcclosure(L, scope_stack::gc, 0); - lua_settable(L, -3); - lua_setmetatable(L, -2); - - lua_pop(L, 1); - } - } - - scope(const char* name) - : m_name(name) - { -#ifndef NDEBUG - m_cloned = false; -#endif - } - - ~scope() - { - for (std::vector::iterator - i = m_children.begin(); i != m_children.end(); ++i) - { - delete *i; - } - } - - scope& operator[](const detail::scoped_object& x) - { - detail::scoped_object* ptr = &const_cast(x); - m_children.push_back(ptr->clone()); - return *this; - } - - virtual detail::scoped_object* clone() - { - assert(!m_cloned && "cannot register the same namespace twice"); -#ifndef NDEBUG - m_cloned = true; -#endif - std::vector tmp; - tmp.swap(this->m_children); - scope* copy = new scope(m_name); - copy->m_children.swap(tmp); - return copy; - } - - virtual void commit(lua_State* L) - { - assert(!m_cloned && "cannot register the same namespace twice"); -#ifndef NDEBUG - m_cloned = true; -#endif - init(L); - - detail::getref(L, scope_stack::top(L)); // get current scope - lua_pushstring(L, m_name); - lua_gettable(L, -2); - lua_remove(L, -2); // remove scope - - if (lua_isnil(L, -1)) - { - lua_pop(L, 1); - - lua_newtable(L); - detail::getref(L, scope_stack::top(L)); - lua_pushstring(L, m_name); - lua_pushvalue(L, -3); - lua_settable(L, -3); - lua_pop(L, 1); - } - - scope_stack::push(L); - - for (std::vector - ::const_iterator i = m_children.begin() - ; i != m_children.end() - ; ++i) - { - detail::scoped_object* ptr = *i; - ptr->commit(L); - delete ptr; - } - -#ifndef NDEBUG - m_children.clear(); -#endif - - scope_stack::pop(L); - } - - private: -#ifndef NDEBUG - bool m_cloned; -#endif - mutable std::vector m_children; - const char* m_name; - }; - - - - - - - - class module_proxy - { - public: - - module_proxy(lua_State* L, const char* name) - : m_state(L) - , m_name(name) - { - scope::init(L); - } - - void operator[](const detail::scoped_object& x) const - { - lua_State* L = m_state; - if (m_name) - { - lua_pushstring(L, m_name); - lua_gettable(L, LUA_GLOBALSINDEX); - if (lua_isnil(L, -1)) - { - lua_pop(L, 1); - // see if the table already exists - lua_newtable(L); - lua_pushstring(L, m_name); - lua_pushvalue(L, -2); - lua_settable(L, LUA_GLOBALSINDEX); - } - } - else - { - lua_pushvalue(L, LUA_GLOBALSINDEX); - } - - scope_stack::push(L); - - detail::scoped_object* ptr = &const_cast(x); - ptr->commit(L); - - scope_stack::pop(L); - } - - private: - - lua_State* m_state; - const char* m_name; - }; - - - inline module_proxy module(lua_State* L) { return module_proxy(L,0); } - inline module_proxy module(lua_State* L, const char* name) { return module_proxy(L, name); } - - typedef scope namespace_; -} - -#endif // LUABIND_SCOPE_HPP_INCLUDED - +// Copyright (c) 2004 Daniel Wallin and Arvid Norberg + +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR +// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +// OR OTHER DEALINGS IN THE SOFTWARE. + +#ifndef NEW_SCOPE_040211_HPP +#define NEW_SCOPE_040211_HPP + +#include +#include + +namespace luabind { namespace detail { + + struct registration + { + registration(); + virtual ~registration(); + + protected: + virtual void register_(lua_State*) const = 0; + + private: + friend struct scope; + registration* m_next; + }; + + struct scope + { + scope(); + explicit scope(std::auto_ptr reg); + scope(scope const& other_); + ~scope(); + + scope& operator,(scope s); + + void register_(lua_State* L) const; + + private: + registration* m_chain; + }; + +}} // namespace luabind::detail + +namespace luabind { + + class namespace_ : public detail::scope + { + public: + explicit namespace_(char const* name); + namespace_& operator[](detail::scope s); + + private: + struct registration_; + registration_* m_registration; + }; + + class module_ + { + public: + module_(lua_State* L_, char const* name); + void operator[](detail::scope s); + + private: + lua_State* m_state; + char const* m_name; + }; + + inline module_ module(lua_State* L, char const* name = 0) + { + return module_(L, name); + } + +} // namespace luabind + +#endif // NEW_SCOPE_040211_HPP + diff --git a/src/makefile b/src/makefile index 94e968d..c1432d1 100755 --- a/src/makefile +++ b/src/makefile @@ -1,6 +1,8 @@ include ../config SOURCES = \ + scope.cpp \ + class.cpp \ class_rep.cpp \ function.cpp \ find_best_match.cpp \ diff --git a/test/makefile b/test/makefile index 980dea9..2113964 100644 --- a/test/makefile +++ b/test/makefile @@ -1,10 +1,10 @@ include ../config SOURCES = \ + test_typetraits.cpp \ main.cpp \ test_iterator.cpp \ test_lua_classes.cpp \ - test_typetraits.cpp \ test_construction.cpp \ test_operators.cpp \ test_attributes.cpp \ diff --git a/test/test_scope.cpp b/test/test_scope.cpp index 2ce85e1..0fd4d83 100755 --- a/test/test_scope.cpp +++ b/test/test_scope.cpp @@ -74,9 +74,9 @@ module(L) [ class_("test_class") .def(constructor<>()) - [ +/* [ def("inner_fun", &f) - ] + ]*/ .enum_("vals") [ value("val1", 1), -- 2.11.4.GIT