<commit_before>// Copyright (c) 2003 <NAME> and <NAME>

// 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.

#include <luabind/lua_include.hpp>

#include <luabind/detail/stack_utils.hpp>
#include <luabind/detail/conversion_storage.hpp>
#include <luabind/luabind.hpp>
#include <luabind/exception_handler.hpp>
#include <utility>

using namespace luabind::detail;

namespace luabind { namespace detail
{
	LUABIND_API int property_tag(lua_State* L)
	{
		lua_pushstring(L, "luabind: property_tag function can't be called");
		lua_error(L);
		return 0;
	}
}}

#ifndef LUABIND_NO_ERROR_CHECKING

	std::string luabind::detail::get_overload_signatures_candidates(
			lua_State* L
			, std::vector<const overload_rep_base*>::iterator start
			, std::vector<const overload_rep_base*>::iterator end
			, std::string name)
	{
		std::string s;
		for (; start != end; ++start)
		{
			s += name;
			(*start)->get_signature(L, s);
			s += "\n";
		}
		return s;
	}

#endif


luabind::detail::class_rep::class_rep(LUABIND_TYPE_INFO type
	, const char* name
	, lua_State* L
	,  void(*destructor)(void*)
	,  void(*const_holder_destructor)(void*)
	, 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(*construct_holder)(void*,void*)
	, void(*construct_const_holder)(void*,void*)
	, void(*default_construct_holder)(void*)
	, void(*default_construct_const_holder)(void*)
	, void(*adopt_fun)(void*)
	, int holder_size
	, int holder_alignment)

	: m_type(type)
	, m_holder_type(holder_type)
	, m_const_holder_type(const_holder_type)
	, m_extractor(extractor)
	, m_const_extractor(const_extractor)
	, m_const_converter(const_converter)
	, m_construct_holder(construct_holder)
	, m_construct_const_holder(construct_const_holder)
	, m_default_construct_holder(default_construct_holder)
	, m_default_construct_const_holder(default_construct_const_holder)
	, m_adopt_fun(adopt_fun)
	, m_holder_size(holder_size)
	, m_holder_alignment(holder_alignment)
	, m_name(name)
	, m_class_type(cpp_class)
	, m_destructor(destructor)
	, m_const_holder_destructor(const_holder_destructor)
	, m_operator_cache(0)
{
	assert(m_holder_alignment >= 1 && "internal error");

	lua_newtable(L);
	handle(L, -1).swap(m_table);
	lua_newtable(L);
	handle(L, -1).swap(m_default_table);
	lua_pop(L, 2);

	class_registry* r = class_registry::get_registry(L);
	assert((r->cpp_class() != LUA_NOREF) && "you must call luabind::open()");

	detail::getref(L, r->cpp_class());
	lua_setmetatable(L, -2);

	lua_pushvalue(L, -1); // duplicate our user data
	m_self_ref.set(L);

	m_instance_metatable = r->cpp_instance();
}

luabind::detail::class_rep::class_rep(lua_State* L, const char* name)
	: m_type(LUABIND_INVALID_TYPE_INFO)
	, m_holder_type(LUABIND_INVALID_TYPE_INFO)
	, m_const_holder_type(LUABIND_INVALID_TYPE_INFO)
	, m_extractor(0)
	, m_const_extractor(0)
	, m_const_converter(0)
	, m_construct_holder(0)
	, m_construct_const_holder(0)
	, m_default_construct_holder(0)
	, m_default_construct_const_holder(0)
	, m_adopt_fun(0)
	, m_holder_size(0)
	, m_holder_alignment(1)
	, m_name(name)
	, m_class_type(lua_class)
	, m_destructor(0)
	, m_const_holder_destructor(0)
	, m_operator_cache(0)
{
	lua_newtable(L);
	handle(L, -1).swap(m_table);
	lua_newtable(L);
	handle(L, -1).swap(m_default_table);
	lua_pop(L, 2);

	class_registry* r = class_registry::get_registry(L);
	assert((r->cpp_class() != LUA_NOREF) && "you must call luabind::open()");

	detail::getref(L, r->lua_class());
	lua_setmetatable(L, -2);
	lua_pushvalue(L, -1); // duplicate our user data
	m_self_ref.set(L);

	m_instance_metatable = r->lua_instance();
}

