class_rep.cpp.svn-base

来自「本人找过多个在linux下c++的lua5.1封装库,但很少.luabind已经」· SVN-BASE 代码 · 共 1,676 行 · 第 1/3 页

SVN-BASE
1,676
字号
	}	// we can only reach this line if an exception was thrown	lua_error(L);	return 0; // will never be reached#endif}/*	the functions dispatcher assumes the following:	upvalues:	1: method_rep* method, points to the method_rep that this dispatcher is to call	2: boolean force_static, is true if this is to be a static call       and false if it is a normal call (= virtual if possible).	stack:	1: object_rep* self, points to the object the call is being made on*/int luabind::detail::class_rep::function_dispatcher(lua_State* L){#ifndef NDEBUG/*	lua_Debug tmp_;	assert(lua_getinfo(L, "u", &tmp_));	assert(tmp_.nups == 2);*/	assert(lua_type(L, lua_upvalueindex(1)) == LUA_TLIGHTUSERDATA);	assert(lua_type(L, lua_upvalueindex(2)) == LUA_TBOOLEAN);	assert(lua_type(L, lua_upvalueindex(3)) == LUA_TLIGHTUSERDATA);	assert(lua_touserdata(L, lua_upvalueindex(3)) == reinterpret_cast<void*>(0x1337));//	assert(lua_type(L, 1) == LUA_TUSERDATA);#endif	method_rep* rep = static_cast<method_rep*>(lua_touserdata(L, lua_upvalueindex(1)));	int force_static_call = lua_toboolean(L, lua_upvalueindex(2));	bool ambiguous = false;	int match_index = -1;	int min_match = std::numeric_limits<int>::max();	bool found;#ifdef LUABIND_NO_ERROR_CHECKING	if (rep->overloads().size() == 1)	{		match_index = 0;	}	else	{#endif		int num_params = lua_gettop(L) /*- 1*/;		found = find_best_match(L, &rep->overloads().front(), rep->overloads().size()			, sizeof(overload_rep), ambiguous, min_match, match_index, num_params);#ifdef LUABIND_NO_ERROR_CHECKING	}#else	if (!found)	{		{			std::string msg = "no overload of  '";			msg += rep->crep->name();			msg += ":";			msg += rep->name;			msg += "' matched the arguments (";			msg += stack_content_by_name(L, 1);			msg += ")\ncandidates are:\n";			std::string function_name;			function_name += rep->crep->name();			function_name += ":";			function_name += rep->name;			msg += get_overload_signatures(L, rep->overloads().begin()				, rep->overloads().end(), function_name);			lua_pushstring(L, msg.c_str());		}		lua_error(L);	}	else if (ambiguous)	{		{			std::string msg = "call of overloaded  '";			msg += rep->crep->name();			msg += ":";			msg += rep->name;			msg += "(";			msg += stack_content_by_name(L, 1);			msg += ")' is ambiguous\nnone of the overloads have a best conversion:\n";			std::vector<const overload_rep_base*> candidates;			find_exact_match(L, &rep->overloads().front(), rep->overloads().size()				, sizeof(overload_rep), min_match, num_params, candidates);			std::string function_name;			function_name += rep->crep->name();			function_name += ":";			function_name += rep->name;			msg += get_overload_signatures_candidates(L, candidates.begin()				, candidates.end(), function_name);			lua_pushstring(L, msg.c_str());		}		lua_error(L);	}#endif#ifndef LUABIND_NO_EXCEPTIONS	try	{#endif		const overload_rep& o = rep->overloads()[match_index];        if (force_static_call && !o.has_static())		{			lua_pushstring(L, "pure virtual function called");        }		else		{	        return o.call(L, force_static_call != 0);		}#ifndef LUABIND_NO_EXCEPTIONS	}    catch(const error&)    {    }    catch(const std::exception& e)	{		lua_pushstring(L, e.what());	}	catch (const char* s)	{		lua_pushstring(L, s);	}	catch(...)	{		std::string msg = rep->crep->name();		msg += ":";		msg += rep->name;		msg += "() threw an exception";		lua_pushstring(L, msg.c_str());	}#endif	// we can only reach this line if an error occured	lua_error(L);	return 0; // will never be reached}#ifndef NDEBUG#ifndef BOOST_NO_STRINGSTREAM#include <sstream>#else#include <strstream>#endifnamespace{	std::string to_string(luabind::object const& o)	{		using namespace luabind;		if (type(o) == LUA_TSTRING) return object_cast<std::string>(o);		lua_State* L = o.interpreter();		LUABIND_CHECK_STACK(L);#ifdef BOOST_NO_STRINGSTREAM		std::strstream s;#else		std::stringstream s;#endif		if (type(o) == LUA_TNUMBER)		{			s << object_cast<float>(o);			return s.str();		}		s << "<" << lua_typename(L, type(o)) << ">";#ifdef BOOST_NO_STRINGSTREAM		s << std::ends;#endif		return s.str();	}	std::string member_to_string(luabind::object const& e)	{#if !defined(LUABIND_NO_ERROR_CHECKING)        using namespace luabind;		lua_State* L = e.interpreter();		LUABIND_CHECK_STACK(L);		if (type(e) == LUA_TFUNCTION)		{			e.push(L);			detail::stack_pop p(L, 1);			{				if (lua_getupvalue(L, -1, 3) == 0) return to_string(e);				detail::stack_pop p2(L, 1);				if (lua_touserdata(L, -1) != reinterpret_cast<void*>(0x1337)) return to_string(e);			}#ifdef BOOST_NO_STRINGSTREAM			std::strstream s;#else			std::stringstream s;#endif			{				lua_getupvalue(L, -1, 2);				detail::stack_pop p2(L, 1);				int b = lua_toboolean(L, -1);				s << "<c++ function";				if (b) s << " (default)";				s << "> ";			}			{				lua_getupvalue(L, -1, 1);				detail::stack_pop p2(L, 1);				method_rep* m = static_cast<method_rep*>(lua_touserdata(L, -1));				s << m << "\n";				for (std::vector<overload_rep>::const_iterator i = m->overloads().begin();					i != m->overloads().end(); ++i)				{					std::string str;					i->get_signature(L, str);					s << "   " << str << "\n";				}			}#ifdef BOOST_NO_STRINGSTREAM			s << std::ends;#endif			return s.str();		}        return to_string(e);#else        return "";#endif	}}std::string luabind::detail::class_rep::class_info_string(lua_State* L) const{#ifdef BOOST_NO_STRINGSTREAM	std::strstream ret;#else	std::stringstream ret;#endif	ret << "CLASS: " << m_name << "\n";	ret << "dynamic dispatch functions:\n------------------\n";	for (luabind::iterator i(m_table), end; i != end; ++i)	{		luabind::object e = *i;		ret << "  " << to_string(i.key()) << ": " << member_to_string(e) << "\n";	}	ret << "default implementations:\n------------------\n";	for (luabind::iterator i(m_default_table), end; i != end; ++i)	{		luabind::object e = *i;		ret << "  " << to_string(i.key()) << ": " << member_to_string(e) << "\n";	}#ifdef BOOST_NO_STRINGSTREAM	ret << std::ends;#endif	return ret.str();}#endifvoid luabind::detail::class_rep::add_base_class(const luabind::detail::class_rep::base_info& binfo){	// If you hit this assert you are deriving from a type that is not registered	// in lua. That is, in the class_<> you are giving a baseclass that isn't registered.	// Please note that if you don't need to have access to the base class or the	// conversion from the derived class to the base class, you don't need	// to tell luabind that it derives.	assert(binfo.base && "You cannot derive from an unregistered type");	class_rep* bcrep = binfo.base;	// import all functions from the base	typedef std::list<detail::method_rep> methods_t;	for (methods_t::const_iterator i = bcrep->m_methods.begin();		i != bcrep->m_methods.end(); ++i)    {		add_method(*i);    }	// import all getters from the base	for (std::map<const char*, callback, ltstr>::const_iterator i = bcrep->m_getters.begin(); 			i != bcrep->m_getters.end(); ++i)	{		callback& m = m_getters[i->first];		m.pointer_offset = i->second.pointer_offset + binfo.pointer_offset;		m.func = i->second.func;#ifndef LUABIND_NO_ERROR_CHECKING		m.match = i->second.match;		m.sig = i->second.sig;#endif	}	// import all setters from the base	for (std::map<const char*, callback, ltstr>::const_iterator i = bcrep->m_setters.begin(); 			i != bcrep->m_setters.end(); ++i)	{		callback& m = m_setters[i->first];		m.pointer_offset = i->second.pointer_offset + binfo.pointer_offset;		m.func = i->second.func;#ifndef LUABIND_NO_ERROR_CHECKING		m.match = i->second.match;		m.sig = i->second.sig;#endif	}	// import all static constants	for (std::map<const char*, int, ltstr>::const_iterator i = bcrep->m_static_constants.begin(); 			i != bcrep->m_static_constants.end(); ++i)	{		int& v = m_static_constants[i->first];		v = i->second;	}	// import all operators	for (int i = 0; i < number_of_operators; ++i)	{		for (std::vector<operator_callback>::const_iterator j = bcrep->m_operators[i].begin(); 				j != bcrep->m_operators[i].end(); ++j)			m_operators[i].push_back(*j);	}	// also, save the baseclass info to be used for typecasts	m_bases.push_back(binfo);}int luabind::detail::class_rep::super_callback(lua_State* L){	int args = lua_gettop(L);			object_rep* obj = static_cast<object_rep*>(lua_touserdata(L, lua_upvalueindex(2)));	class_rep* crep = static_cast<class_rep*>(lua_touserdata(L, lua_upvalueindex(1)));	class_rep* base = crep->bases()[0].base;	if (base->get_class_type() == class_rep::lua_class)	{		if (base->bases().empty())		{			obj->set_flags(obj->flags() & ~object_rep::call_super);			lua_pushstring(L, "super");			lua_pushnil(L);			lua_settable(L, LUA_GLOBALSINDEX);		}		else		{			lua_pushstring(L, "super");			lua_pushlightuserdata(L, base);			lua_pushvalue(L, lua_upvalueindex(2));			lua_pushcclosure(L, super_callback, 2);			lua_settable(L, LUA_GLOBALSINDEX);		}		base->get_table(L);		lua_pushstring(L, "__init");		lua_gettable(L, -2);		lua_insert(L, 1);		lua_pop(L, 1);		lua_pushvalue(L, lua_upvalueindex(2));		lua_insert(L, 2);		lua_call(L, args + 1, 0);		// TODO: instead of clearing the global variable "super"		// store it temporarily in the registry. maybe we should		// have some kind of warning if the super global is used?		lua_pushstring(L, "super");		lua_pushnil(L);		lua_settable(L, LUA_GLOBALSINDEX);	}	else	{		obj->set_flags(obj->flags() & ~object_rep::call_super);		// we need to push some garbage at index 1 to make the construction work		lua_pushboolean(L, 1);		lua_insert(L, 1);		construct_rep* rep = &base->m_constructor;		bool ambiguous = false;		int match_index = -1;		int min_match = std::numeric_limits<int>::max();		bool found;			#ifdef LUABIND_NO_ERROR_CHECKING		if (rep->overloads.size() == 1)		{			match_index = 0;		}		else		{#endif			int num_params = lua_gettop(L) - 1;			found = find_best_match(L, &rep->overloads.front(), rep->overloads.size(), sizeof(construct_rep::overload_t), ambiguous, min_match, match_index, num_params);#ifdef LUABIND_NO_ERROR_CHECKING		}#else						if (!found)		{			{				std::string msg = "no constructor of '";				msg += base->m_name;				msg += "' matched the arguments (";				msg += stack_content_by_name(L, 2);				msg += ")";				lua_pushstring(L, msg.c_str());			}			lua_error(L);		}		else if (ambiguous)		{			{				std::string msg = "call of overloaded constructor '";				msg += base->m_name;				msg +=  "(";				msg += stack_content_by_name(L, 2);				msg += ")' is ambiguous";				lua_pushstring(L, msg.c_str());			}			lua_error(L);		}			// TODO: should this be a warning or something?/*			// since the derived class is a lua class			// it may have reimplemented virtual functions			// therefore, we have to instantiate the Basewrapper			// if there is no basewrapper, throw a run-time error			if (!rep->overloads[match_index].has_wrapped_construct())			{				{					std::string msg = "Cannot derive from C++ class '";					msg += base->name();					msg += "'. It does not have a wrapped type";					lua_pushstring(L, msg.c_str());				}				lua_error(L);			}*/#endif#ifndef LUABIND_NO_EXCEPTIONS		try		{#endif			lua_pushvalue(L, lua_upvalueindex(2));			weak_ref backref(L, -1);			lua_pop(L, 1);			void* storage_ptr = obj->ptr();					if (!rep->overloads[match_index].has_wrapped_construct())			{				// if the type doesn't have a wrapped type, use the ordinary constructor				void* instance = rep->overloads[match_index].construct(L, backref);				if (crep->has_holder())				{					crep->m_construct_holder(storage_ptr, instance);				}				else				{					obj->set_object(instance);				}			}			else			{				// get reference to lua object/*				lua_pushvalue(L, lua_upvalueindex(2));				detail::lua_reference ref;				ref.set(L);				void* instance = rep->overloads[match_index].construct_wrapped(L, ref);*/				void* instance = rep->overloads[match_index].construct_wrapped(L, backref);				if (crep->has_holder())				{					crep->m_construct_holder(storage_ptr, instance);							}				else				{					obj->set_object(instance);				}			}			// TODO: is the wrapped type destructed correctly?			// it should, since the destructor is either the wrapped type's			// destructor or the base type's destructor, depending on wether			// the type has a wrapped type or not.			obj->set_destructor(base->destructor());			return 0;#ifndef LUABIND_NO_EXCEPTIONS		}        catch(const error&)        {        }        catch(const std::exception& e)		{			lua_pushstring(L, e.what());		}		catch(const char* s)		{			lua_pushstring(L, s);		}		catch(...)		{			std::string msg = base->m_name;			msg += "() threw an exception";			lua_pushstring(L, msg.c_str());		}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?