diff --git a/include/cubescript/cubescript.hh b/include/cubescript/cubescript.hh index f5430d3..365d38e 100644 --- a/include/cubescript/cubescript.hh +++ b/include/cubescript/cubescript.hh @@ -345,8 +345,7 @@ struct OSTD_EXPORT CsState { CsMap idents; CsVector identmap; - CsIdentLink noalias; - CsIdentLink *p_callstack = &noalias; + CsIdentLink *p_callstack = nullptr; int identflags = 0; int nodebug = 0; diff --git a/src/cs_vm.cc b/src/cs_vm.cc index 904d664..d47e03d 100644 --- a/src/cs_vm.cc +++ b/src/cs_vm.cc @@ -66,34 +66,34 @@ bool CsStackState::gap() const { CsStackState cs_save_stack(CsState &cs) { CsIvar *dalias = static_cast(cs.identmap[DbgaliasIdx]); if (!dalias->get_value()) { - return CsStackState(nullptr, true); + return CsStackState(nullptr, !!cs.p_callstack); } int total = 0, depth = 0; - for (CsIdentLink *l = cs.p_callstack; l != &cs.noalias; l = l->next) { + for (CsIdentLink *l = cs.p_callstack; l; l = l->next) { total++; } if (!total) { - return CsStackState(nullptr, true); + return CsStackState(nullptr, false); } CsStackStateNode *st = new CsStackStateNode[ostd::min(total, dalias->get_value())]; CsStackStateNode *ret = st, *nd = st; ++st; - for (CsIdentLink *l = cs.p_callstack; l != &cs.noalias; l = l->next) { + for (CsIdentLink *l = cs.p_callstack; l; l = l->next) { ++depth; if (depth < dalias->get_value()) { nd->id = l->id; nd->index = total - depth + 1; - if (l->next == &cs.noalias) { + if (!l->next) { nd->next = nullptr; } else { nd->next = st; } nd = st++; - } else if (l->next == &cs.noalias) { + } else if (!l->next) { nd->id = l->id; nd->index = 1; - nd->next = NULL; + nd->next = nullptr; } } return CsStackState(ret, total != dalias->get_value()); @@ -487,7 +487,7 @@ static inline CsAlias *cs_get_lookup_id(CsState &cs, ostd::Uint32 op) { static inline CsAlias *cs_get_lookuparg_id(CsState &cs, ostd::Uint32 op) { CsIdent *id = cs.identmap[op >> 8]; - if (!(cs.p_callstack->usedargs & (1 << id->get_index()))) { + if (!cs_is_arg_used(cs, id)) { return nullptr; } return static_cast(id); @@ -510,10 +510,7 @@ static inline int cs_get_lookupu_type( if (id->get_flags() & CsIdfUnknown) { break; } - if ( - (id->get_index() < MaxArguments) && - !(cs.p_callstack->usedargs & (1 << id->get_index())) - ) { + if ((id->get_index() < MaxArguments) && !cs_is_arg_used(cs, id)) { return CsIdUnknown; } return CsIdAlias; @@ -655,13 +652,11 @@ static ostd::Uint32 *runcode(CsState &cs, ostd::Uint32 *code, CsValue &result) { case CsCodeDoArgs | CsRetString: case CsCodeDoArgs | CsRetInt: case CsCodeDoArgs | CsRetFloat: - if (cs.p_callstack != &cs.noalias) { - cs_do_args(cs, [&]() { - cs.run(args[--numargs].get_code(), result); - force_arg(result, op & CsCodeRetMask); - }); - continue; - } + cs_do_args(cs, [&]() { + cs.run(args[--numargs].get_code(), result); + force_arg(result, op & CsCodeRetMask); + }); + continue; /* fallthrough */ case CsCodeDo | CsRetNull: case CsCodeDo | CsRetString: @@ -899,7 +894,7 @@ static ostd::Uint32 *runcode(CsState &cs, ostd::Uint32 *code, CsValue &result) { continue; case CsCodeIdentArg: { CsAlias *a = static_cast(cs.identmap[op >> 8]); - if (!(cs.p_callstack->usedargs & (1 << a->get_index()))) { + if (!cs_is_arg_used(cs, a)) { CsValue nv; CsAliasInternal::push_arg( a, nv, cs.p_callstack->argstack[a->get_index()], false @@ -919,10 +914,7 @@ static ostd::Uint32 *runcode(CsState &cs, ostd::Uint32 *code, CsValue &result) { ) { id = cs.new_ident(arg.get_strr()); } - if ( - id->get_index() < MaxArguments && - !(cs.p_callstack->usedargs & (1 << id->get_index())) - ) { + if ((id->get_index() < MaxArguments) && !cs_is_arg_used(cs, id)) { CsValue nv; CsAliasInternal::push_arg( static_cast(id), nv, @@ -1401,7 +1393,7 @@ static ostd::Uint32 *runcode(CsState &cs, ostd::Uint32 *code, CsValue &result) { result.force_null(); CsIdent *id = cs.identmap[op >> 13]; int callargs = (op >> 8) & 0x1F, offset = numargs - callargs; - if (!(cs.p_callstack->usedargs & (1 << id->get_index()))) { + if (!cs_is_arg_used(cs, id)) { numargs = offset; force_arg(result, op & CsCodeRetMask); continue; @@ -1514,8 +1506,8 @@ noid: case CsIdAlias: { CsAlias *a = static_cast(id); if ( - a->get_index() < MaxArguments && - !(cs.p_callstack->usedargs & (1 << a->get_index())) + (a->get_index() < MaxArguments) && + !cs_is_arg_used(cs, a) ) { numargs = offset - 1; force_arg(result, op & CsCodeRetMask); @@ -1619,10 +1611,10 @@ void CsState::run(CsIdent *id, CsValueRange args, CsValue &ret) { break; case CsIdentType::Alias: { CsAlias *a = static_cast(id); - if (a->get_index() < MaxArguments) { - if (!(p_callstack->usedargs & (1 << a->get_index()))) { - break; - } + if ( + (a->get_index() < MaxArguments) && !cs_is_arg_used(*this, a) + ) { + break; } if (a->get_value().get_type() == CsValueType::Null) { break; diff --git a/src/cs_vm.hh b/src/cs_vm.hh index 7bb8fd5..5997978 100644 --- a/src/cs_vm.hh +++ b/src/cs_vm.hh @@ -236,6 +236,13 @@ static inline void bcode_decr(ostd::Uint32 *bc) { } } +static inline bool cs_is_arg_used(CsState &cs, CsIdent *id) { + if (!cs.p_callstack) { + return true; + } + return cs.p_callstack->usedargs & (1 << id->get_index()); +} + struct CsAliasInternal { static void push_arg( CsAlias *a, CsValue &v, CsIdentStack &st, bool um = true @@ -284,7 +291,7 @@ struct CsAliasInternal { } static void set_arg(CsAlias *a, CsState &cs, CsValue &v) { - if (cs.p_callstack->usedargs & (1 << a->get_index())) { + if (cs_is_arg_used(cs, a)) { a->p_val = ostd::move(v); clean_code(a); } else { @@ -323,6 +330,10 @@ struct CsAliasInternal { template static void cs_do_args(CsState &cs, F body) { + if (!cs.p_callstack) { + body(); + return; + } CsIdentStack argstack[MaxArguments]; int argmask1 = cs.p_callstack->usedargs; for (int i = 0; argmask1; argmask1 >>= 1, ++i) { diff --git a/src/cubescript.cc b/src/cubescript.cc index 42209a4..0e83b75 100644 --- a/src/cubescript.cc +++ b/src/cubescript.cc @@ -255,11 +255,6 @@ void cs_init_lib_base(CsState &cs); CsState::CsState(): p_callhook(), p_panicfunc(), p_out(&ostd::out), p_err(&ostd::err) { - noalias.id = nullptr; - noalias.next = nullptr; - noalias.usedargs = (1 << MaxArguments) - 1; - noalias.argstack = nullptr; - /* default panic func */ p_panicfunc = [this](ostd::ConstCharRange v, CsStackState) { get_err().writefln( @@ -286,11 +281,7 @@ CsState::CsState(): })->p_type = CsIdDo; new_command("doargs", "e", [this](CsValueRange args, CsValue &res) { - if (p_callstack != &noalias) { - cs_do_args(*this, [&]() { run(args[0].get_code(), res); }); - } else { - run(args[0].get_code(), res); - } + cs_do_args(*this, [&]() { run(args[0].get_code(), res); }); })->p_type = CsIdDoArgs; new_command("if", "tee", [this](CsValueRange args, CsValue &res) { @@ -881,10 +872,7 @@ CsState::get_alias_val(ostd::ConstCharRange name) { if (!a) { return ostd::nothing; } - if ( - (a->get_index() < MaxArguments) && - !(p_callstack->usedargs & (1 << a->get_index())) - ) { + if ((a->get_index() < MaxArguments) && !cs_is_arg_used(*this, a)) { return ostd::nothing; } return ostd::move(a->get_value().get_str());