From 04441f206dff87993414b14127980baf0976e48d Mon Sep 17 00:00:00 2001 From: Daniel Kolesa Date: Sun, 4 Apr 2021 19:31:29 +0200 Subject: [PATCH] remove the 255 run-depth limitation also add optional per-thread API that sets the maximum run depth (0 means no limit, default) if you want it; since we no longer store stuff on the stack it should not be necessary though --- include/cubescript/cubescript.hh | 3 +++ src/cs_state.cc | 10 ++++++++++ src/cs_thread.hh | 12 ++++++++---- src/cs_vm.cc | 11 ++++------- src/cs_vm.hh | 2 ++ 5 files changed, 27 insertions(+), 11 deletions(-) diff --git a/include/cubescript/cubescript.hh b/include/cubescript/cubescript.hh index 342617f..d700566 100644 --- a/include/cubescript/cubescript.hh +++ b/include/cubescript/cubescript.hh @@ -412,6 +412,9 @@ struct LIBCUBESCRIPT_EXPORT state { bool get_persist_mode() const; bool set_persist_mode(bool v); + std::size_t get_max_run_depth() const; + std::size_t set_max_run_depth(std::size_t v); + void set_alias(std::string_view name, any_value v); std::optional get_alias_val(std::string_view name); diff --git a/src/cs_state.cc b/src/cs_state.cc index 1591b8a..8538416 100644 --- a/src/cs_state.cc +++ b/src/cs_state.cc @@ -859,4 +859,14 @@ LIBCUBESCRIPT_EXPORT bool state::set_persist_mode(bool v) { return was; } +LIBCUBESCRIPT_EXPORT std::size_t state::get_max_run_depth() const { + return p_tstate->max_run_depth; +} + +LIBCUBESCRIPT_EXPORT std::size_t state::set_max_run_depth(std::size_t v) { + auto old = p_tstate->max_run_depth; + p_tstate->max_run_depth = v; + return old; +} + } /* namespace cubescript */ diff --git a/src/cs_thread.hh b/src/cs_thread.hh index a7ec600..967f7ce 100644 --- a/src/cs_thread.hh +++ b/src/cs_thread.hh @@ -35,12 +35,16 @@ struct thread_state { charbuf errbuf; /* we can attach a hook to vm events */ hook_func call_hook{}; - /* loop nesting level */ - int loop_level = 0; - /* thread ident flags */ - int ident_flags = 0; /* whether we own the internal state (i.e. not a side thread */ bool owner = false; + /* thread ident flags */ + int ident_flags = 0; + /* run depth limit */ + std::size_t max_run_depth = 0; + /* current run depth */ + std::size_t run_depth = 0; + /* loop nesting level */ + std::size_t loop_level = 0; thread_state(internal_state *cs); diff --git a/src/cs_vm.cc b/src/cs_vm.cc index dfabc06..598e00e 100644 --- a/src/cs_vm.cc +++ b/src/cs_vm.cc @@ -279,17 +279,14 @@ bool exec_alias( return true; } -static constexpr int MaxRunDepth = 255; -static thread_local int rundepth = 0; - -run_depth_guard::run_depth_guard(thread_state &ts) { - if (rundepth >= MaxRunDepth) { +run_depth_guard::run_depth_guard(thread_state &ts): tsp(&ts) { + if (ts.max_run_depth && (ts.run_depth >= ts.max_run_depth)) { throw error{ts, "exceeded recursion limit"}; } - ++rundepth; + ++ts.run_depth; } -run_depth_guard::~run_depth_guard() { --rundepth; } +run_depth_guard::~run_depth_guard() { --tsp->run_depth; } static inline alias *get_lookup_id( thread_state &ts, std::uint32_t op, alias_stack *&ast diff --git a/src/cs_vm.hh b/src/cs_vm.hh index 4a1edfb..1144269 100644 --- a/src/cs_vm.hh +++ b/src/cs_vm.hh @@ -22,6 +22,8 @@ struct run_depth_guard { run_depth_guard(run_depth_guard const &) = delete; run_depth_guard(run_depth_guard &&) = delete; ~run_depth_guard(); + + thread_state *tsp; }; struct stack_guard {