prepare codebase for per-thread alias stack

master
Daniel Kolesa 2021-04-02 05:47:49 +02:00
parent e8856f8f9d
commit 881ba4bce9
9 changed files with 150 additions and 147 deletions

View File

@ -640,6 +640,7 @@ struct LIBCUBESCRIPT_EXPORT alias_local {
private: private:
alias *p_alias; alias *p_alias;
void *p_sp;
}; };
struct LIBCUBESCRIPT_EXPORT list_parser { struct LIBCUBESCRIPT_EXPORT list_parser {

View File

@ -114,56 +114,6 @@ alias_impl::alias_impl(state &cs, string_ref name, any_value v, int fl):
p_initial.val_s = v; p_initial.val_s = v;
} }
void alias_impl::push_arg(ident_stack &st) {
st.next = p_astack;
p_astack = &st;
}
void alias_impl::pop_arg() {
if (p_astack == &p_initial) {
return;
}
p_astack = p_astack->next;
}
void alias_impl::undo_arg(ident_stack &st) {
st.next = p_astack;
p_astack = p_astack->next;
}
void alias_impl::redo_arg(ident_stack &st) {
p_astack = st.next;
}
void alias_impl::set_arg(thread_state &ts, any_value &v) {
if (ident_is_used_arg(this, ts)) {
p_astack->code = bcode_ref{};
} else {
push_arg(ts.idstack.emplace_back(*ts.pstate));
ts.callstack->usedargs[get_index()] = true;
}
p_astack->val_s = std::move(v);
}
void alias_impl::set_alias(thread_state &ts, any_value &v) {
p_astack->val_s = std::move(v);
p_astack->code = bcode_ref{};
p_flags = (p_flags & ts.pstate->identflags) | ts.pstate->identflags;
}
bcode_ref const &alias_impl::compile_code(thread_state &ts) {
if (!p_astack->code) {
codegen_state gs(ts);
gs.code.reserve(64);
gs.gen_main(p_astack->val_s.get_str());
/* i wish i could steal the memory somehow */
uint32_t *code = bcode_alloc(ts.istate, gs.code.size());
memcpy(code, gs.code.data(), gs.code.size() * sizeof(uint32_t));
p_astack->code = bcode_ref{reinterpret_cast<bcode *>(code + 1)};
}
return p_astack->code;
}
command_impl::command_impl( command_impl::command_impl(
string_ref name, string_ref args, int nargs, command_func f string_ref name, string_ref args, int nargs, command_func f
): ):
@ -190,6 +140,25 @@ bool ident_is_used_arg(ident *id, thread_state &ts) {
return ts.callstack->usedargs[id->get_index()]; return ts.callstack->usedargs[id->get_index()];
} }
void alias_stack::set_arg(alias *a, thread_state &ts, any_value &v) {
if (ident_is_used_arg(a, ts)) {
node->code = bcode_ref{};
} else {
auto &st = ts.idstack.emplace_back(*ts.pstate);
st.next = node;
node = &st;
ts.callstack->usedargs[a->get_index()] = true;
}
node->val_s = std::move(v);
}
void alias_stack::set_alias(alias *a, thread_state &ts, any_value &v) {
node->val_s = std::move(v);
node->code = bcode_ref{};
auto *ai = static_cast<alias_impl *>(a);
ai->p_flags = (ai->p_flags & ts.pstate->identflags) | ts.pstate->identflags;
}
/* public interface */ /* public interface */
LIBCUBESCRIPT_EXPORT int ident::get_raw_type() const { LIBCUBESCRIPT_EXPORT int ident::get_raw_type() const {
@ -390,23 +359,28 @@ LIBCUBESCRIPT_EXPORT alias_local::alias_local(state &cs, ident *a) {
p_alias = nullptr; p_alias = nullptr;
return; return;
} }
auto *aimp = static_cast<alias_impl *>(p_alias); auto &ts = *cs.thread_pointer();
p_alias = aimp; p_alias = static_cast<alias *>(a);
aimp->push_arg( auto &ast = ts.get_astack(p_alias);
cs.thread_pointer()->idstack.emplace_back(cs) auto &st = ts.idstack.emplace_back(cs);
); st.next = ast.node;
aimp->p_flags &= ~IDENT_FLAG_UNKNOWN; ast.node = &st;
p_sp = &ast;
static_cast<alias_impl *>(p_alias)->p_flags &= ~IDENT_FLAG_UNKNOWN;
} }
LIBCUBESCRIPT_EXPORT alias_local::~alias_local() { LIBCUBESCRIPT_EXPORT alias_local::~alias_local() {
static_cast<alias_impl *>(p_alias)->pop_arg(); if (p_alias) {
auto &st = *static_cast<alias_stack *>(p_sp);
st.node = st.node->next;
}
} }
LIBCUBESCRIPT_EXPORT bool alias_local::set(any_value val) { LIBCUBESCRIPT_EXPORT bool alias_local::set(any_value val) {
if (!p_alias) { if (!p_alias) {
return false; return false;
} }
static_cast<alias_impl *>(p_alias)->p_astack->val_s = std::move(val); static_cast<alias_stack *>(p_sp)->node->val_s = std::move(val);
return true; return true;
} }

