diff --git a/src/cs_state.cc b/src/cs_state.cc index c60f9df..2f352d1 100644 --- a/src/cs_state.cc +++ b/src/cs_state.cc @@ -794,11 +794,13 @@ static void do_run( std::uint32_t *cbuf = bcode_alloc(ts.istate, gs.code.size()); std::memcpy(cbuf, gs.code.data(), gs.code.size() * sizeof(std::uint32_t)); bcode_incr(cbuf); - call_with_cleanup([&ts, cbuf, &ret]() { + try { vm_exec(ts, cbuf + 1, ret); - }, [cbuf]() { + } catch (...) { bcode_decr(cbuf); - }); + throw; + } + bcode_decr(cbuf); } LIBCUBESCRIPT_EXPORT void state::run(std::string_view code, any_value &ret) { diff --git a/src/cs_std.hh b/src/cs_std.hh index af1047b..1bfd124 100644 --- a/src/cs_std.hh +++ b/src/cs_std.hh @@ -13,21 +13,6 @@ namespace cubescript { -/* run func, call the second one after finishing */ - -template -inline void call_with_cleanup(F1 &&dof, F2 &&clf) { - struct scope_exit { - scope_exit(std::decay_t &f): func(&f) {} - ~scope_exit() { - (*func)(); - } - std::decay_t *func; - }; - scope_exit cleanup(clf); - dof(); -} - /* a value buffer */ template diff --git a/src/cs_vm.cc b/src/cs_vm.cc index 0d1fadc..991f0e1 100644 --- a/src/cs_vm.cc +++ b/src/cs_vm.cc @@ -224,9 +224,7 @@ void exec_alias( alias_impl * >(a)->compile_code(ts)->get_raw(); bcode_incr(codep); - call_with_cleanup([&]() { - vm_exec(ts, codep+1, result); - }, [&]() { + auto cleanup = [&]() { bcode_decr(codep); ts.callstack = aliaslink.next; ts.pstate->identflags = oldflags; @@ -247,7 +245,14 @@ void exec_alias( force_arg(result, op & BC_INST_RET_MASK); anargs->set_value(integer_type(oldargs)); nargs = offset - skip; - }); + }; + try { + vm_exec(ts, codep + 1, result); + } catch (...) { + cleanup(); + throw; + } + cleanup(); } static constexpr int MaxRunDepth = 255; @@ -520,14 +525,19 @@ std::uint32_t *vm_exec( ts.idstack.emplace_back(*ts.pstate) ); } - call_with_cleanup([&]() { - code = vm_exec(ts, code, result); - }, [&]() { + auto cleanup = [&]() { for (std::size_t i = offset; i < args.size(); ++i) { pop_alias(args[i].get_ident()); } ts.idstack.resize(idstsz, ident_stack{*ts.pstate}); - }); + }; + try { + code = vm_exec(ts, code, result); + } catch (...) { + cleanup(); + throw; + } + cleanup(); return code; } @@ -1138,14 +1148,19 @@ noid: ts.idstack.emplace_back(*ts.pstate) ); } - call_with_cleanup([&]() { - code = vm_exec(ts, code, result); - }, [&]() { + auto cleanup = [&]() { for (size_t j = 0; j < size_t(callargs); ++j) { pop_alias(args[offset + j].get_ident()); } ts.idstack.resize(idstsz, ident_stack{*ts.pstate}); - }); + }; + try { + code = vm_exec(ts, code, result); + } catch (...) { + cleanup(); + throw; + } + cleanup(); return code; } case ID_IVAR: diff --git a/src/cs_vm.hh b/src/cs_vm.hh index 559958d..e7f34e5 100644 --- a/src/cs_vm.hh +++ b/src/cs_vm.hh @@ -66,7 +66,7 @@ static void call_with_args(thread_state &ts, F body) { aliaslink.usedargs.set(); } ts.callstack = &aliaslink; - call_with_cleanup(std::move(body), [&]() { + auto cleanup = [&]() { if (prevstack) { prevstack->usedargs = aliaslink.usedargs; } @@ -81,7 +81,14 @@ static void call_with_args(thread_state &ts, F body) { mask2 >>= 1; } ts.idstack.resize(noff, ident_stack{*ts.pstate}); - }); + }; + try { + body(); + } catch (...) { + cleanup(); + throw; + } + cleanup(); } void exec_command(