diff --git a/include/cubescript/cubescript.hh b/include/cubescript/cubescript.hh index 129706a1..b793a8bc 100644 --- a/include/cubescript/cubescript.hh +++ b/include/cubescript/cubescript.hh @@ -313,12 +313,6 @@ enum { CsLibAll = 0b111 }; -struct CsStackStateNode { - CsStackStateNode const *next; - CsIdent const *id; - int index; -}; - using CsHookCb = ostd::Function; using CsAllocCb = void *(*)(void *, void *, ostd::Size, ostd::Size); @@ -411,6 +405,12 @@ struct OSTD_EXPORT CsState { alloc(v, sizeof(T), 0); } + template + void destroy_array(T *v, ostd::Size len) noexcept { + v->~T(); + alloc(v, len * sizeof(T), 0); + } + void init_libs(int libs = CsLibAll); void clear_override(CsIdent &id); @@ -558,8 +558,15 @@ private: CsStream *p_out, *p_err; }; +struct CsStackStateNode { + CsStackStateNode const *next; + CsIdent const *id; + int index; +}; + struct CsStackState { - CsStackState(CsStackStateNode *nd = nullptr, bool gap = false); + CsStackState() = delete; + CsStackState(CsState &cs, CsStackStateNode *nd = nullptr, bool gap = false); CsStackState(CsStackState const &) = delete; CsStackState(CsStackState &&st); ~CsStackState(); @@ -571,6 +578,7 @@ struct CsStackState { bool gap() const; private: + CsState &p_state; CsStackStateNode *p_node; bool p_gap; }; @@ -597,7 +605,7 @@ struct CsErrorException { } CsErrorException(CsState &cs, ostd::ConstCharRange msg): - p_errmsg(), p_stack() + p_errmsg(), p_stack(cs) { p_errmsg = save_msg(cs, msg); p_stack = save_stack(cs); @@ -605,7 +613,7 @@ struct CsErrorException { template CsErrorException(CsState &cs, ostd::ConstCharRange msg, A &&...args): - p_errmsg(), p_stack() + p_errmsg(), p_stack(cs) { char fbuf[512]; auto ret = ostd::format( diff --git a/src/cs_vm.cc b/src/cs_vm.cc index 5a28416c..4b2e9e80 100644 --- a/src/cs_vm.cc +++ b/src/cs_vm.cc @@ -35,18 +35,22 @@ static inline void cs_pop_alias(CsIdent *id) { } } -CsStackState::CsStackState(CsStackStateNode *nd, bool gap): - p_node(nd), p_gap(gap) +CsStackState::CsStackState(CsState &cs, CsStackStateNode *nd, bool gap): + p_state(cs), p_node(nd), p_gap(gap) {} CsStackState::CsStackState(CsStackState &&st): - p_node(st.p_node), p_gap(st.p_gap) + p_state(st.p_state), p_node(st.p_node), p_gap(st.p_gap) { st.p_node = nullptr; st.p_gap = false; } CsStackState::~CsStackState() { - delete[] p_node; + ostd::Size len = 0; + for (CsStackStateNode const *nd = p_node; nd; nd = nd->next) { + ++len; + } + p_state.destroy_array(p_node, len); } CsStackState &CsStackState::operator=(CsStackState &&st) { @@ -68,17 +72,18 @@ bool CsStackState::gap() const { CsStackState cs_save_stack(CsState &cs) { CsIvar *dalias = static_cast(cs.p_state->identmap[DbgaliasIdx]); if (!dalias->get_value()) { - return CsStackState(nullptr, !!cs.p_callstack); + return CsStackState(cs, nullptr, !!cs.p_callstack); } int total = 0, depth = 0; for (CsIdentLink *l = cs.p_callstack; l; l = l->next) { total++; } if (!total) { - return CsStackState(nullptr, false); + return CsStackState(cs, nullptr, false); } - CsStackStateNode *st = - new CsStackStateNode[ostd::min(total, dalias->get_value())]; + CsStackStateNode *st = cs.create_array( + ostd::min(total, dalias->get_value()) + ); CsStackStateNode *ret = st, *nd = st; ++st; for (CsIdentLink *l = cs.p_callstack; l; l = l->next) { @@ -98,7 +103,7 @@ CsStackState cs_save_stack(CsState &cs) { nd->next = nullptr; } } - return CsStackState(ret, total > dalias->get_value()); + return CsStackState(cs, ret, total > dalias->get_value()); } CsStackState CsErrorException::save_stack(CsState &cs) { diff --git a/src/cubescript.cc b/src/cubescript.cc index ad20f9ea..ba8747a4 100644 --- a/src/cubescript.cc +++ b/src/cubescript.cc @@ -397,6 +397,7 @@ void *CsState::alloc(void *ptr, ostd::Size os, ostd::Size ns) { } if (!ns) { delete[] static_cast(ptr); + return nullptr; } return new unsigned char[ns]; }