complete CsValue copy/move semantics

master
Daniel Kolesa 2016-09-06 22:57:10 +02:00
parent 01c464c619
commit 3a5b8492b5
7 changed files with 49 additions and 74 deletions

View File

@ -14,6 +14,10 @@ CsValue::CsValue():
p_stor(), p_len(0), p_type(CsValueType::null) p_stor(), p_len(0), p_type(CsValueType::null)
{} {}
CsValue::~CsValue() {
cleanup();
}
CsValue::CsValue(CsValue const &v): CsValue() { CsValue::CsValue(CsValue const &v): CsValue() {
*this = v; *this = v;
} }
@ -30,7 +34,7 @@ CsValue &CsValue::operator=(CsValue const &v) {
case CsValueType::ident: case CsValueType::ident:
p_len = v.p_len; p_len = v.p_len;
p_type = v.p_type; p_type = v.p_type;
memcpy(&p_stor, &v.p_stor, sizeof(p_stor)); p_stor = v.p_stor;
break; break;
case CsValueType::string: case CsValueType::string:
case CsValueType::cstring: case CsValueType::cstring:
@ -51,10 +55,9 @@ CsValue &CsValue::operator=(CsValue const &v) {
CsValue &CsValue::operator=(CsValue &&v) { CsValue &CsValue::operator=(CsValue &&v) {
cleanup(); cleanup();
p_len = v.p_len; ostd::swap(p_len, v.p_len);
p_type = v.p_type; ostd::swap(p_type, v.p_type);
memcpy(&p_stor, &v.p_stor, sizeof(p_stor)); ostd::swap(p_stor, v.p_stor);
v.set_null();
return *this; return *this;
} }
@ -107,7 +110,6 @@ void CsValue::set_str(CsString val) {
void CsValue::set_null() { void CsValue::set_null() {
cleanup(); cleanup();
csv_get<CsBytecode *>(p_stor) = nullptr;
} }
void CsValue::set_code(CsBytecode *val) { void CsValue::set_code(CsBytecode *val) {
@ -378,6 +380,7 @@ CsStackedValue::CsStackedValue(CsIdent *id):
} }
CsStackedValue::~CsStackedValue() { CsStackedValue::~CsStackedValue() {
cleanup();
pop(); pop();
} }

View File

@ -22,7 +22,8 @@ struct CsCommandInternal {
static inline void cs_push_alias(CsIdent *id, CsIdentStack &st) { static inline void cs_push_alias(CsIdent *id, CsIdentStack &st) {
if (id->is_alias() && (id->get_index() >= MaxArguments)) { if (id->is_alias() && (id->get_index() >= MaxArguments)) {
CsAliasInternal::push_arg(static_cast<CsAlias *>(id), null_value, st); CsValue nv;
CsAliasInternal::push_arg(static_cast<CsAlias *>(id), nv, st);
} }
} }
@ -400,7 +401,7 @@ static inline void callcommand(
auto buf = ostd::appender<CsString>(); auto buf = ostd::appender<CsString>();
cscript::util::tvals_concat(buf, ostd::iter(args, i), " "); cscript::util::tvals_concat(buf, ostd::iter(args, i), " ");
CsValue tv; CsValue tv;
tv.set_mstr(buf.get().iter()); tv.set_str(ostd::move(buf.get()));
CsCommandInternal::call(id, CsValueRange(&tv, 1), res); CsCommandInternal::call(id, CsValueRange(&tv, 1), res);
goto cleanup; goto cleanup;
} }
@ -642,8 +643,7 @@ static ostd::Uint32 *runcode(CsState &cs, ostd::Uint32 *code, CsValue &result) {
force_arg(result, op & CODE_RET_MASK); force_arg(result, op & CODE_RET_MASK);
/* fallthrough */ /* fallthrough */
case CODE_RESULT_ARG | RET_NULL: case CODE_RESULT_ARG | RET_NULL:
args[numargs++].v_copy_no_alloc(result); args[numargs++] = ostd::move(result);
result.set_null();
continue; continue;
case CODE_PRINT: case CODE_PRINT:
cs.print_var(static_cast<CsVar *>(cs.identmap[op >> 8])); cs.print_var(static_cast<CsVar *>(cs.identmap[op >> 8]));
@ -707,13 +707,12 @@ static ostd::Uint32 *runcode(CsState &cs, ostd::Uint32 *code, CsValue &result) {
} }
case CODE_JUMP_RESULT_TRUE: { case CODE_JUMP_RESULT_TRUE: {
ostd::Uint32 len = op >> 8; ostd::Uint32 len = op >> 8;
result.cleanup();
--numargs; --numargs;
if (args[numargs].get_type() == CsValueType::code) { if (args[numargs].get_type() == CsValueType::code) {
cs.run_ret(args[numargs].get_code(), result); cs.run_ret(args[numargs].get_code(), result);
args[numargs].cleanup(); args[numargs].cleanup();
} else { } else {
result.v_copy_no_alloc(args[numargs]); result = ostd::move(args[numargs]);
} }
if (result.get_bool()) { if (result.get_bool()) {
code += len; code += len;
@ -722,13 +721,12 @@ static ostd::Uint32 *runcode(CsState &cs, ostd::Uint32 *code, CsValue &result) {
} }
case CODE_JUMP_RESULT_FALSE: { case CODE_JUMP_RESULT_FALSE: {
ostd::Uint32 len = op >> 8; ostd::Uint32 len = op >> 8;
result.cleanup();
--numargs; --numargs;
if (args[numargs].get_type() == CsValueType::code) { if (args[numargs].get_type() == CsValueType::code) {
cs.run_ret(args[numargs].get_code(), result); cs.run_ret(args[numargs].get_code(), result);
args[numargs].cleanup(); args[numargs].cleanup();
} else { } else {
result.v_copy_no_alloc(args[numargs]); result = ostd::move(args[numargs]);
} }
if (!result.get_bool()) { if (!result.get_bool()) {
code += len; code += len;
@ -809,14 +807,12 @@ static ostd::Uint32 *runcode(CsState &cs, ostd::Uint32 *code, CsValue &result) {
continue; continue;
case CODE_RESULT | RET_NULL: case CODE_RESULT | RET_NULL:
result.cleanup(); result = ostd::move(args[--numargs]);
result.v_copy_no_alloc(args[--numargs]);
continue; continue;
case CODE_RESULT | RET_STR: case CODE_RESULT | RET_STR:
case CODE_RESULT | RET_INT: case CODE_RESULT | RET_INT:
case CODE_RESULT | RET_FLOAT: case CODE_RESULT | RET_FLOAT:
result.cleanup(); result = ostd::move(args[--numargs]);
result.v_copy_no_alloc(args[--numargs]);
force_arg(result, op & CODE_RET_MASK); force_arg(result, op & CODE_RET_MASK);
continue; continue;
@ -916,9 +912,9 @@ static ostd::Uint32 *runcode(CsState &cs, ostd::Uint32 *code, CsValue &result) {
case CODE_IDENTARG: { case CODE_IDENTARG: {
CsAlias *a = static_cast<CsAlias *>(cs.identmap[op >> 8]); CsAlias *a = static_cast<CsAlias *>(cs.identmap[op >> 8]);
if (!(cs.p_stack->usedargs & (1 << a->get_index()))) { if (!(cs.p_stack->usedargs & (1 << a->get_index()))) {
CsValue nv;
CsAliasInternal::push_arg( CsAliasInternal::push_arg(
a, null_value, cs.p_stack->argstack[a->get_index()], a, nv, cs.p_stack->argstack[a->get_index()], false
false
); );
cs.p_stack->usedargs |= 1 << a->get_index(); 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 && id->get_index() < MaxArguments &&
!(cs.p_stack->usedargs & (1 << id->get_index())) !(cs.p_stack->usedargs & (1 << id->get_index()))
) { ) {
CsValue nv;
CsAliasInternal::push_arg( CsAliasInternal::push_arg(
static_cast<CsAlias *>(id), null_value, static_cast<CsAlias *>(id), nv,
cs.p_stack->argstack[id->get_index()], false cs.p_stack->argstack[id->get_index()], false
); );
cs.p_stack->usedargs |= 1 << id->get_index(); 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), " " buf, ostd::iter(&args[offset], callargs), " "
); );
CsValue tv; CsValue tv;
tv.set_mstr(buf.get().iter()); tv.set_str(ostd::move(buf.get()));
CsCommandInternal::call(id, CsValueRange(&tv, 1), result); CsCommandInternal::call(id, CsValueRange(&tv, 1), result);
} }
force_arg(result, op & CODE_RET_MASK); 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) ? " " : "" ((op & CODE_OP_MASK) == CODE_CONC) ? " " : ""
); );
free_args(args, numargs, numargs - numconc); free_args(args, numargs, numargs - numconc);
args[numargs].set_mstr(buf.get().iter()); args[numargs].set_str(ostd::move(buf.get()));
buf.get().disown();
force_arg(args[numargs], op & CODE_RET_MASK); force_arg(args[numargs], op & CODE_RET_MASK);
numargs++; numargs++;
continue; continue;
@ -1368,8 +1364,7 @@ static ostd::Uint32 *runcode(CsState &cs, ostd::Uint32 *code, CsValue &result) {
buf, ostd::iter(&args[numargs - numconc], numconc) buf, ostd::iter(&args[numargs - numconc], numconc)
); );
free_args(args, numargs, numargs - numconc); free_args(args, numargs, numargs - numconc);
result.set_mstr(buf.get().iter()); result.set_str(ostd::move(buf.get()));
buf.get().disown();
force_arg(result, op & CODE_RET_MASK); force_arg(result, op & CODE_RET_MASK);
continue; continue;
} }
@ -1388,8 +1383,9 @@ static ostd::Uint32 *runcode(CsState &cs, ostd::Uint32 *code, CsValue &result) {
continue; continue;
case CODE_ALIASU: case CODE_ALIASU:
numargs -= 2; numargs -= 2;
cs.set_alias(args[numargs].get_str(), args[numargs + 1]); cs.set_alias(
args[numargs].cleanup(); args[numargs].get_str(), ostd::move(args[numargs + 1])
);
continue; continue;
case CODE_CALL | RET_NULL: 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 idarg.get_type() != CsValueType::cstring
) { ) {
litval: litval:
result.cleanup(); result = ostd::move(idarg);
result.v_copy_no_alloc(idarg);
force_arg(result, op & CODE_RET_MASK); force_arg(result, op & CODE_RET_MASK);
while (--numargs >= offset) { while (--numargs >= offset) {
args[numargs].cleanup(); args[numargs].cleanup();

View File

@ -79,10 +79,6 @@ enum {
RET_FLOAT = VAL_FLOAT << CODE_RET, RET_FLOAT = VAL_FLOAT << CODE_RET,
}; };
struct NullValue: CsValue {
NullValue() { set_null(); }
} const null_value;
ostd::ConstCharRange cs_debug_line( ostd::ConstCharRange cs_debug_line(
ostd::ConstCharRange p, ostd::ConstCharRange fmt, ostd::CharRange buf ostd::ConstCharRange p, ostd::ConstCharRange fmt, ostd::CharRange buf
); );
@ -232,19 +228,18 @@ static inline void bcode_decr(ostd::Uint32 *bc) {
struct CsAliasInternal { struct CsAliasInternal {
static void push_arg( 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) { if (a->p_astack == &st) {
/* prevent cycles and unnecessary code elsewhere */ /* prevent cycles and unnecessary code elsewhere */
a->p_val.cleanup(); a->p_val = ostd::move(v);
a->p_val.v_copy_no_alloc(v);
clean_code(a); clean_code(a);
return; return;
} }
st.val_s.v_copy_no_alloc(a->p_val); st.val_s = ostd::move(a->p_val);
st.next = a->p_astack; st.next = a->p_astack;
a->p_astack = &st; a->p_astack = &st;
a->p_val.v_copy_no_alloc(v); a->p_val = ostd::move(v);
clean_code(a); clean_code(a);
if (um) { if (um) {
a->p_flags &= ~IDF_UNKNOWN; a->p_flags &= ~IDF_UNKNOWN;
@ -256,33 +251,31 @@ struct CsAliasInternal {
return; return;
} }
CsIdentStack *st = a->p_astack; CsIdentStack *st = a->p_astack;
a->p_val.cleanup(); a->p_val = ostd::move(a->p_astack->val_s);
a->p_val.v_copy_no_alloc(a->p_astack->val_s);
clean_code(a); clean_code(a);
a->p_astack = st->next; a->p_astack = st->next;
} }
static void undo_arg(CsAlias *a, CsIdentStack &st) { static void undo_arg(CsAlias *a, CsIdentStack &st) {
CsIdentStack *prev = a->p_astack; 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; st.next = prev;
a->p_astack = prev->next; 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); clean_code(a);
} }
static void redo_arg(CsAlias *a, CsIdentStack const &st) { static void redo_arg(CsAlias *a, CsIdentStack &st) {
CsIdentStack *prev = st.next; 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_astack = prev;
a->p_val.v_copy_no_alloc(st.val_s); a->p_val = ostd::move(st.val_s);
clean_code(a); clean_code(a);
} }
static void set_arg(CsAlias *a, CsState &cs, CsValue &v) { static void set_arg(CsAlias *a, CsState &cs, CsValue &v) {
if (cs.p_stack->usedargs & (1 << a->get_index())) { if (cs.p_stack->usedargs & (1 << a->get_index())) {
a->p_val.cleanup(); a->p_val = ostd::move(v);
a->p_val.v_copy_no_alloc(v);
clean_code(a); clean_code(a);
} else { } else {
push_arg(a, v, cs.p_stack->argstack[a->get_index()], false); 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) { static void set_alias(CsAlias *a, CsState &cs, CsValue &v) {
a->p_val.cleanup(); a->p_val = ostd::move(v);
a->p_val.v_copy_no_alloc(v);
clean_code(a); clean_code(a);
a->p_flags = (a->p_flags & cs.identflags) | cs.identflags; a->p_flags = (a->p_flags & cs.identflags) | cs.identflags;
} }

View File

@ -81,12 +81,10 @@ CsAlias::CsAlias(ostd::ConstCharRange name, int fl):
{ {
p_val.set_null(); 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), CsIdent(CsIdentType::alias, name, fl),
p_acode(nullptr), p_astack(nullptr), p_val() p_acode(nullptr), p_astack(nullptr), p_val(ostd::move(v))
{ {}
p_val.v_copy_no_alloc(v);
}
CsCommand::CsCommand( CsCommand::CsCommand(
ostd::ConstCharRange name, ostd::ConstCharRange args, 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); CsIdent *id = get_ident(name);
if (id) { if (id) {
switch (id->get_type()) { switch (id->get_type()) {
@ -539,12 +537,10 @@ void CsState::set_alias(ostd::ConstCharRange name, CsValue &v) {
); );
break; break;
} }
v.cleanup();
} else if (cs_check_num(name)) { } else if (cs_check_num(name)) {
cs_debug_code(*this, "cannot alias number %s", name); cs_debug_code(*this, "cannot alias number %s", name);
v.cleanup();
} else { } 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(' ');
} }
s.push_n(vstr.data(), vstr.size()); s.push_n(vstr.data(), vstr.size());
v.cleanup();
} }
s.push('\0'); s.push('\0');
ostd::Size len = s.size() - 1; 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 &) { cs.new_command("alias", "sT", [&cs](CsValueRange args, CsValue &) {
CsValue &v = args[1]; cs.set_alias(args[0].get_strr(), ostd::move(args[1]));
cs.set_alias(args[0].get_strr(), v);
v.set_null();
}); });
cs.new_command("getvarmin", "s", [&cs](CsValueRange args, CsValue &res) { cs.new_command("getvarmin", "s", [&cs](CsValueRange args, CsValue &res) {

View File

@ -66,6 +66,7 @@ enum class CsValueType {
struct OSTD_EXPORT CsValue { struct OSTD_EXPORT CsValue {
CsValue(); CsValue();
~CsValue();
CsValue(CsValue const &); CsValue(CsValue const &);
CsValue(CsValue &&); CsValue(CsValue &&);
@ -73,12 +74,6 @@ struct OSTD_EXPORT CsValue {
CsValue &operator=(CsValue const &v); CsValue &operator=(CsValue const &v);
CsValue &operator=(CsValue &&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; CsValueType get_type() const;
void set_int(CsInt val); void set_int(CsInt val);
@ -281,7 +276,7 @@ private:
CsAlias(ostd::ConstCharRange n, CsInt a, int flags); CsAlias(ostd::ConstCharRange n, CsInt a, int flags);
CsAlias(ostd::ConstCharRange n, CsFloat a, int flags); CsAlias(ostd::ConstCharRange n, CsFloat a, int flags);
CsAlias(ostd::ConstCharRange n, 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; CsBytecode *p_acode;
CsIdentStack *p_astack; CsIdentStack *p_astack;
@ -428,7 +423,7 @@ struct OSTD_EXPORT CsState {
bool run_file_ret(ostd::ConstCharRange fname, CsValue &ret); bool run_file_ret(ostd::ConstCharRange fname, CsValue &ret);
bool run_file(ostd::ConstCharRange fname); 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( void set_var_int(
ostd::ConstCharRange name, CsInt v, ostd::ConstCharRange name, CsInt v,

View File

@ -89,7 +89,6 @@ static void cs_loop_list_conc(
cs.run_ret(body, v); cs.run_ret(body, v);
CsString vstr = ostd::move(v.get_str()); CsString vstr = ostd::move(v.get_str());
r.push_n(vstr.data(), vstr.size()); r.push_n(vstr.data(), vstr.size());
v.cleanup();
} }
r.push('\0'); r.push('\0');
ostd::Size len = r.size(); ostd::Size len = r.size();

View File

@ -186,7 +186,6 @@ static void do_call(CsState &cs, ostd::ConstCharRange line) {
cs.run_ret(line, ret); cs.run_ret(line, ret);
} catch (InterruptedException) { } catch (InterruptedException) {
signal(SIGINT, SIG_DFL); signal(SIGINT, SIG_DFL);
ret.cleanup();
ostd::writeln("<execution interrupted>"); ostd::writeln("<execution interrupted>");
return; return;
} }
@ -194,7 +193,6 @@ static void do_call(CsState &cs, ostd::ConstCharRange line) {
if (ret.get_type() != CsValueType::null) { if (ret.get_type() != CsValueType::null) {
ostd::writeln(ret.get_str()); ostd::writeln(ret.get_str());
} }
ret.cleanup();
} }
static void do_tty(CsState &cs) { static void do_tty(CsState &cs) {