hide thread_state, remove state::thread_pointer()

master
Daniel Kolesa 2021-04-05 04:10:39 +02:00
parent 59c0d16d50
commit 06b1661afd
13 changed files with 59 additions and 62 deletions

View File

@ -318,8 +318,6 @@ enum class loop_state {
NORMAL = 0, BREAK, CONTINUE NORMAL = 0, BREAK, CONTINUE
}; };
struct thread_state;
struct LIBCUBESCRIPT_EXPORT state { struct LIBCUBESCRIPT_EXPORT state {
state(); state();
state(alloc_func func, void *data); state(alloc_func func, void *data);
@ -419,15 +417,9 @@ struct LIBCUBESCRIPT_EXPORT state {
std::optional<string_ref> get_alias_val(std::string_view name); std::optional<string_ref> get_alias_val(std::string_view name);
thread_state *thread_pointer() {
return p_tstate;
}
thread_state const *thread_pointer() const {
return p_tstate;
}
private: private:
friend struct state_p;
hook_func set_call_hook(hook_func func); hook_func set_call_hook(hook_func func);
command *new_command( command *new_command(
@ -444,7 +436,7 @@ private:
void *alloc(void *ptr, size_t olds, size_t news); void *alloc(void *ptr, size_t olds, size_t news);
thread_state *p_tstate = nullptr; struct thread_state *p_tstate = nullptr;
}; };
struct LIBCUBESCRIPT_EXPORT stack_state { struct LIBCUBESCRIPT_EXPORT stack_state {
@ -455,7 +447,7 @@ struct LIBCUBESCRIPT_EXPORT stack_state {
}; };
stack_state() = delete; stack_state() = delete;
stack_state(thread_state &ts, node *nd = nullptr, bool gap = false); stack_state(state &cs, node *nd = nullptr, bool gap = false);
stack_state(stack_state const &) = delete; stack_state(stack_state const &) = delete;
stack_state(stack_state &&st); stack_state(stack_state &&st);
~stack_state(); ~stack_state();
@ -467,7 +459,7 @@ struct LIBCUBESCRIPT_EXPORT stack_state {
bool gap() const; bool gap() const;
private: private:
thread_state &p_state; state &p_state;
node *p_node; node *p_node;
bool p_gap; bool p_gap;
}; };
@ -494,31 +486,26 @@ struct LIBCUBESCRIPT_EXPORT error {
return p_stack; return p_stack;
} }
template<typename ...A> error(state &cs, std::string_view msg):
error(state &cs, std::string_view msg, A const &...args): p_errbeg{}, p_errend{}, p_stack{cs}
error{*cs.thread_pointer(), msg, args...}
{}
error(thread_state &ts, std::string_view msg):
p_errbeg{}, p_errend{}, p_stack{ts}
{ {
char *sp; char *sp;
char *buf = request_buf(ts, msg.size(), sp); char *buf = request_buf(cs, msg.size(), sp);
std::memcpy(buf, msg.data(), msg.size()); std::memcpy(buf, msg.data(), msg.size());
buf[msg.size()] = '\0'; buf[msg.size()] = '\0';
p_errbeg = sp; p_errbeg = sp;
p_errend = buf + msg.size(); p_errend = buf + msg.size();
p_stack = save_stack(ts); p_stack = save_stack(cs);
} }
template<typename ...A> template<typename ...A>
error(thread_state &ts, std::string_view msg, A const &...args): error(state &cs, std::string_view msg, A const &...args):
p_errbeg{}, p_errend{}, p_stack{ts} p_errbeg{}, p_errend{}, p_stack{cs}
{ {
std::size_t sz = msg.size() + 64; std::size_t sz = msg.size() + 64;
char *buf, *sp; char *buf, *sp;
for (;;) { for (;;) {
buf = request_buf(ts, sz, sp); buf = request_buf(cs, sz, sp);
int written = std::snprintf(buf, sz, msg.data(), args...); int written = std::snprintf(buf, sz, msg.data(), args...);
if (written <= 0) { if (written <= 0) {
throw internal_error{"format error"}; throw internal_error{"format error"};
@ -529,12 +516,12 @@ struct LIBCUBESCRIPT_EXPORT error {
} }
p_errbeg = sp; p_errbeg = sp;
p_errend = buf + sz; p_errend = buf + sz;
p_stack = save_stack(ts); p_stack = save_stack(cs);
} }
private: private:
stack_state save_stack(thread_state &ts); stack_state save_stack(state &cs);
char *request_buf(thread_state &ts, std::size_t bufs, char *&sp); char *request_buf(state &cs, std::size_t bufs, char *&sp);
char const *p_errbeg, *p_errend; char const *p_errbeg, *p_errend;
stack_state p_stack; stack_state p_stack;

View File

@ -8,9 +8,9 @@
namespace cubescript { namespace cubescript {
LIBCUBESCRIPT_EXPORT stack_state::stack_state( LIBCUBESCRIPT_EXPORT stack_state::stack_state(
thread_state &ts, node *nd, bool gap state &cs, node *nd, bool gap
): ):
p_state{ts}, p_node{nd}, p_gap{gap} p_state{cs}, p_node{nd}, p_gap{gap}
{} {}
LIBCUBESCRIPT_EXPORT stack_state::stack_state(stack_state &&st): LIBCUBESCRIPT_EXPORT stack_state::stack_state(stack_state &&st):
@ -25,7 +25,7 @@ LIBCUBESCRIPT_EXPORT stack_state::~stack_state() {
for (node const *nd = p_node; nd; nd = nd->next) { for (node const *nd = p_node; nd; nd = nd->next) {
++len; ++len;
} }
p_state.istate->destroy_array(p_node, len); state_p{p_state}.ts().istate->destroy_array(p_node, len);
} }
LIBCUBESCRIPT_EXPORT stack_state &stack_state::operator=(stack_state &&st) { LIBCUBESCRIPT_EXPORT stack_state &stack_state::operator=(stack_state &&st) {
@ -45,8 +45,9 @@ LIBCUBESCRIPT_EXPORT bool stack_state::gap() const {
} }
LIBCUBESCRIPT_EXPORT char *error::request_buf( LIBCUBESCRIPT_EXPORT char *error::request_buf(
thread_state &ts, std::size_t bufs, char *&sp state &cs, std::size_t bufs, char *&sp
) { ) {
auto &ts = state_p{cs}.ts();
charbuf &cb = ts.errbuf; charbuf &cb = ts.errbuf;
codegen_state *gs = ts.cstate; codegen_state *gs = ts.cstate;
cb.clear(); cb.clear();
@ -83,20 +84,21 @@ LIBCUBESCRIPT_EXPORT char *error::request_buf(
return &cb[sz]; return &cb[sz];
} }
LIBCUBESCRIPT_EXPORT stack_state error::save_stack(thread_state &ts) { LIBCUBESCRIPT_EXPORT stack_state error::save_stack(state &cs) {
auto &ts = state_p{cs}.ts();
integer_var *dalias = ts.istate->ivar_dbgalias; integer_var *dalias = ts.istate->ivar_dbgalias;
auto dval = std::clamp( auto dval = std::clamp(
dalias->get_value(), integer_type(0), integer_type(1000) dalias->get_value(), integer_type(0), integer_type(1000)
); );
if (!dval) { if (!dval) {
return stack_state{ts, nullptr, !!ts.callstack}; return stack_state{cs, nullptr, !!ts.callstack};
} }
int total = 0, depth = 0; int total = 0, depth = 0;
for (ident_link *l = ts.callstack; l; l = l->next) { for (ident_link *l = ts.callstack; l; l = l->next) {
total++; total++;
} }
if (!total) { if (!total) {
return stack_state{ts, nullptr, false}; return stack_state{cs, nullptr, false};
} }
stack_state::node *st = ts.istate->create_array<stack_state::node>( stack_state::node *st = ts.istate->create_array<stack_state::node>(
std::min(total, dval) std::min(total, dval)
@ -120,7 +122,7 @@ LIBCUBESCRIPT_EXPORT stack_state error::save_stack(thread_state &ts) {
nd->next = nullptr; nd->next = nullptr;
} }
} }
return stack_state{ts, ret, total > dval}; return stack_state{cs, ret, total > dval};
} }
} /* namespace cubescript */ } /* namespace cubescript */

View File

@ -69,7 +69,7 @@ void codegen_state::skip_comments() {
if (current() == '\\') { if (current() == '\\') {
char c = current(1); char c = current(1);
if ((c != '\r') && (c != '\n')) { if ((c != '\r') && (c != '\n')) {
throw error{ts, "invalid line break"}; throw error{*ts.pstate, "invalid line break"};
} }
/* skip backslash */ /* skip backslash */
next_char(); next_char();
@ -551,7 +551,7 @@ static void compileblockmain(codegen_state &gs, int wordtype) {
for (int brak = 1; brak;) { for (int brak = 1; brak;) {
switch (gs.skip_until("@\"/[]")) { switch (gs.skip_until("@\"/[]")) {
case '\0': case '\0':
throw error{gs.ts, "missing \"]\""}; throw error{*gs.ts.pstate, "missing \"]\""};
return; return;
case '\"': case '\"':
gs.get_str(); gs.get_str();
@ -580,7 +580,7 @@ static void compileblockmain(codegen_state &gs, int wordtype) {
if (brak > level) { if (brak > level) {
continue; continue;
} else if (brak < level) { } else if (brak < level) {
throw error{gs.ts, "too many @s"}; throw error{*gs.ts.pstate, "too many @s"};
return; return;
} }
if (compileblockstr(gs, start, esc)) { if (compileblockstr(gs, start, esc)) {
@ -1362,7 +1362,7 @@ endstatement:
switch (gs.skip_until(")];/\n")) { switch (gs.skip_until(")];/\n")) {
case '\0': case '\0':
if (gs.current() != brak) { if (gs.current() != brak) {
throw error{gs.ts, "missing \"%c\"", char(brak)}; throw error{*gs.ts.pstate, "missing \"%c\"", char(brak)};
return; return;
} }
return; return;
@ -1372,7 +1372,7 @@ endstatement:
gs.next_char(); gs.next_char();
return; return;
} }
throw error{gs.ts, "unexpected \"%c\"", gs.current()}; throw error{*gs.ts.pstate, "unexpected \"%c\"", gs.current()};
return; return;
case '/': case '/':
gs.next_char(); gs.next_char();

View File

@ -302,7 +302,7 @@ LIBCUBESCRIPT_EXPORT bool ident::is_overridden(state &cs) const {
case ident_type::SVAR: case ident_type::SVAR:
return (p_impl->p_flags & IDENT_FLAG_OVERRIDDEN); return (p_impl->p_flags & IDENT_FLAG_OVERRIDDEN);
case ident_type::ALIAS: case ident_type::ALIAS:
return (cs.thread_pointer()->get_astack( return (state_p{cs}.ts().get_astack(
static_cast<alias const *>(this) static_cast<alias const *>(this)
).flags & IDENT_FLAG_OVERRIDDEN); ).flags & IDENT_FLAG_OVERRIDDEN);
default: default:
@ -318,7 +318,7 @@ LIBCUBESCRIPT_EXPORT bool ident::is_persistent(state &cs) const {
case ident_type::SVAR: case ident_type::SVAR:
return (p_impl->p_flags & IDENT_FLAG_PERSIST); return (p_impl->p_flags & IDENT_FLAG_PERSIST);
case ident_type::ALIAS: case ident_type::ALIAS:
return (cs.thread_pointer()->get_astack( return (state_p{cs}.ts().get_astack(
static_cast<alias const *>(this) static_cast<alias const *>(this)
).flags & IDENT_FLAG_PERSIST); ).flags & IDENT_FLAG_PERSIST);
default: default:
@ -346,7 +346,7 @@ LIBCUBESCRIPT_EXPORT var_type global_var::get_variable_type() const {
} }
LIBCUBESCRIPT_EXPORT void global_var::save(state &cs) { LIBCUBESCRIPT_EXPORT void global_var::save(state &cs) {
auto &ts = *cs.thread_pointer(); auto &ts = state_p{cs}.ts();
if ((ts.ident_flags & IDENT_FLAG_OVERRIDDEN) || is_overridable()) { if ((ts.ident_flags & IDENT_FLAG_OVERRIDDEN) || is_overridable()) {
if (p_impl->p_flags & IDENT_FLAG_PERSIST) { if (p_impl->p_flags & IDENT_FLAG_PERSIST) {
throw error{ throw error{
@ -380,7 +380,7 @@ LIBCUBESCRIPT_EXPORT void integer_var::set_value(
save(cs); save(cs);
set_raw_value(val); set_raw_value(val);
if (trigger) { if (trigger) {
var_changed(*cs.thread_pointer(), this); var_changed(state_p{cs}.ts(), this);
} }
} }
@ -406,7 +406,7 @@ LIBCUBESCRIPT_EXPORT void float_var::set_value(
save(cs); save(cs);
set_raw_value(val); set_raw_value(val);
if (trigger) { if (trigger) {
var_changed(*cs.thread_pointer(), this); var_changed(state_p{cs}.ts(), this);
} }
} }
@ -432,7 +432,7 @@ LIBCUBESCRIPT_EXPORT void string_var::set_value(
save(cs); save(cs);
set_raw_value(std::move(val)); set_raw_value(std::move(val));
if (trigger) { if (trigger) {
var_changed(*cs.thread_pointer(), this); var_changed(state_p{cs}.ts(), this);
} }
} }
@ -459,7 +459,7 @@ LIBCUBESCRIPT_EXPORT alias_local::alias_local(state &cs, ident *a) {
p_alias = nullptr; p_alias = nullptr;
return; return;
} }
auto &ts = *cs.thread_pointer(); auto &ts = state_p{cs}.ts();
p_alias = static_cast<alias *>(a); p_alias = static_cast<alias *>(a);
auto &ast = ts.get_astack(p_alias); auto &ast = ts.get_astack(p_alias);
ast.push(ts.idstack.emplace_back(cs)); ast.push(ts.idstack.emplace_back(cs));

View File

@ -180,7 +180,7 @@ state::state(alloc_func func, void *data) {
static_cast<command_impl *>(p)->p_type = ID_DO; static_cast<command_impl *>(p)->p_type = ID_DO;
p = new_command("doargs", "e", [](auto &cs, auto args, auto &res) { p = new_command("doargs", "e", [](auto &cs, auto args, auto &res) {
call_with_args(*cs.thread_pointer(), [&cs, &res, &args]() { call_with_args(*cs.p_tstate, [&cs, &res, &args]() {
cs.run(args[0].get_code(), res); cs.run(args[0].get_code(), res);
}); });
}); });
@ -243,7 +243,7 @@ state::state(alloc_func func, void *data) {
static_cast<command_impl *>(p)->p_type = ID_LOCAL; static_cast<command_impl *>(p)->p_type = ID_LOCAL;
p = new_command("break", "", [](auto &cs, auto, auto &) { p = new_command("break", "", [](auto &cs, auto, auto &) {
if (cs.thread_pointer()->loop_level) { if (cs.p_tstate->loop_level) {
throw break_exception{}; throw break_exception{};
} else { } else {
throw error{cs, "no loop to break"}; throw error{cs, "no loop to break"};
@ -252,7 +252,7 @@ state::state(alloc_func func, void *data) {
static_cast<command_impl *>(p)->p_type = ID_BREAK; static_cast<command_impl *>(p)->p_type = ID_BREAK;
p = new_command("continue", "", [](auto &cs, auto, auto &) { p = new_command("continue", "", [](auto &cs, auto, auto &) {
if (cs.thread_pointer()->loop_level) { if (cs.p_tstate->loop_level) {
throw continue_exception{}; throw continue_exception{};
} else { } else {
throw error{cs, "no loop to continue"}; throw error{cs, "no loop to continue"};

View File

@ -103,6 +103,14 @@ struct internal_state {
} }
}; };
struct state_p {
state_p(state &cs): csp{&cs} {}
thread_state &ts() { return *csp->p_tstate; }
state *csp;
};
template<typename T> template<typename T>
inline std_allocator<T>::std_allocator(internal_state *s): istate{s} {} inline std_allocator<T>::std_allocator(internal_state *s): istate{s} {}

View File

@ -4,7 +4,7 @@
namespace cubescript { namespace cubescript {
charbuf::charbuf(state &cs): charbuf{cs.thread_pointer()->istate} {} charbuf::charbuf(state &cs): charbuf{state_p{cs}.ts().istate} {}
charbuf::charbuf(thread_state &ts): charbuf{ts.istate} {} charbuf::charbuf(thread_state &ts): charbuf{ts.istate} {}
} /* namespace cubescript */ } /* namespace cubescript */

View File

@ -121,7 +121,7 @@ LIBCUBESCRIPT_EXPORT string_ref::string_ref(
} }
LIBCUBESCRIPT_EXPORT string_ref::string_ref(state &cs, std::string_view str): LIBCUBESCRIPT_EXPORT string_ref::string_ref(state &cs, std::string_view str):
p_state{cs.thread_pointer()->istate} p_state{state_p{cs}.ts().istate}
{ {
p_str = p_state->strman->add(str); p_str = p_state->strman->add(str);
} }

View File

@ -84,7 +84,7 @@ static inline void csv_cleanup(value_type tv, T *stor) {
} }
} }
any_value::any_value(state &st): any_value(*st.thread_pointer()->istate) {} any_value::any_value(state &st): any_value(*state_p{st}.ts().istate) {}
any_value::any_value(internal_state &st): any_value::any_value(internal_state &st):
p_stor(), p_type(value_type::NONE) p_stor(), p_type(value_type::NONE)
@ -258,11 +258,11 @@ bcode_ref any_value::force_code(state &cs) {
default: default:
break; break;
} }
codegen_state gs{*cs.thread_pointer()}; codegen_state gs{state_p{cs}.ts()};
gs.code.reserve(64); gs.code.reserve(64);
gs.gen_main(get_str()); gs.gen_main(get_str());
gs.done(); gs.done();
uint32_t *cbuf = bcode_alloc(cs.thread_pointer()->istate, gs.code.size()); uint32_t *cbuf = bcode_alloc(state_p{cs}.ts().istate, gs.code.size());
std::memcpy(cbuf, gs.code.data(), gs.code.size() * sizeof(std::uint32_t)); std::memcpy(cbuf, gs.code.data(), gs.code.size() * sizeof(std::uint32_t));
auto *bc = reinterpret_cast<bcode *>(cbuf + 1); auto *bc = reinterpret_cast<bcode *>(cbuf + 1);
set_code(bc); set_code(bc);
@ -276,7 +276,7 @@ ident *any_value::force_ident(state &cs) {
default: default:
break; break;
} }
auto *id = cs.thread_pointer()->istate->new_ident( auto *id = state_p{cs}.ts().istate->new_ident(
cs, get_str(), IDENT_FLAG_UNKNOWN cs, get_str(), IDENT_FLAG_UNKNOWN
); );
set_ident(id); set_ident(id);

View File

@ -281,7 +281,7 @@ bool exec_alias(
run_depth_guard::run_depth_guard(thread_state &ts): tsp(&ts) { run_depth_guard::run_depth_guard(thread_state &ts): tsp(&ts) {
if (ts.max_run_depth && (ts.run_depth >= ts.max_run_depth)) { if (ts.max_run_depth && (ts.run_depth >= ts.max_run_depth)) {
throw error{ts, "exceeded recursion limit"}; throw error{*ts.pstate, "exceeded recursion limit"};
} }
++ts.run_depth; ++ts.run_depth;
} }

View File

@ -91,7 +91,7 @@ void init_lib_base(state &gcs) {
rc = false; rc = false;
} }
ret.set_int(rc); ret.set_int(rc);
auto &ts = *cs.thread_pointer(); auto &ts = state_p{cs}.ts();
ts.get_astack(cret).set_alias(cret, ts, result); ts.get_astack(cret).set_alias(cret, ts, result);
ts.get_astack(css).set_alias(css, ts, tback); ts.get_astack(css).set_alias(css, ts, tback);
}); });

View File

@ -544,7 +544,7 @@ static void list_sort(
return; return;
} }
valbuf<ListSortItem> items{cs.thread_pointer()->istate}; valbuf<ListSortItem> items{state_p{cs}.ts().istate};
size_t total = 0; size_t total = 0;
for (list_parser p{cs, list}; p.parse();) { for (list_parser p{cs, list}; p.parse();) {

View File

@ -60,7 +60,7 @@ void init_lib_string(state &cs) {
cs.new_command("strlower", "s", [](auto &ccs, auto args, auto &res) { cs.new_command("strlower", "s", [](auto &ccs, auto args, auto &res) {
auto inps = std::string_view{args[0].get_str()}; auto inps = std::string_view{args[0].get_str()};
auto *ics = ccs.thread_pointer()->istate; auto *ics = state_p{ccs}.ts().istate;
auto *buf = ics->strman->alloc_buf(inps.size()); auto *buf = ics->strman->alloc_buf(inps.size());
for (std::size_t i = 0; i < inps.size(); ++i) { for (std::size_t i = 0; i < inps.size(); ++i) {
buf[i] = char(tolower(inps[i])); buf[i] = char(tolower(inps[i]));
@ -70,7 +70,7 @@ void init_lib_string(state &cs) {
cs.new_command("strupper", "s", [](auto &ccs, auto args, auto &res) { cs.new_command("strupper", "s", [](auto &ccs, auto args, auto &res) {
auto inps = std::string_view{args[0].get_str()}; auto inps = std::string_view{args[0].get_str()};
auto *ics = ccs.thread_pointer()->istate; auto *ics = state_p{ccs}.ts().istate;
auto *buf = ics->strman->alloc_buf(inps.size()); auto *buf = ics->strman->alloc_buf(inps.size());
for (std::size_t i = 0; i < inps.size(); ++i) { for (std::size_t i = 0; i < inps.size(); ++i) {
buf[i] = char(toupper(inps[i])); buf[i] = char(toupper(inps[i]));