Move to a bit smarter stack based object management

- we store all function parameters until the f
    outer function call exits

  - this results in more values being stored longer than
    they need to be, but the results are predictable
    and no leaks
This commit is contained in:
Jason Turner
2012-05-21 10:16:16 -06:00
parent ef46d1bf60
commit 3a7eff1478
3 changed files with 63 additions and 2 deletions

View File

@@ -897,6 +897,29 @@ namespace chaiscript
m_state = t_state; m_state = t_state;
} }
void save_function_params(const std::vector<Boxed_Value> &t_params)
{
m_stack_holder->call_params.insert(m_stack_holder->call_params.begin(), t_params.begin(), t_params.end());
}
void new_function_call()
{
++m_stack_holder->call_depth;
}
void pop_function_call()
{
--m_stack_holder->call_depth;
assert(m_stack_holder->call_depth >= 0);
if (m_stack_holder->call_depth == 0)
{
/// \todo Critical: this needs to be smarter, memory can expand quickly
/// in tight loops involving function calls
m_stack_holder->call_params.clear();
}
}
private: private:
/** /**
@@ -1083,6 +1106,7 @@ namespace chaiscript
struct Stack_Holder struct Stack_Holder
{ {
Stack_Holder() Stack_Holder()
: call_depth(0)
{ {
Stack s(new StackData()); Stack s(new StackData());
s->push_back(Scope()); s->push_back(Scope());
@@ -1090,6 +1114,9 @@ namespace chaiscript
} }
std::deque<Stack> stacks; std::deque<Stack> stacks;
std::list<Boxed_Value> call_params;
int call_depth;
}; };
std::vector<Dynamic_Cast_Conversion> m_conversions; std::vector<Dynamic_Cast_Conversion> m_conversions;

View File

@@ -214,6 +214,34 @@ namespace chaiscript
chaiscript::detail::Dispatch_Engine &m_de; chaiscript::detail::Dispatch_Engine &m_de;
}; };
/// Creates a new functon call and pops it on destruction
struct Function_Push_Pop
{
Function_Push_Pop(chaiscript::detail::Dispatch_Engine &t_de)
: m_de(t_de)
{
m_de.new_function_call();
}
~Function_Push_Pop()
{
m_de.pop_function_call();
}
void save_params(const std::vector<Boxed_Value> &t_params)
{
m_de.save_function_params(t_params);
}
private:
// explicitly unimplemented copy and assignment
Function_Push_Pop(const Function_Push_Pop &);
Function_Push_Pop& operator=(const Function_Push_Pop &);
chaiscript::detail::Dispatch_Engine &m_de;
};
/// Creates a new scope then pops it on destruction /// Creates a new scope then pops it on destruction
struct Stack_Push_Pop struct Stack_Push_Pop
{ {
@@ -231,8 +259,8 @@ namespace chaiscript
private: private:
// explicitly unimplemented copy and assignment // explicitly unimplemented copy and assignment
Stack_Push_Pop(const Scope_Push_Pop &); Stack_Push_Pop(const Stack_Push_Pop &);
Stack_Push_Pop& operator=(const Scope_Push_Pop &); Stack_Push_Pop& operator=(const Stack_Push_Pop &);
chaiscript::detail::Dispatch_Engine &m_de; chaiscript::detail::Dispatch_Engine &m_de;
}; };

View File

@@ -182,6 +182,7 @@ namespace chaiscript
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { }
virtual ~Fun_Call_AST_Node() {} virtual ~Fun_Call_AST_Node() {}
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){ virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss){
chaiscript::eval::detail::Function_Push_Pop fpp(t_ss);
dispatch::Param_List_Builder plb; dispatch::Param_List_Builder plb;
if ((this->children.size() > 1) && (this->children[1]->identifier == AST_Node_Type::Arg_List)) { if ((this->children.size() > 1) && (this->children[1]->identifier == AST_Node_Type::Arg_List)) {
@@ -190,6 +191,8 @@ namespace chaiscript
} }
} }
fpp.save_params(plb.objects);
Boxed_Value fn = this->children[0]->eval(t_ss); Boxed_Value fn = this->children[0]->eval(t_ss);
try { try {
@@ -431,6 +434,7 @@ namespace chaiscript
if (this->children.size() > 1) { if (this->children.size() > 1) {
for (size_t i = 2; i < this->children.size(); i+=2) { for (size_t i = 2; i < this->children.size(); i+=2) {
chaiscript::eval::detail::Function_Push_Pop fpp(t_ss);
dispatch::Param_List_Builder plb; dispatch::Param_List_Builder plb;
plb << retval; plb << retval;
@@ -440,6 +444,8 @@ namespace chaiscript
} }
} }
fpp.save_params(plb.objects);
std::string fun_name; std::string fun_name;
if ((this->children[i]->identifier == AST_Node_Type::Fun_Call) || (this->children[i]->identifier == AST_Node_Type::Array_Call)) { if ((this->children[i]->identifier == AST_Node_Type::Fun_Call) || (this->children[i]->identifier == AST_Node_Type::Array_Call)) {
fun_name = this->children[i]->children[0]->text; fun_name = this->children[i]->children[0]->text;