luabind::detail::class_rep::~class_rep()
{
}

// leaves object on lua stack
std::pair<void*,void*> 
luabind::detail::class_rep::allocate(lua_State* L) const
{
	const int overlap = sizeof(object_rep)&(m_holder_alignment-1);
	const int padding = overlap==0?0:m_holder_alignment-overlap;
	const int size = sizeof(object_rep) + padding + m_holder_size;

	char* mem = static_cast<char*>(lua_newuserdata(L, size));
	char* ptr = mem + sizeof(object_rep) + padding;

	return std::pair<void*,void*>(mem,ptr);
}

void luabind::detail::class_rep::adopt(bool const_obj, void* obj)
{
	if (m_adopt_fun == 0) return;

	if (m_extractor)
	{
		assert(m_const_extractor);
		if (const_obj)
			m_adopt_fun(const_cast<void*>(m_const_extractor(obj)));
		else
			m_adopt_fun(m_extractor(obj));
	}
	else
	{
		m_adopt_fun(obj);
	}
}

// lua stack: userdata, key
int luabind::detail::class_rep::gettable(lua_State* L)
{
	// if key is nil, return nil
	if (lua_isnil(L, 2))
	{
		lua_pushnil(L);
		return 1;
	}

	object_rep* obj = static_cast<object_rep*>(lua_touserdata(L, 1));

	// we have to ignore the first argument since this may point to
	// a method that is not present in this class (but in a subclass)
	const char* key = lua_tostring(L, 2);

#ifndef LUABIND_NO_ERROR_CHECKING

	if (std::strlen(key) != lua_strlen(L, 2))
	{
		{
			std::string msg("luabind does not support "
				"member names with extra nulls:\n");
			msg += std::string(lua_tostring(L, 2), lua_strlen(L, 2));
			lua_pushstring(L, msg.c_str());
		}
		lua_error(L);
	}

#endif

	// special case to see if this is a null-pointer
	if (key && !std::strcmp(key, "__ok"))
	{
		class_rep* crep = obj->crep();

		void* p = crep->extractor() ? crep->extractor()(obj->ptr())
			: obj->ptr();

		lua_pushboolean(L, p != 0);
		return 1;
	}

// First, look in the instance's table
	detail::lua_reference const& tbl = obj->get_lua_table();
	if (tbl.is_valid())
	{
		tbl.get(L);
		lua_pushvalue(L, 2);
		lua_gettable(L, -2);
		if (!lua_isnil(L, -1)) 
		{
			lua_remove(L, -2); // remove table
			return 1;
		}
		lua_pop(L, 2);
	}

// Then look in the class' table for this member
	obj->crep()->get_table(L);
	lua_pushvalue(L, 2);
	lua_gettable(L, -2);

	if (!lua_isnil(L, -1)) 
	{
		lua_remove(L, -2); // remove table
		return 1;
	}
	lua_pop(L, 2);

	std::map<const char*, callback, ltstr>::iterator j = m_getters.find(key);
	if (j != m_getters.end())
	{
		// the name is a data member
		return j->second.func(L, j->second.pointer_offset);
	}

	lua_pushnil(L);
	return 1;
}

// called from the metamethod for __newindex
// the object pointer is passed on the lua stack
// lua stack: userdata, key, value
bool luabind::detail::class_rep::settable(lua_State* L)
{
	// if the key is 'nil' fail
	if (lua_isnil(L, 2)) return false;

	// we have to ignore the first argument since this may point to
	// a method that is not present in this class (but in a subclass)

	const char* key = lua_tostring(L, 2);

	if (std::strlen(key) == lua_strlen(L, 2))
	{
		std::map<const char*, callback, ltstr>::iterator j = m_setters.find(key);
		if (j != m_setters.end())
		{
			// the name is a data member
#ifndef LUABIND_NO_ERROR_CHECKING
			if (j->second.match(L, 3) < 0)
			{
				std::string msg("the attribute '");
				msg += m_name;
				msg += ".";
				msg += key;
				msg += "' is of type: ";
				j->second.sig(L, msg);
				msg += "\nand does not match: (";
				msg += stack_content_by_name(L, 3);
				msg += ")";
				lua_pushstring(L, msg.c_str());
				return false;
			}
#endif
			j->second.func(L, j->second.pointer_offset);
			return true;
		}

		if (m_getters.find(key) != m_getters.end())
		{
			// this means that we have a getter but no
			// setter for an attribute. We will then fail
			// because that attribute is read-only
			std::string msg("the attribute '");
			msg += m_name;
			msg += ".";
			msg += key;
			msg += "' is read only";
			lua_pushstring(L, msg.c_str());
			return false;
		}
	}

	// set the attribute to the object's table
	object_rep* obj = static_cast<object_rep*>(lua_touserdata(L, 1));
	detail::lua_reference& tbl = obj->get_lua_table();
	if (!tbl.is_valid())
	{
		// this is the first time we are trying to add
		// a member to this instance, create the table.
		lua_newtable(L);
		lua_pushvalue(L, -1);
		tbl.set(L);
	}
	else
	{
		tbl.get(L);
	}
	lua_pushvalue(L, 2);
	lua_pushvalue(L, 3);
	lua_settable(L, 4);
	lua_pop(L, 3);
	return true;
}<commit_msg>Call "get" and "set" property functions.<commit_after>// Copyright (c) 2003 <NAME> and <NAME>

// 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.

#include <luabind/lua_include.hpp>

#include <luabind/detail/stack_utils.hpp>
#include <luabind/detail/conversion_storage.hpp>
#include <luabind/luabind.hpp>
#include <luabind/exception_handler.hpp>
#include <utility>

using namespace luabind::detail;

namespace luabind { namespace detail
{
	LUABIND_API int property_tag(lua_State* L)
	{
		lua_pushstring(L, "luabind: property_tag function can't be called");
		lua_error(L);
		return 0;
	}
}}

#ifndef LUABIND_NO_ERROR_CHECKING

	std::string luabind::detail::get_overload_signatures_candidates(
			lua_State* L
			, std::vector<const overload_rep_base*>::iterator start
			, std::vector<const overload_rep_base*>::iterator end
			, std::string name)
	{
		std::string s;
		for (; start != end; ++start)
		{
			s += name;
			(*start)->get_signature(L, s);
			s += "\n";
		}
		return s;
	}

#endif


luabind::detail::class_rep::class_rep(LUABIND_TYPE_INFO type
	, const char* name
	, lua_State* L
	,  void(*destructor)(void*)
	,  void(*const_holder_destructor)(void*)
	, 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(*construct_holder)(void*,void*)
	, void(*construct_const_holder)(void*,void*)
	, void(*default_construct_holder)(void*)
	, void(*default_construct_const_holder)(void*)
	, void(*adopt_fun)(void*)
	, int holder_size
	, int holder_alignment)

	: m_type(type)
	, m_holder_type(holder_type)
	, m_const_holder_type(const_holder_type)
	, m_extractor(extractor)
	, m_const_extractor(const_extractor)
	, m_const_converter(const_converter)
	, m_construct_holder(construct_holder)
	, m_construct_const_holder(construct_const_holder)
	, m_default_construct_holder(default_construct_holder)
	, m_default_construct_const_holder(default_construct_const_holder)
	, m_adopt_fun(adopt_fun)
	, m_holder_size(holder_size)
	, m_holder_alignment(holder_alignment)
	, m_name(name)
	, m_class_type(cpp_class)
	, m_destructor(destructor)
	, m_const_holder_destructor(const_holder_destructor)
	, m_operator_cache(0)
{
	assert(m_holder_alignment >= 1 && "internal error");

	lua_newtable(L);
	handle(L, -1).swap(m_table);
	lua_newtable(L);
	handle(L, -1).swap(m_default_table);
	lua_pop(L, 2);

	class_registry* r = class_registry::get_registry(L);
	assert((r->cpp_class() != LUA_NOREF) && "you must call luabind::open()");

	detail::getref(L, r->cpp_class());
	lua_setmetatable(L, -2);

	lua_pushvalue(L, -1); // duplicate our user data
	m_self_ref.set(L);

	m_instance_metatable = r->cpp_instance();
}

