throwing errors now does not allocate (besides the stack)

master
Daniel Kolesa 2016-09-12 21:46:36 +02:00
parent ce62593840
commit f97f896017
4 changed files with 28 additions and 16 deletions

View File

@ -424,7 +424,7 @@ struct OSTD_EXPORT CsState {
template<typename F> template<typename F>
bool pcall( bool pcall(
F func, ostd::String *error = nullptr, F func, ostd::ConstCharRange *error = nullptr,
CsStackState *stack = nullptr CsStackState *stack = nullptr
) { ) {
return ipcall([](void *data) { return ipcall([](void *data) {
@ -436,9 +436,15 @@ struct OSTD_EXPORT CsState {
template<typename ...A> template<typename ...A>
void error(ostd::ConstCharRange msg, A &&...args) { void error(ostd::ConstCharRange msg, A &&...args) {
auto app = ostd::appender<CsString>(); char fbuf[512];
ostd::format(app, msg, ostd::forward<A>(args)...); auto ret = ostd::format(
error(app.get()); 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);
@ -579,10 +585,11 @@ struct OSTD_EXPORT CsState {
private: private:
CsIdent *add_ident(CsIdent *id); CsIdent *add_ident(CsIdent *id);
bool ipcall( bool ipcall(
void (*f)(void *data), ostd::String *error, void (*f)(void *data), ostd::ConstCharRange *error,
CsStackState *stack, void *data CsStackState *stack, void *data
); );
char p_errbuf[512];
CsHookCb p_callhook; CsHookCb p_callhook;
CsPanicCb p_panicfunc; CsPanicCb p_panicfunc;
CsStream *p_out, *p_err; CsStream *p_out, *p_err;

View File

@ -99,15 +99,15 @@ constexpr ostd::Size CsTypeStorageSize =
(sizeof(T) - 1) / sizeof(ostd::Uint32) + 1; (sizeof(T) - 1) / sizeof(ostd::Uint32) + 1;
struct CsErrorException { struct CsErrorException {
CsString errmsg; ostd::ConstCharRange errmsg;
CsStackState stack; CsStackState stack;
CsErrorException() = delete; CsErrorException() = delete;
CsErrorException(CsErrorException const &) = delete; CsErrorException(CsErrorException const &) = delete;
CsErrorException(CsErrorException &&v): CsErrorException(CsErrorException &&v):
errmsg(ostd::move(v.errmsg)), stack(ostd::move(v.stack)) errmsg(v.errmsg), stack(ostd::move(v.stack))
{} {}
CsErrorException(CsString &&v, CsStackState &&st): CsErrorException(ostd::ConstCharRange v, CsStackState &&st):
errmsg(ostd::move(v)), stack(ostd::move(st)) errmsg(v), stack(ostd::move(st))
{} {}
}; };

View File

@ -430,7 +430,7 @@ CsPanicCb &CsState::get_panic_func() {
} }
bool CsState::ipcall( bool CsState::ipcall(
void (*f)(void *data), ostd::String *error, void (*f)(void *data), ostd::ConstCharRange *error,
CsStackState *stack, void *data CsStackState *stack, void *data
) { ) {
++protect; ++protect;
@ -439,7 +439,7 @@ bool CsState::ipcall(
} catch (CsErrorException &v) { } catch (CsErrorException &v) {
--protect; --protect;
if (error) { if (error) {
*error = ostd::move(v.errmsg); *error = v.errmsg;
} }
if (stack) { if (stack) {
*stack = ostd::move(v.stack); *stack = ostd::move(v.stack);
@ -454,11 +454,16 @@ bool CsState::ipcall(
} }
void CsState::error(ostd::ConstCharRange msg) { 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());
if (protect) { if (protect) {
throw CsErrorException(msg, cs_save_stack(*this)); throw CsErrorException(err, cs_save_stack(*this));
} else { } else {
if (p_panicfunc) { if (p_panicfunc) {
p_panicfunc(*this, msg, cs_save_stack(*this)); p_panicfunc(*this, err, cs_save_stack(*this));
} }
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
@ -1140,7 +1145,7 @@ void cs_init_lib_base(CsState &gcs) {
ret.set_int(0); ret.set_int(0);
return; return;
} }
CsString errmsg; ostd::ConstCharRange errmsg;
CsValue result, tback; CsValue result, tback;
CsStackState stack; CsStackState stack;
bool rc = cs.pcall([&cs, &args, &result]() { bool rc = cs.pcall([&cs, &args, &result]() {
@ -1148,7 +1153,7 @@ void cs_init_lib_base(CsState &gcs) {
}, &errmsg, &stack); }, &errmsg, &stack);
ret.set_int(rc); ret.set_int(rc);
if (!rc) { if (!rc) {
result.set_str(ostd::move(errmsg)); result.set_str(errmsg);
if (stack.get()) { if (stack.get()) {
auto app = ostd::appender<CsString>(); auto app = ostd::appender<CsString>();
cscript::util::print_stack(app, stack); cscript::util::print_stack(app, stack);

View File

@ -194,7 +194,7 @@ static bool do_call(CsState &cs, ostd::ConstCharRange line, bool file = false) {
CsValue ret; CsValue ret;
scs = &cs; scs = &cs;
signal(SIGINT, do_sigint); signal(SIGINT, do_sigint);
ostd::String err; ostd::ConstCharRange err;
cscript::CsStackState st; cscript::CsStackState st;
auto tocall = [&]() { auto tocall = [&]() {
if (file) { if (file) {