Don't constantly re-create the function objects

This commit is contained in:
Jason Turner 2015-06-19 20:31:39 -06:00
parent 646563eb3f
commit a2577b983c

View File

@ -397,6 +397,7 @@ namespace chaiscript
{ {
std::map<std::string, std::vector<Proxy_Function> > m_functions; std::map<std::string, std::vector<Proxy_Function> > m_functions;
std::map<std::string, Proxy_Function> m_function_objects; std::map<std::string, Proxy_Function> m_function_objects;
std::map<std::string, Boxed_Value> m_boxed_functions;
std::map<std::string, Boxed_Value> m_global_objects; std::map<std::string, Boxed_Value> m_global_objects;
Type_Name_Map m_types; Type_Name_Map m_types;
std::set<std::string> m_reserved_words; std::set<std::string> m_reserved_words;
@ -684,13 +685,13 @@ namespace chaiscript
// std::cout << "Getting function object: " << t_name << '\n'; // std::cout << "Getting function object: " << t_name << '\n';
chaiscript::detail::threading::shared_lock<chaiscript::detail::threading::shared_mutex> l(m_mutex); chaiscript::detail::threading::shared_lock<chaiscript::detail::threading::shared_mutex> l(m_mutex);
const auto &funs = get_function_objects_int(); const auto &funs = get_boxed_functions_int();
auto itr = funs.find(t_name); auto itr = funs.find(t_name);
if (itr != funs.end()) if (itr != funs.end())
{ {
return const_var(itr->second); return itr->second;
} else { } else {
throw std::range_error("Object not found: " + t_name); throw std::range_error("Object not found: " + t_name);
} }
@ -1136,6 +1137,16 @@ namespace chaiscript
return m_stack_holder->stacks.back(); return m_stack_holder->stacks.back();
} }
const std::map<std::string, Boxed_Value> &get_boxed_functions_int() const
{
return m_state.m_boxed_functions;
}
std::map<std::string, Boxed_Value> &get_boxed_functions_int()
{
return m_state.m_boxed_functions;
}
const std::map<std::string, Proxy_Function> &get_function_objects_int() const const std::map<std::string, Proxy_Function> &get_function_objects_int() const
{ {
return m_state.m_function_objects; return m_state.m_function_objects;
@ -1276,7 +1287,10 @@ namespace chaiscript
auto itr = funcs.find(t_name); auto itr = funcs.find(t_name);
auto &func_objs = get_function_objects_int(); auto &func_objs = get_function_objects_int();
auto &boxed_funcs = get_boxed_functions_int();
Proxy_Function new_func =
[&]() -> Proxy_Function {
if (itr != funcs.end()) if (itr != funcs.end())
{ {
auto &vec = itr->second; auto &vec = itr->second;
@ -1290,20 +1304,22 @@ namespace chaiscript
vec.push_back(t_f); vec.push_back(t_f);
std::stable_sort(vec.begin(), vec.end(), &function_less_than); std::stable_sort(vec.begin(), vec.end(), &function_less_than);
func_objs[t_name] = std::make_shared<Dispatch_Function>(vec); return std::make_shared<Dispatch_Function>(vec);
} else if (t_f->has_arithmetic_param()) { } else if (t_f->has_arithmetic_param()) {
// if the function is the only function but it also contains // if the function is the only function but it also contains
// arithmetic operators, we must wrap it in a dispatch function // arithmetic operators, we must wrap it in a dispatch function
// to allow for automatic arithmetic type conversions // to allow for automatic arithmetic type conversions
std::vector<Proxy_Function> vec({t_f}); std::vector<Proxy_Function> vec({t_f});
funcs.insert(std::make_pair(t_name, vec)); funcs.insert(std::make_pair(t_name, vec));
func_objs[t_name] = std::make_shared<Dispatch_Function>(std::move(vec)); return std::make_shared<Dispatch_Function>(std::move(vec));
} else { } else {
funcs.insert(std::make_pair(t_name, std::vector<Proxy_Function>{t_f})); funcs.insert(std::make_pair(t_name, std::vector<Proxy_Function>{t_f}));
func_objs[t_name] = t_f; return t_f;
} }
}();
boxed_funcs[t_name] = const_var(new_func);
func_objs[t_name] = std::move(new_func);
} }
mutable chaiscript::detail::threading::shared_mutex m_mutex; mutable chaiscript::detail::threading::shared_mutex m_mutex;