From e41c3c03a1700e7a7ee125bf0d614e82881331c1 Mon Sep 17 00:00:00 2001 From: q66 Date: Wed, 14 Sep 2016 00:14:21 +0200 Subject: [PATCH] use exceptions to throw errors --- include/cubescript/cubescript.hh | 136 ++++++++++++++++--------------- src/cs_gen.cc | 2 +- src/cs_vm.cc | 14 ++++ src/cubescript.cc | 11 +-- tools/repl.cc | 2 +- 5 files changed, 89 insertions(+), 76 deletions(-) diff --git a/include/cubescript/cubescript.hh b/include/cubescript/cubescript.hh index 68b14e79..7b80771f 100644 --- a/include/cubescript/cubescript.hh +++ b/include/cubescript/cubescript.hh @@ -319,56 +319,7 @@ struct CsStackStateNode { 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; -using CsPanicCb = - ostd::Function; template struct CsAllocator { @@ -402,9 +353,12 @@ private: CsState &p_state; }; +struct CsErrorException; struct CsSharedState; struct OSTD_EXPORT CsState { + friend struct CsErrorException; + CsSharedState *p_state; CsIdentLink *p_callstack = nullptr; @@ -458,21 +412,6 @@ struct OSTD_EXPORT CsState { void init_libs(int libs = CsLibAll); - void error(ostd::ConstCharRange msg); - - template - void error(ostd::ConstCharRange msg, A &&...args) { - char fbuf[512]; - auto ret = ostd::format( - ostd::CharRange(fbuf, sizeof(fbuf)), msg, ostd::forward(args)... - ); - if ((ret < 0) || (ostd::Size(ret) > sizeof(fbuf))) { - error(msg); - } else { - error(ostd::CharRange(fbuf, ret)); - } - } - void clear_override(CsIdent &id); void clear_overrides(); @@ -616,6 +555,75 @@ private: 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 + 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(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 { CsStackedValue(CsIdent *id = nullptr); ~CsStackedValue(); diff --git a/src/cs_gen.cc b/src/cs_gen.cc index 56054344..dbfa675b 100644 --- a/src/cs_gen.cc +++ b/src/cs_gen.cc @@ -51,7 +51,7 @@ static void cs_error_line( p, gs.src_file, gs.src_str, fmt, ostd::CharRange(buf.data(), buf.size()) ); - gs.cs.error(rfmt, ostd::forward(args)...); + throw CsErrorException(gs.cs, rfmt, ostd::forward(args)...); } char *cs_dup_ostr(ostd::ConstCharRange s) { diff --git a/src/cs_vm.cc b/src/cs_vm.cc index 652688fe..5a28416c 100644 --- a/src/cs_vm.cc +++ b/src/cs_vm.cc @@ -101,6 +101,20 @@ CsStackState cs_save_stack(CsState &cs) { 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) { if (!code) { return; diff --git a/src/cubescript.cc b/src/cubescript.cc index 41b61960..98997c40 100644 --- a/src/cubescript.cc +++ b/src/cubescript.cc @@ -396,15 +396,6 @@ void *CsState::alloc(void *ptr, ostd::Size, ostd::Size 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) { if (!(id.get_flags() & CsIdfOverridden)) { return; @@ -1073,7 +1064,7 @@ static inline void cs_loop_conc( void cs_init_lib_base(CsState &gcs) { 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", []( diff --git a/tools/repl.cc b/tools/repl.cc index 41103e40..ab6b1194 100644 --- a/tools/repl.cc +++ b/tools/repl.cc @@ -186,7 +186,7 @@ static void do_sigint(int n) { signal(n, SIG_DFL); scs->set_call_hook([](CsState &cs) { cs.set_call_hook(nullptr); - cs.error(""); + throw cscript::CsErrorException(cs, ""); }); }