luabind::detail::class_rep::class_rep(lua_State* L, const char* name)
	: m_type(LUABIND_INVALID_TYPE_INFO)
	, m_holder_type(LUABIND_INVALID_TYPE_INFO)
	, m_const_holder_type(LUABIND_INVALID_TYPE_INFO)
	, m_extractor(0)
	, m_const_extractor(0)
	, m_const_converter(0)
	, m_construct_holder(0)
	, m_construct_const_holder(0)
	, m_default_construct_holder(0)
	, m_default_construct_const_holder(0)
	, m_adopt_fun(0)
	, m_holder_size(0)
	, m_holder_alignment(1)
	, m_name(name)
	, m_class_type(lua_class)
	, m_destructor(0)
	, m_const_holder_destructor(0)
	, m_operator_cache(0)
{
	lua_newtable(L);
	handle(L, -1).swap(m_table);
	lua_newtable(L);
	handle(L, -1).swap(m_default_table);
	lua_pop(L, 2);

	class_registry* r = class_registry::get_registry(L);
	assert((r->cpp_class() != LUA_NOREF) && "you must call luabind::open()");

	detail::getref(L, r->lua_class());
	lua_setmetatable(L, -2);
	lua_pushvalue(L, -1); // duplicate our user data
	m_self_ref.set(L);

	m_instance_metatable = r->lua_instance();
}

luabind::detail::class_rep::~class_rep()
{
}

// leaves object on lua stack
std::pair<void*,void*> 
luabind::detail::class_rep::allocate(lua_State* L) const
{
	const int overlap = sizeof(object_rep)&(m_holder_alignment-1);
	const int padding = overlap==0?0:m_holder_alignment-overlap;
	const int size = sizeof(object_rep) + padding + m_holder_size;

	char* mem = static_cast<char*>(lua_newuserdata(L, size));
	char* ptr = mem + sizeof(object_rep) + padding;

	return std::pair<void*,void*>(mem,ptr);
}

void luabind::detail::class_rep::adopt(bool const_obj, void* obj)
{
	if (m_adopt_fun == 0) return;

	if (m_extractor)
	{
		assert(m_const_extractor);
		if (const_obj)
			m_adopt_fun(const_cast<void*>(m_const_extractor(obj)));
		else
			m_adopt_fun(m_extractor(obj));
	}
	else
	{
		m_adopt_fun(obj);
	}
}

