use bitset to store usedargs and increase argcount to 32

master
Daniel Kolesa 2021-03-28 23:46:08 +02:00
parent 96592fb6ac
commit 8385ab01e7
5 changed files with 31 additions and 20 deletions

View File

@ -15,8 +15,6 @@
namespace cubescript {
static constexpr int MAX_ARGUMENTS = 25;
static constexpr int ID_IDX_DUMMY = MAX_ARGUMENTS;
static constexpr int ID_IDX_NUMARGS = MAX_ARGUMENTS + 1;
static constexpr int ID_IDX_DBGALIAS = MAX_ARGUMENTS + 2;

View File

@ -164,7 +164,7 @@ void alias_impl::set_arg(thread_state &ts, any_value &v) {
clean_code();
} else {
push_arg(v, ts.callstack->argstack[get_index()], false);
ts.callstack->usedargs |= 1 << get_index();
ts.callstack->usedargs[get_index()] = true;
}
}
@ -206,7 +206,7 @@ bool ident_is_used_arg(ident *id, thread_state &ts) {
if (!ts.callstack) {
return true;
}
return ts.callstack->usedargs & (1 << id->get_index());
return ts.callstack->usedargs[id->get_index()];
}
/* public interface */

View File

@ -3,8 +3,13 @@
#include <cubescript/cubescript.hh>
#include <bitset>
namespace cubescript {
static constexpr int MAX_ARGUMENTS = 32;
using argset = std::bitset<MAX_ARGUMENTS>;
enum {
ID_UNKNOWN = -1, ID_IVAR, ID_FVAR, ID_SVAR, ID_COMMAND, ID_ALIAS,
ID_LOCAL, ID_DO, ID_DOARGS, ID_IF, ID_BREAK, ID_CONTINUE, ID_RESULT,
@ -14,8 +19,8 @@ enum {
struct ident_link {
ident *id;
ident_link *next;
int usedargs;
ident_stack *argstack;
std::bitset<MAX_ARGUMENTS> usedargs;
};
struct ident_impl {

View File

@ -206,17 +206,19 @@ void exec_alias(
ts.istate->identmap[ID_IDX_NUMARGS]
);
valarray<ident_stack, MAX_ARGUMENTS> argstack{*ts.pstate};
argset uargs{};
for(std::size_t i = 0; i < callargs; i++) {
static_cast<alias_impl *>(ts.istate->identmap[i])->push_arg(
args[offset + i], argstack[i], false
);
uargs[i] = true;
}
auto oldargs = anargs->get_value();
anargs->set_value(callargs);
int oldflags = ts.pstate->identflags;
ts.pstate->identflags |= a->get_flags()&IDENT_FLAG_OVERRIDDEN;
ident_link aliaslink = {
a, ts.callstack, (1<<callargs)-1, &argstack[0]
a, ts.callstack, &argstack[0], uargs
};
ts.callstack = &aliaslink;
std::uint32_t *codep = static_cast<
@ -229,16 +231,17 @@ void exec_alias(
bcode_decr(codep);
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();
amask[i] = false;
}
int argmask = aliaslink.usedargs & int(~0U << callargs);
for (; argmask; ++callargs) {
if (argmask & (1 << callargs)) {
for (; amask.any(); ++callargs) {
if (amask[callargs]) {
static_cast<alias_impl *>(
ts.istate->identmap[callargs]
)->pop_arg();
argmask &= ~(1 << callargs);
amask[callargs] = false;
}
}
force_arg(result, op & BC_INST_RET_MASK);
@ -725,7 +728,7 @@ std::uint32_t *vm_exec(
nv, ts.callstack->argstack[a->get_index()],
false
);
ts.callstack->usedargs |= 1 << a->get_index();
ts.callstack->usedargs[a->get_index()] = true;
}
args.emplace_back(cs).set_ident(a);
continue;
@ -745,7 +748,7 @@ std::uint32_t *vm_exec(
nv, ts.callstack->argstack[id->get_index()],
false
);
ts.callstack->usedargs |= 1 << id->get_index();
ts.callstack->usedargs[id->get_index()] = true;
}
arg.set_ident(id);
continue;

View File

@ -48,33 +48,38 @@ static void call_with_args(thread_state &ts, F body) {
return;
}
valarray<ident_stack, MAX_ARGUMENTS> argstack{*ts.pstate};
int argmask1 = ts.callstack->usedargs;
for (int i = 0; argmask1; argmask1 >>= 1, ++i) {
if (argmask1 & 1) {
auto mask = ts.callstack->usedargs;
for (std::size_t i = 0; mask.any(); ++i) {
if (mask[0]) {
static_cast<alias_impl *>(ts.istate->identmap[i])->undo_arg(
argstack[i]
);
}
mask >>= 1;
}
ident_link *prevstack = ts.callstack->next;
ident_link aliaslink = {
ts.callstack->id, ts.callstack,
prevstack ? prevstack->usedargs : ((1 << MAX_ARGUMENTS) - 1),
prevstack ? prevstack->argstack : nullptr
prevstack ? prevstack->argstack : nullptr,
prevstack ? prevstack->usedargs : argset{}
};
if (!prevstack) {
aliaslink.usedargs.set();
}
ts.callstack = &aliaslink;
call_with_cleanup(std::move(body), [&]() {
if (prevstack) {
prevstack->usedargs = aliaslink.usedargs;
}
ts.callstack = aliaslink.next;
int argmask2 = ts.callstack->usedargs;
for (int i = 0; argmask2; argmask2 >>= 1, ++i) {
if (argmask2 & 1) {
auto mask2 = ts.callstack->usedargs;
for (std::size_t i = 0; mask.any(); ++i) {
if (mask2[0]) {
static_cast<alias_impl *>(ts.istate->identmap[i])->redo_arg(
argstack[i]
);
}
mask2 >>= 1;
}
});
}