View File

@ -23,6 +23,13 @@ struct ident_stack {
ident_stack(state &cs): val_s{cs}, code{}, next{nullptr} {} ident_stack(state &cs): val_s{cs}, code{}, next{nullptr} {}
}; };
struct alias_stack {
ident_stack *node;
void set_arg(alias *a, thread_state &ts, any_value &v);
void set_alias(alias *a, thread_state &ts, any_value &v);
};
struct ident_link { struct ident_link {
ident *id; ident *id;
ident_link *next; ident_link *next;
@ -96,17 +103,8 @@ struct alias_impl: ident_impl, alias {
alias_impl(state &cs, string_ref n, int flags); alias_impl(state &cs, string_ref n, int flags);
alias_impl(state &cs, string_ref n, any_value v, int flags); alias_impl(state &cs, string_ref n, any_value v, int flags);
void push_arg(ident_stack &st);
void pop_arg();
void undo_arg(ident_stack &st);
void redo_arg(ident_stack &st);
void set_arg(thread_state &ts, any_value &v);
void set_alias(thread_state &ts, any_value &v);
bcode_ref const &compile_code(thread_state &ts);
ident_stack p_initial; ident_stack p_initial;
ident_stack *p_astack; alias_stack p_astack;
}; };
struct command_impl: ident_impl, command { struct command_impl: ident_impl, command {

View File

@ -365,11 +365,12 @@ LIBCUBESCRIPT_EXPORT void state::set_alias(
if (id) { if (id) {
switch (id->get_type()) { switch (id->get_type()) {
case ident_type::ALIAS: { case ident_type::ALIAS: {
alias_impl *a = static_cast<alias_impl *>(id); alias *a = static_cast<alias *>(id);
auto &ast = p_tstate->get_astack(a);
if (a->get_flags() & IDENT_FLAG_ARG) { if (a->get_flags() & IDENT_FLAG_ARG) {
a->set_arg(*p_tstate, v); ast.set_arg(a, *p_tstate, v);
} else { } else {
a->set_alias(*p_tstate, v); ast.set_alias(a, *p_tstate, v);
} }
return; return;
} }
@ -459,9 +460,9 @@ LIBCUBESCRIPT_EXPORT void state::clear_override(ident &id) {
} }
switch (id.get_type()) { switch (id.get_type()) {
case ident_type::ALIAS: { case ident_type::ALIAS: {
alias_impl &a = static_cast<alias_impl &>(id); auto &ast = p_tstate->get_astack(static_cast<alias *>(&id));
a.p_astack->val_s.set_str(""); ast.node->val_s.set_str("");
a.p_astack->code = bcode_ref{}; ast.node->code = bcode_ref{};
break; break;
} }
case ident_type::IVAR: { case ident_type::IVAR: {
@ -650,7 +651,7 @@ state::get_alias_val(std::string_view name) {
if ((a->get_flags() & IDENT_FLAG_ARG) && !ident_is_used_arg(a, *p_tstate)) { if ((a->get_flags() & IDENT_FLAG_ARG) && !ident_is_used_arg(a, *p_tstate)) {
return std::nullopt; return std::nullopt;
} }
return static_cast<alias_impl *>(a)->p_astack->val_s.get_str(); return p_tstate->get_astack(a).node->val_s.get_str();
} }
integer_type clamp_var(state &cs, integer_var *iv, integer_type v) { integer_type clamp_var(state &cs, integer_var *iv, integer_type v) {
@ -871,14 +872,9 @@ LIBCUBESCRIPT_EXPORT void state::run(
) { ) {
break; break;
} }
if (
static_cast<alias_impl *>(a)->p_astack->val_s.get_type() ==
value_type::NONE
) {
break;
}
exec_alias( exec_alias(
*p_tstate, a, &args[0], ret, nargs, nargs, 0, 0, BC_RET_NULL *p_tstate, a, &args[0], ret, nargs, nargs, 0, 0,
BC_RET_NULL, true
); );
break; break;
} }

View File

@ -17,4 +17,8 @@ hook_func thread_state::set_hook(hook_func f) {
return hk; return hk;
} }
alias_stack &thread_state::get_astack(alias *a) {
return static_cast<alias_impl *>(a)->p_astack;
}
} /* namespace cubescript */ } /* namespace cubescript */

View File

@ -41,6 +41,8 @@ struct thread_state {
hook_func &get_hook() { return call_hook; } hook_func &get_hook() { return call_hook; }
hook_func const &get_hook() const { return call_hook; } hook_func const &get_hook() const { return call_hook; }
alias_stack &get_astack(alias *a);
}; };
} /* namespace cubescript */ } /* namespace cubescript */

View File

@ -9,17 +9,21 @@
namespace cubescript { namespace cubescript {
static inline void push_alias(ident *id, ident_stack &st) { static inline void push_alias(thread_state &ts, ident *id, ident_stack &st) {
if (id->is_alias() && !(id->get_flags() & IDENT_FLAG_ARG)) { if (id->is_alias() && !(id->get_flags() & IDENT_FLAG_ARG)) {
auto *aimp = static_cast<alias_impl *>(id); auto *aimp = static_cast<alias_impl *>(id);
aimp->push_arg(st); auto &ast = ts.get_astack(aimp);
st.next = ast.node;
ast.node = &st;
aimp->p_flags &= ~IDENT_FLAG_UNKNOWN; aimp->p_flags &= ~IDENT_FLAG_UNKNOWN;
} }
} }
static inline void pop_alias(ident *id) { static inline void pop_alias(thread_state &ts, ident *id) {
if (id->is_alias() && !(id->get_flags() & IDENT_FLAG_ARG)) { if (id->is_alias() && !(id->get_flags() & IDENT_FLAG_ARG)) {
static_cast<alias_impl *>(id)->pop_arg(); auto *aimp = static_cast<alias_impl *>(id);
auto &ast = ts.get_astack(aimp);
ast.node = ast.node->next;
} }
} }
@ -199,11 +203,15 @@ void exec_command(
); );
} }
void exec_alias( bool exec_alias(
thread_state &ts, alias *a, any_value *args, any_value &result, thread_state &ts, alias *a, any_value *args, any_value &result,
std::size_t callargs, std::size_t &nargs, std::size_t callargs, std::size_t &nargs,
std::size_t offset, std::size_t skip, std::uint32_t op std::size_t offset, std::size_t skip, std::uint32_t op, bool ncheck
) { ) {
auto &aast = ts.get_astack(a);
if (ncheck && aast.node->val_s.get_type() == value_type::NONE) {
return false;
}
/* excess arguments get ignored (make error maybe?) */ /* excess arguments get ignored (make error maybe?) */
callargs = std::min(callargs, MAX_ARGUMENTS); callargs = std::min(callargs, MAX_ARGUMENTS);
integer_var *anargs = static_cast<integer_var *>( integer_var *anargs = static_cast<integer_var *>(
@ -212,9 +220,13 @@ void exec_alias(
argset uargs{}; argset uargs{};
std::size_t noff = ts.idstack.size(); std::size_t noff = ts.idstack.size();
for(std::size_t i = 0; i < callargs; i++) { for(std::size_t i = 0; i < callargs; i++) {
auto &ap = *static_cast<alias_impl *>(ts.istate->identmap[i]); auto &ast = ts.get_astack(
ap.push_arg(ts.idstack.emplace_back(*ts.pstate)); static_cast<alias *>(ts.istate->identmap[i])
ap.p_astack->val_s = std::move(args[offset + i]); );
auto &st = ts.idstack.emplace_back(*ts.pstate);
st.next = ast.node;
ast.node = &st;
st.val_s = std::move(args[offset + i]);
uargs[i] = true; uargs[i] = true;
} }
auto oldargs = anargs->get_value(); auto oldargs = anargs->get_value();
@ -223,22 +235,33 @@ void exec_alias(
ts.pstate->identflags |= a->get_flags()&IDENT_FLAG_OVERRIDDEN; ts.pstate->identflags |= a->get_flags()&IDENT_FLAG_OVERRIDDEN;
ident_link aliaslink = {a, ts.callstack, uargs}; ident_link aliaslink = {a, ts.callstack, uargs};
ts.callstack = &aliaslink; ts.callstack = &aliaslink;
bcode_ref coderef = static_cast< if (!aast.node->code) {
alias_impl * codegen_state gs{ts};
>(a)->compile_code(ts); gs.code.reserve(64);
gs.gen_main(aast.node->val_s.get_str());
/* i wish i could steal the memory somehow */
uint32_t *code = bcode_alloc(ts.istate, gs.code.size());
memcpy(code, gs.code.data(), gs.code.size() * sizeof(uint32_t));
aast.node->code = bcode_ref{reinterpret_cast<bcode *>(code + 1)};
}
bcode_ref coderef = aast.node->code;
auto cleanup = [&]() { auto cleanup = [&]() {
ts.callstack = aliaslink.next; ts.callstack = aliaslink.next;
ts.pstate->identflags = oldflags; ts.pstate->identflags = oldflags;
auto amask = aliaslink.usedargs; auto amask = aliaslink.usedargs;
for (std::size_t i = 0; i < callargs; i++) { for (std::size_t i = 0; i < callargs; i++) {
static_cast<alias_impl *>(ts.istate->identmap[i])->pop_arg(); auto &ast = ts.get_astack(
static_cast<alias *>(ts.istate->identmap[i])
);
ast.node = ast.node->next;
amask[i] = false; amask[i] = false;
} }
for (; amask.any(); ++callargs) { for (; amask.any(); ++callargs) {
if (amask[callargs]) { if (amask[callargs]) {
static_cast<alias_impl *>( auto &ast = ts.get_astack(
ts.istate->identmap[callargs] static_cast<alias *>(ts.istate->identmap[callargs])
)->pop_arg(); );
ast.node = ast.node->next;
amask[callargs] = false; amask[callargs] = false;
} }
} }
@ -255,6 +278,7 @@ void exec_alias(
throw; throw;
} }
cleanup(); cleanup();
return true;
} }
static constexpr int MaxRunDepth = 255; static constexpr int MaxRunDepth = 255;
@ -523,13 +547,13 @@ std::uint32_t *vm_exec(
std::size_t idstsz = ts.idstack.size(); std::size_t idstsz = ts.idstack.size();
for (std::size_t i = 0; i < numlocals; ++i) { for (std::size_t i = 0; i < numlocals; ++i) {
push_alias( push_alias(
args[offset + i].get_ident(), ts, args[offset + i].get_ident(),
ts.idstack.emplace_back(*ts.pstate) ts.idstack.emplace_back(*ts.pstate)
); );
} }
auto cleanup = [&]() { auto cleanup = [&]() {
for (std::size_t i = offset; i < args.size(); ++i) { for (std::size_t i = offset; i < args.size(); ++i) {
pop_alias(args[i].get_ident()); pop_alias(ts, args[i].get_ident());
} }
ts.idstack.resize(idstsz, ident_stack{*ts.pstate}); ts.idstack.resize(idstsz, ident_stack{*ts.pstate});
}; };
@ -739,9 +763,10 @@ std::uint32_t *vm_exec(
(a->get_flags() & IDENT_FLAG_ARG) && (a->get_flags() & IDENT_FLAG_ARG) &&
!ident_is_used_arg(a, ts) !ident_is_used_arg(a, ts)
) { ) {
static_cast<alias_impl *>(a)->push_arg( auto &ast = ts.get_astack(a);
ts.idstack.emplace_back(*ts.pstate) auto &st = ts.idstack.emplace_back(*ts.pstate);
); st.next = ast.node;
ast.node = &st;
ts.callstack->usedargs[a->get_index()] = true; ts.callstack->usedargs[a->get_index()] = true;
} }
args.emplace_back(cs).set_ident(a); args.emplace_back(cs).set_ident(a);
@ -757,9 +782,11 @@ std::uint32_t *vm_exec(
(id->get_flags() & IDENT_FLAG_ARG) && (id->get_flags() & IDENT_FLAG_ARG) &&
!ident_is_used_arg(id, ts) !ident_is_used_arg(id, ts)
) { ) {
static_cast<alias_impl *>(id)->push_arg( auto *a = static_cast<alias *>(id);
ts.idstack.emplace_back(*ts.pstate) auto &ast = ts.get_astack(a);
); auto &st = ts.idstack.emplace_back(*ts.pstate);
st.next = ast.node;
ast.node = &st;
ts.callstack->usedargs[id->get_index()] = true; ts.callstack->usedargs[id->get_index()] = true;
} }
arg.set_ident(id); arg.set_ident(id);
@ -771,7 +798,9 @@ std::uint32_t *vm_exec(
any_value &arg = args.back(); any_value &arg = args.back();
switch (get_lookupu_type(ts, arg, id, op)) { switch (get_lookupu_type(ts, arg, id, op)) {
case ID_ALIAS: case ID_ALIAS:
arg = static_cast<alias_impl *>(id)->p_astack->val_s; arg = ts.get_astack(
static_cast<alias *>(id)
).node->val_s;
arg.force_str(); arg.force_str();
continue; continue;
case ID_SVAR: case ID_SVAR:
@ -799,7 +828,7 @@ std::uint32_t *vm_exec(
args.emplace_back(cs).set_str(""); args.emplace_back(cs).set_str("");
} else { } else {
auto &v = args.emplace_back(cs); auto &v = args.emplace_back(cs);
v = static_cast<alias_impl *>(a)->p_astack->val_s; v = ts.get_astack(a).node->val_s;
v.force_str(); v.force_str();
} }
continue; continue;
@ -810,9 +839,9 @@ std::uint32_t *vm_exec(
any_value &arg = args.back(); any_value &arg = args.back();
switch (get_lookupu_type(ts, arg, id, op)) { switch (get_lookupu_type(ts, arg, id, op)) {
case ID_ALIAS: case ID_ALIAS:
arg.set_int(static_cast<alias_impl *>( arg.set_int(ts.get_astack(static_cast<alias *>(
id id
)->p_astack->val_s.get_int()); )).node->val_s.get_int());
continue; continue;
case ID_SVAR: case ID_SVAR:
arg.set_int(parse_int( arg.set_int(parse_int(
@ -840,7 +869,7 @@ std::uint32_t *vm_exec(
args.emplace_back(cs).set_int(0); args.emplace_back(cs).set_int(0);
} else { } else {
args.emplace_back(cs).set_int( args.emplace_back(cs).set_int(
static_cast<alias_impl *>(a)->p_astack->val_s.get_int() ts.get_astack(a).node->val_s.get_int()
); );
} }
continue; continue;
@ -850,9 +879,9 @@ std::uint32_t *vm_exec(
any_value &arg = args.back(); any_value &arg = args.back();
switch (get_lookupu_type(ts, arg, id, op)) { switch (get_lookupu_type(ts, arg, id, op)) {
case ID_ALIAS: case ID_ALIAS:
arg.set_float(static_cast<alias_impl *>( arg.set_float(ts.get_astack(static_cast<alias *>(
id id
)->p_astack->val_s.get_float()); )).node->val_s.get_float());
continue; continue;
case ID_SVAR: case ID_SVAR:
arg.set_float(parse_float( arg.set_float(parse_float(
@ -881,9 +910,9 @@ std::uint32_t *vm_exec(
if (!a) { if (!a) {
args.emplace_back(cs).set_float(float_type(0)); args.emplace_back(cs).set_float(float_type(0));
} else { } else {
args.emplace_back(cs).set_float(static_cast<alias_impl *>( args.emplace_back(cs).set_float(
a ts.get_astack(a).node->val_s.get_float()
)->p_astack->val_s.get_float()); );
} }
continue; continue;
} }
@ -892,9 +921,9 @@ std::uint32_t *vm_exec(
any_value &arg = args.back(); any_value &arg = args.back();
switch (get_lookupu_type(ts, arg, id, op)) { switch (get_lookupu_type(ts, arg, id, op)) {
case ID_ALIAS: case ID_ALIAS:
static_cast<alias_impl *>( ts.get_astack(
id static_cast<alias *>(id)
)->p_astack->val_s.get_val(arg); ).node->val_s.get_val(arg);
continue; continue;
case ID_SVAR: case ID_SVAR:
arg.set_str(static_cast<string_var *>(id)->get_value()); arg.set_str(static_cast<string_var *>(id)->get_value());
@ -919,7 +948,7 @@ std::uint32_t *vm_exec(
if (!a) { if (!a) {
args.emplace_back(cs).set_none(); args.emplace_back(cs).set_none();
} else { } else {
static_cast<alias_impl *>(a)->p_astack->val_s.get_val( ts.get_astack(a).node->val_s.get_val(
args.emplace_back(cs) args.emplace_back(cs)
); );
} }
@ -1055,13 +1084,14 @@ std::uint32_t *vm_exec(
} }
case BC_INST_ALIAS: { case BC_INST_ALIAS: {
auto *imp = static_cast<alias_impl *>( auto *a = static_cast<alias *>(
ts.istate->identmap[op >> 8] ts.istate->identmap[op >> 8]
); );
if (imp->get_flags() & IDENT_FLAG_ARG) { auto &ast = ts.get_astack(a);
imp->set_arg(ts, args.back()); if (a->get_flags() & IDENT_FLAG_ARG) {
ast.set_arg(a, ts, args.back());
} else { } else {
imp->set_alias(ts, args.back()); ast.set_alias(a, ts, args.back());
} }
args.pop_back(); args.pop_back();
continue; continue;
@ -1154,13 +1184,13 @@ noid:
std::size_t idstsz = ts.idstack.size(); std::size_t idstsz = ts.idstack.size();
for (size_t j = 0; j < size_t(callargs); ++j) { for (size_t j = 0; j < size_t(callargs); ++j) {
push_alias( push_alias(
args[offset + j].force_ident(cs), ts, args[offset + j].force_ident(cs),
ts.idstack.emplace_back(*ts.pstate) ts.idstack.emplace_back(*ts.pstate)
); );
} }
auto cleanup = [&]() { auto cleanup = [&]() {
for (size_t j = 0; j < size_t(callargs); ++j) { for (size_t j = 0; j < size_t(callargs); ++j) {
pop_alias(args[offset + j].get_ident()); pop_alias(ts, args[offset + j].get_ident());
} }
ts.idstack.resize(idstsz, ident_stack{*ts.pstate}); ts.idstack.resize(idstsz, ident_stack{*ts.pstate});
}; };
@ -1219,15 +1249,12 @@ noid:
force_arg(result, op & BC_INST_RET_MASK); force_arg(result, op & BC_INST_RET_MASK);
continue; continue;
} }
if (static_cast<alias_impl *>( if (!exec_alias(
a ts, a, &args[0], result, callargs, nnargs,
)->p_astack->val_s.get_type() == value_type::NONE) { offset, 1, op, true
)) {
goto noid; goto noid;
} }
exec_alias(
ts, a, &args[0], result, callargs, nnargs,
offset, 1, op
);
args.resize(nnargs, any_value{cs}); args.resize(nnargs, any_value{cs});
continue; continue;
} }

View File

@ -51,9 +51,12 @@ static void call_with_args(thread_state &ts, F body) {
std::size_t noff = ts.idstack.size(); std::size_t noff = ts.idstack.size();
for (std::size_t i = 0; mask.any(); ++i) { for (std::size_t i = 0; mask.any(); ++i) {
if (mask[0]) { if (mask[0]) {
static_cast<alias_impl *>(ts.istate->identmap[i])->undo_arg( auto &ast = ts.get_astack(
ts.idstack.emplace_back(*ts.pstate) static_cast<alias *>(ts.istate->identmap[i])
); );
auto &st = ts.idstack.emplace_back(*ts.pstate);
st.next = ast.node;
ast.node = ast.node->next;
} }
mask >>= 1; mask >>= 1;
} }
@ -74,9 +77,9 @@ static void call_with_args(thread_state &ts, F body) {
auto mask2 = ts.callstack->usedargs; auto mask2 = ts.callstack->usedargs;
for (std::size_t i = 0, nredo = 0; mask2.any(); ++i) { for (std::size_t i = 0, nredo = 0; mask2.any(); ++i) {
if (mask2[0]) { if (mask2[0]) {
static_cast<alias_impl *>(ts.istate->identmap[i])->redo_arg( ts.get_astack(
ts.idstack[noff + nredo++] static_cast<alias *>(ts.istate->identmap[i])
); ).node = ts.idstack[noff + nredo++].next;
} }
mask2 >>= 1; mask2 >>= 1;
} }
@ -96,10 +99,10 @@ void exec_command(
std::size_t nargs, bool lookup = false std::size_t nargs, bool lookup = false
); );
void exec_alias( bool exec_alias(
thread_state &ts, alias *a, any_value *args, any_value &result, thread_state &ts, alias *a, any_value *args, any_value &result,
std::size_t callargs, std::size_t &nargs, std::size_t callargs, std::size_t &nargs, std::size_t offset,
std::size_t offset, std::size_t skip, std::uint32_t op std::size_t skip, std::uint32_t op, bool ncheck = false
); );
std::uint32_t *vm_exec( std::uint32_t *vm_exec(

View File

@ -4,6 +4,7 @@
#include "cs_std.hh" #include "cs_std.hh"
#include "cs_ident.hh" #include "cs_ident.hh"
#include "cs_thread.hh"
namespace cubescript { namespace cubescript {
@ -90,12 +91,9 @@ void init_lib_base(state &gcs) {
rc = false; rc = false;
} }
ret.set_int(rc); ret.set_int(rc);
static_cast<alias_impl *>(cret)->set_alias( auto &ts = *cs.thread_pointer();
*cs.thread_pointer(), result ts.get_astack(cret).set_alias(cret, ts, result);
); ts.get_astack(css).set_alias(css, ts, tback);
static_cast<alias_impl *>(css)->set_alias(
*cs.thread_pointer(), tback
);
}); });
gcs.new_command("?", "ttt", [](auto &, auto args, auto &res) { gcs.new_command("?", "ttt", [](auto &, auto args, auto &res) {