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,34 +1287,39 @@ 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();
if (itr != funcs.end()) Proxy_Function new_func =
{ [&]() -> Proxy_Function {
auto &vec = itr->second; if (itr != funcs.end())
for (const auto &func : vec)
{
if ((*t_f) == *(func))
{ {
throw chaiscript::exception::name_conflict_error(t_name); auto &vec = itr->second;
for (const auto &func : vec)
{
if ((*t_f) == *(func))
{
throw chaiscript::exception::name_conflict_error(t_name);
}
}
vec.push_back(t_f);
std::stable_sort(vec.begin(), vec.end(), &function_less_than);
return std::make_shared<Dispatch_Function>(vec);
} else if (t_f->has_arithmetic_param()) {
// if the function is the only function but it also contains
// arithmetic operators, we must wrap it in a dispatch function
// to allow for automatic arithmetic type conversions
std::vector<Proxy_Function> vec({t_f});
funcs.insert(std::make_pair(t_name, vec));
return std::make_shared<Dispatch_Function>(std::move(vec));
} else {
funcs.insert(std::make_pair(t_name, std::vector<Proxy_Function>{t_f}));
return t_f;
} }
} }();
vec.push_back(t_f);
std::stable_sort(vec.begin(), vec.end(), &function_less_than);
func_objs[t_name] = std::make_shared<Dispatch_Function>(vec);
} else if (t_f->has_arithmetic_param()) {
// if the function is the only function but it also contains
// arithmetic operators, we must wrap it in a dispatch function
// to allow for automatic arithmetic type conversions
std::vector<Proxy_Function> vec({t_f});
funcs.insert(std::make_pair(t_name, vec));
func_objs[t_name] = std::make_shared<Dispatch_Function>(std::move(vec));
} else {
funcs.insert(std::make_pair(t_name, std::vector<Proxy_Function>{t_f}));
func_objs[t_name] = 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;