speed up operator calls by about 10% by reducing Proxy_Function copies and such
This commit is contained in:
@@ -86,7 +86,7 @@ namespace chaiscript
|
|||||||
|
|
||||||
virtual Boxed_Value operator()(const std::vector<Boxed_Value> ¶ms)
|
virtual Boxed_Value operator()(const std::vector<Boxed_Value> ¶ms)
|
||||||
{
|
{
|
||||||
return dispatch(m_funcs, params);
|
return dispatch(m_funcs.begin(), m_funcs.end(), params);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual std::vector<Type_Info> get_param_types() const
|
virtual std::vector<Type_Info> get_param_types() const
|
||||||
@@ -371,6 +371,13 @@ namespace chaiscript
|
|||||||
m_reserved_words.insert(name);
|
m_reserved_words.insert(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Boxed_Value call_function(const std::string &t_name, const std::vector<Boxed_Value> ¶ms)
|
||||||
|
{
|
||||||
|
std::pair<std::multimap<std::string, Proxy_Function >::const_iterator, std::multimap<std::string, Proxy_Function >::const_iterator> range
|
||||||
|
= m_functions.equal_range(t_name);
|
||||||
|
|
||||||
|
return dispatch(range.first, range.second, params);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
|
@@ -410,17 +410,16 @@ namespace chaiscript
|
|||||||
* each function against the set of parameters, in order, until a matching
|
* each function against the set of parameters, in order, until a matching
|
||||||
* function is found or throw dispatch_error if no matching function is found
|
* function is found or throw dispatch_error if no matching function is found
|
||||||
*/
|
*/
|
||||||
Boxed_Value dispatch(const std::vector<std::pair<std::string, Proxy_Function> > &funcs,
|
template<typename InItr>
|
||||||
|
Boxed_Value dispatch(InItr begin, InItr end,
|
||||||
const std::vector<Boxed_Value> &plist)
|
const std::vector<Boxed_Value> &plist)
|
||||||
{
|
{
|
||||||
for (std::vector<std::pair<std::string, Proxy_Function> >::const_iterator itr = funcs.begin();
|
while (begin != end)
|
||||||
itr != funcs.end();
|
|
||||||
++itr)
|
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
if (itr->second->filter(plist))
|
if (begin->second->filter(plist))
|
||||||
{
|
{
|
||||||
return (*itr->second)(plist);
|
return (*begin->second)(plist);
|
||||||
}
|
}
|
||||||
} catch (const bad_boxed_cast &) {
|
} catch (const bad_boxed_cast &) {
|
||||||
//parameter failed to cast, try again
|
//parameter failed to cast, try again
|
||||||
@@ -430,9 +429,22 @@ namespace chaiscript
|
|||||||
//guard failed to allow the function to execute,
|
//guard failed to allow the function to execute,
|
||||||
//try again
|
//try again
|
||||||
}
|
}
|
||||||
|
++begin;
|
||||||
}
|
}
|
||||||
|
|
||||||
throw dispatch_error();
|
throw dispatch_error();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take a vector of functions and a vector of parameters. Attempt to execute
|
||||||
|
* each function against the set of parameters, in order, until a matching
|
||||||
|
* function is found or throw dispatch_error if no matching function is found
|
||||||
|
*/
|
||||||
|
Boxed_Value dispatch(const std::vector<std::pair<std::string, Proxy_Function> > &funcs,
|
||||||
|
const std::vector<Boxed_Value> &plist)
|
||||||
|
{
|
||||||
|
return dispatch(funcs.begin(), funcs.end(), plist);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -125,13 +125,13 @@ namespace chaiscript
|
|||||||
try {
|
try {
|
||||||
if (lhs.is_unknown())
|
if (lhs.is_unknown())
|
||||||
{
|
{
|
||||||
retval = dispatch(ss.get_function("clone"), Param_List_Builder() << retval);
|
retval = ss.call_function("clone", Param_List_Builder() << retval);
|
||||||
}
|
}
|
||||||
Param_List_Builder plb;
|
Param_List_Builder plb;
|
||||||
plb << lhs;
|
plb << lhs;
|
||||||
plb << retval;
|
plb << retval;
|
||||||
try {
|
try {
|
||||||
retval = dispatch(ss.get_function(node->children[i+1]->text), plb);
|
retval = ss.call_function(node->children[i+1]->text, plb);
|
||||||
}
|
}
|
||||||
catch(const dispatch_error &){
|
catch(const dispatch_error &){
|
||||||
throw Eval_Error("Mismatched types in equation", node->children[i+1]);
|
throw Eval_Error("Mismatched types in equation", node->children[i+1]);
|
||||||
@@ -155,7 +155,7 @@ namespace chaiscript
|
|||||||
plb << eval_token(ss, node->children[i]);
|
plb << eval_token(ss, node->children[i]);
|
||||||
plb << retval;
|
plb << retval;
|
||||||
try {
|
try {
|
||||||
retval = dispatch(ss.get_function(node->children[i+1]->text), plb);
|
retval = ss.call_function(node->children[i+1]->text, plb);
|
||||||
}
|
}
|
||||||
catch(const dispatch_error &){
|
catch(const dispatch_error &){
|
||||||
throw Eval_Error("Can not find appropriate '" + node->children[i+1]->text + "'", node->children[i+1]);
|
throw Eval_Error("Can not find appropriate '" + node->children[i+1]->text + "'", node->children[i+1]);
|
||||||
@@ -235,7 +235,7 @@ namespace chaiscript
|
|||||||
plb << eval_token(ss, node->children[i + 1]);
|
plb << eval_token(ss, node->children[i + 1]);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
retval = dispatch(ss.get_function(node->children[i]->text), plb);
|
retval = ss.call_function(node->children[i]->text, plb);
|
||||||
}
|
}
|
||||||
catch(const dispatch_error &){
|
catch(const dispatch_error &){
|
||||||
throw Eval_Error("Can not find appropriate '" + node->children[i]->text + "'", node->children[i]);
|
throw Eval_Error("Can not find appropriate '" + node->children[i]->text + "'", node->children[i]);
|
||||||
@@ -260,7 +260,7 @@ namespace chaiscript
|
|||||||
plb << retval;
|
plb << retval;
|
||||||
plb << eval_token(ss, node->children[i]);
|
plb << eval_token(ss, node->children[i]);
|
||||||
try {
|
try {
|
||||||
retval = dispatch(ss.get_function("[]"), plb);
|
retval = ss.call_function("[]", plb);
|
||||||
}
|
}
|
||||||
catch(std::out_of_range &) {
|
catch(std::out_of_range &) {
|
||||||
throw Eval_Error("Out of bounds exception", node);
|
throw Eval_Error("Out of bounds exception", node);
|
||||||
@@ -286,7 +286,7 @@ namespace chaiscript
|
|||||||
plb << Boxed_Value(-1.0);
|
plb << Boxed_Value(-1.0);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return dispatch(ss.get_function("*"), plb);
|
return ss.call_function("*", plb);
|
||||||
}
|
}
|
||||||
catch(std::exception &){
|
catch(std::exception &){
|
||||||
throw Eval_Error("Can not find appropriate negation", node->children[0]);
|
throw Eval_Error("Can not find appropriate negation", node->children[0]);
|
||||||
@@ -323,7 +323,7 @@ namespace chaiscript
|
|||||||
plb << retval;
|
plb << retval;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return dispatch(ss.get_function(node->children[0]->text), plb);
|
return ss.call_function(node->children[0]->text, plb);
|
||||||
}
|
}
|
||||||
catch(std::exception &){
|
catch(std::exception &){
|
||||||
throw Eval_Error("Can not find appropriate prefix", node->children[0]);
|
throw Eval_Error("Can not find appropriate prefix", node->children[0]);
|
||||||
@@ -339,12 +339,12 @@ namespace chaiscript
|
|||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
retval = dispatch(ss.get_function("Vector"), Param_List_Builder());
|
retval = ss.call_function("Vector", Param_List_Builder());
|
||||||
if (node->children.size() > 0) {
|
if (node->children.size() > 0) {
|
||||||
for (i = 0; i < node->children[0]->children.size(); ++i) {
|
for (i = 0; i < node->children[0]->children.size(); ++i) {
|
||||||
try {
|
try {
|
||||||
Boxed_Value tmp = eval_token(ss, node->children[0]->children[i]);
|
Boxed_Value tmp = eval_token(ss, node->children[0]->children[i]);
|
||||||
dispatch(ss.get_function("push_back"), Param_List_Builder() << retval << tmp);
|
ss.call_function("push_back", Param_List_Builder() << retval << tmp);
|
||||||
}
|
}
|
||||||
catch (const dispatch_error &) {
|
catch (const dispatch_error &) {
|
||||||
throw Eval_Error("Can not find appropriate 'push_back'", node->children[0]->children[i]);
|
throw Eval_Error("Can not find appropriate 'push_back'", node->children[0]->children[i]);
|
||||||
@@ -365,7 +365,7 @@ namespace chaiscript
|
|||||||
template <typename Eval_System>
|
template <typename Eval_System>
|
||||||
Boxed_Value eval_inline_range(Eval_System &ss, TokenPtr node) {
|
Boxed_Value eval_inline_range(Eval_System &ss, TokenPtr node) {
|
||||||
try {
|
try {
|
||||||
return dispatch(ss.get_function("generate_range"), Param_List_Builder()
|
return ss.call_function("generate_range", Param_List_Builder()
|
||||||
<< eval_token(ss, node->children[0]->children[0]->children[0])
|
<< eval_token(ss, node->children[0]->children[0]->children[0])
|
||||||
<< eval_token(ss, node->children[0]->children[0]->children[1]));
|
<< eval_token(ss, node->children[0]->children[0]->children[1]));
|
||||||
}
|
}
|
||||||
@@ -383,12 +383,12 @@ namespace chaiscript
|
|||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
retval = dispatch(ss.get_function("Map"), Param_List_Builder());
|
retval = ss.call_function("Map", Param_List_Builder());
|
||||||
for (i = 0; i < node->children[0]->children.size(); ++i) {
|
for (i = 0; i < node->children[0]->children.size(); ++i) {
|
||||||
try {
|
try {
|
||||||
Boxed_Value key = eval_token(ss, node->children[0]->children[i]->children[0]);
|
Boxed_Value key = eval_token(ss, node->children[0]->children[i]->children[0]);
|
||||||
Boxed_Value slot = dispatch(ss.get_function("[]"), Param_List_Builder() << retval << key);
|
Boxed_Value slot = ss.call_function("[]", Param_List_Builder() << retval << key);
|
||||||
dispatch(ss.get_function("="), Param_List_Builder() << slot << eval_token(ss, node->children[0]->children[i]->children[1]));
|
ss.call_function("=", Param_List_Builder() << slot << eval_token(ss, node->children[0]->children[i]->children[1]));
|
||||||
}
|
}
|
||||||
catch (const dispatch_error &) {
|
catch (const dispatch_error &) {
|
||||||
throw Eval_Error("Can not find appropriate '=' for map init", node->children[0]->children[i]);
|
throw Eval_Error("Can not find appropriate '=' for map init", node->children[0]->children[i]);
|
||||||
|
Reference in New Issue
Block a user