From 50a2773081131cbb15e8d43e2b5aebdf18975fbf Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Tue, 21 Nov 2017 09:01:17 -0700 Subject: [PATCH] Reduce cost of cloning common built in types Re: #356 --- .../chaiscript/dispatchkit/boxed_number.hpp | 4 ++ .../chaiscript/language/chaiscript_eval.hpp | 39 ++++++++++--------- 2 files changed, 25 insertions(+), 18 deletions(-) diff --git a/include/chaiscript/dispatchkit/boxed_number.hpp b/include/chaiscript/dispatchkit/boxed_number.hpp index 8f1e871f..dafc1234 100644 --- a/include/chaiscript/dispatchkit/boxed_number.hpp +++ b/include/chaiscript/dispatchkit/boxed_number.hpp @@ -521,6 +521,10 @@ namespace chaiscript validate_boxed_number(bv); } + static Boxed_Value clone(const Boxed_Value &t_bv) { + return Boxed_Number(t_bv).get_as(t_bv.get_type_info()).bv; + } + static bool is_floating_point(const Boxed_Value &t_bv) { const Type_Info &inp_ = t_bv.get_type_info(); diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index a9819440..508f4d3a 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -88,6 +88,23 @@ namespace chaiscript return std::move(rv.retval); } } + + inline Boxed_Value clone_if_necessary(Boxed_Value incoming, std::atomic_uint_fast32_t &t_loc, const chaiscript::detail::Dispatch_State &t_ss) + { + if (!incoming.is_return_value()) + { + if (incoming.get_type_info().is_arithmetic()) { + return Boxed_Number::clone(incoming); + } else if (incoming.get_type_info().bare_equal_type_info(typeid(bool))) { + return Boxed_Value(*static_cast(incoming.get_const_ptr())); + } else { + return t_ss->call_function("clone", t_loc, {incoming}, t_ss.conversions()); + } + } else { + incoming.reset_return_value(); + return incoming; + } + } } template @@ -459,11 +476,7 @@ namespace chaiscript lhs.reset_return_value(); return rhs; } else { - if (!rhs.is_return_value()) - { - rhs = t_ss->call_function("clone", m_clone_loc, {rhs}, t_ss.conversions()); - } - rhs.reset_return_value(); + rhs = detail::clone_if_necessary(std::move(rhs), m_clone_loc, t_ss); } } @@ -1056,12 +1069,7 @@ namespace chaiscript if (!this->children.empty()) { vec.reserve(this->children[0]->children.size()); for (const auto &child : this->children[0]->children) { - auto obj = child->eval(t_ss); - if (!obj.is_return_value()) { - vec.push_back(t_ss->call_function("clone", m_loc, {obj}, t_ss.conversions())); - } else { - vec.push_back(std::move(obj)); - } + vec.push_back(detail::clone_if_necessary(child->eval(t_ss), m_loc, t_ss)); } } return const_var(std::move(vec)); @@ -1086,12 +1094,8 @@ namespace chaiscript std::map retval; for (const auto &child : this->children[0]->children) { - auto obj = child->children[1]->eval(t_ss); - if (!obj.is_return_value()) { - obj = t_ss->call_function("clone", m_loc, {obj}, t_ss.conversions()); - } - - retval[t_ss->boxed_cast(child->children[0]->eval(t_ss))] = std::move(obj); + retval.insert(std::make_pair(t_ss->boxed_cast(child->children[0]->eval(t_ss)), + detail::clone_if_necessary(child->children[1]->eval(t_ss), m_loc, t_ss))); } return const_var(std::move(retval)); @@ -1450,7 +1454,6 @@ namespace chaiscript function_name); } } catch (const exception::name_conflict_error &e) { - std::cout << "Method!!" << std::endl; throw exception::eval_error("Method redefined '" + e.name() + "'"); } return void_var();