mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 11:07:45 +00:00
LibJS: Store DFS instead of opaque StringImpl inside StringOrSymbol
Additionally, use the second bit (instead of the first) to differentiate between strings and symbols there. This will allow transparent conversion of DFS to StringBase in the future.
This commit is contained in:
parent
a53911717f
commit
761d16141d
1 changed files with 38 additions and 36 deletions
|
@ -15,7 +15,10 @@ namespace JS {
|
||||||
|
|
||||||
class StringOrSymbol {
|
class StringOrSymbol {
|
||||||
public:
|
public:
|
||||||
StringOrSymbol() = default;
|
StringOrSymbol()
|
||||||
|
: m_bits(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
StringOrSymbol(char const* chars)
|
StringOrSymbol(char const* chars)
|
||||||
: StringOrSymbol(DeprecatedFlyString(chars))
|
: StringOrSymbol(DeprecatedFlyString(chars))
|
||||||
|
@ -28,50 +31,53 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
StringOrSymbol(DeprecatedFlyString const& string)
|
StringOrSymbol(DeprecatedFlyString const& string)
|
||||||
: m_ptr(string.impl())
|
: m_string(string)
|
||||||
{
|
{
|
||||||
VERIFY(!string.is_null());
|
VERIFY(!string.is_null());
|
||||||
as_string_impl().ref();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
~StringOrSymbol()
|
~StringOrSymbol()
|
||||||
{
|
{
|
||||||
if (is_string())
|
if (is_string())
|
||||||
as_string_impl().unref();
|
m_string.~DeprecatedFlyString();
|
||||||
}
|
}
|
||||||
|
|
||||||
StringOrSymbol(Symbol const* symbol)
|
StringOrSymbol(Symbol const* symbol)
|
||||||
: m_ptr(symbol)
|
: m_symbol_with_tag(symbol)
|
||||||
{
|
{
|
||||||
set_symbol_flag();
|
set_symbol_flag();
|
||||||
}
|
}
|
||||||
|
|
||||||
StringOrSymbol(StringOrSymbol const& other)
|
StringOrSymbol(StringOrSymbol const& other)
|
||||||
{
|
{
|
||||||
m_ptr = other.m_ptr;
|
if (other.is_string())
|
||||||
if (is_string())
|
new (&m_string) DeprecatedFlyString(other.m_string);
|
||||||
as_string_impl().ref();
|
else
|
||||||
|
m_bits = other.m_bits;
|
||||||
}
|
}
|
||||||
|
|
||||||
StringOrSymbol(StringOrSymbol&& other)
|
StringOrSymbol(StringOrSymbol&& other)
|
||||||
{
|
{
|
||||||
m_ptr = exchange(other.m_ptr, nullptr);
|
if (other.is_string())
|
||||||
|
new (&m_string) DeprecatedFlyString(move(other.m_string));
|
||||||
|
else
|
||||||
|
m_bits = exchange(other.m_bits, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
ALWAYS_INLINE bool is_valid() const { return m_ptr != nullptr; }
|
ALWAYS_INLINE bool is_valid() const { return m_bits != 0; }
|
||||||
ALWAYS_INLINE bool is_symbol() const { return is_valid() && (bits() & 1ul); }
|
ALWAYS_INLINE bool is_symbol() const { return is_valid() && (m_bits & 2); }
|
||||||
ALWAYS_INLINE bool is_string() const { return is_valid() && !(bits() & 1ul); }
|
ALWAYS_INLINE bool is_string() const { return is_valid() && !(m_bits & 2); }
|
||||||
|
|
||||||
ALWAYS_INLINE DeprecatedFlyString as_string() const
|
ALWAYS_INLINE DeprecatedFlyString as_string() const
|
||||||
{
|
{
|
||||||
VERIFY(is_string());
|
VERIFY(is_string());
|
||||||
return DeprecatedFlyString::from_fly_impl(as_string_impl());
|
return m_string;
|
||||||
}
|
}
|
||||||
|
|
||||||
ALWAYS_INLINE Symbol const* as_symbol() const
|
ALWAYS_INLINE Symbol const* as_symbol() const
|
||||||
{
|
{
|
||||||
VERIFY(is_symbol());
|
VERIFY(is_symbol());
|
||||||
return reinterpret_cast<Symbol const*>(bits() & ~1ul);
|
return reinterpret_cast<Symbol const*>(m_bits & ~2ULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
ByteString to_display_string() const
|
ByteString to_display_string() const
|
||||||
|
@ -101,7 +107,7 @@ public:
|
||||||
ALWAYS_INLINE bool operator==(StringOrSymbol const& other) const
|
ALWAYS_INLINE bool operator==(StringOrSymbol const& other) const
|
||||||
{
|
{
|
||||||
if (is_string())
|
if (is_string())
|
||||||
return other.is_string() && &as_string_impl() == &other.as_string_impl();
|
return other.is_string() && m_string == other.m_string;
|
||||||
if (is_symbol())
|
if (is_symbol())
|
||||||
return other.is_symbol() && as_symbol() == other.as_symbol();
|
return other.is_symbol() && as_symbol() == other.as_symbol();
|
||||||
return true;
|
return true;
|
||||||
|
@ -109,47 +115,43 @@ public:
|
||||||
|
|
||||||
StringOrSymbol& operator=(StringOrSymbol const& other)
|
StringOrSymbol& operator=(StringOrSymbol const& other)
|
||||||
{
|
{
|
||||||
if (this == &other)
|
if (this != &other) {
|
||||||
return *this;
|
this->~StringOrSymbol();
|
||||||
m_ptr = other.m_ptr;
|
new (this) StringOrSymbol(other);
|
||||||
if (is_string())
|
}
|
||||||
as_string_impl().ref();
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
StringOrSymbol& operator=(StringOrSymbol&& other)
|
StringOrSymbol& operator=(StringOrSymbol&& other)
|
||||||
{
|
{
|
||||||
if (this != &other)
|
if (this != &other) {
|
||||||
m_ptr = exchange(other.m_ptr, nullptr);
|
this->~StringOrSymbol();
|
||||||
|
new (this) StringOrSymbol(move(other));
|
||||||
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned hash() const
|
unsigned hash() const
|
||||||
{
|
{
|
||||||
if (is_string())
|
if (is_string())
|
||||||
return as_string_impl().hash();
|
return m_string.hash();
|
||||||
return ptr_hash(as_symbol());
|
return ptr_hash(as_symbol());
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ALWAYS_INLINE u64 bits() const
|
|
||||||
{
|
|
||||||
return reinterpret_cast<uintptr_t>(m_ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
ALWAYS_INLINE void set_symbol_flag()
|
ALWAYS_INLINE void set_symbol_flag()
|
||||||
{
|
{
|
||||||
m_ptr = reinterpret_cast<void const*>(bits() | 1ul);
|
m_bits |= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
ALWAYS_INLINE StringImpl const& as_string_impl() const
|
union {
|
||||||
{
|
DeprecatedFlyString m_string;
|
||||||
VERIFY(is_string());
|
Symbol const* m_symbol_with_tag;
|
||||||
return *reinterpret_cast<StringImpl const*>(m_ptr);
|
uintptr_t m_bits;
|
||||||
}
|
|
||||||
|
|
||||||
void const* m_ptr { nullptr };
|
|
||||||
};
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
static_assert(sizeof(StringOrSymbol) == sizeof(uintptr_t));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue