From 126d6ab2b69417e2f1ad0d182443838fed073372 Mon Sep 17 00:00:00 2001 From: Daniel Kolesa Date: Fri, 19 Mar 2021 01:31:34 +0100 Subject: [PATCH] use a stolen buffer for strupper/lower --- include/cubescript/cubescript.hh | 3 +++ src/cs_vm.hh | 8 ++++++++ src/lib_str.cc | 29 ++++++++++++++++++++--------- 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/include/cubescript/cubescript.hh b/include/cubescript/cubescript.hh index d48b285..8abeb8e 100644 --- a/include/cubescript/cubescript.hh +++ b/include/cubescript/cubescript.hh @@ -70,6 +70,8 @@ OSTD_EXPORT bool cs_code_is_empty(cs_bcode *code); struct OSTD_EXPORT cs_strref { friend struct cs_value; + /* FIXME: eliminate this */ + friend inline cs_strref cs_make_strref(char const *p, cs_shared_state &cs); cs_strref() = delete; cs_strref(cs_shared_state &cs, ostd::string_range str); @@ -381,6 +383,7 @@ struct OSTD_EXPORT cs_state { friend struct cs_strref; friend struct cs_value; friend struct cs_gen_state; + friend inline cs_shared_state *cs_get_sstate(cs_state &); cs_shared_state *p_state; cs_ident_link *p_callstack = nullptr; diff --git a/src/cs_vm.hh b/src/cs_vm.hh index 29bb898..a63b1ce 100644 --- a/src/cs_vm.hh +++ b/src/cs_vm.hh @@ -155,6 +155,14 @@ struct cs_shared_state { } }; +inline cs_shared_state *cs_get_sstate(cs_state &cs) { + return cs.p_state; +} + +inline cs_strref cs_make_strref(char const *p, cs_shared_state &cs) { + return cs_strref{p, cs}; +} + struct CsBreakException { }; diff --git a/src/lib_str.cc b/src/lib_str.cc index 1c75d2f..0bd197f 100644 --- a/src/lib_str.cc +++ b/src/lib_str.cc @@ -3,6 +3,7 @@ #include #include "cs_util.hh" +#include "cs_vm.hh" namespace cscript { @@ -56,20 +57,30 @@ void cs_init_lib_string(cs_state &cs) { res.set_str(ostd::string_range{static_cast(p)}); }); - cs.new_command("strlower", "s", [](auto &, auto args, auto &res) { - cs_string s{ostd::string_range{args[0].get_str()}}; - for (auto i: ostd::range(s.size())) { - s[i] = tolower(s[i]); + cs.new_command("strlower", "s", [](auto &ccs, auto args, auto &res) { + auto inps = ostd::string_range{args[0].get_str()}; + auto *ics = cs_get_sstate(ccs); + auto *buf = ics->strman->alloc_buf(inps.size()); + for (auto i: ostd::range(inps.size())) { + buf[i] = tolower(inps[i]); } - res.set_str(s); + auto const *cbuf = ics->strman->steal(buf); + auto sr = cs_make_strref(cbuf, *ics); + sman->unref(cbuf); + res.set_str(sr); }); cs.new_command("strupper", "s", [](auto &, auto args, auto &res) { - cs_string s{ostd::string_range{args[0].get_str()}}; - for (auto i: ostd::range(s.size())) { - s[i] = toupper(s[i]); + auto inps = ostd::string_range{args[0].get_str()}; + auto *ics = cs_get_sstate(ccs); + auto *buf = ics->strman->alloc_buf(inps.size()); + for (auto i: ostd::range(inps.size())) { + buf[i] = toupper(inps[i]); } - res.set_str(s); + auto const *cbuf = ics->strman->steal(buf); + auto sr = cs_make_strref(cbuf, *ics); + sman->unref(cbuf); + res.set_str(sr); }); cs.new_command("escape", "s", [](auto &, auto args, auto &res) {