only store trivial types in any_value (manage strrefs manually)

master
Daniel Kolesa 2021-04-11 03:54:06 +02:00
parent d358dd83e7
commit 3ed7b59d0b
4 changed files with 48 additions and 37 deletions

View File

@ -60,9 +60,7 @@ struct LIBCUBESCRIPT_EXPORT string_ref {
return std::string_view{*this}.length(); return std::string_view{*this}.length();
} }
char const *data() const { char const *data() const;
return std::string_view{*this}.data();
}
std::string_view view() const { std::string_view view() const {
return std::string_view{*this}; return std::string_view{*this};
@ -75,8 +73,7 @@ struct LIBCUBESCRIPT_EXPORT string_ref {
bool operator==(string_ref const &s) const; bool operator==(string_ref const &s) const;
private: private:
/* for internal use only */ string_ref(char const *p);
string_ref(char const *p, internal_state *cs);
char const *p_str; char const *p_str;
}; };
@ -124,12 +121,7 @@ struct LIBCUBESCRIPT_EXPORT any_value {
ident &force_ident(state &cs); ident &force_ident(state &cs);
private: private:
std::aligned_union_t<1, std::aligned_union_t<1, integer_type, float_type, void *> p_stor;
integer_type,
float_type,
void *,
string_ref
> p_stor;
value_type p_type; value_type p_type;
}; };

View File

@ -54,12 +54,12 @@ string_ref string_pool::steal(char *ptr) {
if (st) { if (st) {
/* the buffer is superfluous now */ /* the buffer is superfluous now */
cstate->alloc(ss, ss->length + sizeof(string_ref_state) + 1, 0); cstate->alloc(ss, ss->length + sizeof(string_ref_state) + 1, 0);
return string_ref{reinterpret_cast<char const *>(st + 1), cstate}; return string_ref{reinterpret_cast<char const *>(st + 1)};
} }
} }
ss->refcount = 0; /* string_ref will increment it */ ss->refcount = 0; /* string_ref will increment it */
counts.emplace(sr, ss); counts.emplace(sr, ss);
return string_ref{ptr, cstate}; return string_ref{ptr};
} }
void string_pool::unref(char const *ptr) { void string_pool::unref(char const *ptr) {
@ -108,9 +108,19 @@ char *string_pool::alloc_buf(std::size_t len) const {
return strp; return strp;
} }
/* strref implementation */ char const *str_managed_ref(char const *str) {
return get_ref_state(str)->state->strman->ref(str);
}
/* strref */ void str_managed_unref(char const *str) {
get_ref_state(str)->state->strman->unref(str);
}
std::string_view str_managed_view(char const *str) {
return get_ref_state(str)->state->strman->get(str);
}
/* strref implementation */
LIBCUBESCRIPT_EXPORT string_ref::string_ref( LIBCUBESCRIPT_EXPORT string_ref::string_ref(
internal_state *cs, std::string_view str internal_state *cs, std::string_view str
@ -129,24 +139,25 @@ LIBCUBESCRIPT_EXPORT string_ref::string_ref(string_ref const &ref):
} }
/* this can be used by friends to do quick string_ref creation */ /* this can be used by friends to do quick string_ref creation */
LIBCUBESCRIPT_EXPORT string_ref::string_ref( LIBCUBESCRIPT_EXPORT string_ref::string_ref(char const *p) {
char const *p, internal_state *cs p_str = str_managed_ref(p);
) {
p_str = cs->strman->ref(p);
} }
LIBCUBESCRIPT_EXPORT string_ref::~string_ref() { LIBCUBESCRIPT_EXPORT string_ref::~string_ref() {
get_ref_state(p_str)->state->strman->unref(p_str); str_managed_unref(p_str);
} }
LIBCUBESCRIPT_EXPORT string_ref &string_ref::operator=(string_ref const &ref) { LIBCUBESCRIPT_EXPORT string_ref &string_ref::operator=(string_ref const &ref) {
p_str = ref.p_str; p_str = str_managed_ref(ref.p_str);
get_ref_state(p_str)->state->strman->ref(p_str);
return *this; return *this;
} }
LIBCUBESCRIPT_EXPORT char const *string_ref::data() const {
return p_str;
}
LIBCUBESCRIPT_EXPORT string_ref::operator std::string_view() const { LIBCUBESCRIPT_EXPORT string_ref::operator std::string_view() const {
return get_ref_state(p_str)->state->strman->get(p_str); return str_managed_view(p_str);
} }
LIBCUBESCRIPT_EXPORT bool string_ref::operator==(string_ref const &s) const { LIBCUBESCRIPT_EXPORT bool string_ref::operator==(string_ref const &s) const {

View File

@ -13,6 +13,10 @@ namespace cubescript {
struct string_ref_state; struct string_ref_state;
char const *str_managed_ref(char const *str);
void str_managed_unref(char const *str);
std::string_view str_managed_view(char const *str);
/* string manager /* string manager
* *
* the purpose of this is to handle interning of strings; each string within * the purpose of this is to handle interning of strings; each string within

View File

@ -2,6 +2,7 @@
#include "cs_std.hh" #include "cs_std.hh"
#include "cs_parser.hh" #include "cs_parser.hh"
#include "cs_state.hh" #include "cs_state.hh"
#include "cs_strman.hh"
#include <cmath> #include <cmath>
#include <iterator> #include <iterator>
@ -66,7 +67,7 @@ template<typename T>
static inline void csv_cleanup(value_type tv, T *stor) { static inline void csv_cleanup(value_type tv, T *stor) {
switch (tv) { switch (tv) {
case value_type::STRING: case value_type::STRING:
csv_get<string_ref>(stor).~string_ref(); str_managed_unref(csv_get<char const *>(stor));
break; break;
case value_type::CODE: { case value_type::CODE: {
bcode_unref(csv_get<uint32_t *>(stor)); bcode_unref(csv_get<uint32_t *>(stor));
@ -105,9 +106,8 @@ any_value &any_value::operator=(any_value const &v) {
break; break;
case value_type::STRING: case value_type::STRING:
p_type = value_type::STRING; p_type = value_type::STRING;
new (&csv_get<string_ref>(&p_stor)) string_ref{ p_stor = v.p_stor;
csv_get<string_ref>(&v.p_stor) str_managed_ref(csv_get<char const *>(&p_stor));
};
break; break;
case value_type::CODE: case value_type::CODE:
set_code(v.get_code()); set_code(v.get_code());
@ -142,13 +142,13 @@ void any_value::set_float(float_type val) {
void any_value::set_string(std::string_view val, state &cs) { void any_value::set_string(std::string_view val, state &cs) {
csv_cleanup(p_type, &p_stor); csv_cleanup(p_type, &p_stor);
new (&csv_get<string_ref>(&p_stor)) string_ref{cs, val}; csv_get<char const *>(&p_stor) = state_p{cs}.ts().istate->strman->add(val);
p_type = value_type::STRING; p_type = value_type::STRING;
} }
void any_value::set_string(string_ref const &val) { void any_value::set_string(string_ref const &val) {
csv_cleanup(p_type, &p_stor); csv_cleanup(p_type, &p_stor);
new (&csv_get<string_ref>(&p_stor)) string_ref{val}; csv_get<char const *>(&p_stor) = str_managed_ref(val.p_str);
p_type = value_type::STRING; p_type = value_type::STRING;
} }
@ -197,7 +197,7 @@ float_type any_value::force_float() {
rf = float_type(csv_get<integer_type>(&p_stor)); rf = float_type(csv_get<integer_type>(&p_stor));
break; break;
case value_type::STRING: case value_type::STRING:
rf = parse_float(csv_get<string_ref>(&p_stor)); rf = parse_float(str_managed_view(csv_get<char const *>(&p_stor)));
break; break;
case value_type::FLOAT: case value_type::FLOAT:
return csv_get<float_type>(&p_stor); return csv_get<float_type>(&p_stor);
@ -215,7 +215,7 @@ integer_type any_value::force_integer() {
ri = integer_type(std::floor(csv_get<float_type>(&p_stor))); ri = integer_type(std::floor(csv_get<float_type>(&p_stor)));
break; break;
case value_type::STRING: case value_type::STRING:
ri = parse_int(csv_get<string_ref>(&p_stor)); ri = parse_int(str_managed_view(csv_get<char const *>(&p_stor)));
break; break;
case value_type::INTEGER: case value_type::INTEGER:
return csv_get<integer_type>(&p_stor); return csv_get<integer_type>(&p_stor);
@ -237,13 +237,13 @@ std::string_view any_value::force_string(state &cs) {
str = intstr(csv_get<integer_type>(&p_stor), rs); str = intstr(csv_get<integer_type>(&p_stor), rs);
break; break;
case value_type::STRING: case value_type::STRING:
return csv_get<string_ref>(&p_stor); return str_managed_view(csv_get<char const *>(&p_stor));
default: default:
str = rs.str(); str = rs.str();
break; break;
} }
set_string(str, cs); set_string(str, cs);
return csv_get<string_ref>(&p_stor); return str_managed_view(csv_get<char const *>(&p_stor));
} }
bcode_ref any_value::force_code(state &cs) { bcode_ref any_value::force_code(state &cs) {
@ -281,7 +281,7 @@ integer_type any_value::get_integer() const {
case value_type::INTEGER: case value_type::INTEGER:
return csv_get<integer_type>(&p_stor); return csv_get<integer_type>(&p_stor);
case value_type::STRING: case value_type::STRING:
return parse_int(csv_get<string_ref>(&p_stor)); return parse_int(str_managed_view(csv_get<char const *>(&p_stor)));
default: default:
break; break;
} }
@ -295,7 +295,9 @@ float_type any_value::get_float() const {
case value_type::INTEGER: case value_type::INTEGER:
return float_type(csv_get<integer_type>(&p_stor)); return float_type(csv_get<integer_type>(&p_stor));
case value_type::STRING: case value_type::STRING:
return parse_float(csv_get<string_ref>(&p_stor)); return parse_float(
str_managed_view(csv_get<char const *>(&p_stor))
);
default: default:
break; break;
} }
@ -319,7 +321,7 @@ ident *any_value::get_ident() const {
string_ref any_value::get_string(state &cs) const { string_ref any_value::get_string(state &cs) const {
switch (get_type()) { switch (get_type()) {
case value_type::STRING: case value_type::STRING:
return csv_get<string_ref>(&p_stor); return string_ref{csv_get<char const *>(&p_stor)};
case value_type::INTEGER: { case value_type::INTEGER: {
charbuf rs{cs}; charbuf rs{cs};
return string_ref{ return string_ref{
@ -357,7 +359,9 @@ bool any_value::get_bool() const {
case value_type::INTEGER: case value_type::INTEGER:
return csv_get<integer_type>(&p_stor) != 0; return csv_get<integer_type>(&p_stor) != 0;
case value_type::STRING: { case value_type::STRING: {
std::string_view s = csv_get<string_ref>(&p_stor); std::string_view s = str_managed_view(
csv_get<char const *>(&p_stor)
);
if (s.empty()) { if (s.empty()) {
return false; return false;
} }