kill call_with_args template

master
Daniel Kolesa 2021-05-14 02:54:29 +02:00
parent 8b04bd1488
commit 036362683c
3 changed files with 66 additions and 69 deletions

View File

@ -6,7 +6,7 @@
#include "cs_state.hh"
#include "cs_thread.hh"
#include "cs_strman.hh"
#include "cs_vm.hh" // break/continue, call_with_args
#include "cs_vm.hh"
#include "cs_parser.hh"
#include "cs_error.hh"
@ -179,9 +179,7 @@ state::state(alloc_func func, void *data) {
static_cast<command_impl *>(p)->p_type = ID_DO;
p = &new_command("doargs", "b", [](auto &cs, auto args, auto &res) {
call_with_args(*cs.p_tstate, [&cs, &res, &args]() {
res = args[0].get_code().call(cs);
});
res = exec_code_with_args(*cs.p_tstate, args[0].get_code());
});
static_cast<command_impl *>(p)->p_type = ID_DOARGS;

View File

@ -216,6 +216,62 @@ bool exec_alias(
return true;
}
any_value exec_code_with_args(thread_state &ts, bcode_ref const &body) {
if (!ts.callstack) {
return body.call(*ts.pstate);
}
auto mask = ts.callstack->usedargs;
std::size_t noff = ts.idstack.size();
for (std::size_t i = 0; mask.any(); ++i) {
if (mask[0]) {
auto &ast = ts.get_astack(
static_cast<alias *>(ts.istate->identmap[i])
);
auto &st = ts.idstack.emplace_back();
st.next = ast.node;
ast.node = ast.node->next;
}
mask >>= 1;
}
ident_link *prevstack = ts.callstack->next;
ident_link aliaslink = {
ts.callstack->id, ts.callstack,
prevstack ? prevstack->usedargs : argset{}
};
if (!prevstack) {
aliaslink.usedargs.set();
}
ts.callstack = &aliaslink;
auto cleanup = [](
auto &tss, ident_link *pstack, ident_link &alink, std::size_t offn
) {
if (pstack) {
pstack->usedargs = alink.usedargs;
}
tss.callstack = alink.next;
auto mask2 = tss.callstack->usedargs;
for (std::size_t i = 0, nredo = 0; mask2.any(); ++i) {
if (mask2[0]) {
tss.get_astack(
static_cast<alias *>(tss.istate->identmap[i])
).node = tss.idstack[offn + nredo++].next;
}
mask2 >>= 1;
}
};
any_value ret;
try {
ret = body.call(*ts.pstate);
} catch (...) {
cleanup(ts, prevstack, aliaslink, noff);
ts.idstack.resize(noff);
throw;
}
cleanup(ts, prevstack, aliaslink, noff);
ts.idstack.resize(noff);
return ret;
}
static inline alias *get_lookup_id(
thread_state &ts, std::uint32_t op, alias_stack *&ast
) {
@ -412,16 +468,13 @@ std::uint32_t *vm_exec(
return code;
}
case BC_INST_DO_ARGS:
call_with_args(ts, [](
auto &css, std::uint32_t inst, auto &av, any_value &ret
) {
auto v = std::move(av.back());
av.pop_back();
ret = v.get_code().call(css);
force_arg(css, ret, inst & BC_INST_RET_MASK);
}, cs, op, args, result);
case BC_INST_DO_ARGS: {
auto v = std::move(args.back());
args.pop_back();
result = exec_code_with_args(ts, v.get_code());
force_arg(cs, result, op & BC_INST_RET_MASK);
continue;
}
case BC_INST_DO: {
auto v = std::move(args.back());

View File

@ -17,62 +17,6 @@ struct break_exception {
struct continue_exception {
};
template<typename F, typename ...A>
static void call_with_args(thread_state &ts, F body, A &&...args) {
if (!ts.callstack) {
body(std::forward<A>(args)...);
return;
}
auto mask = ts.callstack->usedargs;
std::size_t noff = ts.idstack.size();
for (std::size_t i = 0; mask.any(); ++i) {
if (mask[0]) {
auto &ast = ts.get_astack(
static_cast<alias *>(ts.istate->identmap[i])
);
auto &st = ts.idstack.emplace_back();
st.next = ast.node;
ast.node = ast.node->next;
}
mask >>= 1;
}
ident_link *prevstack = ts.callstack->next;
ident_link aliaslink = {
ts.callstack->id, ts.callstack,
prevstack ? prevstack->usedargs : argset{}
};
if (!prevstack) {
aliaslink.usedargs.set();
}
ts.callstack = &aliaslink;
auto cleanup = [](
auto &tss, ident_link *pstack, ident_link &alink, std::size_t offn
) {
if (pstack) {
pstack->usedargs = alink.usedargs;
}
tss.callstack = alink.next;
auto mask2 = tss.callstack->usedargs;
for (std::size_t i = 0, nredo = 0; mask2.any(); ++i) {
if (mask2[0]) {
tss.get_astack(
static_cast<alias *>(tss.istate->identmap[i])
).node = tss.idstack[offn + nredo++].next;
}
mask2 >>= 1;
}
};
try {
body(std::forward<A>(args)...);
} catch (...) {
cleanup(ts, prevstack, aliaslink, noff);
ts.idstack.resize(noff);
throw;
}
cleanup(ts, prevstack, aliaslink, noff);
ts.idstack.resize(noff);
}
void exec_command(
thread_state &ts, command_impl *id, ident *self, any_value *args,
any_value &res, std::size_t nargs, bool lookup = false
@ -84,6 +28,8 @@ bool exec_alias(
std::size_t skip, std::uint32_t op, bool ncheck = false
);
any_value exec_code_with_args(thread_state &ts, bcode_ref const &body);
std::uint32_t *vm_exec(
thread_state &ts, std::uint32_t *code, any_value &result
);