forked from OctaForge/libcubescript
complete CsValue copy/move semantics
parent
01c464c619
commit
3a5b8492b5
15
cs_val.cc
15
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<CsBytecode *>(p_stor) = nullptr;
|
||||
}
|
||||
|
||||
void CsValue::set_code(CsBytecode *val) {
|
||||
|
@ -378,6 +380,7 @@ CsStackedValue::CsStackedValue(CsIdent *id):
|
|||
}
|
||||
|
||||
CsStackedValue::~CsStackedValue() {
|
||||
cleanup();
|
||||
pop();
|
||||
}
|
||||
|
||||
|
|
43
cs_vm.cc
43
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<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();
|
||||
|
|
32
cs_vm.hh
32
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;
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue