Provide for caching of objects in the dispatch get get_object side. Also, update chaiscript_eval to not explicitly add a new stack object to each scope as it is created

This commit is contained in:
Jason Turner 2009-08-30 00:48:17 +00:00
parent 89186a86c8
commit 096c8aab50
2 changed files with 37 additions and 19 deletions

View File

@ -155,13 +155,13 @@ namespace chaiscript
public: public:
typedef std::map<std::string, chaiscript::Type_Info> Type_Name_Map; typedef std::map<std::string, chaiscript::Type_Info> Type_Name_Map;
typedef std::map<std::string, Boxed_Value> Scope; typedef std::map<std::string, Boxed_Value> Scope;
typedef boost::shared_ptr<std::deque<Scope> > Stack; typedef boost::shared_ptr<std::pair<std::map<std::string, Boxed_Value>, std::deque<Scope> > > Stack;
Dispatch_Engine() Dispatch_Engine()
: m_scopes(new Stack::element_type()), : m_scopes(new Stack::element_type()),
m_place_holder(boost::shared_ptr<Placeholder_Object>(new Placeholder_Object())) m_place_holder(boost::shared_ptr<Placeholder_Object>(new Placeholder_Object()))
{ {
m_scopes->push_back(Scope()); m_scopes->second.push_back(Scope());
} }
/** /**
@ -188,12 +188,13 @@ namespace chaiscript
void add(const Boxed_Value &obj, const std::string &name) void add(const Boxed_Value &obj, const std::string &name)
{ {
validate_object_name(name); validate_object_name(name);
for (int i = m_scopes->size()-1; i >= 0; --i) for (int i = m_scopes->second.size()-1; i >= 0; --i)
{ {
std::map<std::string, Boxed_Value>::const_iterator itr = (*m_scopes)[i].find(name); std::map<std::string, Boxed_Value>::const_iterator itr = (m_scopes->second)[i].find(name);
if (itr != (*m_scopes)[i].end()) if (itr != (m_scopes->second)[i].end())
{ {
(*m_scopes)[i][name] = Boxed_Value(obj); m_scopes->first.erase(name);
(m_scopes->second)[i][name] = Boxed_Value(obj);
return; return;
} }
} }
@ -206,8 +207,9 @@ namespace chaiscript
*/ */
void add_object(const std::string &name, const Boxed_Value &obj) void add_object(const std::string &name, const Boxed_Value &obj)
{ {
m_scopes->first.erase(name);
validate_object_name(name); validate_object_name(name);
m_scopes->back()[name] = Boxed_Value(obj); m_scopes->second.back()[name] = Boxed_Value(obj);
} }
/** /**
@ -215,7 +217,7 @@ namespace chaiscript
*/ */
void new_scope() void new_scope()
{ {
m_scopes->push_back(Scope()); m_scopes->second.push_back(Scope());
} }
/** /**
@ -223,9 +225,16 @@ namespace chaiscript
*/ */
void pop_scope() void pop_scope()
{ {
if (m_scopes->size() > 1) if (m_scopes->second.size() > 1)
{ {
m_scopes->pop_back(); Scope &scope(m_scopes->second.back());
for (Scope::const_iterator itr = scope.begin();
itr != scope.end();
++itr)
{
m_scopes->first.erase(itr->first);
}
m_scopes->second.pop_back();
} else { } else {
throw std::range_error("Unable to pop global stack"); throw std::range_error("Unable to pop global stack");
} }
@ -253,7 +262,9 @@ namespace chaiscript
Stack new_stack() Stack new_stack()
{ {
return Stack(new Stack::element_type()); Stack s(new Stack::element_type());
s->second.push_back(Scope());
return s;
} }
/** /**
@ -268,11 +279,20 @@ namespace chaiscript
return m_place_holder; return m_place_holder;
} }
for (int i = m_scopes->size()-1; i >= 0; --i) std::map<std::string, Boxed_Value> &cache = m_scopes->first;
std::map<std::string, Boxed_Value>::const_iterator itr = cache.find(name);
if (itr != cache.end())
{ {
std::map<std::string, Boxed_Value>::const_iterator itr = (*m_scopes)[i].find(name); return itr->second;
if (itr != (*m_scopes)[i].end()) }
for (int i = m_scopes->second.size()-1; i >= 0; --i)
{
std::map<std::string, Boxed_Value>::const_iterator itr = (m_scopes->second)[i].find(name);
if (itr != (m_scopes->second)[i].end())
{ {
cache[name] = itr->second;
return itr->second; return itr->second;
} }
} }
@ -283,7 +303,9 @@ namespace chaiscript
{ {
throw std::range_error("Object not known: " + name); throw std::range_error("Object not known: " + name);
} else { } else {
return Boxed_Value(Proxy_Function(new Dispatch_Function(funcs))); Boxed_Value f(Proxy_Function(new Dispatch_Function(funcs)));
cache[name] = f;
return f;
} }
} }

View File

@ -413,8 +413,6 @@ namespace chaiscript
Dispatch_Engine::Stack new_stack = ss.new_stack(); Dispatch_Engine::Stack new_stack = ss.new_stack();
unsigned int i; unsigned int i;
new_stack->push_back(Dispatch_Engine::Scope());
if ((node->children.size() > 1) && (node->children[1]->identifier == Token_Type::Arg_List)) { if ((node->children.size() > 1) && (node->children[1]->identifier == Token_Type::Arg_List)) {
for (i = 0; i < node->children[1]->children.size(); ++i) { for (i = 0; i < node->children[1]->children.size(); ++i) {
plb << eval_token(ss, node->children[1]->children[i]); plb << eval_token(ss, node->children[1]->children[i]);
@ -460,8 +458,6 @@ namespace chaiscript
Dispatch_Engine::Stack new_stack = ss.new_stack(); Dispatch_Engine::Stack new_stack = ss.new_stack();
unsigned int i, j; unsigned int i, j;
new_stack->push_back(Dispatch_Engine::Scope());
//todo: Please extract a single way of doing function calls between this and eval_fun_call //todo: Please extract a single way of doing function calls between this and eval_fun_call
retval = eval_token(ss, node->children[0]); retval = eval_token(ss, node->children[0]);