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

View File

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

View File

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