Favor filtering of functions during dispatch over exceptions to determine appropriate function to call. Results in approximately 50% reduction in runtime for long running scripts
This commit is contained in:
parent
0ff107a818
commit
a3d4b6698a
@ -97,11 +97,6 @@ namespace chaiscript
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool get_false()
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Type_Info m_type_info;
|
Type_Info m_type_info;
|
||||||
boost::any m_obj;
|
boost::any m_obj;
|
||||||
bool m_is_ref;
|
bool m_is_ref;
|
||||||
|
@ -94,6 +94,11 @@ namespace chaiscript
|
|||||||
return std::vector<Type_Info>();
|
return std::vector<Type_Info>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual int get_arity() const
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
virtual bool call_match(const std::vector<Boxed_Value> &vals) const
|
virtual bool call_match(const std::vector<Boxed_Value> &vals) const
|
||||||
{
|
{
|
||||||
typedef std::vector<std::pair<std::string, Proxy_Function > > function_vec;
|
typedef std::vector<std::pair<std::string, Proxy_Function > > function_vec;
|
||||||
|
@ -178,6 +178,47 @@ namespace chaiscript
|
|||||||
virtual std::vector<Type_Info> get_param_types() const = 0;
|
virtual std::vector<Type_Info> get_param_types() const = 0;
|
||||||
virtual bool operator==(const Proxy_Function_Base &) const = 0;
|
virtual bool operator==(const Proxy_Function_Base &) const = 0;
|
||||||
virtual bool call_match(const std::vector<Boxed_Value> &vals) const = 0;
|
virtual bool call_match(const std::vector<Boxed_Value> &vals) const = 0;
|
||||||
|
|
||||||
|
//! Return true if the function is a possible match
|
||||||
|
//! to the passed in values
|
||||||
|
bool filter(const std::vector<Boxed_Value> &vals) const
|
||||||
|
{
|
||||||
|
int arity = get_arity();
|
||||||
|
|
||||||
|
if (arity < 0)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
} else if (size_t(arity) == vals.size()) {
|
||||||
|
if (arity == 0)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
const std::vector<Type_Info> &types = get_param_types();
|
||||||
|
|
||||||
|
if (types.size() < 2)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Type_Info &ti = types[1];
|
||||||
|
|
||||||
|
if (!ti.m_bare_type_info || !(vals[0].get_type_info().m_bare_type_info)
|
||||||
|
|| (*ti.m_bare_type_info) == (*user_type<Boxed_Value>().m_bare_type_info)
|
||||||
|
|| (*ti.m_bare_type_info) == (*user_type<Boxed_POD_Value>().m_bare_type_info)
|
||||||
|
|| (*vals[0].get_type_info().m_bare_type_info) == (*ti.m_bare_type_info))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual int get_arity() const = 0;
|
||||||
|
|
||||||
virtual std::string annotation() const = 0;
|
virtual std::string annotation() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -209,7 +250,8 @@ namespace chaiscript
|
|||||||
int t_arity=-1,
|
int t_arity=-1,
|
||||||
const std::string &t_description = "",
|
const std::string &t_description = "",
|
||||||
const Proxy_Function &t_guard = Proxy_Function())
|
const Proxy_Function &t_guard = Proxy_Function())
|
||||||
: m_f(t_f), m_arity(t_arity), m_description(t_description), m_guard(t_guard)
|
: m_f(t_f), m_arity(t_arity), m_description(t_description), m_guard(t_guard),
|
||||||
|
m_types(build_param_type_list(t_arity))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -243,23 +285,14 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual int get_arity() const
|
||||||
|
{
|
||||||
|
return m_arity;
|
||||||
|
}
|
||||||
|
|
||||||
virtual std::vector<Type_Info> get_param_types() const
|
virtual std::vector<Type_Info> get_param_types() const
|
||||||
{
|
{
|
||||||
std::vector<Type_Info> types;
|
return m_types;
|
||||||
|
|
||||||
types.push_back(Get_Type_Info<Boxed_Value>::get());
|
|
||||||
|
|
||||||
if (m_arity >= 0)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < m_arity; ++i)
|
|
||||||
{
|
|
||||||
types.push_back(Get_Type_Info<Boxed_Value>::get());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
types.push_back(Get_Type_Info<std::vector<Boxed_Value> >::get());
|
|
||||||
}
|
|
||||||
|
|
||||||
return types;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual std::string annotation() const
|
virtual std::string annotation() const
|
||||||
@ -284,10 +317,30 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::vector<Type_Info> build_param_type_list(int arity)
|
||||||
|
{
|
||||||
|
std::vector<Type_Info> types;
|
||||||
|
|
||||||
|
types.push_back(Get_Type_Info<Boxed_Value>::get());
|
||||||
|
|
||||||
|
if (arity >= 0)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < arity; ++i)
|
||||||
|
{
|
||||||
|
types.push_back(Get_Type_Info<Boxed_Value>::get());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
types.push_back(Get_Type_Info<std::vector<Boxed_Value> >::get());
|
||||||
|
}
|
||||||
|
|
||||||
|
return types;
|
||||||
|
}
|
||||||
|
|
||||||
boost::function<Boxed_Value (const std::vector<Boxed_Value> &)> m_f;
|
boost::function<Boxed_Value (const std::vector<Boxed_Value> &)> m_f;
|
||||||
int m_arity;
|
int m_arity;
|
||||||
std::string m_description;
|
std::string m_description;
|
||||||
Proxy_Function m_guard;
|
Proxy_Function m_guard;
|
||||||
|
std::vector<Type_Info> m_types;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -309,7 +362,7 @@ namespace chaiscript
|
|||||||
public:
|
public:
|
||||||
Bound_Function(const Proxy_Function &t_f,
|
Bound_Function(const Proxy_Function &t_f,
|
||||||
const std::vector<Boxed_Value> &t_args)
|
const std::vector<Boxed_Value> &t_args)
|
||||||
: m_f(t_f), m_args(t_args)
|
: m_f(t_f), m_args(t_args), m_arity(m_f->get_arity()<0?-1:(m_f->get_arity() - m_args.size()))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -373,6 +426,11 @@ namespace chaiscript
|
|||||||
return std::vector<Type_Info>();
|
return std::vector<Type_Info>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual int get_arity() const
|
||||||
|
{
|
||||||
|
return m_arity;
|
||||||
|
}
|
||||||
|
|
||||||
virtual std::string annotation() const
|
virtual std::string annotation() const
|
||||||
{
|
{
|
||||||
return "";
|
return "";
|
||||||
@ -381,6 +439,7 @@ namespace chaiscript
|
|||||||
private:
|
private:
|
||||||
Proxy_Function m_f;
|
Proxy_Function m_f;
|
||||||
std::vector<Boxed_Value> m_args;
|
std::vector<Boxed_Value> m_args;
|
||||||
|
int m_arity;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -393,7 +452,7 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Proxy_Function_Impl(const boost::function<Func> &f)
|
Proxy_Function_Impl(const boost::function<Func> &f)
|
||||||
: m_f(f)
|
: m_f(f), m_dummy_func(0), m_types(build_param_type_list(m_dummy_func))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -416,14 +475,18 @@ namespace chaiscript
|
|||||||
|
|
||||||
virtual std::vector<Type_Info> get_param_types() const
|
virtual std::vector<Type_Info> get_param_types() const
|
||||||
{
|
{
|
||||||
Func *f = 0;
|
return m_types;
|
||||||
return build_param_type_list(f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual int get_arity() const
|
||||||
|
{
|
||||||
|
return m_types.size() - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
virtual bool call_match(const std::vector<Boxed_Value> &vals) const
|
virtual bool call_match(const std::vector<Boxed_Value> &vals) const
|
||||||
{
|
{
|
||||||
Func *f = 0;
|
return compare_types(m_dummy_func, vals);
|
||||||
return compare_types(f, vals);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual std::string annotation() const
|
virtual std::string annotation() const
|
||||||
@ -433,6 +496,8 @@ namespace chaiscript
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
boost::function<Func> m_f;
|
boost::function<Func> m_f;
|
||||||
|
Func *m_dummy_func;
|
||||||
|
std::vector<Type_Info> m_types;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -464,7 +529,10 @@ namespace chaiscript
|
|||||||
++itr)
|
++itr)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
return (*itr->second)(plist);
|
if (itr->second->filter(plist))
|
||||||
|
{
|
||||||
|
return (*itr->second)(plist);
|
||||||
|
}
|
||||||
} catch (const bad_boxed_cast &) {
|
} catch (const bad_boxed_cast &) {
|
||||||
//parameter failed to cast, try again
|
//parameter failed to cast, try again
|
||||||
} catch (const arity_error &) {
|
} catch (const arity_error &) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user