kill call_with_args template
parent
8b04bd1488
commit
036362683c
|
@ -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;
|
||||
|
||||
|
|
71
src/cs_vm.cc
71
src/cs_vm.cc
|
@ -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());
|
||||
|
|
58
src/cs_vm.hh
58
src/cs_vm.hh
|
@ -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
|
||||
);
|
||||
|
|
Loading…
Reference in New Issue