diff --git a/CMakeLists.txt b/CMakeLists.txt index ca8a1ee..8c817ab 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -296,6 +296,10 @@ if(BUILD_TESTING) target_link_libraries(object_lifetime_test ${LIBS}) add_test(NAME Object_Lifetime_Test COMMAND object_lifetime_test) + add_executable(object_lifetime_test2 unittests/object_lifetime_test2.cpp) + target_link_libraries(object_lifetime_test2 ${LIBS}) + add_test(NAME Object_Lifetime_Test2 COMMAND object_lifetime_test2) + add_executable(function_ordering_test unittests/function_ordering_test.cpp) target_link_libraries(function_ordering_test ${LIBS}) add_test(NAME Function_Ordering_Test COMMAND function_ordering_test) diff --git a/include/chaiscript/dispatchkit/dispatchkit.hpp b/include/chaiscript/dispatchkit/dispatchkit.hpp index fbf6d53..dfa167d 100644 --- a/include/chaiscript/dispatchkit/dispatchkit.hpp +++ b/include/chaiscript/dispatchkit/dispatchkit.hpp @@ -493,11 +493,13 @@ namespace chaiscript void new_scope() { get_stack_data().emplace_back(); + m_stack_holder->call_params.emplace_back(); } /// Pops the current scope from the stack void pop_scope() { + m_stack_holder->call_params.pop_back(); StackData &stack = get_stack_data(); if (stack.size() > 1) { @@ -914,7 +916,7 @@ namespace chaiscript void save_function_params(std::initializer_list t_params) { Stack_Holder &s = *m_stack_holder; - s.call_params.insert(s.call_params.begin(), std::move(t_params)); + s.call_params.back().insert(s.call_params.back().begin(), std::move(t_params)); } void save_function_params(std::vector &&t_params) @@ -923,14 +925,14 @@ namespace chaiscript for (auto &¶m : t_params) { - s.call_params.insert(s.call_params.begin(), std::move(param)); + s.call_params.back().insert(s.call_params.back().begin(), std::move(param)); } } void save_function_params(const std::vector &t_params) { Stack_Holder &s = *m_stack_holder; - s.call_params.insert(s.call_params.begin(), t_params.begin(), t_params.end()); + s.call_params.back().insert(s.call_params.back().begin(), t_params.begin(), t_params.end()); } void new_function_call() @@ -941,7 +943,7 @@ namespace chaiscript m_conversions.enable_conversion_saves(true); } - ++m_stack_holder->call_depth; + ++s.call_depth; save_function_params(m_conversions.take_saves()); } @@ -955,9 +957,7 @@ namespace chaiscript if (s.call_depth == 0) { - /// \todo Critical: this needs to be smarter, memory can expand quickly - /// in tight loops involving function calls - s.call_params.clear(); + s.call_params.back().clear(); m_conversions.enable_conversion_saves(false); } } @@ -1149,11 +1149,12 @@ namespace chaiscript : call_depth(0) { stacks.emplace_back(1); + call_params.emplace_back(); } std::deque stacks; - std::list call_params; + std::deque> call_params; int call_depth; }; diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index 36978ab..f87b87f 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -382,6 +382,7 @@ namespace chaiscript virtual ~Equation_AST_Node() {} virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss) const CHAISCRIPT_OVERRIDE { + chaiscript::eval::detail::Function_Push_Pop fpp(t_ss); Boxed_Value retval = this->children.back()->eval(t_ss); @@ -595,8 +596,8 @@ namespace chaiscript AST_Node(t_ast_node_text, AST_Node_Type::Dot_Access, t_fname, t_start_line, t_start_col, t_end_line, t_end_col) { } virtual ~Dot_Access_AST_Node() {} virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &t_ss) const CHAISCRIPT_OVERRIDE{ - Boxed_Value retval = this->children[0]->eval(t_ss); chaiscript::eval::detail::Function_Push_Pop fpp(t_ss); + Boxed_Value retval = this->children[0]->eval(t_ss); if (this->children.size() > 1) { for (size_t i = 2; i < this->children.size(); i+=2) { diff --git a/unittests/object_lifetime_test2.cpp b/unittests/object_lifetime_test2.cpp new file mode 100644 index 0000000..c99b191 --- /dev/null +++ b/unittests/object_lifetime_test2.cpp @@ -0,0 +1,69 @@ +#include +#include + +template +struct Vector2 +{ + Vector2() : x(0), y(0) {}; + Vector2(T px, T py) : x(px), y(py) {}; + Vector2(const Vector2& cp) : x(cp.x), y(cp.y) {}; + + Vector2& operator+=(const Vector2& vec_r) + { + x += vec_r.x; + y += vec_r.y; + return *this; + } + + Vector2 operator+(const Vector2& vec_r) + { + return Vector2(*this += vec_r); + } + + void operator=(const Vector2& ver_r) + { + x = ver_r.x; + y = ver_r.y; + } + + + T x; + T y; +}; + +Vector2 GetValue() +{ + return Vector2(10,15); +} + +int main() +{ + chaiscript::ChaiScript _script(chaiscript::Std_Lib::library()); + + //Registering stuff + _script.add(chaiscript::user_type>(), "Vector2f"); + _script.add(chaiscript::constructor ()>(), "Vector2f"); + _script.add(chaiscript::constructor (float, float)>(), "Vector2f"); + _script.add(chaiscript::constructor (const Vector2&)>(), "Vector2f"); + _script.add(chaiscript::fun(&Vector2::x), "x"); + _script.add(chaiscript::fun(&Vector2::y), "y"); + _script.add(chaiscript::fun(&Vector2::operator +), "+"); + _script.add(chaiscript::fun(&Vector2::operator +=), "+="); + _script.add(chaiscript::fun(&Vector2::operator =), "="); + _script.add(chaiscript::fun(&GetValue), "getValue"); + + _script.eval(R"( + var test = 0.0 + var test2 = Vector2f(10,10) + + test = getValue().x + print(test) + print(test2.x) + )"); + + if (_script.eval("to_string(test)") != "10") { return EXIT_FAILURE; } + if (_script.eval("to_string(test2.x)") != "10") { return EXIT_FAILURE; } + + + //_script.eval_file("object_lifetime_test2.inc"); +}