From 3a904d9f74171ce632347c370e4327b4855945ae Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sat, 7 Aug 2010 19:27:15 +0000 Subject: [PATCH] Drastically reduce the number of exceptions thrown at runtime (cannot completely eliminate them all, it's the nature of doing what we are doing with making a runtime interface to a compiled system like we are). profile.chai should see something like a reduction from 35,000 exceptions to about 100. --- .../chaiscript/dispatchkit/dynamic_object.hpp | 59 +++++++++++------ .../dispatchkit/proxy_functions.hpp | 65 ++++++++++--------- 2 files changed, 73 insertions(+), 51 deletions(-) diff --git a/include/chaiscript/dispatchkit/dynamic_object.hpp b/include/chaiscript/dispatchkit/dynamic_object.hpp index c617113..c25a945 100644 --- a/include/chaiscript/dispatchkit/dynamic_object.hpp +++ b/include/chaiscript/dispatchkit/dynamic_object.hpp @@ -71,11 +71,11 @@ namespace chaiscript virtual bool operator==(const Proxy_Function_Base &f) const { - try + const Dynamic_Object_Function *df = dynamic_cast(&f); + if (df) { - const Dynamic_Object_Function &df = dynamic_cast(f); - return df.m_type_name == m_type_name && (*df.m_func) == (*m_func); - } catch (const std::bad_cast &) { + return df->m_type_name == m_type_name && (*df->m_func) == (*m_func); + } else { return false; } } @@ -102,7 +102,7 @@ namespace chaiscript virtual int get_arity() const { - return m_func->get_arity(); + return m_func->get_arity(); } virtual std::string annotation() const @@ -110,23 +110,42 @@ namespace chaiscript return m_func->annotation(); } + protected: + virtual bool compare_first_type(const Boxed_Value &bv) const + { + return dynamic_object_typename_match(bv, m_type_name, m_ti); + } + private: + static bool dynamic_object_typename_match(const Boxed_Value &bv, const std::string &name, + const boost::optional &ti) + { + static Type_Info doti = user_type(); + if (bv.get_type_info().bare_equal(doti)) + { + try { + const Dynamic_Object &d = boxed_cast(bv); + return name == "Dynamic_Object" || d.get_type_name() == name; + } catch (const std::bad_cast &) { + return false; + } + } else { + if (ti) + { + return bv.get_type_info().bare_equal(*ti); + } else { + return false; + } + } + + } + static bool dynamic_object_typename_match(const std::vector &bvs, const std::string &name, const boost::optional &ti) { if (bvs.size() > 0) { - try { - const Dynamic_Object &d = boxed_cast(bvs[0]); - return name == "Dynamic_Object" || d.get_type_name() == name; - } catch (const std::bad_cast &) { - if (ti) - { - return bvs[0].get_type_info().bare_equal(*ti); - } else { - return false; - } - } + return dynamic_object_typename_match(bvs[0], name, ti); } else { return false; } @@ -175,11 +194,11 @@ namespace chaiscript virtual bool operator==(const Proxy_Function_Base &f) const { - try + const Dynamic_Object_Constructor *dc = dynamic_cast(&f); + if (dc) { - const Dynamic_Object_Constructor &dc = dynamic_cast(f); - return dc.m_type_name == m_type_name && (*dc.m_func) == (*m_func); - } catch (const std::bad_cast &) { + return dc->m_type_name == m_type_name && (*dc->m_func) == (*m_func); + } else { return false; } } diff --git a/include/chaiscript/dispatchkit/proxy_functions.hpp b/include/chaiscript/dispatchkit/proxy_functions.hpp index bea6c67..6151a25 100644 --- a/include/chaiscript/dispatchkit/proxy_functions.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions.hpp @@ -72,6 +72,7 @@ namespace chaiscript virtual bool operator==(const Proxy_Function_Base &) const = 0; virtual bool call_match(const std::vector &vals) const = 0; + //! Return true if the function is a possible match //! to the passed in values bool filter(const std::vector &vals) const @@ -86,26 +87,7 @@ namespace chaiscript { return true; } else { - const std::vector &types = get_param_types(); - - if (types.size() < 2) - { - return true; - } - - const Type_Info &ti = types[1]; - - - if (ti.is_undef() || vals[0].get_type_info().is_undef() - || ti.bare_equal(user_type()) - || ti.bare_equal(user_type()) - || ti.bare_equal(vals[0].get_type_info()) - || dynamic_cast_converts(ti, vals[0].get_type_info()) ) - { - return true; - } else { - return false; - } + return compare_first_type(vals[0]); } } else { return false; @@ -122,6 +104,31 @@ namespace chaiscript { } + virtual bool compare_first_type(const Boxed_Value &bv) const + { + const std::vector &types = get_param_types(); + + if (types.size() < 2) + { + return true; + } + const Type_Info &ti = types[1]; + if (ti.is_undef() + || ti.bare_equal(user_type()) + || (!bv.get_type_info().is_undef() + && (ti.bare_equal(user_type()) + || ti.bare_equal(bv.get_type_info()) + || dynamic_cast_converts(ti, bv.get_type_info()) + ) + ) + ) + { + return true; + } else { + return false; + } + } + bool compare_types(const std::vector &tis, const std::vector &bvs) const { if (tis.size() - 1 != bvs.size()) @@ -368,12 +375,8 @@ namespace chaiscript virtual bool operator==(const Proxy_Function_Base &t_func) const { - try { - dynamic_cast &>(t_func); - return true; - } catch (const std::bad_cast &) { - return false; - } + const Proxy_Function_Impl *pimpl = dynamic_cast *>(&t_func); + return pimpl != 0; } virtual Boxed_Value operator()(const std::vector ¶ms) const @@ -424,11 +427,11 @@ namespace chaiscript virtual bool operator==(const Proxy_Function_Base &t_func) const { - try { - const Attribute_Access &aa - = dynamic_cast &>(t_func); - return m_attr == aa.m_attr; - } catch (const std::bad_cast &) { + const Attribute_Access * aa + = dynamic_cast *>(&t_func); + if (aa) { + return m_attr == aa->m_attr; + } else { return false; } }