use bitset to store usedargs and increase argcount to 32
parent
96592fb6ac
commit
8385ab01e7
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 {
|
||||
|
|
17
src/cs_vm.cc
17
src/cs_vm.cc
|
@ -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;
|
||||
|
|
21
src/cs_vm.hh
21
src/cs_vm.hh
|
@ -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;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue