diff --git a/cs_val.cc b/cs_val.cc index ecf2b05e..ae4257a3 100644 --- a/cs_val.cc +++ b/cs_val.cc @@ -14,6 +14,10 @@ CsValue::CsValue(): p_stor(), p_len(0), p_type(CsValueType::null) {} +CsValue::~CsValue() { + cleanup(); +} + CsValue::CsValue(CsValue const &v): CsValue() { *this = v; } @@ -30,7 +34,7 @@ CsValue &CsValue::operator=(CsValue const &v) { case CsValueType::ident: p_len = v.p_len; p_type = v.p_type; - memcpy(&p_stor, &v.p_stor, sizeof(p_stor)); + p_stor = v.p_stor; break; case CsValueType::string: case CsValueType::cstring: @@ -51,10 +55,9 @@ CsValue &CsValue::operator=(CsValue const &v) { CsValue &CsValue::operator=(CsValue &&v) { cleanup(); - p_len = v.p_len; - p_type = v.p_type; - memcpy(&p_stor, &v.p_stor, sizeof(p_stor)); - v.set_null(); + ostd::swap(p_len, v.p_len); + ostd::swap(p_type, v.p_type); + ostd::swap(p_stor, v.p_stor); return *this; } @@ -107,7 +110,6 @@ void CsValue::set_str(CsString val) { void CsValue::set_null() { cleanup(); - csv_get(p_stor) = nullptr; } void CsValue::set_code(CsBytecode *val) { @@ -378,6 +380,7 @@ CsStackedValue::CsStackedValue(CsIdent *id): } CsStackedValue::~CsStackedValue() { + cleanup(); pop(); } diff --git a/cs_vm.cc b/cs_vm.cc index 46b7b981..9674330a 100644 --- a/cs_vm.cc +++ b/cs_vm.cc @@ -22,7 +22,8 @@ struct CsCommandInternal { static inline void cs_push_alias(CsIdent *id, CsIdentStack &st) { if (id->is_alias() && (id->get_index() >= MaxArguments)) { - CsAliasInternal::push_arg(static_cast(id), null_value, st); + CsValue nv; + CsAliasInternal::push_arg(static_cast(id), nv, st); } } @@ -400,7 +401,7 @@ static inline void callcommand( auto buf = ostd::appender(); cscript::util::tvals_concat(buf, ostd::iter(args, i), " "); CsValue tv; - tv.set_mstr(buf.get().iter()); + tv.set_str(ostd::move(buf.get())); CsCommandInternal::call(id, CsValueRange(&tv, 1), res); goto cleanup; } @@ -642,8 +643,7 @@ static ostd::Uint32 *runcode(CsState &cs, ostd::Uint32 *code, CsValue &result) { force_arg(result, op & CODE_RET_MASK); /* fallthrough */ case CODE_RESULT_ARG | RET_NULL: - args[numargs++].v_copy_no_alloc(result); - result.set_null(); + args[numargs++] = ostd::move(result); continue; case CODE_PRINT: cs.print_var(static_cast(cs.identmap[op >> 8])); @@ -707,13 +707,12 @@ static ostd::Uint32 *runcode(CsState &cs, ostd::Uint32 *code, CsValue &result) { } case CODE_JUMP_RESULT_TRUE: { ostd::Uint32 len = op >> 8; - result.cleanup(); --numargs; if (args[numargs].get_type() == CsValueType::code) { cs.run_ret(args[numargs].get_code(), result); args[numargs].cleanup(); } else { - result.v_copy_no_alloc(args[numargs]); + result = ostd::move(args[numargs]); } if (result.get_bool()) { code += len; @@ -722,13 +721,12 @@ static ostd::Uint32 *runcode(CsState &cs, ostd::Uint32 *code, CsValue &result) { } case CODE_JUMP_RESULT_FALSE: { ostd::Uint32 len = op >> 8; - result.cleanup(); --numargs; if (args[numargs].get_type() == CsValueType::code) { cs.run_ret(args[numargs].get_code(), result); args[numargs].cleanup(); } else { - result.v_copy_no_alloc(args[numargs]); + result = ostd::move(args[numargs]); } if (!result.get_bool()) { code += len; @@ -809,14 +807,12 @@ static ostd::Uint32 *runcode(CsState &cs, ostd::Uint32 *code, CsValue &result) { continue; case CODE_RESULT | RET_NULL: - result.cleanup(); - result.v_copy_no_alloc(args[--numargs]); + result = ostd::move(args[--numargs]); continue; case CODE_RESULT | RET_STR: case CODE_RESULT | RET_INT: case CODE_RESULT | RET_FLOAT: - result.cleanup(); - result.v_copy_no_alloc(args[--numargs]); + result = ostd::move(args[--numargs]); force_arg(result, op & CODE_RET_MASK); continue; @@ -916,9 +912,9 @@ static ostd::Uint32 *runcode(CsState &cs, ostd::Uint32 *code, CsValue &result) { case CODE_IDENTARG: { CsAlias *a = static_cast(cs.identmap[op >> 8]); if (!(cs.p_stack->usedargs & (1 << a->get_index()))) { + CsValue nv; CsAliasInternal::push_arg( - a, null_value, cs.p_stack->argstack[a->get_index()], - false + a, nv, cs.p_stack->argstack[a->get_index()], false ); cs.p_stack->usedargs |= 1 << a->get_index(); } @@ -939,8 +935,9 @@ static ostd::Uint32 *runcode(CsState &cs, ostd::Uint32 *code, CsValue &result) { id->get_index() < MaxArguments && !(cs.p_stack->usedargs & (1 << id->get_index())) ) { + CsValue nv; CsAliasInternal::push_arg( - static_cast(id), null_value, + static_cast(id), nv, cs.p_stack->argstack[id->get_index()], false ); cs.p_stack->usedargs |= 1 << id->get_index(); @@ -1328,7 +1325,7 @@ static ostd::Uint32 *runcode(CsState &cs, ostd::Uint32 *code, CsValue &result) { buf, ostd::iter(&args[offset], callargs), " " ); CsValue tv; - tv.set_mstr(buf.get().iter()); + tv.set_str(ostd::move(buf.get())); CsCommandInternal::call(id, CsValueRange(&tv, 1), result); } force_arg(result, op & CODE_RET_MASK); @@ -1351,8 +1348,7 @@ static ostd::Uint32 *runcode(CsState &cs, ostd::Uint32 *code, CsValue &result) { ((op & CODE_OP_MASK) == CODE_CONC) ? " " : "" ); free_args(args, numargs, numargs - numconc); - args[numargs].set_mstr(buf.get().iter()); - buf.get().disown(); + args[numargs].set_str(ostd::move(buf.get())); force_arg(args[numargs], op & CODE_RET_MASK); numargs++; continue; @@ -1368,8 +1364,7 @@ static ostd::Uint32 *runcode(CsState &cs, ostd::Uint32 *code, CsValue &result) { buf, ostd::iter(&args[numargs - numconc], numconc) ); free_args(args, numargs, numargs - numconc); - result.set_mstr(buf.get().iter()); - buf.get().disown(); + result.set_str(ostd::move(buf.get())); force_arg(result, op & CODE_RET_MASK); continue; } @@ -1388,8 +1383,9 @@ static ostd::Uint32 *runcode(CsState &cs, ostd::Uint32 *code, CsValue &result) { continue; case CODE_ALIASU: numargs -= 2; - cs.set_alias(args[numargs].get_str(), args[numargs + 1]); - args[numargs].cleanup(); + cs.set_alias( + args[numargs].get_str(), ostd::move(args[numargs + 1]) + ); continue; case CODE_CALL | RET_NULL: @@ -1442,8 +1438,7 @@ static ostd::Uint32 *runcode(CsState &cs, ostd::Uint32 *code, CsValue &result) { idarg.get_type() != CsValueType::cstring ) { litval: - result.cleanup(); - result.v_copy_no_alloc(idarg); + result = ostd::move(idarg); force_arg(result, op & CODE_RET_MASK); while (--numargs >= offset) { args[numargs].cleanup(); diff --git a/cs_vm.hh b/cs_vm.hh index 09815743..40bd1112 100644 --- a/cs_vm.hh +++ b/cs_vm.hh @@ -79,10 +79,6 @@ enum { RET_FLOAT = VAL_FLOAT << CODE_RET, }; -struct NullValue: CsValue { - NullValue() { set_null(); } -} const null_value; - ostd::ConstCharRange cs_debug_line( ostd::ConstCharRange p, ostd::ConstCharRange fmt, ostd::CharRange buf ); @@ -232,19 +228,18 @@ static inline void bcode_decr(ostd::Uint32 *bc) { struct CsAliasInternal { static void push_arg( - CsAlias *a, CsValue const &v, CsIdentStack &st, bool um = true + CsAlias *a, CsValue &v, CsIdentStack &st, bool um = true ) { if (a->p_astack == &st) { /* prevent cycles and unnecessary code elsewhere */ - a->p_val.cleanup(); - a->p_val.v_copy_no_alloc(v); + a->p_val = ostd::move(v); clean_code(a); return; } - st.val_s.v_copy_no_alloc(a->p_val); + st.val_s = ostd::move(a->p_val); st.next = a->p_astack; a->p_astack = &st; - a->p_val.v_copy_no_alloc(v); + a->p_val = ostd::move(v); clean_code(a); if (um) { a->p_flags &= ~IDF_UNKNOWN; @@ -256,33 +251,31 @@ struct CsAliasInternal { return; } CsIdentStack *st = a->p_astack; - a->p_val.cleanup(); - a->p_val.v_copy_no_alloc(a->p_astack->val_s); + a->p_val = ostd::move(a->p_astack->val_s); clean_code(a); a->p_astack = st->next; } static void undo_arg(CsAlias *a, CsIdentStack &st) { CsIdentStack *prev = a->p_astack; - st.val_s.v_copy_no_alloc(a->p_val); + st.val_s = ostd::move(a->p_val); st.next = prev; a->p_astack = prev->next; - a->p_val.v_copy_no_alloc(prev->val_s); + a->p_val = ostd::move(prev->val_s); clean_code(a); } - static void redo_arg(CsAlias *a, CsIdentStack const &st) { + static void redo_arg(CsAlias *a, CsIdentStack &st) { CsIdentStack *prev = st.next; - prev->val_s.v_copy_no_alloc(a->p_val); + prev->val_s = ostd::move(a->p_val); a->p_astack = prev; - a->p_val.v_copy_no_alloc(st.val_s); + a->p_val = ostd::move(st.val_s); clean_code(a); } static void set_arg(CsAlias *a, CsState &cs, CsValue &v) { if (cs.p_stack->usedargs & (1 << a->get_index())) { - a->p_val.cleanup(); - a->p_val.v_copy_no_alloc(v); + a->p_val = ostd::move(v); clean_code(a); } else { push_arg(a, v, cs.p_stack->argstack[a->get_index()], false); @@ -291,8 +284,7 @@ struct CsAliasInternal { } static void set_alias(CsAlias *a, CsState &cs, CsValue &v) { - a->p_val.cleanup(); - a->p_val.v_copy_no_alloc(v); + a->p_val = ostd::move(v); clean_code(a); a->p_flags = (a->p_flags & cs.identflags) | cs.identflags; } diff --git a/cubescript.cc b/cubescript.cc index 56dbc246..7b6dc9a8 100644 --- a/cubescript.cc +++ b/cubescript.cc @@ -81,12 +81,10 @@ CsAlias::CsAlias(ostd::ConstCharRange name, int fl): { p_val.set_null(); } -CsAlias::CsAlias(ostd::ConstCharRange name, CsValue const &v, int fl): +CsAlias::CsAlias(ostd::ConstCharRange name, CsValue v, int fl): CsIdent(CsIdentType::alias, name, fl), - p_acode(nullptr), p_astack(nullptr), p_val() -{ - p_val.v_copy_no_alloc(v); -} + p_acode(nullptr), p_astack(nullptr), p_val(ostd::move(v)) +{} CsCommand::CsCommand( ostd::ConstCharRange name, ostd::ConstCharRange args, @@ -510,7 +508,7 @@ void CsState::touch_var(ostd::ConstCharRange name) { } } -void CsState::set_alias(ostd::ConstCharRange name, CsValue &v) { +void CsState::set_alias(ostd::ConstCharRange name, CsValue v) { CsIdent *id = get_ident(name); if (id) { switch (id->get_type()) { @@ -539,12 +537,10 @@ void CsState::set_alias(ostd::ConstCharRange name, CsValue &v) { ); break; } - v.cleanup(); } else if (cs_check_num(name)) { cs_debug_code(*this, "cannot alias number %s", name); - v.cleanup(); } else { - add_ident(new CsAlias(name, v, identflags)); + add_ident(new CsAlias(name, ostd::move(v), identflags)); } } @@ -1018,7 +1014,6 @@ static inline void cs_loop_conc( s.push(' '); } s.push_n(vstr.data(), vstr.size()); - v.cleanup(); } s.push('\0'); ostd::Size len = s.size() - 1; @@ -1239,9 +1234,7 @@ void cs_init_lib_base(CsState &cs) { }); cs.new_command("alias", "sT", [&cs](CsValueRange args, CsValue &) { - CsValue &v = args[1]; - cs.set_alias(args[0].get_strr(), v); - v.set_null(); + cs.set_alias(args[0].get_strr(), ostd::move(args[1])); }); cs.new_command("getvarmin", "s", [&cs](CsValueRange args, CsValue &res) { diff --git a/cubescript.hh b/cubescript.hh index b7ea6596..ad527281 100644 --- a/cubescript.hh +++ b/cubescript.hh @@ -66,6 +66,7 @@ enum class CsValueType { struct OSTD_EXPORT CsValue { CsValue(); + ~CsValue(); CsValue(CsValue const &); CsValue(CsValue &&); @@ -73,12 +74,6 @@ struct OSTD_EXPORT CsValue { CsValue &operator=(CsValue const &v); CsValue &operator=(CsValue &&v); - void v_copy_no_alloc(CsValue const &v) { - memcpy(&p_stor, &v.p_stor, sizeof(p_stor)); - p_len = v.p_len; - p_type = v.p_type; - } - CsValueType get_type() const; void set_int(CsInt val); @@ -281,7 +276,7 @@ private: CsAlias(ostd::ConstCharRange n, CsInt a, int flags); CsAlias(ostd::ConstCharRange n, CsFloat a, int flags); CsAlias(ostd::ConstCharRange n, int flags); - CsAlias(ostd::ConstCharRange n, CsValue const &v, int flags); + CsAlias(ostd::ConstCharRange n, CsValue v, int flags); CsBytecode *p_acode; CsIdentStack *p_astack; @@ -428,7 +423,7 @@ struct OSTD_EXPORT CsState { bool run_file_ret(ostd::ConstCharRange fname, CsValue &ret); bool run_file(ostd::ConstCharRange fname); - void set_alias(ostd::ConstCharRange name, CsValue &v); + void set_alias(ostd::ConstCharRange name, CsValue v); void set_var_int( ostd::ConstCharRange name, CsInt v, diff --git a/lib_list.cc b/lib_list.cc index 82564d74..46707dcb 100644 --- a/lib_list.cc +++ b/lib_list.cc @@ -89,7 +89,6 @@ static void cs_loop_list_conc( cs.run_ret(body, v); CsString vstr = ostd::move(v.get_str()); r.push_n(vstr.data(), vstr.size()); - v.cleanup(); } r.push('\0'); ostd::Size len = r.size(); diff --git a/tools/repl.cc b/tools/repl.cc index 08148555..2b1f1e8b 100644 --- a/tools/repl.cc +++ b/tools/repl.cc @@ -186,7 +186,6 @@ static void do_call(CsState &cs, ostd::ConstCharRange line) { cs.run_ret(line, ret); } catch (InterruptedException) { signal(SIGINT, SIG_DFL); - ret.cleanup(); ostd::writeln(""); return; } @@ -194,7 +193,6 @@ static void do_call(CsState &cs, ostd::ConstCharRange line) { if (ret.get_type() != CsValueType::null) { ostd::writeln(ret.get_str()); } - ret.cleanup(); } static void do_tty(CsState &cs) {