refactor cs_value and related structures to contain state

this will allow us to intern strings inside cs_value
master
Daniel Kolesa 2021-03-17 01:26:16 +01:00
parent 8c77724f88
commit c004db42c6
7 changed files with 151 additions and 93 deletions

View File

@ -42,6 +42,7 @@ enum {
struct cs_bcode; struct cs_bcode;
struct cs_value; struct cs_value;
struct cs_state;
struct cs_shared_state; struct cs_shared_state;
struct OSTD_EXPORT cs_bcode_ref { struct OSTD_EXPORT cs_bcode_ref {
@ -88,8 +89,8 @@ private:
/* for internal use only */ /* for internal use only */
cs_strref(char const *p, cs_shared_state &cs); cs_strref(char const *p, cs_shared_state &cs);
char const *p_str;
cs_shared_state *p_state; cs_shared_state *p_state;
char const *p_str;
}; };
enum class cs_value_type { enum class cs_value_type {
@ -97,14 +98,17 @@ enum class cs_value_type {
}; };
struct OSTD_EXPORT cs_value { struct OSTD_EXPORT cs_value {
cs_value(); cs_value() = delete;
~cs_value(); ~cs_value();
cs_value(cs_state &);
cs_value(cs_shared_state &);
cs_value(cs_value const &); cs_value(cs_value const &);
cs_value(cs_value &&); cs_value(cs_value &&);
cs_value &operator=(cs_value const &v); cs_value &operator=(cs_value const &);
cs_value &operator=(cs_value &&v); cs_value &operator=(cs_value &&);
cs_value_type get_type() const; cs_value_type get_type() const;
@ -135,7 +139,22 @@ struct OSTD_EXPORT cs_value {
bool code_is_empty() const; bool code_is_empty() const;
private: private:
std::aligned_union_t<1, cs_int, cs_float, void *> p_stor; template<typename T>
struct stor_t {
cs_shared_state *state;
T val;
};
cs_shared_state *state() const {
return reinterpret_cast<stor_t<void *> const *>(&p_stor)->state;
}
std::aligned_union_t<1,
stor_t<cs_int>,
stor_t<cs_float>,
stor_t<void *>,
cs_strref
> p_stor;
size_t p_len; size_t p_len;
cs_value_type p_type; cs_value_type p_type;
}; };
@ -143,6 +162,8 @@ private:
struct cs_ident_stack { struct cs_ident_stack {
cs_value val_s; cs_value val_s;
cs_ident_stack *next; cs_ident_stack *next;
cs_ident_stack(cs_state &cs): val_s{cs}, next{nullptr} {}
}; };
struct cs_error; struct cs_error;
@ -308,11 +329,11 @@ struct OSTD_EXPORT cs_alias: cs_ident {
void get_cstr(cs_value &v) const; void get_cstr(cs_value &v) const;
void get_cval(cs_value &v) const; void get_cval(cs_value &v) const;
private: private:
cs_alias(ostd::string_range n, cs_string a, int flags); cs_alias(cs_state &cs, ostd::string_range n, cs_string a, int flags);
cs_alias(ostd::string_range n, cs_int a, int flags); cs_alias(cs_state &cs, ostd::string_range n, cs_int a, int flags);
cs_alias(ostd::string_range n, cs_float a, int flags); cs_alias(cs_state &cs, ostd::string_range n, cs_float a, int flags);
cs_alias(ostd::string_range n, int flags); cs_alias(cs_state &cs, ostd::string_range n, int flags);
cs_alias(ostd::string_range n, cs_value v, int flags); cs_alias(cs_state &cs, ostd::string_range n, cs_value v, int flags);
cs_bcode *p_acode; cs_bcode *p_acode;
cs_ident_stack *p_astack; cs_ident_stack *p_astack;
@ -362,6 +383,7 @@ static inline void *cs_default_alloc(void *, void *p, size_t, size_t ns) {
struct OSTD_EXPORT cs_state { struct OSTD_EXPORT cs_state {
friend struct cs_error; friend struct cs_error;
friend struct cs_strman; friend struct cs_strman;
friend struct cs_value;
friend struct cs_gen_state; friend struct cs_gen_state;
cs_shared_state *p_state; cs_shared_state *p_state;
@ -603,7 +625,7 @@ private:
}; };
struct OSTD_EXPORT cs_stacked_value: cs_value { struct OSTD_EXPORT cs_stacked_value: cs_value {
cs_stacked_value(cs_ident *id = nullptr); cs_stacked_value(cs_state &cs, cs_ident *id = nullptr);
~cs_stacked_value(); ~cs_stacked_value();
cs_stacked_value(cs_stacked_value const &) = delete; cs_stacked_value(cs_stacked_value const &) = delete;

View File

@ -4,10 +4,16 @@
namespace cscript { namespace cscript {
template<typename T>
struct stor_priv_t {
cs_shared_state *state;
T val;
};
template<typename T, typename U> template<typename T, typename U>
static inline T &csv_get(U &stor) { static inline T &csv_get(U &stor) {
/* ugly, but internal and unlikely to cause bugs */ /* ugly, but internal and unlikely to cause bugs */
return const_cast<T &>(reinterpret_cast<T const &>(stor)); return const_cast<T &>(reinterpret_cast<stor_priv_t<T> const &>(stor).val);
} }
template<typename T> template<typename T>
@ -28,19 +34,23 @@ static inline void csv_cleanup(cs_value_type tv, T &stor) {
} }
} }
cs_value::cs_value(): cs_value::cs_value(cs_state &st): cs_value(*st.p_state) {}
cs_value::cs_value(cs_shared_state &st):
p_stor(), p_len(0), p_type(cs_value_type::Null) p_stor(), p_len(0), p_type(cs_value_type::Null)
{} {
reinterpret_cast<stor_priv_t<void *> *>(&p_stor)->state = &st;
}
cs_value::~cs_value() { cs_value::~cs_value() {
csv_cleanup(p_type, p_stor); csv_cleanup(p_type, p_stor);
} }
cs_value::cs_value(cs_value const &v): cs_value() { cs_value::cs_value(cs_value const &v): cs_value(*v.state()) {
*this = v; *this = v;
} }
cs_value::cs_value(cs_value &&v): cs_value() { cs_value::cs_value(cs_value &&v): cs_value(*v.state()) {
*this = std::move(v); *this = std::move(v);
} }
@ -375,8 +385,8 @@ bool cs_value::get_bool() const {
/* stacked value for easy stack management */ /* stacked value for easy stack management */
cs_stacked_value::cs_stacked_value(cs_ident *id): cs_stacked_value::cs_stacked_value(cs_state &cs, cs_ident *id):
cs_value(), p_a(nullptr), p_stack(), p_pushed(false) cs_value(cs), p_a(nullptr), p_stack{cs}, p_pushed(false)
{ {
set_alias(id); set_alias(id);
} }

View File

@ -12,7 +12,7 @@ cs_strref::cs_strref(cs_shared_state &cs, ostd::string_range str):
p_str = cs.strman->add(str); p_str = cs.strman->add(str);
} }
cs_strref::cs_strref(cs_strref const &ref): p_str{ref.p_str}, p_state{ref.p_state} cs_strref::cs_strref(cs_strref const &ref): p_state{ref.p_state}, p_str{ref.p_str}
{ {
p_state->strman->ref(p_str); p_state->strman->ref(p_str);
} }
@ -55,9 +55,9 @@ struct cs_cmd_internal {
} }
}; };
static inline void cs_push_alias(cs_ident *id, cs_ident_stack &st) { static inline void cs_push_alias(cs_state &cs, cs_ident *id, cs_ident_stack &st) {
if (id->is_alias() && (id->get_index() >= MaxArguments)) { if (id->is_alias() && (id->get_index() >= MaxArguments)) {
cs_value nv; cs_value nv{cs};
cs_alias_internal::push_arg(static_cast<cs_alias *>(id), nv, st); cs_alias_internal::push_arg(static_cast<cs_alias *>(id), nv, st);
} }
} }
@ -470,7 +470,7 @@ static inline void callcommand(
i = std::max(i + 1, numargs); i = std::max(i + 1, numargs);
auto buf = ostd::appender<cs_string>(); auto buf = ostd::appender<cs_string>();
cscript::util::tvals_concat(buf, ostd::iter(args, args + i), " "); cscript::util::tvals_concat(buf, ostd::iter(args, args + i), " ");
cs_value tv; cs_value tv{cs};
tv.set_str(std::move(buf.get())); tv.set_str(std::move(buf.get()));
cs_cmd_internal::call(cs, id, cs_value_r(&tv, &tv + 1), res); cs_cmd_internal::call(cs, id, cs_value_r(&tv, &tv + 1), res);
return; return;
@ -503,7 +503,7 @@ static inline void cs_call_alias(
int callargs, int &nargs, int offset, int skip, uint32_t op int callargs, int &nargs, int offset, int skip, uint32_t op
) { ) {
cs_ivar *anargs = static_cast<cs_ivar *>(cs.p_state->identmap[NumargsIdx]); cs_ivar *anargs = static_cast<cs_ivar *>(cs.p_state->identmap[NumargsIdx]);
cs_ident_stack argstack[MaxArguments]; cs_valarray<cs_ident_stack, MaxArguments> argstack{cs};
for(int i = 0; i < callargs; i++) { for(int i = 0; i < callargs; i++) {
cs_alias_internal::push_arg( cs_alias_internal::push_arg(
static_cast<cs_alias *>(cs.p_state->identmap[i]), static_cast<cs_alias *>(cs.p_state->identmap[i]),
@ -515,7 +515,7 @@ static inline void cs_call_alias(
int oldflags = cs.identflags; int oldflags = cs.identflags;
cs.identflags |= a->get_flags()&CS_IDF_OVERRIDDEN; cs.identflags |= a->get_flags()&CS_IDF_OVERRIDDEN;
cs_identLink aliaslink = { cs_identLink aliaslink = {
a, cs.p_callstack, (1<<callargs)-1, argstack a, cs.p_callstack, (1<<callargs)-1, &argstack[0]
}; };
cs.p_callstack = &aliaslink; cs.p_callstack = &aliaslink;
uint32_t *codep = reinterpret_cast<uint32_t *>( uint32_t *codep = reinterpret_cast<uint32_t *>(
@ -609,8 +609,8 @@ static inline int cs_get_lookupu_type(
return CsIdFvar; return CsIdFvar;
case cs_ident_type::Command: { case cs_ident_type::Command: {
arg.set_null(); arg.set_null();
cs_value buf[MaxArguments]; cs_valarray<cs_value, MaxArguments> buf{cs};
callcommand(cs, static_cast<cs_command *>(id), buf, arg, 0, true); callcommand(cs, static_cast<cs_command *>(id), &buf[0], arg, 0, true);
force_arg(arg, op & CsCodeRetMask); force_arg(arg, op & CsCodeRetMask);
return -2; /* ignore */ return -2; /* ignore */
} }
@ -625,7 +625,7 @@ static uint32_t *runcode(cs_state &cs, uint32_t *code, cs_value &result) {
result.set_null(); result.set_null();
RunDepthRef level{cs}; /* incr and decr on scope exit */ RunDepthRef level{cs}; /* incr and decr on scope exit */
int numargs = 0; int numargs = 0;
cs_value args[MaxArguments + MaxResults]; cs_valarray<cs_value, MaxArguments + MaxResults> args{cs};
auto &chook = cs.get_call_hook(); auto &chook = cs.get_call_hook();
if (chook) { if (chook) {
chook(cs); chook(cs);
@ -716,9 +716,9 @@ static uint32_t *runcode(cs_state &cs, uint32_t *code, cs_value &result) {
case CsCodeLocal: { case CsCodeLocal: {
int numlocals = op >> 8, offset = numargs - numlocals; int numlocals = op >> 8, offset = numargs - numlocals;
cs_ident_stack locals[MaxArguments]; cs_valarray<cs_ident_stack, MaxArguments> locals{cs};
for (int i = 0; i < numlocals; ++i) { for (int i = 0; i < numlocals; ++i) {
cs_push_alias(args[offset + i].get_ident(), locals[i]); cs_push_alias(cs, args[offset + i].get_ident(), locals[i]);
} }
cs_do_and_cleanup([&]() { cs_do_and_cleanup([&]() {
code = runcode(cs, code, result); code = runcode(cs, code, result);
@ -1002,7 +1002,7 @@ static uint32_t *runcode(cs_state &cs, uint32_t *code, cs_value &result) {
cs.p_state->identmap[op >> 8] cs.p_state->identmap[op >> 8]
); );
if (!cs_is_arg_used(cs, a)) { if (!cs_is_arg_used(cs, a)) {
cs_value nv; cs_value nv{cs};
cs_alias_internal::push_arg( cs_alias_internal::push_arg(
a, nv, cs.p_callstack->argstack[a->get_index()], false a, nv, cs.p_callstack->argstack[a->get_index()], false
); );
@ -1022,7 +1022,7 @@ static uint32_t *runcode(cs_state &cs, uint32_t *code, cs_value &result) {
id = cs.new_ident(arg.get_strr()); id = cs.new_ident(arg.get_strr());
} }
if ((id->get_index() < MaxArguments) && !cs_is_arg_used(cs, id)) { if ((id->get_index() < MaxArguments) && !cs_is_arg_used(cs, id)) {
cs_value nv; cs_value nv{cs};
cs_alias_internal::push_arg( cs_alias_internal::push_arg(
static_cast<cs_alias *>(id), nv, static_cast<cs_alias *>(id), nv,
cs.p_callstack->argstack[id->get_index()], false cs.p_callstack->argstack[id->get_index()], false
@ -1383,7 +1383,7 @@ static uint32_t *runcode(cs_state &cs, uint32_t *code, cs_value &result) {
int offset = numargs - id->get_num_args(); int offset = numargs - id->get_num_args();
result.force_null(); result.force_null();
cs_cmd_internal::call(cs, id, cs_value_r( cs_cmd_internal::call(cs, id, cs_value_r(
args + offset, args + offset + id->get_num_args() &args[0] + offset, &args[0] + offset + id->get_num_args()
), result); ), result);
force_arg(result, op & CsCodeRetMask); force_arg(result, op & CsCodeRetMask);
numargs = offset; numargs = offset;
@ -1420,7 +1420,7 @@ static uint32_t *runcode(cs_state &cs, uint32_t *code, cs_value &result) {
cscript::util::tvals_concat(buf, ostd::iter( cscript::util::tvals_concat(buf, ostd::iter(
&args[offset], &args[offset + callargs] &args[offset], &args[offset + callargs]
), " "); ), " ");
cs_value tv; cs_value tv{cs};
tv.set_str(std::move(buf.get())); tv.set_str(std::move(buf.get()));
cs_cmd_internal::call(cs, id, cs_value_r(&tv, &tv + 1), result); cs_cmd_internal::call(cs, id, cs_value_r(&tv, &tv + 1), result);
} }
@ -1498,7 +1498,7 @@ static uint32_t *runcode(cs_state &cs, uint32_t *code, cs_value &result) {
); );
} }
cs_call_alias( cs_call_alias(
cs, static_cast<cs_alias *>(id), args, result, callargs, cs, static_cast<cs_alias *>(id), &args[0], result, callargs,
numargs, offset, 0, op numargs, offset, 0, op
); );
continue; continue;
@ -1516,7 +1516,7 @@ static uint32_t *runcode(cs_state &cs, uint32_t *code, cs_value &result) {
continue; continue;
} }
cs_call_alias( cs_call_alias(
cs, static_cast<cs_alias *>(id), args, result, callargs, cs, static_cast<cs_alias *>(id), &args[0], result, callargs,
numargs, offset, 0, op numargs, offset, 0, op
); );
continue; continue;
@ -1569,9 +1569,9 @@ noid:
numargs = offset - 1; numargs = offset - 1;
continue; continue;
case CsIdLocal: { case CsIdLocal: {
cs_ident_stack locals[MaxArguments]; cs_valarray<cs_ident_stack, MaxArguments> locals{cs};
for (size_t j = 0; j < size_t(callargs); ++j) { for (size_t j = 0; j < size_t(callargs); ++j) {
cs_push_alias(cs.force_ident( cs_push_alias(cs, cs.force_ident(
args[offset + j] args[offset + j]
), locals[j]); ), locals[j]);
} }
@ -1634,7 +1634,7 @@ noid:
goto noid; goto noid;
} }
cs_call_alias( cs_call_alias(
cs, a, args, result, callargs, numargs, cs, a, &args[0], result, callargs, numargs,
offset, 1, op offset, 1, op
); );
continue; continue;
@ -1684,10 +1684,10 @@ void cs_state::run(cs_ident *id, cs_value_r args, cs_value &ret) {
/* fallthrough */ /* fallthrough */
case cs_ident_type::Command: case cs_ident_type::Command:
if (nargs < static_cast<cs_command *>(id)->get_num_args()) { if (nargs < static_cast<cs_command *>(id)->get_num_args()) {
cs_value buf[MaxArguments]; cs_valarray<cs_value, MaxArguments> buf{*this};
memcpy(buf, &args[0], args.size() * sizeof(cs_value)); memcpy(&buf[0], &args[0], args.size() * sizeof(cs_value));
callcommand( callcommand(
*this, static_cast<cs_command *>(id), buf, ret, *this, static_cast<cs_command *>(id), &buf[0], ret,
nargs, false nargs, false
); );
} else { } else {
@ -1743,89 +1743,89 @@ void cs_state::run(cs_ident *id, cs_value_r args, cs_value &ret) {
} }
cs_string cs_state::run_str(cs_bcode *code) { cs_string cs_state::run_str(cs_bcode *code) {
cs_value ret; cs_value ret{*this};
run(code, ret); run(code, ret);
return ret.get_str(); return ret.get_str();
} }
cs_string cs_state::run_str(ostd::string_range code) { cs_string cs_state::run_str(ostd::string_range code) {
cs_value ret; cs_value ret{*this};
run(code, ret); run(code, ret);
return ret.get_str(); return ret.get_str();
} }
cs_string cs_state::run_str(cs_ident *id, cs_value_r args) { cs_string cs_state::run_str(cs_ident *id, cs_value_r args) {
cs_value ret; cs_value ret{*this};
run(id, args, ret); run(id, args, ret);
return ret.get_str(); return ret.get_str();
} }
cs_int cs_state::run_int(cs_bcode *code) { cs_int cs_state::run_int(cs_bcode *code) {
cs_value ret; cs_value ret{*this};
run(code, ret); run(code, ret);
return ret.get_int(); return ret.get_int();
} }
cs_int cs_state::run_int(ostd::string_range code) { cs_int cs_state::run_int(ostd::string_range code) {
cs_value ret; cs_value ret{*this};
run(code, ret); run(code, ret);
return ret.get_int(); return ret.get_int();
} }
cs_int cs_state::run_int(cs_ident *id, cs_value_r args) { cs_int cs_state::run_int(cs_ident *id, cs_value_r args) {
cs_value ret; cs_value ret{*this};
run(id, args, ret); run(id, args, ret);
return ret.get_int(); return ret.get_int();
} }
cs_float cs_state::run_float(cs_bcode *code) { cs_float cs_state::run_float(cs_bcode *code) {
cs_value ret; cs_value ret{*this};
run(code, ret); run(code, ret);
return ret.get_float(); return ret.get_float();
} }
cs_float cs_state::run_float(ostd::string_range code) { cs_float cs_state::run_float(ostd::string_range code) {
cs_value ret; cs_value ret{*this};
run(code, ret); run(code, ret);
return ret.get_float(); return ret.get_float();
} }
cs_float cs_state::run_float(cs_ident *id, cs_value_r args) { cs_float cs_state::run_float(cs_ident *id, cs_value_r args) {
cs_value ret; cs_value ret{*this};
run(id, args, ret); run(id, args, ret);
return ret.get_float(); return ret.get_float();
} }
bool cs_state::run_bool(cs_bcode *code) { bool cs_state::run_bool(cs_bcode *code) {
cs_value ret; cs_value ret{*this};
run(code, ret); run(code, ret);
return ret.get_bool(); return ret.get_bool();
} }
bool cs_state::run_bool(ostd::string_range code) { bool cs_state::run_bool(ostd::string_range code) {
cs_value ret; cs_value ret{*this};
run(code, ret); run(code, ret);
return ret.get_bool(); return ret.get_bool();
} }
bool cs_state::run_bool(cs_ident *id, cs_value_r args) { bool cs_state::run_bool(cs_ident *id, cs_value_r args) {
cs_value ret; cs_value ret{*this};
run(id, args, ret); run(id, args, ret);
return ret.get_bool(); return ret.get_bool();
} }
void cs_state::run(cs_bcode *code) { void cs_state::run(cs_bcode *code) {
cs_value ret; cs_value ret{*this};
run(code, ret); run(code, ret);
} }
void cs_state::run(ostd::string_range code) { void cs_state::run(ostd::string_range code) {
cs_value ret; cs_value ret{*this};
run(code, ret); run(code, ret);
} }
void cs_state::run(cs_ident *id, cs_value_r args) { void cs_state::run(cs_ident *id, cs_value_r args) {
cs_value ret; cs_value ret{*this};
run(id, args, ret); run(id, args, ret);
} }
@ -1847,7 +1847,7 @@ CsLoopState cs_state::run_loop(cs_bcode *code, cs_value &ret) {
} }
CsLoopState cs_state::run_loop(cs_bcode *code) { CsLoopState cs_state::run_loop(cs_bcode *code) {
cs_value ret; cs_value ret{*this};
return run_loop(code, ret); return run_loop(code, ret);
} }
@ -1879,7 +1879,7 @@ static bool cs_run_file(
} }
std::optional<cs_string> cs_state::run_file_str(ostd::string_range fname) { std::optional<cs_string> cs_state::run_file_str(ostd::string_range fname) {
cs_value ret; cs_value ret{*this};
if (!cs_run_file(*this, fname, ret)) { if (!cs_run_file(*this, fname, ret)) {
return std::nullopt; return std::nullopt;
} }
@ -1887,7 +1887,7 @@ std::optional<cs_string> cs_state::run_file_str(ostd::string_range fname) {
} }
std::optional<cs_int> cs_state::run_file_int(ostd::string_range fname) { std::optional<cs_int> cs_state::run_file_int(ostd::string_range fname) {
cs_value ret; cs_value ret{*this};
if (!cs_run_file(*this, fname, ret)) { if (!cs_run_file(*this, fname, ret)) {
return std::nullopt; return std::nullopt;
} }
@ -1895,7 +1895,7 @@ std::optional<cs_int> cs_state::run_file_int(ostd::string_range fname) {
} }
std::optional<cs_float> cs_state::run_file_float(ostd::string_range fname) { std::optional<cs_float> cs_state::run_file_float(ostd::string_range fname) {
cs_value ret; cs_value ret{*this};
if (!cs_run_file(*this, fname, ret)) { if (!cs_run_file(*this, fname, ret)) {
return std::nullopt; return std::nullopt;
} }
@ -1903,7 +1903,7 @@ std::optional<cs_float> cs_state::run_file_float(ostd::string_range fname) {
} }
std::optional<bool> cs_state::run_file_bool(ostd::string_range fname) { std::optional<bool> cs_state::run_file_bool(ostd::string_range fname) {
cs_value ret; cs_value ret{*this};
if (!cs_run_file(*this, fname, ret)) { if (!cs_run_file(*this, fname, ret)) {
return std::nullopt; return std::nullopt;
} }
@ -1915,7 +1915,7 @@ bool cs_state::run_file(ostd::string_range fname, cs_value &ret) {
} }
bool cs_state::run_file(ostd::string_range fname) { bool cs_state::run_file(ostd::string_range fname) {
cs_value ret; cs_value ret{*this};
if (!cs_run_file(*this, fname, ret)) { if (!cs_run_file(*this, fname, ret)) {
return false; return false;
} }

View File

@ -6,6 +6,7 @@
#include <cstdlib> #include <cstdlib>
#include <array> #include <array>
#include <vector> #include <vector>
#include <type_traits>
#include "cs_util.hh" #include "cs_util.hh"
@ -31,6 +32,27 @@ struct cs_identLink {
cs_ident_stack *argstack; cs_ident_stack *argstack;
}; };
template<typename T, std::size_t N>
struct cs_valarray {
cs_valarray(cs_state &cs) {
for (std::size_t i = 0; i < N; ++i) {
new (&stor[i]) T{cs};
}
}
~cs_valarray() {
for (std::size_t i = 0; i < N; ++i) {
reinterpret_cast<T *>(&stor[i])->~T();
}
}
T &operator[](std::size_t i) {
return *reinterpret_cast<T *>(&stor[i]);
}
std::aligned_storage_t<sizeof(T), alignof(T)> stor[N];
};
enum { enum {
CsValNull = 0, CsValInt, CsValFloat, CsValString, CsValNull = 0, CsValInt, CsValFloat, CsValString,
CsValAny, CsValCode, CsValMacro, CsValIdent, CsValCstring, CsValAny, CsValCode, CsValMacro, CsValIdent, CsValCstring,
@ -409,7 +431,7 @@ static void cs_do_args(cs_state &cs, F body) {
body(); body();
return; return;
} }
cs_ident_stack argstack[MaxArguments]; cs_valarray<cs_ident_stack, MaxArguments> argstack{cs};
int argmask1 = cs.p_callstack->usedargs; int argmask1 = cs.p_callstack->usedargs;
for (int i = 0; argmask1; argmask1 >>= 1, ++i) { for (int i = 0; argmask1; argmask1 >>= 1, ++i) {
if (argmask1 & 1) { if (argmask1 & 1) {

View File

@ -57,31 +57,32 @@ cs_svar::cs_svar(ostd::string_range name, cs_string v, cs_var_cb f, int fl):
p_storage(std::move(v)), p_overrideval() p_storage(std::move(v)), p_overrideval()
{} {}
cs_alias::cs_alias(ostd::string_range name, cs_string a, int fl): cs_alias::cs_alias(cs_state &cs, ostd::string_range name, cs_string a, int fl):
cs_ident(cs_ident_type::Alias, name, fl), cs_ident(cs_ident_type::Alias, name, fl),
p_acode(nullptr), p_astack(nullptr) p_acode(nullptr), p_astack(nullptr), p_val{cs}
{ {
p_val.set_str(std::move(a)); p_val.set_str(std::move(a));
} }
cs_alias::cs_alias(ostd::string_range name, cs_int a, int fl): cs_alias::cs_alias(cs_state &cs, ostd::string_range name, cs_int a, int fl):
cs_ident(cs_ident_type::Alias, name, fl), cs_ident(cs_ident_type::Alias, name, fl),
p_acode(nullptr), p_astack(nullptr) p_acode(nullptr), p_astack(nullptr), p_val{cs}
{ {
p_val.set_int(a); p_val.set_int(a);
} }
cs_alias::cs_alias(ostd::string_range name, cs_float a, int fl): cs_alias::cs_alias(cs_state &cs, ostd::string_range name, cs_float a, int fl):
cs_ident(cs_ident_type::Alias, name, fl), cs_ident(cs_ident_type::Alias, name, fl),
p_acode(nullptr), p_astack(nullptr) p_acode(nullptr), p_astack(nullptr), p_val{cs}
{ {
p_val.set_float(a); p_val.set_float(a);
} }
cs_alias::cs_alias(ostd::string_range name, int fl): cs_alias::cs_alias(cs_state &cs, ostd::string_range name, int fl):
cs_ident(cs_ident_type::Alias, name, fl), cs_ident(cs_ident_type::Alias, name, fl),
p_acode(nullptr), p_astack(nullptr) p_acode(nullptr), p_astack(nullptr), p_val{cs}
{ {
p_val.set_null(); p_val.set_null();
} }
cs_alias::cs_alias(ostd::string_range name, cs_value v, int fl): /* FIXME: use cs rather than val's cs */
cs_alias::cs_alias(cs_state &, ostd::string_range name, cs_value v, int fl):
cs_ident(cs_ident_type::Alias, name, fl), cs_ident(cs_ident_type::Alias, name, fl),
p_acode(nullptr), p_astack(nullptr), p_val(std::move(v)) p_acode(nullptr), p_astack(nullptr), p_val(std::move(v))
{} {}
@ -522,7 +523,7 @@ OSTD_EXPORT cs_ident *cs_state::new_ident(ostd::string_range name, int flags) {
*this, "number %s is not a valid identifier name", name *this, "number %s is not a valid identifier name", name
); );
} }
id = add_ident(p_state->create<cs_alias>(name, flags)); id = add_ident(p_state->create<cs_alias>(*this, name, flags));
} }
return id; return id;
} }
@ -650,7 +651,9 @@ OSTD_EXPORT void cs_state::set_alias(ostd::string_range name, cs_value v) {
} else if (cs_check_num(name)) { } else if (cs_check_num(name)) {
throw cs_error(*this, "cannot alias number %s", name); throw cs_error(*this, "cannot alias number %s", name);
} else { } else {
add_ident(p_state->create<cs_alias>(name, std::move(v), identflags)); add_ident(p_state->create<cs_alias>(
*this, name, std::move(v), identflags
));
} }
} }
@ -1028,7 +1031,7 @@ static inline void cs_do_loop(
cs_state &cs, cs_ident &id, cs_int offset, cs_int n, cs_int step, cs_state &cs, cs_ident &id, cs_int offset, cs_int n, cs_int step,
cs_bcode *cond, cs_bcode *body cs_bcode *cond, cs_bcode *body
) { ) {
cs_stacked_value idv{&id}; cs_stacked_value idv{cs, &id};
if (n <= 0 || !idv.has_alias()) { if (n <= 0 || !idv.has_alias()) {
return; return;
} }
@ -1053,7 +1056,7 @@ static inline void cs_loop_conc(
cs_state &cs, cs_value &res, cs_ident &id, cs_int offset, cs_int n, cs_state &cs, cs_value &res, cs_ident &id, cs_int offset, cs_int n,
cs_int step, cs_bcode *body, bool space cs_int step, cs_bcode *body, bool space
) { ) {
cs_stacked_value idv{&id}; cs_stacked_value idv{cs, &id};
if (n <= 0 || !idv.has_alias()) { if (n <= 0 || !idv.has_alias()) {
return; return;
} }
@ -1061,7 +1064,7 @@ static inline void cs_loop_conc(
for (cs_int i = 0; i < n; ++i) { for (cs_int i = 0; i < n; ++i) {
idv.set_int(offset + i * step); idv.set_int(offset + i * step);
idv.push(); idv.push();
cs_value v; cs_value v{cs};
switch (cs.run_loop(body, v)) { switch (cs.run_loop(body, v)) {
case CsLoopState::Break: case CsLoopState::Break:
goto end; goto end;
@ -1091,7 +1094,7 @@ void cs_init_lib_base(cs_state &gcs) {
ret.set_int(0); ret.set_int(0);
return; return;
} }
cs_value result, tback; cs_value result{cs}, tback{cs};
bool rc = true; bool rc = true;
try { try {
cs.run(args[0].get_code(), result); cs.run(args[0].get_code(), result);
@ -1171,7 +1174,7 @@ void cs_init_lib_base(cs_state &gcs) {
}); });
gcs.new_command("pushif", "rTe", [](auto &cs, auto args, auto &res) { gcs.new_command("pushif", "rTe", [](auto &cs, auto args, auto &res) {
cs_stacked_value idv{args[0].get_ident()}; cs_stacked_value idv{cs, args[0].get_ident()};
if (!idv.has_alias() || (idv.get_alias()->get_index() < MaxArguments)) { if (!idv.has_alias() || (idv.get_alias()->get_index() < MaxArguments)) {
return; return;
} }
@ -1315,7 +1318,7 @@ end:
}); });
gcs.new_command("push", "rTe", [](auto &cs, auto args, auto &res) { gcs.new_command("push", "rTe", [](auto &cs, auto args, auto &res) {
cs_stacked_value idv{args[0].get_ident()}; cs_stacked_value idv{cs, args[0].get_ident()};
if (!idv.has_alias() || (idv.get_alias()->get_index() < MaxArguments)) { if (!idv.has_alias() || (idv.get_alias()->get_index() < MaxArguments)) {
return; return;
} }

View File

@ -73,7 +73,7 @@ static void cs_loop_list_conc(
cs_state &cs, cs_value &res, cs_ident *id, ostd::string_range list, cs_state &cs, cs_value &res, cs_ident *id, ostd::string_range list,
cs_bcode *body, bool space cs_bcode *body, bool space
) { ) {
cs_stacked_value idv{id}; cs_stacked_value idv{cs, id};
if (!idv.has_alias()) { if (!idv.has_alias()) {
return; return;
} }
@ -85,7 +85,7 @@ static void cs_loop_list_conc(
if (n && space) { if (n && space) {
r += ' '; r += ' ';
} }
cs_value v; cs_value v{cs};
switch (cs.run_loop(body, v)) { switch (cs.run_loop(body, v)) {
case CsLoopState::Break: case CsLoopState::Break:
goto end; goto end;
@ -197,7 +197,7 @@ void cs_init_lib_list(cs_state &gcs) {
}); });
gcs.new_command("listfind", "rse", [](auto &cs, auto args, auto &res) { gcs.new_command("listfind", "rse", [](auto &cs, auto args, auto &res) {
cs_stacked_value idv{args[0].get_ident()}; cs_stacked_value idv{cs, args[0].get_ident()};
if (!idv.has_alias()) { if (!idv.has_alias()) {
res.set_int(-1); res.set_int(-1);
return; return;
@ -217,7 +217,7 @@ void cs_init_lib_list(cs_state &gcs) {
}); });
gcs.new_command("listassoc", "rse", [](auto &cs, auto args, auto &res) { gcs.new_command("listassoc", "rse", [](auto &cs, auto args, auto &res) {
cs_stacked_value idv{args[0].get_ident()}; cs_stacked_value idv{cs, args[0].get_ident()};
if (!idv.has_alias()) { if (!idv.has_alias()) {
return; return;
} }
@ -284,7 +284,7 @@ void cs_init_lib_list(cs_state &gcs) {
}); });
gcs.new_command("looplist", "rse", [](auto &cs, auto args, auto &) { gcs.new_command("looplist", "rse", [](auto &cs, auto args, auto &) {
cs_stacked_value idv{args[0].get_ident()}; cs_stacked_value idv{cs, args[0].get_ident()};
if (!idv.has_alias()) { if (!idv.has_alias()) {
return; return;
} }
@ -305,7 +305,8 @@ end:
}); });
gcs.new_command("looplist2", "rrse", [](auto &cs, auto args, auto &) { gcs.new_command("looplist2", "rrse", [](auto &cs, auto args, auto &) {
cs_stacked_value idv1{args[0].get_ident()}, idv2{args[1].get_ident()}; cs_stacked_value idv1{cs, args[0].get_ident()};
cs_stacked_value idv2{cs, args[1].get_ident()};
if (!idv1.has_alias() || !idv2.has_alias()) { if (!idv1.has_alias() || !idv2.has_alias()) {
return; return;
} }
@ -332,9 +333,9 @@ end:
}); });
gcs.new_command("looplist3", "rrrse", [](auto &cs, auto args, auto &) { gcs.new_command("looplist3", "rrrse", [](auto &cs, auto args, auto &) {
cs_stacked_value idv1{args[0].get_ident()}; cs_stacked_value idv1{cs, args[0].get_ident()};
cs_stacked_value idv2{args[1].get_ident()}; cs_stacked_value idv2{cs, args[1].get_ident()};
cs_stacked_value idv3{args[2].get_ident()}; cs_stacked_value idv3{cs, args[2].get_ident()};
if (!idv1.has_alias() || !idv2.has_alias() || !idv3.has_alias()) { if (!idv1.has_alias() || !idv2.has_alias() || !idv3.has_alias()) {
return; return;
} }
@ -383,7 +384,7 @@ end:
}); });
gcs.new_command("listfilter", "rse", [](auto &cs, auto args, auto &res) { gcs.new_command("listfilter", "rse", [](auto &cs, auto args, auto &res) {
cs_stacked_value idv{args[0].get_ident()}; cs_stacked_value idv{cs, args[0].get_ident()};
if (!idv.has_alias()) { if (!idv.has_alias()) {
return; return;
} }
@ -404,7 +405,7 @@ end:
}); });
gcs.new_command("listcount", "rse", [](auto &cs, auto args, auto &res) { gcs.new_command("listcount", "rse", [](auto &cs, auto args, auto &res) {
cs_stacked_value idv{args[0].get_ident()}; cs_stacked_value idv{cs, args[0].get_ident()};
if (!idv.has_alias()) { if (!idv.has_alias()) {
return; return;
} }
@ -555,7 +556,7 @@ static void cs_list_sort(
return; return;
} }
cs_stacked_value xval{xa}, yval{ya}; cs_stacked_value xval{cs, xa}, yval{cs, ya};
xval.set_null(); xval.set_null();
yval.set_null(); yval.set_null();
xval.push(); xval.push();

View File

@ -188,7 +188,7 @@ static void do_sigint(int n) {
} }
static bool do_call(cs_state &cs, ostd::string_range line, bool file = false) { static bool do_call(cs_state &cs, ostd::string_range line, bool file = false) {
cs_value ret; cs_value ret{cs};
scs = &cs; scs = &cs;
signal(SIGINT, do_sigint); signal(SIGINT, do_sigint);
try { try {