From 8385ab01e745b4fd9ac23b83a696acb1a1cc65e7 Mon Sep 17 00:00:00 2001 From: Daniel Kolesa Date: Sun, 28 Mar 2021 23:46:08 +0200 Subject: [PATCH] use bitset to store usedargs and increase argcount to 32 --- src/cs_gen.hh | 2 -- src/cs_ident.cc | 4 ++-- src/cs_ident.hh | 7 ++++++- src/cs_vm.cc | 17 ++++++++++------- src/cs_vm.hh | 21 +++++++++++++-------- 5 files changed, 31 insertions(+), 20 deletions(-) diff --git a/src/cs_gen.hh b/src/cs_gen.hh index 0083697..e2661e1 100644 --- a/src/cs_gen.hh +++ b/src/cs_gen.hh @@ -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; diff --git a/src/cs_ident.cc b/src/cs_ident.cc index fa5a7dc..f15347e 100644 --- a/src/cs_ident.cc +++ b/src/cs_ident.cc @@ -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 */ diff --git a/src/cs_ident.hh b/src/cs_ident.hh index 69fcbac..d946fa6 100644 --- a/src/cs_ident.hh +++ b/src/cs_ident.hh @@ -3,8 +3,13 @@ #include +#include + namespace cubescript { +static constexpr int MAX_ARGUMENTS = 32; +using argset = std::bitset; + 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 usedargs; }; struct ident_impl { diff --git a/src/cs_vm.cc b/src/cs_vm.cc index 5e1cf34..5d416a3 100644 --- a/src/cs_vm.cc +++ b/src/cs_vm.cc @@ -206,17 +206,19 @@ void exec_alias( ts.istate->identmap[ID_IDX_NUMARGS] ); valarray argstack{*ts.pstate}; + argset uargs{}; for(std::size_t i = 0; i < callargs; i++) { static_cast(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<identflags = oldflags; + auto amask = aliaslink.usedargs; for (std::size_t i = 0; i < callargs; i++) { static_cast(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( 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; diff --git a/src/cs_vm.hh b/src/cs_vm.hh index c741c74..723d44d 100644 --- a/src/cs_vm.hh +++ b/src/cs_vm.hh @@ -48,33 +48,38 @@ static void call_with_args(thread_state &ts, F body) { return; } valarray 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(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(ts.istate->identmap[i])->redo_arg( argstack[i] ); } + mask2 >>= 1; } }); }