use exceptions to throw errors
parent
4510e53916
commit
e41c3c03a1
|
@ -319,56 +319,7 @@ struct CsStackStateNode {
|
||||||
int index;
|
int index;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CsStackState {
|
|
||||||
CsStackState(CsStackStateNode *nd = nullptr, bool gap = false);
|
|
||||||
CsStackState(CsStackState const &) = delete;
|
|
||||||
CsStackState(CsStackState &&st);
|
|
||||||
~CsStackState();
|
|
||||||
|
|
||||||
CsStackState &operator=(CsStackState const &) = delete;
|
|
||||||
CsStackState &operator=(CsStackState &&);
|
|
||||||
|
|
||||||
CsStackStateNode const *get() const;
|
|
||||||
bool gap() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
CsStackStateNode *p_node;
|
|
||||||
bool p_gap;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct CsErrorException {
|
|
||||||
friend struct CsState;
|
|
||||||
|
|
||||||
CsErrorException() = delete;
|
|
||||||
CsErrorException(CsErrorException const &) = delete;
|
|
||||||
CsErrorException(CsErrorException &&v):
|
|
||||||
p_errmsg(v.p_errmsg), p_stack(ostd::move(v.p_stack))
|
|
||||||
{}
|
|
||||||
|
|
||||||
ostd::ConstCharRange what() const {
|
|
||||||
return p_errmsg;
|
|
||||||
}
|
|
||||||
|
|
||||||
CsStackState &get_stack() {
|
|
||||||
return p_stack;
|
|
||||||
}
|
|
||||||
|
|
||||||
CsStackState const &get_stack() const {
|
|
||||||
return p_stack;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
CsErrorException(ostd::ConstCharRange v, CsStackState &&st):
|
|
||||||
p_errmsg(v), p_stack(ostd::move(st))
|
|
||||||
{}
|
|
||||||
|
|
||||||
ostd::ConstCharRange p_errmsg;
|
|
||||||
CsStackState p_stack;
|
|
||||||
};
|
|
||||||
|
|
||||||
using CsHookCb = ostd::Function<void(CsState &)>;
|
using CsHookCb = ostd::Function<void(CsState &)>;
|
||||||
using CsPanicCb =
|
|
||||||
ostd::Function<void(CsState &, ostd::ConstCharRange, CsStackState)>;
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct CsAllocator {
|
struct CsAllocator {
|
||||||
|
@ -402,9 +353,12 @@ private:
|
||||||
CsState &p_state;
|
CsState &p_state;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct CsErrorException;
|
||||||
struct CsSharedState;
|
struct CsSharedState;
|
||||||
|
|
||||||
struct OSTD_EXPORT CsState {
|
struct OSTD_EXPORT CsState {
|
||||||
|
friend struct CsErrorException;
|
||||||
|
|
||||||
CsSharedState *p_state;
|
CsSharedState *p_state;
|
||||||
CsIdentLink *p_callstack = nullptr;
|
CsIdentLink *p_callstack = nullptr;
|
||||||
|
|
||||||
|
@ -458,21 +412,6 @@ struct OSTD_EXPORT CsState {
|
||||||
|
|
||||||
void init_libs(int libs = CsLibAll);
|
void init_libs(int libs = CsLibAll);
|
||||||
|
|
||||||
void error(ostd::ConstCharRange msg);
|
|
||||||
|
|
||||||
template<typename ...A>
|
|
||||||
void error(ostd::ConstCharRange msg, A &&...args) {
|
|
||||||
char fbuf[512];
|
|
||||||
auto ret = ostd::format(
|
|
||||||
ostd::CharRange(fbuf, sizeof(fbuf)), msg, ostd::forward<A>(args)...
|
|
||||||
);
|
|
||||||
if ((ret < 0) || (ostd::Size(ret) > sizeof(fbuf))) {
|
|
||||||
error(msg);
|
|
||||||
} else {
|
|
||||||
error(ostd::CharRange(fbuf, ret));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void clear_override(CsIdent &id);
|
void clear_override(CsIdent &id);
|
||||||
void clear_overrides();
|
void clear_overrides();
|
||||||
|
|
||||||
|
@ -616,6 +555,75 @@ private:
|
||||||
CsStream *p_out, *p_err;
|
CsStream *p_out, *p_err;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct CsStackState {
|
||||||
|
CsStackState(CsStackStateNode *nd = nullptr, bool gap = false);
|
||||||
|
CsStackState(CsStackState const &) = delete;
|
||||||
|
CsStackState(CsStackState &&st);
|
||||||
|
~CsStackState();
|
||||||
|
|
||||||
|
CsStackState &operator=(CsStackState const &) = delete;
|
||||||
|
CsStackState &operator=(CsStackState &&);
|
||||||
|
|
||||||
|
CsStackStateNode const *get() const;
|
||||||
|
bool gap() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
CsStackStateNode *p_node;
|
||||||
|
bool p_gap;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CsErrorException {
|
||||||
|
friend struct CsState;
|
||||||
|
|
||||||
|
CsErrorException() = delete;
|
||||||
|
CsErrorException(CsErrorException const &) = delete;
|
||||||
|
CsErrorException(CsErrorException &&v):
|
||||||
|
p_errmsg(v.p_errmsg), p_stack(ostd::move(v.p_stack))
|
||||||
|
{}
|
||||||
|
|
||||||
|
ostd::ConstCharRange what() const {
|
||||||
|
return p_errmsg;
|
||||||
|
}
|
||||||
|
|
||||||
|
CsStackState &get_stack() {
|
||||||
|
return p_stack;
|
||||||
|
}
|
||||||
|
|
||||||
|
CsStackState const &get_stack() const {
|
||||||
|
return p_stack;
|
||||||
|
}
|
||||||
|
|
||||||
|
CsErrorException(CsState &cs, ostd::ConstCharRange msg):
|
||||||
|
p_errmsg(), p_stack()
|
||||||
|
{
|
||||||
|
p_errmsg = save_msg(cs, msg);
|
||||||
|
p_stack = save_stack(cs);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ...A>
|
||||||
|
CsErrorException(CsState &cs, ostd::ConstCharRange msg, A &&...args):
|
||||||
|
p_errmsg(), p_stack()
|
||||||
|
{
|
||||||
|
char fbuf[512];
|
||||||
|
auto ret = ostd::format(
|
||||||
|
ostd::CharRange(fbuf, sizeof(fbuf)), msg, ostd::forward<A>(args)...
|
||||||
|
);
|
||||||
|
if ((ret < 0) || (ostd::Size(ret) > sizeof(fbuf))) {
|
||||||
|
p_errmsg = save_msg(cs, msg);
|
||||||
|
} else {
|
||||||
|
p_errmsg = save_msg(cs, ostd::CharRange(fbuf, ret));
|
||||||
|
}
|
||||||
|
p_stack = save_stack(cs);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
CsStackState save_stack(CsState &cs);
|
||||||
|
ostd::ConstCharRange save_msg(CsState &cs, ostd::ConstCharRange v);
|
||||||
|
|
||||||
|
ostd::ConstCharRange p_errmsg;
|
||||||
|
CsStackState p_stack;
|
||||||
|
};
|
||||||
|
|
||||||
struct OSTD_EXPORT CsStackedValue: CsValue {
|
struct OSTD_EXPORT CsStackedValue: CsValue {
|
||||||
CsStackedValue(CsIdent *id = nullptr);
|
CsStackedValue(CsIdent *id = nullptr);
|
||||||
~CsStackedValue();
|
~CsStackedValue();
|
||||||
|
|
|
@ -51,7 +51,7 @@ static void cs_error_line(
|
||||||
p, gs.src_file, gs.src_str, fmt,
|
p, gs.src_file, gs.src_str, fmt,
|
||||||
ostd::CharRange(buf.data(), buf.size())
|
ostd::CharRange(buf.data(), buf.size())
|
||||||
);
|
);
|
||||||
gs.cs.error(rfmt, ostd::forward<A>(args)...);
|
throw CsErrorException(gs.cs, rfmt, ostd::forward<A>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *cs_dup_ostr(ostd::ConstCharRange s) {
|
char *cs_dup_ostr(ostd::ConstCharRange s) {
|
||||||
|
|
14
src/cs_vm.cc
14
src/cs_vm.cc
|
@ -101,6 +101,20 @@ CsStackState cs_save_stack(CsState &cs) {
|
||||||
return CsStackState(ret, total > dalias->get_value());
|
return CsStackState(ret, total > dalias->get_value());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CsStackState CsErrorException::save_stack(CsState &cs) {
|
||||||
|
return cs_save_stack(cs);
|
||||||
|
}
|
||||||
|
|
||||||
|
ostd::ConstCharRange CsErrorException::save_msg(
|
||||||
|
CsState &cs, ostd::ConstCharRange msg
|
||||||
|
) {
|
||||||
|
if (msg.size() > sizeof(cs.p_errbuf)) {
|
||||||
|
msg = msg.slice(0, sizeof(cs.p_errbuf));
|
||||||
|
}
|
||||||
|
memcpy(cs.p_errbuf, msg.data(), msg.size());
|
||||||
|
return ostd::ConstCharRange(cs.p_errbuf, msg.size());
|
||||||
|
}
|
||||||
|
|
||||||
static void bcode_ref(ostd::Uint32 *code) {
|
static void bcode_ref(ostd::Uint32 *code) {
|
||||||
if (!code) {
|
if (!code) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -396,15 +396,6 @@ void *CsState::alloc(void *ptr, ostd::Size, ostd::Size ns) {
|
||||||
return new unsigned char[ns];
|
return new unsigned char[ns];
|
||||||
}
|
}
|
||||||
|
|
||||||
void CsState::error(ostd::ConstCharRange msg) {
|
|
||||||
if (msg.size() > sizeof(p_errbuf)) {
|
|
||||||
msg = msg.slice(0, sizeof(p_errbuf));
|
|
||||||
}
|
|
||||||
memcpy(p_errbuf, msg.data(), msg.size());
|
|
||||||
auto err = ostd::ConstCharRange(p_errbuf, msg.size());
|
|
||||||
throw CsErrorException(err, cs_save_stack(*this));
|
|
||||||
}
|
|
||||||
|
|
||||||
void CsState::clear_override(CsIdent &id) {
|
void CsState::clear_override(CsIdent &id) {
|
||||||
if (!(id.get_flags() & CsIdfOverridden)) {
|
if (!(id.get_flags() & CsIdfOverridden)) {
|
||||||
return;
|
return;
|
||||||
|
@ -1073,7 +1064,7 @@ static inline void cs_loop_conc(
|
||||||
|
|
||||||
void cs_init_lib_base(CsState &gcs) {
|
void cs_init_lib_base(CsState &gcs) {
|
||||||
gcs.new_command("error", "s", [](CsState &cs, CsValueRange args, CsValue &) {
|
gcs.new_command("error", "s", [](CsState &cs, CsValueRange args, CsValue &) {
|
||||||
cs.error(args[0].get_strr());
|
throw cscript::CsErrorException(cs, args[0].get_strr());
|
||||||
});
|
});
|
||||||
|
|
||||||
gcs.new_command("pcall", "err", [](
|
gcs.new_command("pcall", "err", [](
|
||||||
|
|
|
@ -186,7 +186,7 @@ static void do_sigint(int n) {
|
||||||
signal(n, SIG_DFL);
|
signal(n, SIG_DFL);
|
||||||
scs->set_call_hook([](CsState &cs) {
|
scs->set_call_hook([](CsState &cs) {
|
||||||
cs.set_call_hook(nullptr);
|
cs.set_call_hook(nullptr);
|
||||||
cs.error("<execution interrupted>");
|
throw cscript::CsErrorException(cs, "<execution interrupted>");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue