redo alias_stack for robustness (guarantee order of push/pop)

master
Daniel Kolesa 2021-03-30 20:37:50 +02:00
parent 970e37f318
commit 1def48cf76
3 changed files with 20 additions and 50 deletions

View File

@ -826,19 +826,15 @@ struct LIBCUBESCRIPT_EXPORT alias_stack {
alias_stack &operator=(alias_stack const &) = delete;
alias_stack &operator=(alias_stack &&v) = delete;
bool set_alias(ident *id);
alias *get_alias() const noexcept;
bool has_alias() const noexcept;
alias *get_alias() noexcept { return p_alias; }
alias const *get_alias() const noexcept { return p_alias; }
bool push(any_value val);
bool pop();
bool set(any_value val);
explicit operator bool() const noexcept;
private:
state &p_state;
alias *p_alias;
bool p_pushed;
};
struct LIBCUBESCRIPT_EXPORT stacked_value: any_value {

View File

@ -413,57 +413,31 @@ LIBCUBESCRIPT_EXPORT int command::get_num_args() const {
/* external API for alias stack management */
LIBCUBESCRIPT_EXPORT alias_stack::alias_stack(state &cs, ident *a):
p_state{cs}, p_pushed{false}
{
set_alias(a);
LIBCUBESCRIPT_EXPORT alias_stack::alias_stack(state &cs, ident *a) {
if (!a || !a->is_alias()) {
p_alias = nullptr;
return;
}
p_alias = static_cast<alias *>(a);
static_cast<alias_impl *>(p_alias)->push_arg(
cs.thread_pointer()->idstack.emplace_back(cs)
);
}
LIBCUBESCRIPT_EXPORT alias_stack::~alias_stack() {
pop();
static_cast<alias_impl *>(p_alias)->pop_arg();
}
LIBCUBESCRIPT_EXPORT bool alias_stack::set_alias(ident *id) {
if (!id || !id->is_alias()) {
return false;
}
p_alias = static_cast<alias *>(id);
return true;
}
LIBCUBESCRIPT_EXPORT alias *alias_stack::get_alias() const noexcept {
return p_alias;
}
LIBCUBESCRIPT_EXPORT bool alias_stack::has_alias() const noexcept {
return !!p_alias;
}
LIBCUBESCRIPT_EXPORT bool alias_stack::push(any_value val) {
LIBCUBESCRIPT_EXPORT bool alias_stack::set(any_value val) {
if (!p_alias) {
return false;
}
auto &ts = *p_state.thread_pointer();
auto &ap = *static_cast<alias_impl *>(p_alias);
if (!p_pushed) {
ap.push_arg(ts.idstack.emplace_back(p_state));
p_pushed = true;
}
ap.p_val = std::move(val);
return true;
}
LIBCUBESCRIPT_EXPORT bool alias_stack::pop() {
if (!p_pushed || !p_alias) {
return false;
}
static_cast<alias_impl *>(p_alias)->pop_arg();
p_pushed = false;
static_cast<alias_impl *>(p_alias)->p_val = std::move(val);
return true;
}
LIBCUBESCRIPT_EXPORT alias_stack::operator bool() const noexcept {
return has_alias();
return !!p_alias;
}
} /* namespace cubescript */

View File

@ -16,7 +16,7 @@ static inline void do_loop(
any_value idv{cs};
for (integer_type i = 0; i < n; ++i) {
idv.set_int(offset + i * step);
st.push(idv);
st.set(idv);
if (cond && !cs.run(cond).get_bool()) {
break;
}
@ -42,7 +42,7 @@ static inline void do_loop_conc(
any_value idv{cs};
for (integer_type i = 0; i < n; ++i) {
idv.set_int(offset + i * step);
st.push(idv);
st.set(idv);
any_value v{cs};
switch (cs.run_loop(body, v)) {
case loop_state::BREAK:
@ -163,7 +163,7 @@ void init_lib_base(state &gcs) {
return;
}
if (args[1].get_bool()) {
st.push(args[1]);
st.set(args[1]);
cs.run(args[2].get_code(), res);
}
}
@ -306,7 +306,7 @@ end:
if (st.get_alias()->get_flags() & IDENT_FLAG_ARG) {
return;
}
st.push(args[1]);
st.set(args[1]);
cs.run(args[2].get_code(), res);
}
});