diff --git a/include/cubescript/cubescript/value.hh b/include/cubescript/cubescript/value.hh index 7593c89..bda5e09 100644 --- a/include/cubescript/cubescript/value.hh +++ b/include/cubescript/cubescript/value.hh @@ -78,7 +78,6 @@ private: /* for internal use only */ string_ref(char const *p, internal_state *cs); - internal_state *p_state; char const *p_str; }; @@ -87,11 +86,9 @@ enum class value_type { }; struct LIBCUBESCRIPT_EXPORT any_value { - any_value() = delete; - ~any_value(); + any_value(); - any_value(state &); - any_value(internal_state &); + ~any_value(); any_value(any_value const &); any_value(any_value &&v); @@ -103,13 +100,13 @@ struct LIBCUBESCRIPT_EXPORT any_value { void set_integer(integer_type val); void set_float(float_type val); - void set_string(std::string_view val); + void set_string(std::string_view val, state &cs); void set_string(string_ref const &val); void set_none(); void set_code(bcode_ref const &val); void set_ident(ident *val); - string_ref get_string() const; + string_ref get_string(state &cs) const; integer_type get_integer() const; float_type get_float() const; bcode_ref get_code() const; @@ -122,27 +119,15 @@ struct LIBCUBESCRIPT_EXPORT any_value { void force_plain(); float_type force_float(); integer_type force_integer(); - std::string_view force_string(); + std::string_view force_string(state &cs); bcode_ref force_code(state &cs); ident &force_ident(state &cs); private: - template - struct stor_t { - internal_state *state; - T val; - }; - - internal_state *get_state() const { - return std::launder( - reinterpret_cast const *>(&p_stor) - )->state; - } - std::aligned_union_t<1, - stor_t, - stor_t, - stor_t, + integer_type, + float_type, + void *, string_ref > p_stor; value_type p_type; diff --git a/src/cs_ident.cc b/src/cs_ident.cc index eb02d84..8d051a5 100644 --- a/src/cs_ident.cc +++ b/src/cs_ident.cc @@ -35,9 +35,9 @@ svar_impl::svar_impl(string_ref name, string_ref v, int fl): {} alias_impl::alias_impl( - state &cs, string_ref name, string_ref a, int fl + state &, string_ref name, string_ref a, int fl ): - ident_impl{ident_type::ALIAS, name, fl}, p_initial{cs} + ident_impl{ident_type::ALIAS, name, fl}, p_initial{} { p_initial.val_s.set_string(a); } @@ -45,31 +45,31 @@ alias_impl::alias_impl( alias_impl::alias_impl( state &cs, string_ref name, std::string_view a, int fl ): - ident_impl{ident_type::ALIAS, name, fl}, p_initial{cs} + ident_impl{ident_type::ALIAS, name, fl}, p_initial{} { - p_initial.val_s.set_string(a); + p_initial.val_s.set_string(a, cs); } -alias_impl::alias_impl(state &cs, string_ref name, integer_type a, int fl): - ident_impl{ident_type::ALIAS, name, fl}, p_initial{cs} +alias_impl::alias_impl(state &, string_ref name, integer_type a, int fl): + ident_impl{ident_type::ALIAS, name, fl}, p_initial{} { p_initial.val_s.set_integer(a); } -alias_impl::alias_impl(state &cs, string_ref name, float_type a, int fl): - ident_impl{ident_type::ALIAS, name, fl}, p_initial{cs} +alias_impl::alias_impl(state &, string_ref name, float_type a, int fl): + ident_impl{ident_type::ALIAS, name, fl}, p_initial{} { p_initial.val_s.set_float(a); } -alias_impl::alias_impl(state &cs, string_ref name, int fl): - ident_impl{ident_type::ALIAS, name, fl}, p_initial{cs} +alias_impl::alias_impl(state &, string_ref name, int fl): + ident_impl{ident_type::ALIAS, name, fl}, p_initial{} { p_initial.val_s.set_none(); } -alias_impl::alias_impl(state &cs, string_ref name, any_value v, int fl): - ident_impl{ident_type::ALIAS, name, fl}, p_initial{cs} +alias_impl::alias_impl(state &, string_ref name, any_value v, int fl): + ident_impl{ident_type::ALIAS, name, fl}, p_initial{} { p_initial.val_s = v.get_plain(); } @@ -87,7 +87,7 @@ void var_changed(thread_state &ts, ident *id) { return; } auto *cimp = static_cast(cid); - any_value val{*ts.pstate}; + any_value val{}; val.set_ident(id); cimp->call(ts, std::span{&val, 1}, val); } @@ -111,10 +111,10 @@ void command_impl::call( try { p_cb_cftv(*ts.pstate, args, ret); } catch (...) { - ts.idstack.resize(idstsz, ident_stack{*ts.pstate}); + ts.idstack.resize(idstsz); throw; } - ts.idstack.resize(idstsz, ident_stack{*ts.pstate}); + ts.idstack.resize(idstsz); } bool ident_is_used_arg(ident *id, thread_state &ts) { @@ -137,7 +137,7 @@ void alias_stack::set_arg(alias *a, thread_state &ts, any_value &v) { if (ident_is_used_arg(a, ts)) { node->code = bcode_ref{}; } else { - push(ts.idstack.emplace_back(*ts.pstate)); + push(ts.idstack.emplace_back()); ts.callstack->usedargs[a->get_index()] = true; } node->val_s = std::move(v); @@ -470,7 +470,7 @@ LIBCUBESCRIPT_EXPORT alias_local::alias_local(state &cs, ident *a) { auto &ts = state_p{cs}.ts(); p_alias = static_cast(a); auto &ast = ts.get_astack(p_alias); - ast.push(ts.idstack.emplace_back(cs)); + ast.push(ts.idstack.emplace_back()); p_sp = * ast.flags &= ~IDENT_FLAG_UNKNOWN; } diff --git a/src/cs_ident.hh b/src/cs_ident.hh index 32d72e9..0d6fd5d 100644 --- a/src/cs_ident.hh +++ b/src/cs_ident.hh @@ -29,7 +29,7 @@ struct ident_stack { any_value val_s; bcode_ref code; ident_stack *next; - ident_stack(state &cs): val_s{cs}, code{}, next{nullptr} {} + ident_stack(): val_s{}, code{}, next{nullptr} {} }; struct alias_stack { diff --git a/src/cs_state.cc b/src/cs_state.cc index b86d50a..f1af81e 100644 --- a/src/cs_state.cc +++ b/src/cs_state.cc @@ -169,7 +169,7 @@ state::state(alloc_func func, void *data) { std::printf("%s = [%s]\n", sv->get_name().data(), val.data()); } } else { - sv->set_value(cs, args[1].get_string()); + sv->set_value(cs, args[1].get_string(cs)); } }); @@ -342,7 +342,7 @@ LIBCUBESCRIPT_EXPORT void state::clear_override(ident &id) { switch (id.get_type()) { case ident_type::ALIAS: { auto &ast = p_tstate->get_astack(static_cast(&id)); - ast.node->val_s.set_string(""); + ast.node->val_s.set_string("", *this); ast.node->code = bcode_ref{}; ast.flags &= ~IDENT_FLAG_OVERRIDDEN; return; @@ -645,7 +645,7 @@ LIBCUBESCRIPT_EXPORT void state::init_libs(int libs) { } LIBCUBESCRIPT_EXPORT any_value state::run(bcode_ref const &code) { - any_value ret{*this}; + any_value ret{}; vm_exec(*p_tstate, bcode_p{code}.get()->get_raw(), ret); return ret; } @@ -653,7 +653,7 @@ LIBCUBESCRIPT_EXPORT any_value state::run(bcode_ref const &code) { static any_value do_run( thread_state &ts, std::string_view file, std::string_view code ) { - any_value ret{*ts.pstate}; + any_value ret{}; gen_state gs{ts}; gs.gen_main(code, file); auto cref = gs.steal_ref(); @@ -674,7 +674,7 @@ LIBCUBESCRIPT_EXPORT any_value state::run( LIBCUBESCRIPT_EXPORT any_value state::run( ident &id, std::span args ) { - any_value ret{*this}; + any_value ret{}; std::size_t nargs = args.size(); run_depth_guard level{*p_tstate}; /* incr and decr on scope exit */ switch (id.get_type()) { @@ -689,7 +689,7 @@ LIBCUBESCRIPT_EXPORT any_value state::run( stack_guard s{*p_tstate}; /* restore after call */ auto &targs = p_tstate->vmstack; auto osz = targs.size(); - targs.resize(osz + cimpl.get_num_args(), any_value{*this}); + targs.resize(osz + cimpl.get_num_args()); for (std::size_t i = 0; i < nargs; ++i) { targs[osz + i] = args[i]; } @@ -711,7 +711,7 @@ LIBCUBESCRIPT_EXPORT any_value state::run( auto osz = targs.size(); auto anargs = std::size_t(cimp->get_num_args()); targs.resize( - osz + std::max(args.size(), anargs + 1), any_value{*this} + osz + std::max(args.size(), anargs + 1) ); for (std::size_t i = 0; i < nargs; ++i) { targs[osz + i + 1] = args[i]; @@ -728,7 +728,7 @@ LIBCUBESCRIPT_EXPORT any_value state::run( auto osz = targs.size(); auto anargs = std::size_t(cimp->get_num_args()); targs.resize( - osz + std::max(args.size(), anargs + 1), any_value{*this} + osz + std::max(args.size(), anargs + 1) ); for (std::size_t i = 0; i < nargs; ++i) { targs[osz + i + 1] = args[i]; @@ -745,7 +745,7 @@ LIBCUBESCRIPT_EXPORT any_value state::run( auto osz = targs.size(); auto anargs = std::size_t(cimp->get_num_args()); targs.resize( - osz + std::max(args.size(), anargs + 1), any_value{*this} + osz + std::max(args.size(), anargs + 1) ); for (std::size_t i = 0; i < nargs; ++i) { targs[osz + i + 1] = args[i]; @@ -790,7 +790,7 @@ LIBCUBESCRIPT_EXPORT loop_state state::run_loop( } LIBCUBESCRIPT_EXPORT loop_state state::run_loop(bcode_ref const &code) { - any_value ret{*this}; + any_value ret{}; return run_loop(code, ret); } diff --git a/src/cs_strman.cc b/src/cs_strman.cc index e53048a..7d7fc2c 100644 --- a/src/cs_strman.cc +++ b/src/cs_strman.cc @@ -6,6 +6,7 @@ namespace cubescript { struct string_ref_state { + internal_state *state; std::size_t length; std::size_t refcount; }; @@ -97,6 +98,7 @@ char *string_pool::alloc_buf(std::size_t len) const { auto mem = cstate->alloc(nullptr, 0, len + sizeof(string_ref_state) + 1); /* write length and initial refcount */ auto *sst = static_cast(mem); + sst->state = cstate; sst->length = len; sst->refcount = 1; /* pre-terminate */ @@ -112,43 +114,39 @@ char *string_pool::alloc_buf(std::size_t len) const { LIBCUBESCRIPT_EXPORT string_ref::string_ref( internal_state *cs, std::string_view str -): p_state{cs} -{ +) { p_str = cs->strman->add(str); } -LIBCUBESCRIPT_EXPORT string_ref::string_ref(state &cs, std::string_view str): - p_state{state_p{cs}.ts().istate} -{ - p_str = p_state->strman->add(str); +LIBCUBESCRIPT_EXPORT string_ref::string_ref(state &cs, std::string_view str) { + p_str = state_p{cs}.ts().istate->strman->add(str); } LIBCUBESCRIPT_EXPORT string_ref::string_ref(string_ref const &ref): - p_state{ref.p_state}, p_str{ref.p_str} + p_str{ref.p_str} { - p_state->strman->ref(p_str); + get_ref_state(p_str)->state->strman->ref(p_str); } /* this can be used by friends to do quick string_ref creation */ -LIBCUBESCRIPT_EXPORT string_ref::string_ref(char const *p, internal_state *cs): - p_state{cs} -{ - p_str = p_state->strman->ref(p); +LIBCUBESCRIPT_EXPORT string_ref::string_ref( + char const *p, internal_state *cs +) { + p_str = cs->strman->ref(p); } LIBCUBESCRIPT_EXPORT string_ref::~string_ref() { - p_state->strman->unref(p_str); + get_ref_state(p_str)->state->strman->unref(p_str); } LIBCUBESCRIPT_EXPORT string_ref &string_ref::operator=(string_ref const &ref) { p_str = ref.p_str; - p_state = ref.p_state; - p_state->strman->ref(p_str); + get_ref_state(p_str)->state->strman->ref(p_str); return *this; } LIBCUBESCRIPT_EXPORT string_ref::operator std::string_view() const { - return p_state->strman->get(p_str); + return get_ref_state(p_str)->state->strman->get(p_str); } LIBCUBESCRIPT_EXPORT bool string_ref::operator==(string_ref const &s) const { diff --git a/src/cs_val.cc b/src/cs_val.cc index b1832b0..b704648 100644 --- a/src/cs_val.cc +++ b/src/cs_val.cc @@ -54,25 +54,19 @@ static std::string_view floatstr(float_type v, charbuf &buf) { return std::string_view{buf.data(), std::size_t(n)}; } -template -struct stor_priv_t { - internal_state *state; - T val; -}; - template static inline T &csv_get(U *stor) { /* ugly, but internal and unlikely to cause bugs */ - return const_cast(std::launder( - reinterpret_cast const *>(stor) - )->val); + return const_cast(*std::launder( + reinterpret_cast(stor) + )); } template static inline void csv_cleanup(value_type tv, T *stor) { switch (tv) { case value_type::STRING: - std::launder(reinterpret_cast(stor))->~string_ref(); + csv_get(stor).~string_ref(); break; case value_type::CODE: { bcode_unref(csv_get(stor)); @@ -83,23 +77,19 @@ static inline void csv_cleanup(value_type tv, T *stor) { } } -any_value::any_value(state &st): any_value(*state_p{st}.ts().istate) {} - -any_value::any_value(internal_state &st): - p_stor(), p_type(value_type::NONE) -{ - std::launder(reinterpret_cast *>(&p_stor))->state = &st; -} +any_value::any_value(): + p_stor{}, p_type{value_type::NONE} +{} any_value::~any_value() { csv_cleanup(p_type, &p_stor); } -any_value::any_value(any_value const &v): any_value(*v.get_state()) { +any_value::any_value(any_value const &v): any_value{} { *this = v; } -any_value::any_value(any_value &&v): any_value(*v.get_state()) { +any_value::any_value(any_value &&v): any_value{} { *this = std::move(v); } @@ -115,8 +105,8 @@ any_value &any_value::operator=(any_value const &v) { break; case value_type::STRING: p_type = value_type::STRING; - new (&p_stor) string_ref{ - *std::launder(reinterpret_cast(&v.p_stor)) + new (&csv_get(&p_stor)) string_ref{ + csv_get(&v.p_stor) }; break; case value_type::CODE: @@ -150,15 +140,15 @@ void any_value::set_float(float_type val) { csv_get(&p_stor) = val; } -void any_value::set_string(std::string_view val) { +void any_value::set_string(std::string_view val, state &cs) { csv_cleanup(p_type, &p_stor); - new (&p_stor) string_ref{get_state(), val}; + new (&csv_get(&p_stor)) string_ref{cs, val}; p_type = value_type::STRING; } void any_value::set_string(string_ref const &val) { csv_cleanup(p_type, &p_stor); - new (&p_stor) string_ref{val}; + new (&csv_get(&p_stor)) string_ref{val}; p_type = value_type::STRING; } @@ -207,9 +197,7 @@ float_type any_value::force_float() { rf = float_type(csv_get(&p_stor)); break; case value_type::STRING: - rf = parse_float( - *std::launder(reinterpret_cast(&p_stor)) - ); + rf = parse_float(csv_get(&p_stor)); break; case value_type::FLOAT: return csv_get(&p_stor); @@ -227,9 +215,7 @@ integer_type any_value::force_integer() { ri = integer_type(std::floor(csv_get(&p_stor))); break; case value_type::STRING: - ri = parse_int( - *std::launder(reinterpret_cast(&p_stor)) - ); + ri = parse_int(csv_get(&p_stor)); break; case value_type::INTEGER: return csv_get(&p_stor); @@ -240,8 +226,8 @@ integer_type any_value::force_integer() { return ri; } -std::string_view any_value::force_string() { - charbuf rs{get_state()}; +std::string_view any_value::force_string(state &cs) { + charbuf rs{cs}; std::string_view str; switch (get_type()) { case value_type::FLOAT: @@ -251,15 +237,13 @@ std::string_view any_value::force_string() { str = intstr(csv_get(&p_stor), rs); break; case value_type::STRING: - return *std::launder(reinterpret_cast(&p_stor)); + return csv_get(&p_stor); default: str = rs.str(); break; } - set_string(str); - return std::string_view(*std::launder( - reinterpret_cast(&p_stor) - )); + set_string(str, cs); + return csv_get(&p_stor); } bcode_ref any_value::force_code(state &cs) { @@ -270,7 +254,7 @@ bcode_ref any_value::force_code(state &cs) { break; } gen_state gs{state_p{cs}.ts()}; - gs.gen_main(get_string()); + gs.gen_main(get_string(cs)); auto bc = gs.steal_ref(); set_code(bc); return bc; @@ -284,7 +268,7 @@ ident &any_value::force_ident(state &cs) { break; } auto &id = state_p{cs}.ts().istate->new_ident( - cs, get_string(), IDENT_FLAG_UNKNOWN + cs, get_string(cs), IDENT_FLAG_UNKNOWN ); set_ident(&id); return id; @@ -297,9 +281,7 @@ integer_type any_value::get_integer() const { case value_type::INTEGER: return csv_get(&p_stor); case value_type::STRING: - return parse_int( - *std::launder(reinterpret_cast(&p_stor)) - ); + return parse_int(csv_get(&p_stor)); default: break; } @@ -313,9 +295,7 @@ float_type any_value::get_float() const { case value_type::INTEGER: return float_type(csv_get(&p_stor)); case value_type::STRING: - return parse_float( - *std::launder(reinterpret_cast(&p_stor)) - ); + return parse_float(csv_get(&p_stor)); default: break; } @@ -336,26 +316,26 @@ ident *any_value::get_ident() const { return csv_get(&p_stor); } -string_ref any_value::get_string() const { +string_ref any_value::get_string(state &cs) const { switch (get_type()) { case value_type::STRING: - return *std::launder(reinterpret_cast(&p_stor)); + return csv_get(&p_stor); case value_type::INTEGER: { - charbuf rs{get_state()}; + charbuf rs{cs}; return string_ref{ - get_state(), intstr(csv_get(&p_stor), rs) + cs, intstr(csv_get(&p_stor), rs) }; } case value_type::FLOAT: { - charbuf rs{get_state()}; + charbuf rs{cs}; return string_ref{ - get_state(), floatstr(csv_get(&p_stor), rs) + cs, floatstr(csv_get(&p_stor), rs) }; } default: break; } - return string_ref{get_state(), ""}; + return string_ref{cs, ""}; } any_value any_value::get_plain() const { @@ -367,7 +347,7 @@ any_value any_value::get_plain() const { default: break; } - return any_value{*get_state()}; + return any_value{}; } bool any_value::get_bool() const { @@ -377,9 +357,7 @@ bool any_value::get_bool() const { case value_type::INTEGER: return csv_get(&p_stor) != 0; case value_type::STRING: { - std::string_view s = *std::launder( - reinterpret_cast(&p_stor) - ); + std::string_view s = csv_get(&p_stor); if (s.empty()) { return false; } @@ -412,7 +390,8 @@ LIBCUBESCRIPT_EXPORT string_ref concat_values( case value_type::FLOAT: case value_type::STRING: std::ranges::copy( - any_value{vals[i]}.force_string(), std::back_inserter(buf) + any_value{vals[i]}.force_string(cs), + std::back_inserter(buf) ); break; default: diff --git a/src/cs_vm.cc b/src/cs_vm.cc index 102f773..7e94ddf 100644 --- a/src/cs_vm.cc +++ b/src/cs_vm.cc @@ -24,11 +24,11 @@ static inline void pop_alias(thread_state &ts, ident *id) { } } -static inline void force_arg(any_value &v, int type) { +static inline void force_arg(state &cs, any_value &v, int type) { switch (type) { case BC_RET_STRING: if (v.get_type() != value_type::STRING) { - v.force_string(); + v.force_string(cs); } break; case BC_RET_INT: @@ -104,10 +104,10 @@ void exec_command( if (rep) { break; } - args[i].set_string(""); + args[i].set_string("", *ts.pstate); fakeargs++; } else { - args[i].force_string(); + args[i].force_string(*ts.pstate); } break; case 'T': @@ -128,7 +128,7 @@ void exec_command( args[i].set_none(); fakeargs++; } else if (args[i].get_type() == value_type::STRING) { - auto str = args[i].get_string(); + auto str = args[i].get_string(*ts.pstate); if (str.empty()) { args[i].set_integer(0); } else { @@ -170,7 +170,7 @@ void exec_command( break; case 'C': { i = std::max(i + 1, numargs); - any_value tv{*ts.pstate}; + any_value tv{}; tv.set_string(concat_values( *ts.pstate, std::span{args, std::size_t(i)}, " " )); @@ -227,7 +227,7 @@ bool exec_alias( auto &ast = ts.get_astack( static_cast(ts.istate->identmap[i]) ); - auto &st = ts.idstack.emplace_back(*ts.pstate); + auto &st = ts.idstack.emplace_back(); ast.push(st); st.val_s = std::move(args[offset + i]); uargs[i] = true; @@ -240,7 +240,7 @@ bool exec_alias( ts.callstack = &aliaslink; if (!aast.node->code) { gen_state gs{ts}; - gs.gen_main(aast.node->val_s.get_string()); + gs.gen_main(aast.node->val_s.get_string(*ts.pstate)); aast.node->code = gs.steal_ref(); } bcode_ref coderef = aast.node->code; @@ -262,8 +262,8 @@ bool exec_alias( amask[callargs] = false; } } - ts.idstack.resize(noff, ident_stack{*ts.pstate}); - force_arg(result, op & BC_INST_RET_MASK); + ts.idstack.resize(noff); + force_arg(*ts.pstate, result, op & BC_INST_RET_MASK); anargs->set_raw_value(integer_type(oldargs)); nargs = offset - skip; }; @@ -315,7 +315,7 @@ static inline int get_lookupu_type( if (arg.get_type() != value_type::STRING) { return -2; /* default case */ } - id = ts.pstate->get_ident(arg.get_string()); + id = ts.pstate->get_ident(arg.get_string(*ts.pstate)); if (id) { switch(id->get_type()) { case ident_type::ALIAS: { @@ -342,17 +342,20 @@ static inline int get_lookupu_type( auto &args = ts.vmstack; auto osz = args.size(); /* pad with as many empty values as we need */ - args.resize(osz + cimpl->get_num_args(), any_value{*ts.pstate}); + args.resize(osz + cimpl->get_num_args()); arg.set_none(); exec_command(ts, cimpl, cimpl, &args[osz], arg, 0, true); - force_arg(arg, op & BC_INST_RET_MASK); + force_arg(*ts.pstate, arg, op & BC_INST_RET_MASK); return -2; /* ignore */ } default: return ID_UNKNOWN; } } - throw error{*ts.pstate, "unknown alias lookup: %s", arg.get_string().data()}; + throw error{ + *ts.pstate, "unknown alias lookup: %s", + arg.get_string(*ts.pstate).data() + }; } std::uint32_t *vm_exec( @@ -378,7 +381,7 @@ std::uint32_t *vm_exec( result.set_none(); continue; case BC_INST_NULL | BC_RET_STRING: - result.set_string(""); + result.set_string("", cs); continue; case BC_INST_NULL | BC_RET_INT: result.set_integer(0); @@ -388,7 +391,7 @@ std::uint32_t *vm_exec( continue; case BC_INST_FALSE | BC_RET_STRING: - result.set_string("0"); + result.set_string("0", cs); continue; case BC_INST_FALSE | BC_RET_NULL: case BC_INST_FALSE | BC_RET_INT: @@ -399,7 +402,7 @@ std::uint32_t *vm_exec( continue; case BC_INST_TRUE | BC_RET_STRING: - result.set_string("1"); + result.set_string("1", cs); continue; case BC_INST_TRUE | BC_RET_NULL: case BC_INST_TRUE | BC_RET_INT: @@ -410,7 +413,7 @@ std::uint32_t *vm_exec( continue; case BC_INST_NOT | BC_RET_STRING: - result.set_string(args.back().get_bool() ? "0" : "1"); + result.set_string(args.back().get_bool() ? "0" : "1", cs); args.pop_back(); continue; case BC_INST_NOT | BC_RET_NULL: @@ -427,7 +430,7 @@ std::uint32_t *vm_exec( args.pop_back(); continue; case BC_INST_ENTER: - code = vm_exec(ts, code, args.emplace_back(cs)); + code = vm_exec(ts, code, args.emplace_back()); continue; case BC_INST_ENTER_RESULT: code = vm_exec(ts, code, result); @@ -435,7 +438,7 @@ std::uint32_t *vm_exec( case BC_INST_EXIT | BC_RET_STRING: case BC_INST_EXIT | BC_RET_INT: case BC_INST_EXIT | BC_RET_FLOAT: - force_arg(result, op & BC_INST_RET_MASK); + force_arg(cs, result, op & BC_INST_RET_MASK); /* fallthrough */ case BC_INST_EXIT | BC_RET_NULL: return code; @@ -449,20 +452,20 @@ std::uint32_t *vm_exec( case BC_INST_RESULT | BC_RET_FLOAT: result = std::move(args.back()); args.pop_back(); - force_arg(result, op & BC_INST_RET_MASK); + force_arg(cs, result, op & BC_INST_RET_MASK); continue; case BC_INST_RESULT_ARG | BC_RET_STRING: case BC_INST_RESULT_ARG | BC_RET_INT: case BC_INST_RESULT_ARG | BC_RET_FLOAT: - force_arg(result, op & BC_INST_RET_MASK); + force_arg(cs, result, op & BC_INST_RET_MASK); /* fallthrough */ case BC_INST_RESULT_ARG | BC_RET_NULL: args.emplace_back(std::move(result)); continue; case BC_INST_FORCE | BC_RET_STRING: - args.back().force_string(); + args.back().force_string(cs); continue; case BC_INST_FORCE | BC_RET_INT: args.back().force_integer(); @@ -473,32 +476,32 @@ std::uint32_t *vm_exec( case BC_INST_DUP | BC_RET_NULL: { auto &v = args.back(); - args.emplace_back(cs) = v.get_plain(); + args.emplace_back() = v.get_plain(); continue; } case BC_INST_DUP | BC_RET_INT: { auto &v = args.back(); - args.emplace_back(cs).set_integer(v.get_integer()); + args.emplace_back().set_integer(v.get_integer()); continue; } case BC_INST_DUP | BC_RET_FLOAT: { auto &v = args.back(); - args.emplace_back(cs).set_float(v.get_float()); + args.emplace_back().set_float(v.get_float()); continue; } case BC_INST_DUP | BC_RET_STRING: { auto &v = args.back(); - auto &nv = args.emplace_back(cs); + auto &nv = args.emplace_back(); nv = v; - nv.force_string(); + nv.force_string(cs); continue; } case BC_INST_VAL | BC_RET_STRING: { std::uint32_t len = op >> 8; - args.emplace_back(cs).set_string(std::string_view{ + args.emplace_back().set_string(std::string_view{ reinterpret_cast(code), len - }); + }, cs); code += len / sizeof(std::uint32_t) + 1; continue; } @@ -509,30 +512,32 @@ std::uint32_t *vm_exec( char((op >> 24) & 0xFF), '\0' }; /* gotta cast or r.size() == potentially 3 */ - args.emplace_back(cs).set_string(static_cast(s)); + args.emplace_back().set_string( + static_cast(s), cs + ); continue; } case BC_INST_VAL | BC_RET_NULL: case BC_INST_VAL_INT | BC_RET_NULL: - args.emplace_back(cs).set_none(); + args.emplace_back().set_none(); continue; case BC_INST_VAL | BC_RET_INT: - args.emplace_back(cs).set_integer( + args.emplace_back().set_integer( *reinterpret_cast(code) ); code += bc_store_size; continue; case BC_INST_VAL_INT | BC_RET_INT: - args.emplace_back(cs).set_integer(integer_type(op) >> 8); + args.emplace_back().set_integer(integer_type(op) >> 8); continue; case BC_INST_VAL | BC_RET_FLOAT: - args.emplace_back(cs).set_float( + args.emplace_back().set_float( *reinterpret_cast(code) ); code += bc_store_size; continue; case BC_INST_VAL_INT | BC_RET_FLOAT: - args.emplace_back(cs).set_float( + args.emplace_back().set_float( float_type(integer_type(op) >> 8) ); continue; @@ -544,14 +549,14 @@ std::uint32_t *vm_exec( for (std::size_t i = 0; i < numlocals; ++i) { push_alias( ts, args[offset + i].get_ident(), - ts.idstack.emplace_back(*ts.pstate) + ts.idstack.emplace_back() ); } auto cleanup = [&]() { for (std::size_t i = offset; i < args.size(); ++i) { pop_alias(ts, args[i].get_ident()); } - ts.idstack.resize(idstsz, ident_stack{*ts.pstate}); + ts.idstack.resize(idstsz); }; try { code = vm_exec(ts, code, result); @@ -571,7 +576,7 @@ std::uint32_t *vm_exec( auto v = std::move(args.back()); args.pop_back(); result = cs.run(v.get_code()); - force_arg(result, op & BC_INST_RET_MASK); + force_arg(cs, result, op & BC_INST_RET_MASK); }); continue; /* fallthrough */ @@ -582,7 +587,7 @@ std::uint32_t *vm_exec( auto v = std::move(args.back()); args.pop_back(); result = cs.run(v.get_code()); - force_arg(result, op & BC_INST_RET_MASK); + force_arg(cs, result, op & BC_INST_RET_MASK); continue; } @@ -652,7 +657,7 @@ std::uint32_t *vm_exec( case BC_INST_BLOCK: { std::uint32_t len = op >> 8; - args.emplace_back(cs).set_code(bcode_p::make_ref( + args.emplace_back().set_code(bcode_p::make_ref( reinterpret_cast(code + 1) )); code += len; @@ -660,22 +665,22 @@ std::uint32_t *vm_exec( } case BC_INST_EMPTY | BC_RET_NULL: - args.emplace_back(cs).set_code(bcode_p::make_ref( + args.emplace_back().set_code(bcode_p::make_ref( bcode_get_empty(ts.istate->empty, VAL_NULL) )); break; case BC_INST_EMPTY | BC_RET_STRING: - args.emplace_back(cs).set_code(bcode_p::make_ref( + args.emplace_back().set_code(bcode_p::make_ref( bcode_get_empty(ts.istate->empty, VAL_STRING) )); break; case BC_INST_EMPTY | BC_RET_INT: - args.emplace_back(cs).set_code(bcode_p::make_ref( + args.emplace_back().set_code(bcode_p::make_ref( bcode_get_empty(ts.istate->empty, VAL_INT) )); break; case BC_INST_EMPTY | BC_RET_FLOAT: - args.emplace_back(cs).set_code(bcode_p::make_ref( + args.emplace_back().set_code(bcode_p::make_ref( bcode_get_empty(ts.istate->empty, VAL_FLOAT) )); break; @@ -691,7 +696,7 @@ std::uint32_t *vm_exec( gs.gen_main_float(arg.get_float()); break; case value_type::STRING: - gs.gen_main(arg.get_string()); + gs.gen_main(arg.get_string(cs)); break; default: gs.gen_main_null(); @@ -705,7 +710,7 @@ std::uint32_t *vm_exec( any_value &arg = args.back(); switch (arg.get_type()) { case value_type::STRING: { - std::string_view s = arg.get_string(); + std::string_view s = arg.get_string(cs); if (!s.empty()) { gen_state gs{ts}; gs.gen_main(s); @@ -726,10 +731,10 @@ std::uint32_t *vm_exec( ts.istate->identmap[op >> 8] ); if (a->is_arg() && !ident_is_used_arg(a, ts)) { - ts.get_astack(a).push(ts.idstack.emplace_back(*ts.pstate)); + ts.get_astack(a).push(ts.idstack.emplace_back()); ts.callstack->usedargs[a->get_index()] = true; } - args.emplace_back(cs).set_ident(a); + args.emplace_back().set_ident(a); continue; } case BC_INST_IDENT_U: { @@ -737,12 +742,12 @@ std::uint32_t *vm_exec( ident *id = ts.istate->id_dummy; if (arg.get_type() == value_type::STRING) { id = &ts.istate->new_ident( - cs, arg.get_string(), IDENT_FLAG_UNKNOWN + cs, arg.get_string(cs), IDENT_FLAG_UNKNOWN ); } alias *a = static_cast(id); if (a->is_arg() && !ident_is_used_arg(id, ts)) { - ts.get_astack(a).push(ts.idstack.emplace_back(*ts.pstate)); + ts.get_astack(a).push(ts.idstack.emplace_back()); ts.callstack->usedargs[id->get_index()] = true; } arg.set_ident(id); @@ -756,7 +761,7 @@ std::uint32_t *vm_exec( switch (get_lookupu_type(ts, arg, id, op, ast)) { case ID_ALIAS: arg = ast->node->val_s; - arg.force_string(); + arg.force_string(cs); continue; case ID_SVAR: arg.set_string( @@ -767,16 +772,16 @@ std::uint32_t *vm_exec( arg.set_integer( static_cast(id)->get_value() ); - arg.force_string(); + arg.force_string(cs); continue; case ID_FVAR: arg.set_float( static_cast(id)->get_value() ); - arg.force_string(); + arg.force_string(cs); continue; case ID_UNKNOWN: - arg.set_string(""); + arg.set_string("", cs); continue; default: continue; @@ -787,11 +792,11 @@ std::uint32_t *vm_exec( alias_stack *ast; alias *a = get_lookup_id(ts, op, ast); if (!a) { - args.emplace_back(cs).set_string(""); + args.emplace_back().set_string("", cs); } else { - auto &v = args.emplace_back(cs); + auto &v = args.emplace_back(); v = ast->node->val_s; - v.force_string(); + v.force_string(cs); } continue; } @@ -830,9 +835,9 @@ std::uint32_t *vm_exec( alias_stack *ast; alias *a = get_lookup_id(ts, op, ast); if (!a) { - args.emplace_back(cs).set_integer(0); + args.emplace_back().set_integer(0); } else { - args.emplace_back(cs).set_integer( + args.emplace_back().set_integer( ast->node->val_s.get_integer() ); } @@ -872,9 +877,9 @@ std::uint32_t *vm_exec( alias_stack *ast; alias *a = get_lookup_id(ts, op, ast); if (!a) { - args.emplace_back(cs).set_float(float_type(0)); + args.emplace_back().set_float(float_type(0)); } else { - args.emplace_back(cs).set_float( + args.emplace_back().set_float( ast->node->val_s.get_float() ); } @@ -914,9 +919,9 @@ std::uint32_t *vm_exec( alias_stack *ast; alias *a = get_lookup_id(ts, op, ast); if (!a) { - args.emplace_back(cs).set_none(); + args.emplace_back().set_none(); } else { - args.emplace_back(cs) = ast->node->val_s.get_plain(); + args.emplace_back() = ast->node->val_s.get_plain(); } continue; } @@ -934,27 +939,27 @@ std::uint32_t *vm_exec( cs, std::span{&args[args.size() - numconc], numconc}, ((op & BC_INST_OP_MASK) == BC_INST_CONC) ? " " : "" ); - args.resize(args.size() - numconc, any_value{cs}); - args.emplace_back(cs).set_string(buf); - force_arg(args.back(), op & BC_INST_RET_MASK); + args.resize(args.size() - numconc); + args.emplace_back().set_string(buf); + force_arg(cs, args.back(), op & BC_INST_RET_MASK); continue; } case BC_INST_SVAR | BC_RET_STRING: case BC_INST_SVAR | BC_RET_NULL: - args.emplace_back(cs).set_string(static_cast( + args.emplace_back().set_string(static_cast( ts.istate->identmap[op >> 8] )->get_value()); continue; case BC_INST_SVAR | BC_RET_INT: - args.emplace_back(cs).set_integer(parse_int( + args.emplace_back().set_integer(parse_int( static_cast( ts.istate->identmap[op >> 8] )->get_value() )); continue; case BC_INST_SVAR | BC_RET_FLOAT: - args.emplace_back(cs).set_float(parse_float( + args.emplace_back().set_float(parse_float( static_cast( ts.istate->identmap[op >> 8] )->get_value() @@ -963,20 +968,20 @@ std::uint32_t *vm_exec( case BC_INST_IVAR | BC_RET_INT: case BC_INST_IVAR | BC_RET_NULL: - args.emplace_back(cs).set_integer(static_cast( + args.emplace_back().set_integer(static_cast( ts.istate->identmap[op >> 8] )->get_value()); continue; case BC_INST_IVAR | BC_RET_STRING: { - auto &v = args.emplace_back(cs); + auto &v = args.emplace_back(); v.set_integer(static_cast( ts.istate->identmap[op >> 8] )->get_value()); - v.force_string(); + v.force_string(cs); continue; } case BC_INST_IVAR | BC_RET_FLOAT: - args.emplace_back(cs).set_float(float_type( + args.emplace_back().set_float(float_type( static_cast( ts.istate->identmap[op >> 8] )->get_value() @@ -985,20 +990,20 @@ std::uint32_t *vm_exec( case BC_INST_FVAR | BC_RET_FLOAT: case BC_INST_FVAR | BC_RET_NULL: - args.emplace_back(cs).set_float(static_cast( + args.emplace_back().set_float(static_cast( ts.istate->identmap[op >> 8] )->get_value()); continue; case BC_INST_FVAR | BC_RET_STRING: { - auto &v = args.emplace_back(cs); + auto &v = args.emplace_back(); v.set_float(static_cast( ts.istate->identmap[op >> 8] )->get_value()); - v.force_string(); + v.force_string(cs); continue; } case BC_INST_FVAR | BC_RET_INT: - args.emplace_back(cs).set_integer( + args.emplace_back().set_integer( integer_type(std::floor(static_cast( ts.istate->identmap[op >> 8] )->get_value())) @@ -1021,7 +1026,7 @@ std::uint32_t *vm_exec( case BC_INST_ALIAS_U: { auto v = std::move(args.back()); args.pop_back(); - cs.set_alias(args.back().get_string(), std::move(v)); + cs.set_alias(args.back().get_string(cs), std::move(v)); args.pop_back(); continue; } @@ -1038,8 +1043,8 @@ std::uint32_t *vm_exec( auto *imp = static_cast(id); if (imp->is_arg()) { if (!ident_is_used_arg(id, ts)) { - args.resize(offset, any_value{cs}); - force_arg(result, op & BC_INST_RET_MASK); + args.resize(offset); + force_arg(cs, result, op & BC_INST_RET_MASK); continue; } } @@ -1047,7 +1052,7 @@ std::uint32_t *vm_exec( ts, imp, &args[0], result, callargs, nnargs, offset, 0, op ); - args.resize(nnargs, any_value{cs}); + args.resize(nnargs); continue; } @@ -1062,11 +1067,11 @@ std::uint32_t *vm_exec( if (idarg.get_type() != value_type::STRING) { litval: result = std::move(idarg); - force_arg(result, op & BC_INST_RET_MASK); - args.resize(offset - 1, any_value{cs}); + force_arg(cs, result, op & BC_INST_RET_MASK); + args.resize(offset - 1); continue; } - auto idn = idarg.get_string(); + auto idn = idarg.get_string(cs); ident *id = cs.get_ident(idn); if (!id) { noid: @@ -1074,7 +1079,7 @@ noid: goto litval; } result.force_none(); - force_arg(result, op & BC_INST_RET_MASK); + force_arg(cs, result, op & BC_INST_RET_MASK); std::string_view ids{idn}; throw error{ cs, "unknown command: %s", ids.data() @@ -1084,8 +1089,8 @@ noid: switch (ident_p{*id}.impl().p_type) { default: if (!ident_is_callable(id)) { - args.resize(offset - 1, any_value{cs}); - force_arg(result, op & BC_INST_RET_MASK); + args.resize(offset - 1); + force_arg(cs, result, op & BC_INST_RET_MASK); continue; } /* fallthrough */ @@ -1093,12 +1098,12 @@ noid: auto *cimp = static_cast(id); args.resize(offset + std::max( std::size_t(cimp->get_num_args()), callargs - ), any_value{cs}); + )); exec_command( ts, cimp, cimp, &args[offset], result, callargs ); - force_arg(result, op & BC_INST_RET_MASK); - args.resize(offset - 1, any_value{cs}); + force_arg(cs, result, op & BC_INST_RET_MASK); + args.resize(offset - 1); continue; } case ID_LOCAL: { @@ -1106,14 +1111,14 @@ noid: for (size_t j = 0; j < size_t(callargs); ++j) { push_alias( ts, &args[offset + j].force_ident(cs), - ts.idstack.emplace_back(*ts.pstate) + ts.idstack.emplace_back() ); } auto cleanup = [&]() { for (size_t j = 0; j < size_t(callargs); ++j) { pop_alias(ts, args[offset + j].get_ident()); } - ts.idstack.resize(idstsz, ident_stack{*ts.pstate}); + ts.idstack.resize(idstsz); }; try { code = vm_exec(ts, code, result); @@ -1128,52 +1133,52 @@ noid: auto *hid = ts.istate->cmd_ivar; auto *cimp = static_cast(hid); /* the $ argument */ - args.insert(offset, any_value{cs}); + args.insert(offset, any_value{}); args.resize(offset + std::max( std::size_t(cimp->get_num_args()), callargs - ), any_value{cs}); + )); exec_command( ts, cimp, id, &args[offset], result, callargs ); - force_arg(result, op & BC_INST_RET_MASK); - args.resize(offset - 1, any_value{cs}); + force_arg(cs, result, op & BC_INST_RET_MASK); + args.resize(offset - 1); continue; } case ID_FVAR: { auto *hid = ts.istate->cmd_fvar; auto *cimp = static_cast(hid); /* the $ argument */ - args.insert(offset, any_value{cs}); + args.insert(offset, any_value{}); args.resize(offset + std::max( std::size_t(cimp->get_num_args()), callargs - ), any_value{cs}); + )); exec_command( ts, cimp, id, &args[offset], result, callargs ); - force_arg(result, op & BC_INST_RET_MASK); - args.resize(offset - 1, any_value{cs}); + force_arg(cs, result, op & BC_INST_RET_MASK); + args.resize(offset - 1); continue; } case ID_SVAR: { auto *hid = ts.istate->cmd_svar; auto *cimp = static_cast(hid); /* the $ argument */ - args.insert(offset, any_value{cs}); + args.insert(offset, any_value{}); args.resize(offset + std::max( std::size_t(cimp->get_num_args()), callargs - ), any_value{cs}); + )); exec_command( ts, cimp, id, &args[offset], result, callargs ); - force_arg(result, op & BC_INST_RET_MASK); - args.resize(offset - 1, any_value{cs}); + force_arg(cs, result, op & BC_INST_RET_MASK); + args.resize(offset - 1); continue; } case ID_ALIAS: { alias *a = static_cast(id); if (a->is_arg() && !ident_is_used_arg(a, ts)) { - args.resize(offset - 1, any_value{cs}); - force_arg(result, op & BC_INST_RET_MASK); + args.resize(offset - 1); + force_arg(cs, result, op & BC_INST_RET_MASK); continue; } if (!exec_alias( @@ -1182,7 +1187,7 @@ noid: )) { goto noid; } - args.resize(nnargs, any_value{cs}); + args.resize(nnargs); continue; } } @@ -1200,8 +1205,8 @@ noid: id->call(ts, std::span{ &args[offset], std::size_t(id->get_num_args()) }, result); - force_arg(result, op & BC_INST_RET_MASK); - args.resize(offset, any_value{cs}); + force_arg(cs, result, op & BC_INST_RET_MASK); + args.resize(offset); continue; } @@ -1216,8 +1221,8 @@ noid: std::size_t offset = args.size() - callargs; result.force_none(); id->call(ts, std::span{&args[offset], callargs}, result); - force_arg(result, op & BC_INST_RET_MASK); - args.resize(offset, any_value{cs}); + force_arg(cs, result, op & BC_INST_RET_MASK); + args.resize(offset); continue; } case BC_INST_COM_C | BC_RET_NULL: @@ -1231,14 +1236,14 @@ noid: std::size_t offset = args.size() - callargs; result.force_none(); { - any_value tv{cs}; + any_value tv{}; tv.set_string(concat_values(cs, std::span{ &args[offset], callargs }, " ")); id->call(ts, std::span{&tv, 1}, result); } - force_arg(result, op & BC_INST_RET_MASK); - args.resize(offset, any_value{cs}); + force_arg(cs, result, op & BC_INST_RET_MASK); + args.resize(offset); continue; } } diff --git a/src/cs_vm.hh b/src/cs_vm.hh index f3ae933..368c1c6 100644 --- a/src/cs_vm.hh +++ b/src/cs_vm.hh @@ -35,7 +35,7 @@ struct stack_guard { {} ~stack_guard() { - tsp->vmstack.resize(oldtop, any_value{*tsp->pstate}); + tsp->vmstack.resize(oldtop); } stack_guard(stack_guard const &) = delete; @@ -55,7 +55,7 @@ static void call_with_args(thread_state &ts, F body) { auto &ast = ts.get_astack( static_cast(ts.istate->identmap[i]) ); - auto &st = ts.idstack.emplace_back(*ts.pstate); + auto &st = ts.idstack.emplace_back(); st.next = ast.node; ast.node = ast.node->next; } @@ -84,7 +84,7 @@ static void call_with_args(thread_state &ts, F body) { } mask2 >>= 1; } - ts.idstack.resize(noff, ident_stack{*ts.pstate}); + ts.idstack.resize(noff); }; try { body(); diff --git a/src/lib_base.cc b/src/lib_base.cc index 78b5889..18fdb39 100644 --- a/src/lib_base.cc +++ b/src/lib_base.cc @@ -16,7 +16,7 @@ static inline void do_loop( return; } if (alias_local st{cs, &id}; st) { - any_value idv{cs}; + any_value idv{}; for (integer_type i = 0; i < n; ++i) { idv.set_integer(offset + i * step); st.set(idv); @@ -42,11 +42,11 @@ static inline void do_loop_conc( } if (alias_local st{cs, &id}; st) { charbuf s{cs}; - any_value idv{cs}; + any_value idv{}; for (integer_type i = 0; i < n; ++i) { idv.set_integer(offset + i * step); st.set(idv); - any_value v{cs}; + any_value v{}; switch (cs.run_loop(body, v)) { case loop_state::BREAK: goto end; @@ -58,16 +58,16 @@ static inline void do_loop_conc( if (space && i) { s.push_back(' '); } - s.append(v.get_string()); + s.append(v.get_string(cs)); } end: - res.set_string(s.str()); + res.set_string(s.str(), cs); } } void init_lib_base(state &gcs) { gcs.new_command("error", "s", [](auto &cs, auto args, auto &) { - throw error{cs, args[0].get_string()}; + throw error{cs, args[0].get_string(cs)}; }); gcs.new_command("pcall", "err", [](auto &cs, auto args, auto &ret) { @@ -77,16 +77,16 @@ void init_lib_base(state &gcs) { ret.set_integer(0); return; } - any_value result{cs}, tback{cs}; + any_value result{}, tback{}; bool rc = true; try { result = cs.run(args[0].get_code()); } catch (error const &e) { - result.set_string(e.what()); + result.set_string(e.what(), cs); if (e.get_stack().get()) { charbuf buf{cs}; print_stack(std::back_inserter(buf), e.get_stack()); - tback.set_string(buf.str()); + tback.set_string(buf.str(), cs); } rc = false; } @@ -145,11 +145,11 @@ void init_lib_base(state &gcs) { }); gcs.new_command("cases", "ste2V", [](auto &cs, auto args, auto &res) { - string_ref val = args[0].get_string(); + string_ref val = args[0].get_string(cs); for (size_t i = 1; (i + 1) < args.size(); i += 2) { if ( (args[i].get_type() == value_type::NONE) || - (args[i].get_string() == val) + (args[i].get_string(cs) == val) ) { res = cs.run(args[i + 1].get_code()); return; @@ -317,19 +317,19 @@ end: }); gcs.new_command("resetvar", "s", [](auto &cs, auto args, auto &) { - cs.reset_var(args[0].get_string()); + cs.reset_var(args[0].get_string(cs)); }); gcs.new_command("alias", "st", [](auto &cs, auto args, auto &) { - cs.set_alias(args[0].get_string(), args[1]); + cs.set_alias(args[0].get_string(cs), args[1]); }); gcs.new_command("identexists", "s", [](auto &cs, auto args, auto &res) { - res.set_integer(cs.have_ident(args[0].get_string())); + res.set_integer(cs.have_ident(args[0].get_string(cs))); }); gcs.new_command("getalias", "s", [](auto &cs, auto args, auto &res) { - auto *id = cs.get_alias(args[0].get_string()); + auto *id = cs.get_alias(args[0].get_string(cs)); if (id) { res = id->get_value(cs); } diff --git a/src/lib_list.cc b/src/lib_list.cc index c85ed05..69edea3 100644 --- a/src/lib_list.cc +++ b/src/lib_list.cc @@ -13,22 +13,22 @@ struct arg_val; template<> struct arg_val { - static integer_type get(any_value &tv) { + static integer_type get(any_value &tv, state &) { return tv.get_integer(); } }; template<> struct arg_val { - static float_type get(any_value &tv) { + static float_type get(any_value &tv, state &) { return tv.get_float(); } }; template<> struct arg_val { - static std::string_view get(any_value &tv) { - return tv.get_string(); + static std::string_view get(any_value &tv, state &cs) { + return tv.get_string(cs); } }; @@ -37,8 +37,8 @@ static inline void list_find( state &cs, std::span args, any_value &res, F cmp ) { integer_type n = 0, skip = args[2].get_integer(); - T val = arg_val::get(args[1]); - for (list_parser p{cs, args[0].get_string()}; p.parse(); ++n) { + T val = arg_val::get(args[1], cs); + for (list_parser p{cs, args[0].get_string(cs)}; p.parse(); ++n) { if (cmp(p, val)) { res.set_integer(n); return; @@ -58,8 +58,8 @@ template static inline void list_assoc( state &cs, std::span args, any_value &res, F cmp ) { - T val = arg_val::get(args[1]); - for (list_parser p{cs, args[0].get_string()}; p.parse();) { + T val = arg_val::get(args[1], cs); + for (list_parser p{cs, args[0].get_string(cs)}; p.parse();) { if (cmp(p, val)) { if (p.parse()) { res.set_string(p.get_item()); @@ -77,7 +77,7 @@ static void loop_list_conc( bcode_ref &&body, bool space ) { if (alias_local st{cs, id}; st) { - any_value idv{cs}; + any_value idv{}; charbuf r{cs}; int n = 0; for (list_parser p{cs, list}; p.parse(); ++n) { @@ -86,7 +86,7 @@ static void loop_list_conc( if (n && space) { r.push_back(' '); } - any_value v{cs}; + any_value v{}; switch (cs.run_loop(body, v)) { case loop_state::BREAK: goto end; @@ -95,10 +95,10 @@ static void loop_list_conc( default: break; } - r.append(v.get_string()); + r.append(v.get_string(cs)); } end: - res.set_string(r.str()); + res.set_string(r.str(), cs); } } @@ -119,8 +119,8 @@ template static inline void list_merge( state &cs, std::span args, any_value &res, F cmp ) { - std::string_view list = args[0].get_string(); - std::string_view elems = args[1].get_string(); + std::string_view list = args[0].get_string(cs); + std::string_view elems = args[1].get_string(cs); charbuf buf{cs}; if (PushList) { buf.append(list); @@ -136,14 +136,16 @@ static inline void list_merge( buf.append(p.get_quoted_item()); } } - res.set_string(buf.str()); + res.set_string(buf.str(), cs); } static void init_lib_list_sort(state &cs); void init_lib_list(state &gcs) { gcs.new_command("listlen", "s", [](auto &cs, auto args, auto &res) { - res.set_integer(integer_type(list_parser{cs, args[0].get_string()}.count())); + res.set_integer( + integer_type(list_parser{cs, args[0].get_string(cs)}.count()) + ); }); gcs.new_command("at", "si1V", [](auto &cs, auto args, auto &res) { @@ -154,7 +156,7 @@ void init_lib_list(state &gcs) { res = args[0]; return; } - auto str = args[0].get_string(); + auto str = args[0].get_string(cs); list_parser p{cs, str}; for (size_t i = 1; i < args.size(); ++i) { p.set_input(str); @@ -179,7 +181,7 @@ void init_lib_list(state &gcs) { integer_type offset = std::max(skip, integer_type(0)), len = (numargs >= 3) ? std::max(count, integer_type(0)) : -1; - list_parser p{cs, args[0].get_string()}; + list_parser p{cs, args[0].get_string(cs)}; for (integer_type i = 0; i < offset; ++i) { if (!p.parse()) break; } @@ -187,7 +189,7 @@ void init_lib_list(state &gcs) { if (offset > 0) { p.skip_until_item(); } - res.set_string(p.get_input()); + res.set_string(p.get_input(), cs); return; } @@ -195,22 +197,22 @@ void init_lib_list(state &gcs) { if (len > 0 && p.parse()) { while (--len > 0 && p.parse()); } else { - res.set_string(""); + res.set_string("", cs); return; } auto quote = p.get_quoted_item(); auto *qend = "e[quote.size()]; - res.set_string(std::string_view{list, qend}); + res.set_string(std::string_view{list, qend}, cs); }); gcs.new_command("listfind", "rse", [](auto &cs, auto args, auto &res) { if (alias_local st{cs, args[0].get_ident()}; st) { - any_value idv{cs}; + any_value idv{}; auto body = args[2].get_code(); int n = -1; - for (list_parser p{cs, args[1].get_string()}; p.parse();) { + for (list_parser p{cs, args[1].get_string(cs)}; p.parse();) { ++n; - idv.set_string(p.get_raw_item()); + idv.set_string(p.get_raw_item(), cs); st.set(std::move(idv)); if (cs.run(body).get_bool()) { res.set_integer(integer_type(n)); @@ -223,12 +225,12 @@ void init_lib_list(state &gcs) { gcs.new_command("listassoc", "rse", [](auto &cs, auto args, auto &res) { if (alias_local st{cs, args[0].get_ident()}; st) { - any_value idv{cs}; + any_value idv{}; auto body = args[2].get_code(); int n = -1; - for (list_parser p{cs, args[1].get_string()}; p.parse();) { + for (list_parser p{cs, args[1].get_string(cs)}; p.parse();) { ++n; - idv.set_string(p.get_raw_item()); + idv.set_string(p.get_raw_item(), cs); st.set(std::move(idv)); if (cs.run(body).get_bool()) { if (p.parse()) { @@ -289,10 +291,10 @@ void init_lib_list(state &gcs) { gcs.new_command("looplist", "rse", [](auto &cs, auto args, auto &) { if (alias_local st{cs, args[0].get_ident()}; st) { - any_value idv{cs}; + any_value idv{}; auto body = args[2].get_code(); int n = 0; - for (list_parser p{cs, args[1].get_string()}; p.parse(); ++n) { + for (list_parser p{cs, args[1].get_string(cs)}; p.parse(); ++n) { idv.set_string(p.get_item()); st.set(std::move(idv)); switch (cs.run_loop(body)) { @@ -311,16 +313,16 @@ void init_lib_list(state &gcs) { if (!st1 || !st2) { return; } - any_value idv{cs}; + any_value idv{}; auto body = args[3].get_code(); int n = 0; - for (list_parser p{cs, args[2].get_string()}; p.parse(); n += 2) { + for (list_parser p{cs, args[2].get_string(cs)}; p.parse(); n += 2) { idv.set_string(p.get_item()); st1.set(std::move(idv)); if (p.parse()) { idv.set_string(p.get_item()); } else { - idv.set_string(""); + idv.set_string("", cs); } st2.set(std::move(idv)); switch (cs.run_loop(body)) { @@ -339,22 +341,22 @@ void init_lib_list(state &gcs) { if (!st1 || !st2 || !st3) { return; } - any_value idv{cs}; + any_value idv{}; auto body = args[4].get_code(); int n = 0; - for (list_parser p{cs, args[3].get_string()}; p.parse(); n += 3) { + for (list_parser p{cs, args[3].get_string(cs)}; p.parse(); n += 3) { idv.set_string(p.get_item()); st1.set(std::move(idv)); if (p.parse()) { idv.set_string(p.get_item()); } else { - idv.set_string(""); + idv.set_string("", cs); } st2.set(std::move(idv)); if (p.parse()) { idv.set_string(p.get_item()); } else { - idv.set_string(""); + idv.set_string("", cs); } st3.set(std::move(idv)); switch (cs.run_loop(body)) { @@ -368,7 +370,7 @@ void init_lib_list(state &gcs) { gcs.new_command("looplistconcat", "rse", [](auto &cs, auto args, auto &res) { loop_list_conc( - cs, res, args[0].get_ident(), args[1].get_string(), + cs, res, args[0].get_ident(), args[1].get_string(cs), args[2].get_code(), true ); }); @@ -377,19 +379,19 @@ void init_lib_list(state &gcs) { auto &cs, auto args, auto &res ) { loop_list_conc( - cs, res, args[0].get_ident(), args[1].get_string(), + cs, res, args[0].get_ident(), args[1].get_string(cs), args[2].get_code(), false ); }); gcs.new_command("listfilter", "rse", [](auto &cs, auto args, auto &res) { if (alias_local st{cs, args[0].get_ident()}; st) { - any_value idv{cs}; + any_value idv{}; auto body = args[2].get_code(); charbuf r{cs}; int n = 0; - for (list_parser p{cs, args[1].get_string()}; p.parse(); ++n) { - idv.set_string(p.get_raw_item()); + for (list_parser p{cs, args[1].get_string(cs)}; p.parse(); ++n) { + idv.set_string(p.get_raw_item(), cs); st.set(std::move(idv)); if (cs.run(body).get_bool()) { if (r.size()) { @@ -398,17 +400,17 @@ void init_lib_list(state &gcs) { r.append(p.get_quoted_item()); } } - res.set_string(r.str()); + res.set_string(r.str(), cs); } }); gcs.new_command("listcount", "rse", [](auto &cs, auto args, auto &res) { if (alias_local st{cs, args[0].get_ident()}; st) { - any_value idv{cs}; + any_value idv{}; auto body = args[2].get_code(); int n = 0, r = 0; - for (list_parser p{cs, args[1].get_string()}; p.parse(); ++n) { - idv.set_string(p.get_raw_item()); + for (list_parser p{cs, args[1].get_string(cs)}; p.parse(); ++n) { + idv.set_string(p.get_raw_item(), cs); st.set(std::move(idv)); if (cs.run(body).get_bool()) { r++; @@ -420,8 +422,8 @@ void init_lib_list(state &gcs) { gcs.new_command("prettylist", "ss", [](auto &cs, auto args, auto &res) { charbuf buf{cs}; - std::string_view s = args[0].get_string(); - std::string_view conj = args[1].get_string(); + std::string_view s = args[0].get_string(cs); + std::string_view conj = args[1].get_string(cs); list_parser p{cs, s}; size_t len = p.count(); size_t n = 0; @@ -443,12 +445,12 @@ void init_lib_list(state &gcs) { buf.push_back(' '); } } - res.set_string(buf.str()); + res.set_string(buf.str(), cs); }); gcs.new_command("indexof", "ss", [](auto &cs, auto args, auto &res) { res.set_integer( - list_includes(cs, args[0].get_string(), args[1].get_string()) + list_includes(cs, args[0].get_string(cs), args[1].get_string(cs)) ); }); @@ -465,8 +467,8 @@ void init_lib_list(state &gcs) { gcs.new_command("listsplice", "ssii", [](auto &cs, auto args, auto &res) { integer_type offset = std::max(args[2].get_integer(), integer_type(0)); integer_type len = std::max(args[3].get_integer(), integer_type(0)); - std::string_view s = args[0].get_string(); - std::string_view vals = args[1].get_string(); + std::string_view s = args[0].get_string(cs); + std::string_view vals = args[1].get_string(cs); char const *list = s.data(); list_parser p{cs, s}; for (integer_type i = 0; i < offset; ++i) { @@ -505,7 +507,7 @@ void init_lib_list(state &gcs) { break; } } - res.set_string(buf.str()); + res.set_string(buf.str(), cs); }); init_lib_list_sort(gcs); @@ -522,10 +524,10 @@ struct ListSortFun { bcode_ref const *body; bool operator()(ListSortItem const &xval, ListSortItem const &yval) { - any_value v{cs}; - v.set_string(xval.str); + any_value v{}; + v.set_string(xval.str, cs); xst.set(std::move(v)); - v.set_string(yval.str); + v.set_string(yval.str, cs); yst.set(std::move(v)); return cs.run(*body).get_bool(); } @@ -554,7 +556,7 @@ static void list_sort( } if (items.empty()) { - res.set_string(list); + res.set_string(list, cs); return; } @@ -609,19 +611,19 @@ static void list_sort( } sorted.append(item.quote); } - res.set_string(sorted.str()); + res.set_string(sorted.str(), cs); } static void init_lib_list_sort(state &gcs) { gcs.new_command("sortlist", "srree", [](auto &cs, auto args, auto &res) { list_sort( - cs, res, args[0].get_string(), args[1].get_ident(), + cs, res, args[0].get_string(cs), args[1].get_ident(), args[2].get_ident(), args[3].get_code(), args[4].get_code() ); }); gcs.new_command("uniquelist", "srre", [](auto &cs, auto args, auto &res) { list_sort( - cs, res, args[0].get_string(), args[1].get_ident(), + cs, res, args[0].get_string(cs), args[1].get_ident(), args[2].get_ident(), bcode_ref{}, args[3].get_code() ); }); diff --git a/src/lib_str.cc b/src/lib_str.cc index 8b7b16b..de3d5d3 100644 --- a/src/lib_str.cc +++ b/src/lib_str.cc @@ -11,17 +11,17 @@ namespace cubescript { template static inline void str_cmp_by( - std::span args, any_value &res, F cfunc + state &cs, std::span args, any_value &res, F cfunc ) { bool val; if (args.size() >= 2) { - val = cfunc(args[0].get_string(), args[1].get_string()); + val = cfunc(args[0].get_string(cs), args[1].get_string(cs)); for (size_t i = 2; (i < args.size()) && val; ++i) { - val = cfunc(args[i - 1].get_string(), args[i].get_string()); + val = cfunc(args[i - 1].get_string(cs), args[i].get_string(cs)); } } else { val = cfunc( - !args.empty() ? args[0].get_string() : std::string_view(), + !args.empty() ? args[0].get_string(cs) : std::string_view(), std::string_view() ); } @@ -29,8 +29,9 @@ static inline void str_cmp_by( } void init_lib_string(state &cs) { - cs.new_command("strstr", "ss", [](auto &, auto args, auto &res) { - std::string_view a = args[0].get_string(), b = args[1].get_string(); + cs.new_command("strstr", "ss", [](auto &ccs, auto args, auto &res) { + std::string_view a = args[0].get_string(ccs); + std::string_view b = args[1].get_string(ccs); auto pos = a.find(b); if (pos == a.npos) { res.set_integer(-1); @@ -39,12 +40,12 @@ void init_lib_string(state &cs) { } }); - cs.new_command("strlen", "s", [](auto &, auto args, auto &res) { - res.set_integer(integer_type(args[0].get_string().size())); + cs.new_command("strlen", "s", [](auto &ccs, auto args, auto &res) { + res.set_integer(integer_type(args[0].get_string(ccs).size())); }); - cs.new_command("strcode", "si", [](auto &, auto args, auto &res) { - std::string_view str = args[0].get_string(); + cs.new_command("strcode", "si", [](auto &ccs, auto args, auto &res) { + std::string_view str = args[0].get_string(ccs); integer_type i = args[1].get_integer(); if (i >= integer_type(str.size())) { res.set_integer(0); @@ -53,13 +54,13 @@ void init_lib_string(state &cs) { } }); - cs.new_command("codestr", "i", [](auto &, auto args, auto &res) { + cs.new_command("codestr", "i", [](auto &ccs, auto args, auto &res) { char const p[2] = { char(args[0].get_integer()), '\0' }; - res.set_string(std::string_view{static_cast(p)}); + res.set_string(std::string_view{static_cast(p)}, ccs); }); cs.new_command("strlower", "s", [](auto &ccs, auto args, auto &res) { - auto inps = args[0].get_string(); + auto inps = args[0].get_string(ccs); auto *ics = state_p{ccs}.ts().istate; auto *buf = ics->strman->alloc_buf(inps.size()); for (std::size_t i = 0; i < inps.size(); ++i) { @@ -69,7 +70,7 @@ void init_lib_string(state &cs) { }); cs.new_command("strupper", "s", [](auto &ccs, auto args, auto &res) { - auto inps = args[0].get_string(); + auto inps = args[0].get_string(ccs); auto *ics = state_p{ccs}.ts().istate; auto *buf = ics->strman->alloc_buf(inps.size()); for (std::size_t i = 0; i < inps.size(); ++i) { @@ -80,14 +81,14 @@ void init_lib_string(state &cs) { cs.new_command("escape", "s", [](auto &ccs, auto args, auto &res) { charbuf s{ccs}; - escape_string(std::back_inserter(s), args[0].get_string()); - res.set_string(s.str()); + escape_string(std::back_inserter(s), args[0].get_string(ccs)); + res.set_string(s.str(), ccs); }); cs.new_command("unescape", "s", [](auto &ccs, auto args, auto &res) { charbuf s{ccs}; - unescape_string(std::back_inserter(s), args[0].get_string()); - res.set_string(s.str()); + unescape_string(std::back_inserter(s), args[0].get_string(ccs)); + res.set_string(s.str(), ccs); }); cs.new_command("concat", "V", [](auto &ccs, auto args, auto &res) { @@ -103,7 +104,7 @@ void init_lib_string(state &cs) { return; } charbuf s{ccs}; - string_ref fs = args[0].get_string(); + string_ref fs = args[0].get_string(ccs); std::string_view f{fs}; for (auto it = f.begin(); it != f.end(); ++it) { char c = *it; @@ -114,7 +115,7 @@ void init_lib_string(state &cs) { if ((ic >= '1') && (ic <= '9')) { int i = ic - '0'; if (std::size_t(i) < args.size()) { - s.append(args[i].get_string()); + s.append(args[i].get_string(ccs)); } } else { s.push_back(ic); @@ -123,7 +124,7 @@ void init_lib_string(state &cs) { s.push_back(c); } } - res.set_string(s.str()); + res.set_string(s.str(), ccs); }); cs.new_command("tohex", "ii", [](auto &ccs, auto args, auto &res) { @@ -138,19 +139,21 @@ void init_lib_string(state &cs) { s.data()[0] = '\0'; int nn = snprintf(s.data(), n + 1, "0x%.*llX", prec, val); if ((nn > 0) && (nn <= n)) { - res.set_string(std::string_view{s.data(), std::size_t(nn)}); + res.set_string( + std::string_view{s.data(), std::size_t(nn)}, ccs + ); return; } } else if (n > 0) { - res.set_string(static_cast(buf)); + res.set_string(static_cast(buf), ccs); return; } /* should pretty much be unreachable */ throw internal_error{"format error"}; }); - cs.new_command("substr", "siiN", [](auto &, auto args, auto &res) { - std::string_view s = args[0].get_string(); + cs.new_command("substr", "siiN", [](auto &ccs, auto args, auto &res) { + std::string_view s = args[0].get_string(ccs); auto start = args[1].get_integer(), count = args[2].get_integer(); auto numargs = args[3].get_integer(); auto len = integer_type(s.size()); @@ -160,41 +163,41 @@ void init_lib_string(state &cs) { ((numargs >= 3) ? size_t(std::clamp(count, integer_type(0), len - offset)) : size_t(len - offset)) - }); + }, ccs); }); - cs.new_command("strcmp", "s1V", [](auto &, auto args, auto &res) { - str_cmp_by(args, res, std::equal_to()); + cs.new_command("strcmp", "s1V", [](auto &ccs, auto args, auto &res) { + str_cmp_by(ccs, args, res, std::equal_to()); }); - cs.new_command("=s", "s1V", [](auto &, auto args, auto &res) { - str_cmp_by(args, res, std::equal_to()); + cs.new_command("=s", "s1V", [](auto &ccs, auto args, auto &res) { + str_cmp_by(ccs, args, res, std::equal_to()); }); - cs.new_command("!=s", "s1V", [](auto &, auto args, auto &res) { - str_cmp_by(args, res, std::not_equal_to()); + cs.new_command("!=s", "s1V", [](auto &ccs, auto args, auto &res) { + str_cmp_by(ccs, args, res, std::not_equal_to()); }); - cs.new_command("()); + cs.new_command("()); }); - cs.new_command(">s", "s1V", [](auto &, auto args, auto &res) { - str_cmp_by(args, res, std::greater()); + cs.new_command(">s", "s1V", [](auto &ccs, auto args, auto &res) { + str_cmp_by(ccs, args, res, std::greater()); }); - cs.new_command("<=s", "s1V", [](auto &, auto args, auto &res) { - str_cmp_by(args, res, std::less_equal()); + cs.new_command("<=s", "s1V", [](auto &ccs, auto args, auto &res) { + str_cmp_by(ccs, args, res, std::less_equal()); }); - cs.new_command(">=s", "s1V", [](auto &, auto args, auto &res) { - str_cmp_by(args, res, std::greater_equal()); + cs.new_command(">=s", "s1V", [](auto &ccs, auto args, auto &res) { + str_cmp_by(ccs, args, res, std::greater_equal()); }); cs.new_command("strreplace", "ssss", [](auto &ccs, auto args, auto &res) { - std::string_view s = args[0].get_string(); - std::string_view oldval = args[1].get_string(), - newval = args[2].get_string(), - newval2 = args[3].get_string(); + std::string_view s = args[0].get_string(ccs); + std::string_view oldval = args[1].get_string(ccs), + newval = args[2].get_string(ccs), + newval2 = args[3].get_string(ccs); if (newval2.empty()) { newval2 = newval; } if (oldval.empty()) { - res.set_string(s); + res.set_string(s, ccs); return; } charbuf buf{ccs}; @@ -202,7 +205,7 @@ void init_lib_string(state &cs) { auto p = s.find(oldval); if (p == s.npos) { buf.append(s); - res.set_string(s); + res.set_string(s, ccs); return; } buf.append(s.substr(0, p)); @@ -215,8 +218,8 @@ void init_lib_string(state &cs) { }); cs.new_command("strsplice", "ssii", [](auto &ccs, auto args, auto &res) { - std::string_view s = args[0].get_string(); - std::string_view vals = args[1].get_string(); + std::string_view s = args[0].get_string(ccs); + std::string_view vals = args[1].get_string(ccs); integer_type skip = args[2].get_integer(), count = args[3].get_integer(); integer_type offset = std::clamp(skip, integer_type(0), integer_type(s.size())), @@ -230,7 +233,7 @@ void init_lib_string(state &cs) { if ((offset + len) < integer_type(s.size())) { p.append(s.substr(offset + len, s.size() - offset - len)); } - res.set_string(p.str()); + res.set_string(p.str(), ccs); }); } diff --git a/tools/repl.cc b/tools/repl.cc index 90d8dd5..52a7b98 100644 --- a/tools/repl.cc +++ b/tools/repl.cc @@ -229,7 +229,7 @@ static bool do_run_file( } static bool do_call(cs::state &cs, std::string_view line, bool file = false) { - cs::any_value ret{cs}; + cs::any_value ret{}; scs = &cs; signal(SIGINT, do_sigint); try { @@ -271,7 +271,7 @@ static bool do_call(cs::state &cs, std::string_view line, bool file = false) { signal(SIGINT, SIG_DFL); scs = nullptr; if (ret.get_type() != cs::value_type::NONE) { - std::printf("%s\n", std::string_view{ret.get_string()}.data()); + std::printf("%s\n", std::string_view{ret.get_string(cs)}.data()); } return false; } @@ -362,8 +362,8 @@ int main(int argc, char **argv) { }); gcs.new_command("exec", "s", [](auto &css, auto args, auto &) { - auto file = args[0].get_string(); - cs::any_value val{css}; + auto file = args[0].get_string(css); + cs::any_value val{}; bool ret = do_run_file(css, file, val); if (!ret) { throw cs::error( @@ -372,8 +372,8 @@ int main(int argc, char **argv) { } }); - gcs.new_command("echo", "C", [](auto &, auto args, auto &) { - std::printf("%s\n", std::string_view{args[0].get_string()}.data()); + gcs.new_command("echo", "C", [](auto &css, auto args, auto &) { + std::printf("%s\n", std::string_view{args[0].get_string(css)}.data()); }); int firstarg = 0;