// lua stack: userdata, key
int luabind::detail::class_rep::gettable(lua_State* L)
{
	// if key is nil, return nil
	if (lua_isnil(L, 2))
	{
		lua_pushnil(L);
		return 1;
	}

	object_rep* obj = static_cast<object_rep*>(lua_touserdata(L, 1));

	// we have to ignore the first argument since this may point to
	// a method that is not present in this class (but in a subclass)
	const char* key = lua_tostring(L, 2);

#ifndef LUABIND_NO_ERROR_CHECKING

	if (std::strlen(key) != lua_strlen(L, 2))
	{
		{
			std::string msg("luabind does not support "
				"member names with extra nulls:\n");
			msg += std::string(lua_tostring(L, 2), lua_strlen(L, 2));
			lua_pushstring(L, msg.c_str());
		}
		lua_error(L);
	}

#endif

	// special case to see if this is a null-pointer
	if (key && !std::strcmp(key, "__ok"))
	{
		class_rep* crep = obj->crep();

		void* p = crep->extractor() ? crep->extractor()(obj->ptr())
			: obj->ptr();

		lua_pushboolean(L, p != 0);
		return 1;
	}

	// first, look in the instance's table..
	detail::lua_reference const& tbl = obj->get_lua_table();
	if (tbl.is_valid())
	{
		tbl.get(L);
		lua_pushvalue(L, 2);
		lua_gettable(L, -2);
		lua_remove(L, -2);
	}
	else
	{
		lua_pushnil(L);
	}

	// .. if it's not found in the instance, look in the class table.
	if (lua_isnil(L, -1))
	{
		lua_pop(L, 1);
		obj->crep()->get_table(L);
		lua_pushvalue(L, 2);
		lua_gettable(L, -2);
		lua_remove(L, -2);
	}

	if (lua_tocfunction(L, -1) == &property_tag)
	{
		// this member is a property, extract the "get" function and call it.
		lua_getupvalue(L, -1, 1);
		lua_pushvalue(L, 1);
		lua_call(L, 1, 1);
	}

	return 1;
}

// called from the metamethod for __newindex
// the object pointer is passed on the lua stack
// lua stack: userdata, key, value
bool luabind::detail::class_rep::settable(lua_State* L)
{
	// if the key is 'nil' fail
	if (lua_isnil(L, 2)) return false;

	// we have to ignore the first argument since this may point to
	// a method that is not present in this class (but in a subclass)

	const char* key = lua_tostring(L, 2);

#ifndef LUABIND_NO_ERROR_CHECKING
	if (std::strlen(key) != lua_strlen(L, 2))
	{
		{
			std::string msg("luabind does not support "
				"member names with extra nulls:\n");
			msg += std::string(lua_tostring(L, 2), lua_strlen(L, 2));
			lua_pushstring(L, msg.c_str());
		}
		lua_error(L);
	}
#endif

	// set the attribute to the object's table
	object_rep* obj = static_cast<object_rep*>(lua_touserdata(L, 1));
	detail::lua_reference& tbl = obj->get_lua_table();
	if (!tbl.is_valid())
	{
		// this is the first time we are trying to add
		// a member to this instance, create the table.
		lua_newtable(L);
		lua_pushvalue(L, -1);
		tbl.set(L);
		lua_pushnil(L);
	}
	else
	{
		tbl.get(L);
		lua_pushvalue(L, 2);
		lua_gettable(L, -2);
	}

	if (lua_isnil(L, -1))
	{
		lua_pop(L, 1);
		obj->crep()->get_table(L);
		lua_pushvalue(L, 2);
		lua_gettable(L, -2);
		lua_remove(L, -2);
	}

	if (lua_tocfunction(L, -1) == &property_tag)
	{
		// this member is a property, extract the "set" function and call it.
		lua_getupvalue(L, -1, 2);

		if (lua_isnil(L, -1))
		{
			lua_pushstringf(L, "property '%s' is read only", lua_tostring(L, 2));
			lua_error(L);
		}

		lua_pushvalue(L, 1);
		lua_pushvalue(L, 3);
		lua_call(L, 2, 0);
		return true;
	}

	lua_pushvalue(L, 2);
	lua_pushvalue(L, 3);
	lua_settable(L, 4);
	lua_pop(L, 3);

	return true;
}
{'fraction_non_alphanumeric': 0.14244636142446362, 'fraction_numerical': 0.008460517584605176, 'mean_word_length': 4.687106918238993, 'pattern_counts': {'":': 0, '<': 38, '<?xml version=': 0, '>': 79, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4693839', 'n_tokens_mistral': 7321, 'n_tokens_neox': 6809, 'n_words': 1598}