libcubescript/src/cs_vm.hh

94 lines
2.4 KiB
C++
Raw Normal View History

2021-03-23 23:29:32 +01:00
#ifndef LIBCUBESCRIPT_VM_HH
#define LIBCUBESCRIPT_VM_HH
2016-08-12 18:38:43 +02:00
#include <cubescript/cubescript.hh>
2016-08-12 18:38:43 +02:00
2021-03-23 01:11:21 +01:00
#include "cs_std.hh"
#include "cs_ident.hh"
#include "cs_thread.hh"
2021-05-13 04:48:55 +02:00
#include <utility>
2021-03-23 23:32:25 +01:00
namespace cubescript {
2016-08-12 18:38:43 +02:00
2021-03-24 02:21:27 +01:00
struct break_exception {
2016-09-14 23:24:13 +02:00
};
2021-03-24 02:21:27 +01:00
struct continue_exception {
2016-08-12 18:38:43 +02:00
};
2021-05-13 04:48:55 +02:00
template<typename F, typename ...A>
static void call_with_args(thread_state &ts, F body, A &&...args) {
if (!ts.callstack) {
2021-05-13 04:48:55 +02:00
body(std::forward<A>(args)...);
2016-09-10 19:54:55 +02:00
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;
2021-03-23 23:29:32 +01:00
ident_link aliaslink = {
ts.callstack->id, ts.callstack,
prevstack ? prevstack->usedargs : argset{}
};
if (!prevstack) {
aliaslink.usedargs.set();
}
ts.callstack = &aliaslink;
2021-05-13 04:48:55 +02:00
auto cleanup = [](
auto &tss, ident_link *pstack, ident_link &alink, std::size_t offn
) {
if (pstack) {
pstack->usedargs = alink.usedargs;
2016-09-15 04:30:37 +02:00
}
2021-05-13 04:48:55 +02:00
tss.callstack = alink.next;
auto mask2 = tss.callstack->usedargs;
for (std::size_t i = 0, nredo = 0; mask2.any(); ++i) {
if (mask2[0]) {
2021-05-13 04:48:55 +02:00
tss.get_astack(
static_cast<alias *>(tss.istate->identmap[i])
).node = tss.idstack[offn + nredo++].next;
}
mask2 >>= 1;
}
2021-03-30 23:49:50 +02:00
};
try {
2021-05-13 04:48:55 +02:00
body(std::forward<A>(args)...);
2021-03-30 23:49:50 +02:00
} catch (...) {
2021-05-13 04:48:55 +02:00
cleanup(ts, prevstack, aliaslink, noff);
ts.idstack.resize(noff);
2021-03-30 23:49:50 +02:00
throw;
}
2021-05-13 04:48:55 +02:00
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
);
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, bool ncheck = false
);
std::uint32_t *vm_exec(
thread_state &ts, std::uint32_t *code, any_value &result
);
2021-03-23 23:32:25 +01:00
} /* namespace cubescript */
2016-08-12 18:38:43 +02:00
2021-03-23 23:29:32 +01:00
#endif /* LIBCUBESCRIPT_VM_HH */