Reduce virtual calls for get_arity

Saves compiled code size and some minor runtime differences
This commit is contained in:
Jason Turner 2014-11-01 18:40:42 -06:00
parent 87cee688a8
commit dd12785b72
3 changed files with 24 additions and 56 deletions

View File

@ -257,7 +257,7 @@ namespace chaiscript
{ {
public: public:
Dispatch_Function(std::vector<Proxy_Function> t_funcs) Dispatch_Function(std::vector<Proxy_Function> t_funcs)
: Proxy_Function_Base(build_type_infos(t_funcs)), : Proxy_Function_Base(build_type_infos(t_funcs), calculate_arity(t_funcs)),
m_funcs(std::move(t_funcs)) m_funcs(std::move(t_funcs))
{ {
} }
@ -280,15 +280,15 @@ namespace chaiscript
} }
virtual int get_arity() const CHAISCRIPT_OVERRIDE static int calculate_arity(const std::vector<Proxy_Function> &t_funcs)
{ {
if (m_funcs.empty()) { if (t_funcs.empty()) {
return -1; return -1;
} }
const auto arity = m_funcs.front()->get_arity(); const auto arity = t_funcs.front()->get_arity();
for (const auto &func : m_funcs) for (const auto &func : t_funcs)
{ {
if (arity != func->get_arity()) if (arity != func->get_arity())
{ {

View File

@ -73,7 +73,7 @@ namespace chaiscript
Dynamic_Object_Function( Dynamic_Object_Function(
std::string t_type_name, std::string t_type_name,
const Proxy_Function &t_func) const Proxy_Function &t_func)
: Proxy_Function_Base(t_func->get_param_types()), : Proxy_Function_Base(t_func->get_param_types(), t_func->get_arity()),
m_type_name(std::move(t_type_name)), m_func(t_func), m_doti(user_type<Dynamic_Object>()) m_type_name(std::move(t_type_name)), m_func(t_func), m_doti(user_type<Dynamic_Object>())
{ {
assert( (t_func->get_arity() > 0 || t_func->get_arity() < 0) assert( (t_func->get_arity() > 0 || t_func->get_arity() < 0)
@ -84,7 +84,7 @@ namespace chaiscript
std::string t_type_name, std::string t_type_name,
const Proxy_Function &t_func, const Proxy_Function &t_func,
const Type_Info &t_ti) const Type_Info &t_ti)
: Proxy_Function_Base(build_param_types(t_func->get_param_types(), t_ti)), : Proxy_Function_Base(build_param_types(t_func->get_param_types(), t_ti), t_func->get_arity()),
m_type_name(std::move(t_type_name)), m_func(t_func), m_ti(new Type_Info(t_ti)), m_doti(user_type<Dynamic_Object>()) m_type_name(std::move(t_type_name)), m_func(t_func), m_ti(new Type_Info(t_ti)), m_doti(user_type<Dynamic_Object>())
{ {
assert( (t_func->get_arity() > 0 || t_func->get_arity() < 0) assert( (t_func->get_arity() > 0 || t_func->get_arity() < 0)
@ -121,12 +121,6 @@ namespace chaiscript
return {m_func}; return {m_func};
} }
virtual int get_arity() const CHAISCRIPT_OVERRIDE
{
return m_func->get_arity();
}
virtual std::string annotation() const CHAISCRIPT_OVERRIDE virtual std::string annotation() const CHAISCRIPT_OVERRIDE
{ {
return m_func->annotation(); return m_func->annotation();
@ -215,7 +209,7 @@ namespace chaiscript
Dynamic_Object_Constructor( Dynamic_Object_Constructor(
std::string t_type_name, std::string t_type_name,
const Proxy_Function &t_func) const Proxy_Function &t_func)
: Proxy_Function_Base(build_type_list(t_func->get_param_types())), : Proxy_Function_Base(build_type_list(t_func->get_param_types()), t_func->get_arity() - 1),
m_type_name(std::move(t_type_name)), m_func(t_func) m_type_name(std::move(t_type_name)), m_func(t_func)
{ {
assert( (t_func->get_arity() > 0 || t_func->get_arity() < 0) assert( (t_func->get_arity() > 0 || t_func->get_arity() < 0)
@ -256,13 +250,6 @@ namespace chaiscript
return m_func->call_match(new_vals, t_conversions); return m_func->call_match(new_vals, t_conversions);
} }
virtual int get_arity() const CHAISCRIPT_OVERRIDE
{
// "this" is not considered part of the arity
return m_func->get_arity() - 1;
}
virtual std::string annotation() const CHAISCRIPT_OVERRIDE virtual std::string annotation() const CHAISCRIPT_OVERRIDE
{ {
return m_func->annotation(); return m_func->annotation();

View File

@ -84,13 +84,11 @@ namespace chaiscript
//! to the passed in values //! to the passed in values
bool filter(const std::vector<Boxed_Value> &vals, const Type_Conversions &t_conversions) const bool filter(const std::vector<Boxed_Value> &vals, const Type_Conversions &t_conversions) const
{ {
int arity = get_arity(); if (m_arity < 0)
if (arity < 0)
{ {
return true; return true;
} else if (size_t(arity) == vals.size()) { } else if (size_t(m_arity) == vals.size()) {
if (arity == 0) if (m_arity == 0)
{ {
return true; return true;
} else { } else {
@ -102,7 +100,10 @@ namespace chaiscript
} }
/// \returns the number of arguments the function takes or -1 if it is variadic /// \returns the number of arguments the function takes or -1 if it is variadic
virtual int get_arity() const = 0; int get_arity() const
{
return m_arity;
}
virtual std::string annotation() const = 0; virtual std::string annotation() const = 0;
@ -127,8 +128,8 @@ namespace chaiscript
protected: protected:
virtual Boxed_Value do_call(const std::vector<Boxed_Value> &params, const Type_Conversions &t_conversions) const = 0; virtual Boxed_Value do_call(const std::vector<Boxed_Value> &params, const Type_Conversions &t_conversions) const = 0;
Proxy_Function_Base(std::vector<Type_Info> t_types) Proxy_Function_Base(std::vector<Type_Info> t_types, int t_arity)
: m_types(std::move(t_types)), m_has_arithmetic_param(false) : m_types(std::move(t_types)), m_has_arithmetic_param(false), m_arity(t_arity)
{ {
for (size_t i = 1; i < m_types.size(); ++i) for (size_t i = 1; i < m_types.size(); ++i)
{ {
@ -175,7 +176,7 @@ namespace chaiscript
std::vector<Type_Info> m_types; std::vector<Type_Info> m_types;
bool m_has_arithmetic_param; bool m_has_arithmetic_param;
int m_arity;
}; };
} }
@ -216,7 +217,7 @@ namespace chaiscript
AST_NodePtr t_parsenode = AST_NodePtr(), AST_NodePtr t_parsenode = AST_NodePtr(),
std::string t_description = "", std::string t_description = "",
Proxy_Function t_guard = Proxy_Function()) Proxy_Function t_guard = Proxy_Function())
: Proxy_Function_Base(build_param_type_list(t_arity)), : Proxy_Function_Base(build_param_type_list(t_arity), t_arity),
m_f(std::move(t_f)), m_arity(t_arity), m_description(std::move(t_description)), m_guard(std::move(t_guard)), m_parsenode(std::move(t_parsenode)) m_f(std::move(t_f)), m_arity(t_arity), m_description(std::move(t_description)), m_guard(std::move(t_guard)), m_parsenode(std::move(t_parsenode))
{ {
} }
@ -239,10 +240,6 @@ namespace chaiscript
&& test_guard(vals, t_conversions); && test_guard(vals, t_conversions);
} }
virtual int get_arity() const CHAISCRIPT_OVERRIDE
{
return m_arity;
}
Proxy_Function get_guard() const Proxy_Function get_guard() const
{ {
@ -338,8 +335,8 @@ namespace chaiscript
public: public:
Bound_Function(const Const_Proxy_Function &t_f, Bound_Function(const Const_Proxy_Function &t_f,
const std::vector<Boxed_Value> &t_args) const std::vector<Boxed_Value> &t_args)
: Proxy_Function_Base(build_param_type_info(t_f, t_args)), : Proxy_Function_Base(build_param_type_info(t_f, t_args), (t_f->get_arity()<0?-1:static_cast<int>(build_param_type_info(t_f, t_args).size())-1)),
m_f(t_f), m_args(t_args), m_arity(t_f->get_arity()<0?-1:static_cast<int>(get_param_types().size())-1) m_f(t_f), m_args(t_args)
{ {
assert(m_f->get_arity() < 0 || m_f->get_arity() == static_cast<int>(m_args.size())); assert(m_f->get_arity() < 0 || m_f->get_arity() == static_cast<int>(m_args.size()));
} }
@ -395,11 +392,6 @@ namespace chaiscript
return args; return args;
} }
virtual int get_arity() const CHAISCRIPT_OVERRIDE
{
return m_arity;
}
virtual std::string annotation() const CHAISCRIPT_OVERRIDE virtual std::string annotation() const CHAISCRIPT_OVERRIDE
{ {
return "Bound: " + m_f->annotation(); return "Bound: " + m_f->annotation();
@ -444,17 +436,12 @@ namespace chaiscript
{ {
public: public:
Proxy_Function_Impl_Base(std::vector<Type_Info> t_types) Proxy_Function_Impl_Base(std::vector<Type_Info> t_types)
: Proxy_Function_Base(std::move(t_types)) : Proxy_Function_Base(std::move(t_types), t_types.size() - 1)
{ {
} }
virtual ~Proxy_Function_Impl_Base() {} virtual ~Proxy_Function_Impl_Base() {}
virtual int get_arity() const CHAISCRIPT_OVERRIDE
{
return static_cast<int>(m_types.size()) - 1;
}
virtual std::string annotation() const CHAISCRIPT_OVERRIDE virtual std::string annotation() const CHAISCRIPT_OVERRIDE
{ {
return ""; return "";
@ -524,7 +511,7 @@ namespace chaiscript
{ {
public: public:
Attribute_Access(T Class::* t_attr) Attribute_Access(T Class::* t_attr)
: Proxy_Function_Base(param_types()), : Proxy_Function_Base(param_types(), 1),
m_attr(t_attr) m_attr(t_attr)
{ {
} }
@ -543,12 +530,6 @@ namespace chaiscript
} }
} }
virtual int get_arity() const CHAISCRIPT_OVERRIDE
{
return 1;
}
virtual bool call_match(const std::vector<Boxed_Value> &vals, const Type_Conversions &) const CHAISCRIPT_OVERRIDE virtual bool call_match(const std::vector<Boxed_Value> &vals, const Type_Conversions &) const CHAISCRIPT_OVERRIDE
{ {
if (vals.size() != 1) if (vals.size() != 1)