alloc error stack using CsState

master
Daniel Kolesa 2016-09-14 21:46:47 +02:00
parent e7f3213588
commit b20eb94a9e
3 changed files with 32 additions and 18 deletions

View File

@ -313,12 +313,6 @@ enum {
CsLibAll = 0b111 CsLibAll = 0b111
}; };
struct CsStackStateNode {
CsStackStateNode const *next;
CsIdent const *id;
int index;
};
using CsHookCb = ostd::Function<void(CsState &)>; using CsHookCb = ostd::Function<void(CsState &)>;
using CsAllocCb = void *(*)(void *, void *, ostd::Size, ostd::Size); using CsAllocCb = void *(*)(void *, void *, ostd::Size, ostd::Size);
@ -411,6 +405,12 @@ struct OSTD_EXPORT CsState {
alloc(v, sizeof(T), 0); alloc(v, sizeof(T), 0);
} }
template<typename T>
void destroy_array(T *v, ostd::Size len) noexcept {
v->~T();
alloc(v, len * sizeof(T), 0);
}
void init_libs(int libs = CsLibAll); void init_libs(int libs = CsLibAll);
void clear_override(CsIdent &id); void clear_override(CsIdent &id);
@ -558,8 +558,15 @@ private:
CsStream *p_out, *p_err; CsStream *p_out, *p_err;
}; };
struct CsStackStateNode {
CsStackStateNode const *next;
CsIdent const *id;
int index;
};
struct CsStackState { 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 const &) = delete;
CsStackState(CsStackState &&st); CsStackState(CsStackState &&st);
~CsStackState(); ~CsStackState();
@ -571,6 +578,7 @@ struct CsStackState {
bool gap() const; bool gap() const;
private: private:
CsState &p_state;
CsStackStateNode *p_node; CsStackStateNode *p_node;
bool p_gap; bool p_gap;
}; };
@ -597,7 +605,7 @@ struct CsErrorException {
} }
CsErrorException(CsState &cs, ostd::ConstCharRange msg): CsErrorException(CsState &cs, ostd::ConstCharRange msg):
p_errmsg(), p_stack() p_errmsg(), p_stack(cs)
{ {
p_errmsg = save_msg(cs, msg); p_errmsg = save_msg(cs, msg);
p_stack = save_stack(cs); p_stack = save_stack(cs);
@ -605,7 +613,7 @@ struct CsErrorException {
template<typename ...A> template<typename ...A>
CsErrorException(CsState &cs, ostd::ConstCharRange msg, A &&...args): CsErrorException(CsState &cs, ostd::ConstCharRange msg, A &&...args):
p_errmsg(), p_stack() p_errmsg(), p_stack(cs)
{ {
char fbuf[512]; char fbuf[512];
auto ret = ostd::format( auto ret = ostd::format(

View File

@ -35,18 +35,22 @@ static inline void cs_pop_alias(CsIdent *id) {
} }
} }
CsStackState::CsStackState(CsStackStateNode *nd, bool gap): CsStackState::CsStackState(CsState &cs, CsStackStateNode *nd, bool gap):
p_node(nd), p_gap(gap) p_state(cs), p_node(nd), p_gap(gap)
{} {}
CsStackState::CsStackState(CsStackState &&st): 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_node = nullptr;
st.p_gap = false; st.p_gap = false;
} }
CsStackState::~CsStackState() { 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) { CsStackState &CsStackState::operator=(CsStackState &&st) {
@ -68,17 +72,18 @@ bool CsStackState::gap() const {
CsStackState cs_save_stack(CsState &cs) { CsStackState cs_save_stack(CsState &cs) {
CsIvar *dalias = static_cast<CsIvar *>(cs.p_state->identmap[DbgaliasIdx]); CsIvar *dalias = static_cast<CsIvar *>(cs.p_state->identmap[DbgaliasIdx]);
if (!dalias->get_value()) { if (!dalias->get_value()) {
return CsStackState(nullptr, !!cs.p_callstack); return CsStackState(cs, nullptr, !!cs.p_callstack);
} }
int total = 0, depth = 0; int total = 0, depth = 0;
for (CsIdentLink *l = cs.p_callstack; l; l = l->next) { for (CsIdentLink *l = cs.p_callstack; l; l = l->next) {
total++; total++;
} }
if (!total) { if (!total) {
return CsStackState(nullptr, false); return CsStackState(cs, nullptr, false);
} }
CsStackStateNode *st = CsStackStateNode *st = cs.create_array<CsStackStateNode>(
new CsStackStateNode[ostd::min(total, dalias->get_value())]; ostd::min(total, dalias->get_value())
);
CsStackStateNode *ret = st, *nd = st; CsStackStateNode *ret = st, *nd = st;
++st; ++st;
for (CsIdentLink *l = cs.p_callstack; l; l = l->next) { for (CsIdentLink *l = cs.p_callstack; l; l = l->next) {
@ -98,7 +103,7 @@ CsStackState cs_save_stack(CsState &cs) {
nd->next = nullptr; nd->next = nullptr;
} }
} }
return CsStackState(ret, total > dalias->get_value()); return CsStackState(cs, ret, total > dalias->get_value());
} }
CsStackState CsErrorException::save_stack(CsState &cs) { CsStackState CsErrorException::save_stack(CsState &cs) {

View File

@ -397,6 +397,7 @@ void *CsState::alloc(void *ptr, ostd::Size os, ostd::Size ns) {
} }
if (!ns) { if (!ns) {
delete[] static_cast<unsigned char *>(ptr); delete[] static_cast<unsigned char *>(ptr);
return nullptr;
} }
return new unsigned char[ns]; return new unsigned char[ns];
} }