do not access parser state from error

master
Daniel Kolesa 2021-04-10 03:50:05 +02:00
parent 83aa8bfd07
commit 416c6ba8fb
4 changed files with 23 additions and 27 deletions

View File

@ -2,7 +2,6 @@
#include <algorithm> #include <algorithm>
#include "cs_parser.hh"
#include "cs_thread.hh" #include "cs_thread.hh"
namespace cubescript { namespace cubescript {
@ -49,26 +48,25 @@ LIBCUBESCRIPT_EXPORT char *error::request_buf(
) { ) {
auto &ts = state_p{cs}.ts(); auto &ts = state_p{cs}.ts();
charbuf &cb = ts.errbuf; charbuf &cb = ts.errbuf;
parser_state *gs = ts.cstate;
cb.clear(); cb.clear();
std::size_t sz = 0; std::size_t sz = 0;
if (gs) { if (ts.current_line) {
/* we can attach line number */ /* we can attach line number */
sz = gs->src_name.size() + 32; sz = ts.source.size() + 32;
for (;;) { for (;;) {
/* we are using so the buffer tracks the elements and therefore /* we are using so the buffer tracks the elements and therefore
* does not wipe them when we attempt to reserve more capacity * does not wipe them when we attempt to reserve more capacity
*/ */
cb.resize(sz); cb.resize(sz);
int nsz; int nsz;
if (!gs->src_name.empty()) { if (!ts.source.empty()) {
nsz = std::snprintf( nsz = std::snprintf(
cb.data(), sz, "%.*s:%zu: ", cb.data(), sz, "%.*s:%zu: ",
int(gs->src_name.size()), gs->src_name.data(), int(ts.source.size()), ts.source.data(),
gs->current_line *ts.current_line
); );
} else { } else {
nsz = std::snprintf(cb.data(), sz, "%zu: ", gs->current_line); nsz = std::snprintf(cb.data(), sz, "%zu: ", *ts.current_line);
} }
if (nsz <= 0) { if (nsz <= 0) {
throw internal_error{"format error"}; throw internal_error{"format error"};

View File

@ -431,10 +431,17 @@ void gen_state::gen_main(std::string_view v, std::string_view src) {
parser_state ps{ts, *this}; parser_state ps{ts, *this};
ps.source = v.data(); ps.source = v.data();
ps.send = v.data() + v.size(); ps.send = v.data() + v.size();
ps.src_name = src; auto psrc = ts.source;
code.push_back(BC_INST_START); ts.source = src;
ps.parse_block(VAL_ANY); try {
code.push_back(BC_INST_EXIT); code.push_back(BC_INST_START);
ps.parse_block(VAL_ANY);
code.push_back(BC_INST_EXIT);
} catch (...) {
ts.source = psrc;
throw;
}
ts.source = psrc;
} }
void gen_state::gen_main_null() { void gen_state::gen_main_null() {

View File

@ -23,26 +23,18 @@ bool is_valid_name(std::string_view input);
struct parser_state { struct parser_state {
thread_state &ts; thread_state &ts;
gen_state &gs; gen_state &gs;
parser_state *prevps;
bool parsing = true;
char const *source, *send; char const *source, *send;
std::size_t current_line; std::size_t current_line;
std::string_view src_name;
parser_state() = delete; parser_state() = delete;
parser_state(thread_state &tsr, gen_state &gsr): parser_state(thread_state &tsr, gen_state &gsr):
ts{tsr}, gs{gsr}, prevps{tsr.cstate}, ts{tsr}, gs{gsr}, source{}, send{}, current_line{1}
source{}, send{}, current_line{1}, src_name{}
{ {
tsr.cstate = this; ts.current_line = &current_line;
} }
~parser_state() { ~parser_state() {
if (!parsing) { ts.current_line = nullptr;
return;
}
ts.cstate = prevps;
parsing = false;
} }
std::string_view get_str(); std::string_view get_str();

View File

@ -11,8 +11,6 @@
namespace cubescript { namespace cubescript {
struct parser_state;
struct thread_state { struct thread_state {
using astack_allocator = std_allocator<std::pair<int const, alias_stack>>; using astack_allocator = std_allocator<std::pair<int const, alias_stack>>;
/* thread call stack */ /* thread call stack */
@ -21,8 +19,6 @@ struct thread_state {
internal_state *istate{}; internal_state *istate{};
/* the public state interface */ /* the public state interface */
state *pstate{}; state *pstate{};
/* current codegen state for diagnostics */
parser_state *cstate{};
/* VM stack */ /* VM stack */
valbuf<any_value> vmstack; valbuf<any_value> vmstack;
/* ident stack */ /* ident stack */
@ -45,6 +41,9 @@ struct thread_state {
std::size_t run_depth = 0; std::size_t run_depth = 0;
/* loop nesting level */ /* loop nesting level */
std::size_t loop_level = 0; std::size_t loop_level = 0;
/* debug info */
std::string_view source{};
std::size_t *current_line = nullptr;
thread_state(internal_state *cs); thread_state(internal_state *cs);