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)
{}
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<CsBytecode *>(p_stor) = nullptr;
}
void CsValue::set_code(CsBytecode *val) {
@ -378,6 +380,7 @@ CsStackedValue::CsStackedValue(CsIdent *id):
}
CsStackedValue::~CsStackedValue() {
cleanup();
pop();
}

View File

@ -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<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>();
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<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: {
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<CsAlias *>(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<CsAlias *>(id), null_value,
static_cast<CsAlias *>(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();

View File

@ -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;
}

View File

@ -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) {

View File

@ -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,

View File

@ -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();

View File

@ -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("<execution interrupted>");
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) {