prepare codebase for per-thread alias stack
parent
e8856f8f9d
commit
881ba4bce9
|
@ -640,6 +640,7 @@ struct LIBCUBESCRIPT_EXPORT alias_local {
|
|||
|
||||
private:
|
||||
alias *p_alias;
|
||||
void *p_sp;
|
||||
};
|
||||
|
||||
struct LIBCUBESCRIPT_EXPORT list_parser {
|
||||
|
|
|
@ -114,56 +114,6 @@ alias_impl::alias_impl(state &cs, string_ref name, any_value v, int fl):
|
|||
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(
|
||||
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()];
|
||||
}
|
||||
|
||||
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 */
|
||||
|
||||
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;
|
||||
return;
|
||||
}
|
||||
auto *aimp = static_cast<alias_impl *>(p_alias);
|
||||
p_alias = aimp;
|
||||
aimp->push_arg(
|
||||
cs.thread_pointer()->idstack.emplace_back(cs)
|
||||
);
|
||||
aimp->p_flags &= ~IDENT_FLAG_UNKNOWN;
|
||||
auto &ts = *cs.thread_pointer();
|
||||
p_alias = static_cast<alias *>(a);
|
||||
auto &ast = ts.get_astack(p_alias);
|
||||
auto &st = ts.idstack.emplace_back(cs);
|
||||
st.next = ast.node;
|
||||
ast.node = &st;
|
||||
p_sp = *
|
||||
static_cast<alias_impl *>(p_alias)->p_flags &= ~IDENT_FLAG_UNKNOWN;
|
||||
}
|
||||
|
||||
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) {
|
||||
if (!p_alias) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,13 @@ struct ident_stack {
|
|||
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 {
|
||||
ident *id;
|
||||
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, 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_astack;
|
||||
alias_stack p_astack;
|
||||
};
|
||||
|
||||
struct command_impl: ident_impl, command {
|
||||
|
|
|
@ -365,11 +365,12 @@ LIBCUBESCRIPT_EXPORT void state::set_alias(
|
|||
if (id) {
|
||||
switch (id->get_type()) {
|
||||
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) {
|
||||
a->set_arg(*p_tstate, v);
|
||||
ast.set_arg(a, *p_tstate, v);
|
||||
} else {
|
||||
a->set_alias(*p_tstate, v);
|
||||
ast.set_alias(a, *p_tstate, v);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -459,9 +460,9 @@ LIBCUBESCRIPT_EXPORT void state::clear_override(ident &id) {
|
|||
}
|
||||
switch (id.get_type()) {
|
||||
case ident_type::ALIAS: {
|
||||
alias_impl &a = static_cast<alias_impl &>(id);
|
||||
a.p_astack->val_s.set_str("");
|
||||
a.p_astack->code = bcode_ref{};
|
||||
auto &ast = p_tstate->get_astack(static_cast<alias *>(&id));
|
||||
ast.node->val_s.set_str("");
|
||||
ast.node->code = bcode_ref{};
|
||||
break;
|
||||
}
|
||||
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)) {
|
||||
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) {
|
||||
|
@ -871,14 +872,9 @@ LIBCUBESCRIPT_EXPORT void state::run(
|
|||
) {
|
||||
break;
|
||||
}
|
||||
if (
|
||||
static_cast<alias_impl *>(a)->p_astack->val_s.get_type() ==
|
||||
value_type::NONE
|
||||
) {
|
||||
break;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -17,4 +17,8 @@ hook_func thread_state::set_hook(hook_func f) {
|
|||
return hk;
|
||||
}
|
||||
|
||||
alias_stack &thread_state::get_astack(alias *a) {
|
||||
return static_cast<alias_impl *>(a)->p_astack;
|
||||
}
|
||||
|
||||
} /* namespace cubescript */
|
||||
|
|
|
@ -41,6 +41,8 @@ struct thread_state {
|
|||
|
||||
hook_func &get_hook() { return call_hook; }
|
||||
hook_func const &get_hook() const { return call_hook; }
|
||||
|
||||
alias_stack &get_astack(alias *a);
|
||||
};
|
||||
|
||||
} /* namespace cubescript */
|
||||
|
|
129
src/cs_vm.cc
129
src/cs_vm.cc
|
@ -9,17 +9,21 @@
|
|||
|
||||
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)) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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)) {
|
||||
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,
|
||||
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?) */
|
||||
callargs = std::min(callargs, MAX_ARGUMENTS);
|
||||
integer_var *anargs = static_cast<integer_var *>(
|
||||
|
@ -212,9 +220,13 @@ void exec_alias(
|
|||
argset uargs{};
|
||||
std::size_t noff = ts.idstack.size();
|
||||
for(std::size_t i = 0; i < callargs; i++) {
|
||||
auto &ap = *static_cast<alias_impl *>(ts.istate->identmap[i]);
|
||||
ap.push_arg(ts.idstack.emplace_back(*ts.pstate));
|
||||
ap.p_astack->val_s = std::move(args[offset + i]);
|
||||
auto &ast = ts.get_astack(
|
||||
static_cast<alias *>(ts.istate->identmap[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;
|
||||
}
|
||||
auto oldargs = anargs->get_value();
|
||||
|
@ -223,22 +235,33 @@ void exec_alias(
|
|||
ts.pstate->identflags |= a->get_flags()&IDENT_FLAG_OVERRIDDEN;
|
||||
ident_link aliaslink = {a, ts.callstack, uargs};
|
||||
ts.callstack = &aliaslink;
|
||||
bcode_ref coderef = static_cast<
|
||||
alias_impl *
|
||||
>(a)->compile_code(ts);
|
||||
if (!aast.node->code) {
|
||||
codegen_state gs{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 = [&]() {
|
||||
ts.callstack = aliaslink.next;
|
||||
ts.pstate->identflags = oldflags;
|
||||
auto amask = aliaslink.usedargs;
|
||||
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;
|
||||
}
|
||||
for (; amask.any(); ++callargs) {
|
||||
if (amask[callargs]) {
|
||||
static_cast<alias_impl *>(
|
||||
ts.istate->identmap[callargs]
|
||||
)->pop_arg();
|
||||
auto &ast = ts.get_astack(
|
||||
static_cast<alias *>(ts.istate->identmap[callargs])
|
||||
);
|
||||
ast.node = ast.node->next;
|
||||
amask[callargs] = false;
|
||||
}
|
||||
}
|
||||
|
@ -255,6 +278,7 @@ void exec_alias(
|
|||
throw;
|
||||
}
|
||||
cleanup();
|
||||
return true;
|
||||
}
|
||||
|
||||
static constexpr int MaxRunDepth = 255;
|
||||
|
@ -523,13 +547,13 @@ std::uint32_t *vm_exec(
|
|||
std::size_t idstsz = ts.idstack.size();
|
||||
for (std::size_t i = 0; i < numlocals; ++i) {
|
||||
push_alias(
|
||||
args[offset + i].get_ident(),
|
||||
ts, args[offset + i].get_ident(),
|
||||
ts.idstack.emplace_back(*ts.pstate)
|
||||
);
|
||||
}
|
||||
auto cleanup = [&]() {
|
||||
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});
|
||||
};
|
||||
|
@ -739,9 +763,10 @@ std::uint32_t *vm_exec(
|
|||
(a->get_flags() & IDENT_FLAG_ARG) &&
|
||||
!ident_is_used_arg(a, ts)
|
||||
) {
|
||||
static_cast<alias_impl *>(a)->push_arg(
|
||||
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[a->get_index()] = true;
|
||||
}
|
||||
args.emplace_back(cs).set_ident(a);
|
||||
|
@ -757,9 +782,11 @@ std::uint32_t *vm_exec(
|
|||
(id->get_flags() & IDENT_FLAG_ARG) &&
|
||||
!ident_is_used_arg(id, ts)
|
||||
) {
|
||||
static_cast<alias_impl *>(id)->push_arg(
|
||||
ts.idstack.emplace_back(*ts.pstate)
|
||||
);
|
||||
auto *a = static_cast<alias *>(id);
|
||||
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;
|
||||
}
|
||||
arg.set_ident(id);
|
||||
|
@ -771,7 +798,9 @@ std::uint32_t *vm_exec(
|
|||
any_value &arg = args.back();
|
||||
switch (get_lookupu_type(ts, arg, id, op)) {
|
||||
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();
|
||||
continue;
|
||||
case ID_SVAR:
|
||||
|
@ -799,7 +828,7 @@ std::uint32_t *vm_exec(
|
|||
args.emplace_back(cs).set_str("");
|
||||
} else {
|
||||
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();
|
||||
}
|
||||
continue;
|
||||
|
@ -810,9 +839,9 @@ std::uint32_t *vm_exec(
|
|||
any_value &arg = args.back();
|
||||
switch (get_lookupu_type(ts, arg, id, op)) {
|
||||
case ID_ALIAS:
|
||||
arg.set_int(static_cast<alias_impl *>(
|
||||
arg.set_int(ts.get_astack(static_cast<alias *>(
|
||||
id
|
||||
)->p_astack->val_s.get_int());
|
||||
)).node->val_s.get_int());
|
||||
continue;
|
||||
case ID_SVAR:
|
||||
arg.set_int(parse_int(
|
||||
|
@ -840,7 +869,7 @@ std::uint32_t *vm_exec(
|
|||
args.emplace_back(cs).set_int(0);
|
||||
} else {
|
||||
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;
|
||||
|
@ -850,9 +879,9 @@ std::uint32_t *vm_exec(
|
|||
any_value &arg = args.back();
|
||||
switch (get_lookupu_type(ts, arg, id, op)) {
|
||||
case ID_ALIAS:
|
||||
arg.set_float(static_cast<alias_impl *>(
|
||||
arg.set_float(ts.get_astack(static_cast<alias *>(
|
||||
id
|
||||
)->p_astack->val_s.get_float());
|
||||
)).node->val_s.get_float());
|
||||
continue;
|
||||
case ID_SVAR:
|
||||
arg.set_float(parse_float(
|
||||
|
@ -881,9 +910,9 @@ std::uint32_t *vm_exec(
|
|||
if (!a) {
|
||||
args.emplace_back(cs).set_float(float_type(0));
|
||||
} else {
|
||||
args.emplace_back(cs).set_float(static_cast<alias_impl *>(
|
||||
a
|
||||
)->p_astack->val_s.get_float());
|
||||
args.emplace_back(cs).set_float(
|
||||
ts.get_astack(a).node->val_s.get_float()
|
||||
);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
@ -892,9 +921,9 @@ std::uint32_t *vm_exec(
|
|||
any_value &arg = args.back();
|
||||
switch (get_lookupu_type(ts, arg, id, op)) {
|
||||
case ID_ALIAS:
|
||||
static_cast<alias_impl *>(
|
||||
id
|
||||
)->p_astack->val_s.get_val(arg);
|
||||
ts.get_astack(
|
||||
static_cast<alias *>(id)
|
||||
).node->val_s.get_val(arg);
|
||||
continue;
|
||||
case ID_SVAR:
|
||||
arg.set_str(static_cast<string_var *>(id)->get_value());
|
||||
|
@ -919,7 +948,7 @@ std::uint32_t *vm_exec(
|
|||
if (!a) {
|
||||
args.emplace_back(cs).set_none();
|
||||
} 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)
|
||||
);
|
||||
}
|
||||
|
@ -1055,13 +1084,14 @@ std::uint32_t *vm_exec(
|
|||
}
|
||||
|
||||
case BC_INST_ALIAS: {
|
||||
auto *imp = static_cast<alias_impl *>(
|
||||
auto *a = static_cast<alias *>(
|
||||
ts.istate->identmap[op >> 8]
|
||||
);
|
||||
if (imp->get_flags() & IDENT_FLAG_ARG) {
|
||||
imp->set_arg(ts, args.back());
|
||||
auto &ast = ts.get_astack(a);
|
||||
if (a->get_flags() & IDENT_FLAG_ARG) {
|
||||
ast.set_arg(a, ts, args.back());
|
||||
} else {
|
||||
imp->set_alias(ts, args.back());
|
||||
ast.set_alias(a, ts, args.back());
|
||||
}
|
||||
args.pop_back();
|
||||
continue;
|
||||
|
@ -1154,13 +1184,13 @@ noid:
|
|||
std::size_t idstsz = ts.idstack.size();
|
||||
for (size_t j = 0; j < size_t(callargs); ++j) {
|
||||
push_alias(
|
||||
args[offset + j].force_ident(cs),
|
||||
ts, args[offset + j].force_ident(cs),
|
||||
ts.idstack.emplace_back(*ts.pstate)
|
||||
);
|
||||
}
|
||||
auto cleanup = [&]() {
|
||||
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});
|
||||
};
|
||||
|
@ -1219,15 +1249,12 @@ noid:
|
|||
force_arg(result, op & BC_INST_RET_MASK);
|
||||
continue;
|
||||
}
|
||||
if (static_cast<alias_impl *>(
|
||||
a
|
||||
)->p_astack->val_s.get_type() == value_type::NONE) {
|
||||
if (!exec_alias(
|
||||
ts, a, &args[0], result, callargs, nnargs,
|
||||
offset, 1, op, true
|
||||
)) {
|
||||
goto noid;
|
||||
}
|
||||
exec_alias(
|
||||
ts, a, &args[0], result, callargs, nnargs,
|
||||
offset, 1, op
|
||||
);
|
||||
args.resize(nnargs, any_value{cs});
|
||||
continue;
|
||||
}
|
||||
|
|
19
src/cs_vm.hh
19
src/cs_vm.hh
|
@ -51,9 +51,12 @@ static void call_with_args(thread_state &ts, F body) {
|
|||
std::size_t noff = ts.idstack.size();
|
||||
for (std::size_t i = 0; mask.any(); ++i) {
|
||||
if (mask[0]) {
|
||||
static_cast<alias_impl *>(ts.istate->identmap[i])->undo_arg(
|
||||
ts.idstack.emplace_back(*ts.pstate)
|
||||
auto &ast = ts.get_astack(
|
||||
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;
|
||||
}
|
||||
|
@ -74,9 +77,9 @@ static void call_with_args(thread_state &ts, F body) {
|
|||
auto mask2 = ts.callstack->usedargs;
|
||||
for (std::size_t i = 0, nredo = 0; mask2.any(); ++i) {
|
||||
if (mask2[0]) {
|
||||
static_cast<alias_impl *>(ts.istate->identmap[i])->redo_arg(
|
||||
ts.idstack[noff + nredo++]
|
||||
);
|
||||
ts.get_astack(
|
||||
static_cast<alias *>(ts.istate->identmap[i])
|
||||
).node = ts.idstack[noff + nredo++].next;
|
||||
}
|
||||
mask2 >>= 1;
|
||||
}
|
||||
|
@ -96,10 +99,10 @@ void exec_command(
|
|||
std::size_t nargs, bool lookup = false
|
||||
);
|
||||
|
||||
void exec_alias(
|
||||
bool exec_alias(
|
||||
thread_state &ts, alias *a, any_value *args, any_value &result,
|
||||
std::size_t callargs, std::size_t &nargs,
|
||||
std::size_t offset, std::size_t skip, std::uint32_t op
|
||||
std::size_t callargs, std::size_t &nargs, std::size_t offset,
|
||||
std::size_t skip, std::uint32_t op, bool ncheck = false
|
||||
);
|
||||
|
||||
std::uint32_t *vm_exec(
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#include "cs_std.hh"
|
||||
#include "cs_ident.hh"
|
||||
#include "cs_thread.hh"
|
||||
|
||||
namespace cubescript {
|
||||
|
||||
|
@ -90,12 +91,9 @@ void init_lib_base(state &gcs) {
|
|||
rc = false;
|
||||
}
|
||||
ret.set_int(rc);
|
||||
static_cast<alias_impl *>(cret)->set_alias(
|
||||
*cs.thread_pointer(), result
|
||||
);
|
||||
static_cast<alias_impl *>(css)->set_alias(
|
||||
*cs.thread_pointer(), tback
|
||||
);
|
||||
auto &ts = *cs.thread_pointer();
|
||||
ts.get_astack(cret).set_alias(cret, ts, result);
|
||||
ts.get_astack(css).set_alias(css, ts, tback);
|
||||
});
|
||||
|
||||
gcs.new_command("?", "ttt", [](auto &, auto args, auto &res) {
|
||||
|
|
Loading…
Reference in New Issue